Browse Source

* fixed evaluation of "mod" operator for tconstexprint with signed operands
(part of mantis #15453)

git-svn-id: trunk@14516 -

Jonas Maebe 15 years ago
parent
commit
04606982ac
3 changed files with 33 additions and 7 deletions
  1. 1 0
      .gitattributes
  2. 20 7
      compiler/constexp.pas
  3. 12 0
      tests/webtbs/tw15453a.pp

+ 1 - 0
.gitattributes

@@ -10166,6 +10166,7 @@ tests/webtbs/tw15377.pp svneol=native#text/pascal
 tests/webtbs/tw1539.pp svneol=native#text/plain
 tests/webtbs/tw15391.pp svneol=native#text/plain
 tests/webtbs/tw15415.pp svneol=native#text/plain
+tests/webtbs/tw15453a.pp svneol=native#text/plain
 tests/webtbs/tw1567.pp svneol=native#text/plain
 tests/webtbs/tw1573.pp svneol=native#text/plain
 tests/webtbs/tw1592.pp svneol=native#text/plain

+ 20 - 7
compiler/constexp.pas

@@ -380,7 +380,8 @@ end;
 
 operator mod (const a,b:Tconstexprint):Tconstexprint;
 
-var aa,bb:qword;
+var aa,bb,r:qword;
+    sa,sb:boolean;
 
 begin
   if a.overflow or b.overflow then
@@ -389,20 +390,32 @@ begin
       exit;
     end;
   result.overflow:=false;
-  if a.signed then
-    aa:=qword(a.svalue)
+  sa:=a.signed and (a.svalue<0);
+  if sa then
+    {$Q-}
+    aa:=qword(-a.svalue)
+    {$ifdef ena_q}{$Q+}{$endif}
   else
     aa:=a.uvalue;
-  if b.signed then
-    bb:=qword(b.svalue)
+  sb:=b.signed and (b.svalue<0);
+  if sb then
+    {$Q-}
+    bb:=qword(-b.svalue)
+    {$ifdef ena_q}{$Q+}{$endif}
   else
     bb:=b.uvalue;
   if bb=0 then
     result.overflow:=true
   else
     begin
-      result.signed:=false;
-      result.uvalue:=aa mod bb;
+      { the sign of a modulo operation only depends on the sign of the
+        dividend }
+      r:=aa mod bb;
+      result.signed:=sa;
+      if not sa then
+        result.uvalue:=r
+      else
+        result.svalue:=-int64(r);
     end;
 end;
 

+ 12 - 0
tests/webtbs/tw15453a.pp

@@ -0,0 +1,12 @@
+uses Math;
+
+var
+  Result, Remainder: SmallInt;
+begin
+  Result := -9 div 5;
+  Remainder := -9 mod 5;
+  writeln(result,' - ',remainder);
+  if (result<>-1) or
+     (remainder<>-4) then
+    halt(1);
+end.