Pārlūkot izejas kodu

Merged revisions 7505,7510,7512,7516 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r7505 | peter | 2007-05-28 21:12:12 +0200 (Mon, 28 May 2007) | 2 lines

* check register type to not mixup sse registers

........
r7510 | jonas | 2007-05-29 13:12:37 +0200 (Tue, 29 May 2007) | 3 lines

* another check for register types (should fix new failure
of webtbs/tw7161)

........
r7512 | jonas | 2007-05-29 15:42:49 +0200 (Tue, 29 May 2007) | 11 lines

* mark invisible high parameters of open arrays/arrays of const
of parent procedures which are implicitly accessed from within
nested procedures for range checking purposes as non-regable in
the resulttype pass of the nested procedure (as opposed to in its
pass1/pass2, because by then the regvar assignment of the parent
procedure is already finished) (mantis #8975)
* related fix regarding checking whether the high parameter actually
exists (must check calling convention of the procedure to which the
high parameter belongs, which is not the same as checking that of
the current procedure in case of nested procedures)

........
r7516 | jonas | 2007-05-29 18:53:28 +0200 (Tue, 29 May 2007) | 3 lines

* only check validity of assembler instructions in pass_2, after all
local operands have been resolved (mantis #8950)

........

git-svn-id: branches/fixes_2_2@7527 -

Jonas Maebe 18 gadi atpakaļ
vecāks
revīzija
9b6ca90aae

+ 2 - 1
compiler/i386/csopt386.pas

@@ -85,7 +85,8 @@ begin
       if p.oper[1]^.typ = top_ref then
         for regCounter := RS_EAX to RS_EDI do
           begin
-            if p.oper[0]^.typ<>top_reg then
+            if (p.oper[0]^.typ<>top_reg) or
+               (getregtype(p.oper[0]^.reg) <> R_INTREGISTER) then
                break;
             if writeToMemDestroysContents(getsupreg(p.oper[0]^.reg),p.oper[1]^.ref^,
                  regCounter,topsize2tcgsize[p.opsize],c[regCounter],dummy) then

+ 3 - 0
compiler/i386/daopt386.pas

@@ -1265,6 +1265,7 @@ begin
     begin
       p := tai(p.previous);
       if (p.typ = ait_regalloc) and
+         (getregtype(tai_regalloc(p).reg) = R_INTREGISTER) and
          (getsupreg(tai_regalloc(p).reg) = supreg) then
         if (tai_regalloc(p).ratype=ra_dealloc) then
           if first then
@@ -1901,6 +1902,7 @@ begin
   case op.typ of
     top_reg:
       writeDestroysContents :=
+        (getregtype(op.reg) = R_INTREGISTER) and
         writeToRegDestroysContents(getsupreg(op.reg),supreg,c);
     top_ref:
       writeDestroysContents :=
@@ -2097,6 +2099,7 @@ begin
             labeltable^[tai_label(p).labsym.labelnr-lolab].taiobj := p;
 {$ifdef i386}
         ait_regalloc:
+         if (getregtype(tai_regalloc(p).reg) = R_INTREGISTER) then
           begin
             supreg:=getsupreg(tai_regalloc(p).reg);
             case tai_regalloc(p).ratype of

+ 11 - 1
compiler/ncgbas.pas

@@ -268,8 +268,13 @@ interface
                              end;
                            end;
                         end;
+{$ifdef x86}
+                        { can only be checked now that all local operands }
+                        { have been resolved                              }
+                        taicpu(hp2).CheckIfValid;
+{$endif x86}
                      end;
-                   ait_marker :
+                  ait_marker :
                      begin
                      { it's not an assembler block anymore }
                        if (tai_marker(hp2).kind in [mark_AsmBlockStart, mark_AsmBlockEnd]) then
@@ -303,6 +308,11 @@ interface
                        { fixup the references }
                        for i:=1 to taicpu(hp).ops do
                          ResolveRef(taicpu(hp).oper[i-1]^);
+{$ifdef x86}
+                      { can only be checked now that all local operands }
+                      { have been resolved                              }
+                      taicpu(hp).CheckIfValid;
+{$endif x86}
                      end;
                 end;
                 hp:=tai(hp.next);

+ 2 - 1
compiler/ncgmem.pas

@@ -543,7 +543,8 @@ implementation
             is_array_of_const(left.resultdef) then
           begin
             { cdecl functions don't have high() so we can not check the range }
-            if not(current_procinfo.procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
+            { (can't use current_procdef, since it may be a nested procedure) }
+            if not(tprocdef(tparasymtable(tparavarsym(tloadnode(left).symtableentry).owner).defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]) then
              begin
                { Get high value }
                hightree:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry));

+ 27 - 0
compiler/nmem.pas

@@ -677,6 +677,7 @@ implementation
 
     function tvecnode.pass_typecheck:tnode;
       var
+         hightree: tnode;
          htype,elementdef : tdef;
          valid : boolean;
       begin
@@ -739,6 +740,31 @@ implementation
                  resultdef:=left.resultdef
                else
                  resultdef:=Tarraydef(left.resultdef).elementdef;
+
+               { if we are range checking an open array or array of const, we }
+               { need to load the high parameter. If the current procedure is }
+               { nested inside the procedure to which the open array/of const }
+               { was passed, then the high parameter must not be a regvar.    }
+               { So create a loadnode for the high parameter here and         }
+               { typecheck it, then the loadnode will make the high parameter }
+               { not regable. Otherwise this would only happen inside pass_2, }
+               { which is too late since by then the regvars are already      }
+               { assigned (pass_1 is also already too late, because then the  }
+               { regvars of the parent are also already assigned).            }
+               { webtbs/tw8975                                                }
+               if (cs_check_range in current_settings.localswitches) and
+                  (is_open_array(left.resultdef) or
+                   is_array_of_const(left.resultdef)) and
+                  { cdecl functions don't have high() so we can not check the range }
+                  { (can't use current_procdef, since it may be a nested procedure) }
+                  not(tprocdef(tparasymtable(tparavarsym(tloadnode(left).symtableentry).owner).defowner).proccalloption in [pocall_cdecl,pocall_cppdecl]) then
+                   begin
+                     { load_high_value_node already typechecks }
+                     hightree:=load_high_value_node(tparavarsym(tloadnode(left).symtableentry));
+                     hightree.free;
+                   end;
+      
+      
              end;
            pointerdef :
              begin
@@ -874,6 +900,7 @@ implementation
                 registersint:=max(registersint,1);
               }
            end;
+
          registersfpu:=max(left.registersfpu,right.registersfpu);
 {$ifdef SUPPORT_MMX}
          registersmmx:=max(left.registersmmx,right.registersmmx);

+ 1 - 5
compiler/x86/rax86.pas

@@ -744,11 +744,7 @@ begin
 
  { Concat the opcode or give an error }
   if assigned(ai) then
-   begin
-     { Check the instruction if it's valid }
-     ai.CheckIfValid;
-     p.concat(ai);
-   end
+    p.concat(ai)
   else
    Message(asmr_e_invalid_opcode_and_operand);
   result:=ai;