Browse Source

* explicit typecasting of any ordinal type to a boolean of the same
size must happen without any mangling of the value (mantis #11027)
* moved checking for signed-to-unsigned (or vice versa) type
conversions in assignments from htypechk to ncnv (where there
was already code for similar checks) and added support for
bool_to_bool there as well

git-svn-id: trunk@10521 -

Jonas Maebe 17 years ago
parent
commit
62e66d2a56

+ 1 - 0
.gitattributes

@@ -8105,6 +8105,7 @@ tests/webtbs/tw10966.pp svneol=native#text/plain
 tests/webtbs/tw1097.pp svneol=native#text/plain
 tests/webtbs/tw10979.pp svneol=native#text/plain
 tests/webtbs/tw11006.pp svneol=native#text/plain
+tests/webtbs/tw11027.pp svneol=native#text/plain
 tests/webtbs/tw1103.pp svneol=native#text/plain
 tests/webtbs/tw1104.pp svneol=native#text/plain
 tests/webtbs/tw1111.pp svneol=native#text/plain

+ 3 - 6
compiler/arm/narmcnv.pas

@@ -190,14 +190,11 @@ implementation
          if codegenerror then
           exit;
 
-         { bytebool(byte) or wordbool(word) or longbool(longint) must }
-         { be accepted for var parameters, and must not change the    }
-         { the ordinal value                                          }
+         { Explicit typecasts from any ordinal type to a boolean type }
+         { must not change the ordinal value                          }
          if (nf_explicit in flags) and
             (left.resultdef.size=resultdef.size) and
-            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
-            is_cbool(resultdef) and
-            not is_pasbool(left.resultdef) then
+            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
            begin
               location_copy(location,left.location);
               location.size:=def_cgsize(resultdef);

+ 0 - 10
compiler/htypechk.pas

@@ -1068,16 +1068,6 @@ implementation
                         CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size));
                   end;
 
-                 { when typecasting to the same size but changing the signdness of
-                   an ordinal, the value cannot be in a register if it's < sizeof(aint).
-                   The reason is that a tc_int_2_int type conversion changing the sign
-                   of a such value in a register also has to modify this register (JM)   }
-                 if is_ordinal(fromdef) and is_ordinal(todef) and
-                    (fromdef.size=todef.size) and
-                    (fromdef.size<sizeof(aint)) and
-                    (is_signed(fromdef) xor is_signed(todef)) then
-                   make_not_regable(hp,[ra_addr_regable]);
-
                  { don't allow assignments to typeconvs that need special code }
                  if not(gotsubscript or gotvec or gotderef) and
                     not(ttypeconvnode(hp).assign_allowed) then

+ 3 - 6
compiler/m68k/n68kcnv.pas

@@ -164,14 +164,11 @@ implementation
 
 {$warning needs LOC_JUMP support, because called for bool_to_bool from ncgcnv }
 
-         { bytebool(byte) or wordbool(word) or longbool(longint) must }
-         { be accepted for var parameters, and must not change the    }
-         { the ordinal value                                          }
+         { Explicit typecasts from any ordinal type to a boolean type }
+         { must not change the ordinal value                          }
          if (nf_explicit in flags) and
             (left.resultdef.size=resultdef.size) and
-            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
-            is_cbool(resultdef) and
-            not is_pasbool(left.resultdef) then
+            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
            begin
               location_copy(location,left.location);
               location.size:=def_cgsize(resultdef);

+ 7 - 2
compiler/ncnv.pas

@@ -2923,13 +2923,18 @@ implementation
                  )
                 ) or
                 { int 2 bool/bool 2 int, explicit typecast, see also nx86cnv }
-                ((convtype in [tc_int_2_bool,tc_bool_2_int]) and
+                ((convtype in [tc_int_2_bool,tc_bool_2_int,tc_bool_2_bool]) and
                  (nf_explicit in flags) and
                  (resultdef.size=left.resultdef.size));
 
         { When using only a part of the value it can't be in a register since
           that will load the value in a new register first }
-        if (resultdef.size<left.resultdef.size) then
+        { the same goes for changing the sign of equal-sized values which
+          are smaller than an entire register }
+        if (resultdef.size<left.resultdef.size) or
+           ((resultdef.size=left.resultdef.size) and
+            (left.resultdef.size<sizeof(aint)) and
+            (is_signed(resultdef) xor is_signed(left.resultdef))) then
           make_not_regable(left,[ra_addr_regable]);
       end;
 

+ 3 - 6
compiler/ppcgen/ngppccnv.pas

@@ -85,14 +85,11 @@ implementation
          if codegenerror then
           exit;
 
-         { bytebool(byte) or wordbool(word) or longbool(longint) must }
-         { be accepted for var parameters, and must not change the    }
-         { the ordinal value                                          }
+         { Explicit typecasts from any ordinal type to a boolean type }
+         { must not change the ordinal value                          }
          if (nf_explicit in flags) and
             (left.resultdef.size=resultdef.size) and
-            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
-            is_cbool(resultdef) and
-            not is_pasbool(left.resultdef) then
+            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
            begin
               location_copy(location,left.location);
               location.size:=def_cgsize(resultdef);

+ 3 - 6
compiler/sparc/ncpucnv.pas

@@ -233,14 +233,11 @@ implementation
         if codegenerror then
           exit;
 
-         { bytebool(byte) or wordbool(word) or longbool(longint) must }
-         { be accepted for var parameters, and must not change the    }
-         { the ordinal value                                          }
+         { Explicit typecasts from any ordinal type to a boolean type }
+         { must not change the ordinal value                          }
          if (nf_explicit in flags) and
             (left.resultdef.size=resultdef.size) and
-            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
-            is_cbool(resultdef) and
-            not is_pasbool(left.resultdef) then
+            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
            begin
               location_copy(location,left.location);
               location.size:=def_cgsize(resultdef);

+ 3 - 6
compiler/x86/nx86cnv.pas

@@ -102,14 +102,11 @@ implementation
          secondpass(left);
          if codegenerror then
           exit;
-         { bytebool(byte) or wordbool(word) or longbool(longint) must }
-         { be accepted for var parameters, and must not change the    }
-         { the ordinal value                                          }
+         { Explicit typecasts from any ordinal type to a boolean type }
+         { must not change the ordinal value                          }
          if (nf_explicit in flags) and
             (left.resultdef.size=resultdef.size) and
-            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) and
-            is_cbool(resultdef) and
-            not is_pasbool(left.resultdef) then
+            not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
            begin
               location_copy(location,left.location);
               location.size:=def_cgsize(resultdef);

+ 10 - 0
tests/webtbs/tw11027.pp

@@ -0,0 +1,10 @@
+var i : char;
+    bb: bytebool;
+begin
+  boolean(i) := (1=1);
+  if not boolean(i) then
+    halt(1);
+  boolean(bb):=boolean(i); 
+  if not(bb) then
+    halt(2);
+end.