Pārlūkot izejas kodu

* convert LOC_FLAGS/LOC_JUMP to cbool value in bool_to_bool conversion,
otherwise it stays 0/1 instead of becoming 0/-1 (mantis #17180)

git-svn-id: trunk@15830 -

Jonas Maebe 15 gadi atpakaļ
vecāks
revīzija
97f9157a7a
3 mainītis faili ar 91 papildinājumiem un 13 dzēšanām
  1. 1 0
      .gitattributes
  2. 14 13
      compiler/ncgcnv.pas
  3. 76 0
      tests/webtbs/tw17180.pp

+ 1 - 0
.gitattributes

@@ -10607,6 +10607,7 @@ tests/webtbs/tw1696.pp svneol=native#text/plain
 tests/webtbs/tw1699.pp svneol=native#text/plain
 tests/webtbs/tw1709.pp svneol=native#text/plain
 tests/webtbs/tw17118.pp svneol=native#text/plain
+tests/webtbs/tw17180.pp svneol=native#text/plain
 tests/webtbs/tw1720.pp svneol=native#text/plain
 tests/webtbs/tw1735.pp svneol=native#text/plain
 tests/webtbs/tw1737.pp svneol=native#text/plain

+ 14 - 13
compiler/ncgcnv.pas

@@ -452,24 +452,25 @@ interface
           the bits that define the true status can be outside the limits
           of the new size and truncating the register can result in a 0
           value }
-        if (left.expectloc in [LOC_FLAGS,LOC_JUMP]) then
+        if (left.expectloc in [LOC_FLAGS,LOC_JUMP]) and
+           { a cbool must be converted to -1/0 }
+           not is_cbool(resultdef) then
           begin
             secondpass(left);
             if (left.location.loc <> left.expectloc) then
-              internalerror(20060409);
+              internalerror(2010081601);
             location_copy(location,left.location);
           end
-         else if (resultdef.size=left.resultdef.size) and
-                 not(is_cbool(resultdef) xor
-                     is_cbool(left.resultdef)) then
-           second_bool_to_int
-         else
-           begin
-             if (resultdef.size<>left.resultdef.size) then
-               { remove nf_explicit to perform full conversion if boolean sizes are different }
-               exclude(flags, nf_explicit);
-             second_int_to_bool;
-           end;
+        else if (resultdef.size=left.resultdef.size) and
+           (is_cbool(resultdef)=is_cbool(left.resultdef)) then
+          second_bool_to_int
+        else
+          begin
+            if (resultdef.size<>left.resultdef.size) then
+              { remove nf_explicit to perform full conversion if boolean sizes are different }
+              exclude(flags, nf_explicit);
+            second_int_to_bool;
+          end;
       end;
 
 

+ 76 - 0
tests/webtbs/tw17180.pp

@@ -0,0 +1,76 @@
+program testbug;
+{$APPTYPE CONSOLE}
+{$ifdef fpc}
+ {$mode delphi}
+ {$ifdef cpui386}
+  {$define cpu386}
+ {$endif}
+ {$ifdef cpu386}
+  {$asmmode intel}
+ {$endif}
+ {$ifdef FPC_LITTLE_ENDIAN}
+  {$define LITTLE_ENDIAN}
+ {$else}
+  {$ifdef FPC_BIG_ENDIAN}
+   {$define BIG_ENDIAN}
+  {$endif}
+ {$endif}
+ {$define caninline}
+{$else}
+ {$define LITTLE_ENDIAN}
+ {$ifndef cpu64}
+  {$define cpu32}
+ {$endif}
+{$endif}
+{$ifdef win32}
+ {$define windows}
+{$endif}
+{$ifdef win64}
+ {$define windows}
+{$endif}
+{$ifdef wince}
+ {$define windows}
+{$endif}
+{$rangechecks off}
+{$extendedsyntax on}
+{$hints off}
+{$rangechecks off}
+{$extendedsyntax on}
+{$writeableconst on}
+{$hints off}
+{$booleval off}
+{$typedaddress off}
+{$stackframes off}
+{$varstringchecks on}
+{$typeinfo on}
+{$overflowchecks off}
+{$longstrings on}
+{$openstrings on}
+{$j+}
+{$define UseRegister}
+
+type TBla=(b0,b1,b2,b3,b4,b5);
+
+     TBlas=set of TBla;
+     
+var b,ba:longbool;
+    Blas:TBlas;
+    
+function BlaFunc(ABool:longbool):longbool;
+begin
+ result:=ABool;
+end;
+
+begin
+
+ Blas:=[b1,b2,b3];
+ b:=BlaFunc(b1 in Blas);
+ ba:=true;
+ writeln(b);
+ writeln(longword(pointer(@b)^));
+ if longword(pointer(@b)^)<>longword(pointer(@ba)^) then
+   halt(1);
+ if b<>ba then
+   halt(1);
+end.
+