Explorar o código

* don't narrow expressions that contain a mod/div followed by an "and",
since the mod/div get a different result if calculated using fewer
bits (mantis #29930)

git-svn-id: trunk@33413 -

Jonas Maebe %!s(int64=9) %!d(string=hai) anos
pai
achega
1e1b36515e
Modificáronse 3 ficheiros con 25 adicións e 2 borrados
  1. 1 0
      .gitattributes
  2. 5 2
      compiler/ncnv.pas
  3. 19 0
      tests/webtbs/tw29930.pp

+ 1 - 0
.gitattributes

@@ -14996,6 +14996,7 @@ tests/webtbs/tw2984.pp svneol=native#text/plain
 tests/webtbs/tw29893.pp svneol=native#text/pascal
 tests/webtbs/tw29912.pp svneol=native#text/plain
 tests/webtbs/tw29923.pp svneol=native#text/plain
+tests/webtbs/tw29930.pp svneol=native#text/plain
 tests/webtbs/tw2998.pp svneol=native#text/plain
 tests/webtbs/tw2999.pp svneol=native#text/plain
 tests/webtbs/tw3004.pp svneol=native#text/plain

+ 5 - 2
compiler/ncnv.pas

@@ -2563,8 +2563,11 @@ implementation
                 result:=
                   (docheckremoveinttypeconvs(tbinarynode(n).left) and
                    docheckremoveinttypeconvs(tbinarynode(n).right)) or
-                  ((n.nodetype=andn) and wasoriginallysmallerint(tbinarynode(n).left)) or
-                  ((n.nodetype=andn) and wasoriginallysmallerint(tbinarynode(n).right));
+                  { in case of div/mod, the result of that division/modulo can
+                    usually be different in 32 and 64 bit }
+                  (not gotdivmod and
+                   (((n.nodetype=andn) and wasoriginallysmallerint(tbinarynode(n).left)) or
+                    ((n.nodetype=andn) and wasoriginallysmallerint(tbinarynode(n).right))));
               end;
           end;
         end;

+ 19 - 0
tests/webtbs/tw29930.pp

@@ -0,0 +1,19 @@
+program and_problem;
+{$mode objfpc}{$H+}
+
+var
+  a : extended;
+  d : longint;
+begin
+  a := -1;
+  d := (round(a*512) div 180) and 1023;
+  writeln(d);
+  if d<>1022 then
+    halt(1);
+
+  d := (round(a*512) div 180);
+  while (d<0) do d := d+1024;
+  writeln(d);
+  if d<>1022 then
+    halt(1);
+end.