소스 검색

* Some fixes for r8515:
* fixed set add-nodes in case left and right are swapped (taddset4)
* fixed "in" expressions with packed sets in case left is < setbase
(now tested by tw8258b, which was missing a {$packset 1} directive)

git-svn-id: trunk@8519 -

Jonas Maebe 18 년 전
부모
커밋
89ed91509a
9개의 변경된 파일62개의 추가작업 그리고 17개의 파일을 삭제
  1. 1 0
      .gitattributes
  2. 4 1
      compiler/ncgadd.pas
  3. 8 5
      compiler/ncgset.pas
  4. 2 2
      compiler/nset.pas
  5. 4 1
      compiler/ppcgen/ngppcadd.pas
  6. 4 1
      compiler/x86/nx86add.pas
  7. 9 7
      compiler/x86/nx86set.pas
  8. 29 0
      tests/test/cg/taddset4.pp
  9. 1 0
      tests/webtbs/tw8258b.pp

+ 1 - 0
.gitattributes

@@ -6499,6 +6499,7 @@ tests/test/cg/taddreal2.pp svneol=native#text/plain
 tests/test/cg/taddset.pp svneol=native#text/plain
 tests/test/cg/taddset.pp svneol=native#text/plain
 tests/test/cg/taddset2.pp svneol=native#text/plain
 tests/test/cg/taddset2.pp svneol=native#text/plain
 tests/test/cg/taddset3.pp svneol=native#text/plain
 tests/test/cg/taddset3.pp svneol=native#text/plain
+tests/test/cg/taddset4.pp svneol=native#text/plain
 tests/test/cg/tadint64.pp svneol=native#text/plain
 tests/test/cg/tadint64.pp svneol=native#text/plain
 tests/test/cg/tassign1.pp svneol=native#text/plain
 tests/test/cg/tassign1.pp svneol=native#text/plain
 tests/test/cg/tassign2.pp svneol=native#text/plain
 tests/test/cg/tassign2.pp svneol=native#text/plain

+ 4 - 1
compiler/ncgadd.pas

@@ -269,7 +269,10 @@ interface
           location_force_reg(current_asmdata.CurrAsmList,left.location,left.location.size,false);
           location_force_reg(current_asmdata.CurrAsmList,left.location,left.location.size,false);
 
 
         set_result_location_reg;
         set_result_location_reg;
-        setbase:=tsetdef(left.resultdef).setbase;
+        if (left.resultdef.typ=setdef) then
+          setbase:=tsetdef(left.resultdef).setbase
+        else
+          setbase:=tsetdef(right.resultdef).setbase;
 
 
         case nodetype of
         case nodetype of
           addn :
           addn :

+ 8 - 5
compiler/ncgset.pas

@@ -418,17 +418,22 @@ implementation
                else
                else
                 begin
                 begin
                   location_force_reg(current_asmdata.CurrAsmList, left.location, opsize, true);
                   location_force_reg(current_asmdata.CurrAsmList, left.location, opsize, true);
+                  register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
                   pleftreg := left.location.register;
                   pleftreg := left.location.register;
 
 
                   if (opsize >= OS_S8) or { = if signed }
                   if (opsize >= OS_S8) or { = if signed }
-                     ((left.resultdef.typ=orddef)  and (torddef(left.resultdef).high > tsetdef(right.resultdef).setmax)) or
-                     ((left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax)) then
+                     ((left.resultdef.typ=orddef) and 
+                      ((torddef(left.resultdef).low < int64(tsetdef(right.resultdef).setbase)) or
+                       (torddef(left.resultdef).high > int64(tsetdef(right.resultdef).setmax)))) or
+                     ((left.resultdef.typ=enumdef) and
+                      ((tenumdef(left.resultdef).min < tsetdef(right.resultdef).setbase) or
+                       (tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax))) then
                     begin
                     begin
                       current_asmdata.getjumplabel(l);
                       current_asmdata.getjumplabel(l);
                       current_asmdata.getjumplabel(l2);
                       current_asmdata.getjumplabel(l2);
                       needslabel := True;
                       needslabel := True;
 
 
-                      cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, left.location.size, OC_BE, tsetdef(right.resultdef).setmax, pleftreg, l);
+                      cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList, left.location.size, OC_BE, tsetdef(right.resultdef).setmax-tsetdef(right.resultdef).setbase, pleftreg, l);
 
 
                       cg.a_load_const_reg(current_asmdata.CurrAsmList, location.size, 0, location.register);
                       cg.a_load_const_reg(current_asmdata.CurrAsmList, location.size, 0, location.register);
                       cg.a_jmp_always(current_asmdata.CurrAsmList, l2);
                       cg.a_jmp_always(current_asmdata.CurrAsmList, l2);
@@ -436,8 +441,6 @@ implementation
                       cg.a_label(current_asmdata.CurrAsmList, l);
                       cg.a_label(current_asmdata.CurrAsmList, l);
                     end;
                     end;
 
 
-                  register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
-                  pleftreg:=left.location.register;
                   cg.a_bit_test_reg_loc_reg(current_asmdata.CurrAsmList,left.location.size,location.size,
                   cg.a_bit_test_reg_loc_reg(current_asmdata.CurrAsmList,left.location.size,location.size,
                     pleftreg,right.location,location.register);
                     pleftreg,right.location,location.register);
 
 

+ 2 - 2
compiler/nset.pas

@@ -313,8 +313,8 @@ implementation
                end
                end
              else
              else
                begin
                begin
-                 if (Tordconstnode(left).value.signed and (Tordconstnode(left).value<0)) or
-                    (Tordconstnode(left).value.uvalue>Tsetdef(right.resultdef).setmax) then
+                 if (Tordconstnode(left).value<int64(tsetdef(right.resultdef).setbase)) or
+                    (Tordconstnode(left).value>int64(Tsetdef(right.resultdef).setmax)) then
                    begin
                    begin
                      t:=cordconstnode.create(0, booltype, true);
                      t:=cordconstnode.create(0, booltype, true);
                      typecheckpass(t);
                      typecheckpass(t);

+ 4 - 1
compiler/ppcgen/ngppcadd.pas

@@ -404,7 +404,10 @@ implementation
         if not(cmpop) then
         if not(cmpop) then
           location.register := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
           location.register := cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
 
 
-        setbase:=tsetdef(left.resultdef).setbase;
+        if (left.resultdef.typ=setdef) then
+          setbase:=tsetdef(left.resultdef).setbase
+        else
+          setbase:=tsetdef(right.resultdef).setbase;
         case nodetype of
         case nodetype of
           addn :
           addn :
             begin
             begin

+ 4 - 1
compiler/x86/nx86add.pas

@@ -350,7 +350,10 @@ unit nx86add;
         extra_not:=false;
         extra_not:=false;
         all_member_optimization:=false;
         all_member_optimization:=false;
         opsize:=int_cgsize(resultdef.size);
         opsize:=int_cgsize(resultdef.size);
-        setbase:=tsetdef(left.resultdef).setbase;
+        if (left.resultdef.typ=setdef) then
+          setbase:=tsetdef(left.resultdef).setbase
+        else
+          setbase:=tsetdef(right.resultdef).setbase;
         case nodetype of
         case nodetype of
           addn :
           addn :
             begin
             begin

+ 9 - 7
compiler/x86/nx86set.pas

@@ -39,7 +39,7 @@ interface
 implementation
 implementation
 
 
     uses
     uses
-      globtype,systems,
+      globtype,systems,constexp,
       verbose,globals,
       verbose,globals,
       symconst,symdef,defutil,
       symconst,symdef,defutil,
       aasmbase,aasmtai,aasmdata,aasmcpu,
       aasmbase,aasmtai,aasmdata,aasmcpu,
@@ -413,11 +413,16 @@ implementation
                else
                else
                 begin
                 begin
                   location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,false);
                   location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,false);
+                    register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
                   pleftreg:=left.location.register;
                   pleftreg:=left.location.register;
 
 
                   if (opsize >= OS_S8) or { = if signed }
                   if (opsize >= OS_S8) or { = if signed }
-                    ((left.resultdef.typ=orddef)  and (torddef(left.resultdef).high.svalue > tsetdef(right.resultdef).setmax)) or
-                    ((left.resultdef.typ=enumdef) and (tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax)) then
+                     ((left.resultdef.typ=orddef) and 
+                      ((torddef(left.resultdef).low < int64(tsetdef(right.resultdef).setbase)) or
+                       (torddef(left.resultdef).high > int64(tsetdef(right.resultdef).setmax)))) or
+                     ((left.resultdef.typ=enumdef) and
+                      ((tenumdef(left.resultdef).min < tsetdef(right.resultdef).setbase) or
+                       (tenumdef(left.resultdef).max > tsetdef(right.resultdef).setmax))) then
                    begin
                    begin
 
 
                     { we have to check if the value is < 0 or > setmax }
                     { we have to check if the value is < 0 or > setmax }
@@ -426,14 +431,13 @@ implementation
                     current_asmdata.getjumplabel(l2);
                     current_asmdata.getjumplabel(l2);
 
 
                     { BE will be false for negative values }
                     { BE will be false for negative values }
-                    cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_BE,tsetdef(right.resultdef).setmax,pleftreg,l);
+                    cg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,opsize,OC_BE,tsetdef(right.resultdef).setmax-tsetdef(right.resultdef).setbase,pleftreg,l);
                     { reset carry flag }
                     { reset carry flag }
                     current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO));
                     current_asmdata.CurrAsmList.concat(taicpu.op_none(A_CLC,S_NO));
                     cg.a_jmp_always(current_asmdata.CurrAsmList,l2);
                     cg.a_jmp_always(current_asmdata.CurrAsmList,l2);
 
 
                     cg.a_label(current_asmdata.CurrAsmList,l);
                     cg.a_label(current_asmdata.CurrAsmList,l);
 
 
-                    register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
                     pleftreg:=left.location.register;
                     pleftreg:=left.location.register;
                     case right.location.loc of
                     case right.location.loc of
                       LOC_REGISTER, LOC_CREGISTER :
                       LOC_REGISTER, LOC_CREGISTER :
@@ -451,8 +455,6 @@ implementation
                    end
                    end
                   else
                   else
                    begin
                    begin
-                      register_maybe_adjust_setbase(current_asmdata.CurrAsmList,left.location,setbase);
-                      pleftreg:=left.location.register;
                       case right.location.loc of
                       case right.location.loc of
                         LOC_REGISTER, LOC_CREGISTER :
                         LOC_REGISTER, LOC_CREGISTER :
                           emit_reg_reg(A_BT,S_L,pleftreg,right.location.register);
                           emit_reg_reg(A_BT,S_L,pleftreg,right.location.register);

+ 29 - 0
tests/test/cg/taddset4.pp

@@ -0,0 +1,29 @@
+type
+  TCompilerIntfFlag = (ifHasGuid,ifDispInterface,ifDispatch,ifHasStrGUID);
+  TCompilerIntfFlags = set of TCompilerIntfFlag;
+
+procedure t(l: longint);
+begin
+  writeln(hexstr(l,8));
+  { exactly 3 bits must be set }
+  l:=l and (l-1);
+  if (l = 0) then
+    halt(1);
+  l:=l and (l-1);
+  if (l = 0) then
+    halt(2);
+  l:=l and (l-1);
+  if (l <> 0) then
+    halt(3);
+end;
+
+var
+  b:boolean;
+begin
+  b:=true;
+  t(longint([
+      TCompilerIntfFlag(ord(ifHasGuid)*ord(b)),
+      TCompilerIntfFlag(ord(ifHasStrGUID)*ord(b)),
+      TCompilerIntfFlag(ord(ifDispInterface)*ord(b))
+    ]));
+end.

+ 1 - 0
tests/webtbs/tw8258b.pp

@@ -4,6 +4,7 @@ program SetTests;
 
 
 {$IFDEF FPC}
 {$IFDEF FPC}
   {$mode delphi}
   {$mode delphi}
+  {$packset 1}
 {$ENDIF}
 {$ENDIF}
 
 
 {$R+}
 {$R+}