Browse Source

* Bug fix that prevents downsizing of
"(x div y) and z" when "x div y" is 64-bit and
z is 32-bit or less. Fixes i39646

J. Gareth "Curious Kit" Moreton 3 years ago
parent
commit
54aae023ea
1 changed files with 15 additions and 4 deletions
  1. 15 4
      compiler/ncnv.pas

+ 15 - 4
compiler/ncnv.pas

@@ -2969,8 +2969,15 @@ implementation
 
                    (not(n.nodetype in [modn,divn]) or (not(gotminus1)))
                   ) or
-                  ((((n.nodetype=andn) and wasoriginallysmallerint(tbinarynode(n).left)) or
-                    ((n.nodetype=andn) and wasoriginallysmallerint(tbinarynode(n).right))));
+                  (
+                    (n.nodetype=andn) and
+                    (
+                      { Right node is more likely to be a constant, so check
+                        this one first }
+                      wasoriginallysmallerint(tbinarynode(n).right) or
+                      wasoriginallysmallerint(tbinarynode(n).left)
+                    )
+                  );
               end;
             else
               result:=false;
@@ -3001,9 +3008,13 @@ implementation
 
           dword1:=dword1+((dword2+dword3) shr 2);
 
-          while we can remove an extension on the addition, we cannot remove it from the shr
+          while we can remove an extension on the outermost addition, we cannot
+          remove it from the shr
         }
-        if (n.nodetype=shrn) and (level<>0) then
+        { Don't downsize into a division operation either, as the numerator can
+          be much larger than the result and non-linear properties prevent
+          accurate truncation; fixes #39646 [Kit] }
+        if (n.nodetype in [shrn,divn,modn]) and (level<>0) then
           begin
             inserttypeconv_internal(n,todef);
             exit;