Переглянути джерело

Merged revisions 9791,9804,9809 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

........
r9791 | daniel | 2008-01-19 14:50:58 +0100 (Sat, 19 Jan 2008) | 3 lines

* Labels that are defined or referenced in a different lexical level
than their declaration need to be code generated as global asmlabels.

........
r9804 | jonas | 2008-01-20 11:29:04 +0100 (Sun, 20 Jan 2008) | 2 lines

* fixed crash when compiling inlined procedures containing labels

........
r9809 | daniel | 2008-01-20 13:08:12 +0100 (Sun, 20 Jan 2008) | 2 lines

* Procedures containing a non-local label should not be inlined.

........

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

Jonas Maebe 17 роки тому
батько
коміт
8096106bcc
5 змінених файлів з 38 додано та 6 видалено
  1. 6 0
      compiler/aasmdata.pas
  2. 7 1
      compiler/ncgflw.pas
  3. 5 0
      compiler/pexpr.pas
  4. 12 3
      compiler/rautils.pas
  5. 8 2
      compiler/symsym.pas

+ 6 - 0
compiler/aasmdata.pas

@@ -135,6 +135,7 @@ interface
         { create new assembler label }
         procedure getlabel(out l : TAsmLabel;alt:TAsmLabeltype);
         procedure getjumplabel(out l : TAsmLabel);
+        procedure getglobaljumplabel(out l : TAsmLabel);
         procedure getaddrlabel(out l : TAsmLabel);
         procedure getdatalabel(out l : TAsmLabel);
         { generate an alternative (duplicate) symbol }
@@ -397,6 +398,11 @@ implementation
         inc(FNextLabelNr[alt_jump]);
       end;
 
+    procedure TAsmData.getglobaljumplabel(out l : TAsmLabel);
+      begin
+        l:=TAsmLabel.createglobal(AsmSymbolDict,name,FNextLabelNr[alt_jump],alt_jump);
+        inc(FNextLabelNr[alt_jump]);
+      end;
 
     procedure TAsmData.getdatalabel(out l : TAsmLabel);
       begin

+ 7 - 1
compiler/ncgflw.pas

@@ -850,7 +850,13 @@ implementation
     function tcglabelnode.getasmlabel : tasmlabel;
       begin
         if not(assigned(asmlabel)) then
-          current_asmdata.getjumplabel(asmlabel);
+          { labsym is not set in inlined procedures, but since assembler }
+          { routines can't be inlined, that shouldn't matter             }
+          if assigned(labsym) and
+             labsym.nonlocal then
+            current_asmdata.getglobaljumplabel(asmlabel)
+          else
+            current_asmdata.getjumplabel(asmlabel);
         result:=asmlabel
       end;
 

+ 5 - 0
compiler/pexpr.pas

@@ -1700,6 +1700,11 @@ implementation
                         consume(_COLON);
                         if tlabelsym(srsym).defined then
                           Message(sym_e_label_already_defined);
+                        if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
+                          begin
+                            tlabelsym(srsym).nonlocal:=true;
+                            exclude(current_procinfo.procdef.procoptions,po_inline);
+                          end;
                         tlabelsym(srsym).defined:=true;
                         p1:=clabelnode.create(nil,tlabelsym(srsym));
                         tlabelsym(srsym).code:=p1;

+ 12 - 3
compiler/rautils.pas

@@ -1419,13 +1419,22 @@ Begin
   case sym.typ of
     labelsym :
       begin
+        if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
+          begin
+            Tlabelsym(sym).nonlocal:=true;
+            if emit then
+              exclude(current_procinfo.procdef.procoptions,po_inline);
+          end;
         if not(assigned(tlabelsym(sym).asmblocklabel)) then
-          current_asmdata.getjumplabel(tlabelsym(sym).asmblocklabel);
+          if Tlabelsym(sym).nonlocal then
+            current_asmdata.getglobaljumplabel(tlabelsym(sym).asmblocklabel)
+          else
+            current_asmdata.getjumplabel(tlabelsym(sym).asmblocklabel);
         hl:=tlabelsym(sym).asmblocklabel;
         if emit then
-         tlabelsym(sym).defined:=true
+          tlabelsym(sym).defined:=true
         else
-         tlabelsym(sym).used:=true;
+          tlabelsym(sym).used:=true;
         SearchLabel:=true;
       end;
   end;

+ 8 - 2
compiler/symsym.pas

@@ -51,7 +51,8 @@ interface
 
        tlabelsym = class(tstoredsym)
           used,
-          defined : boolean;
+          defined,
+          nonlocal : boolean;
           { points to the matching node, only valid resultdef pass is run and
             the goto<->label relation in the node tree is created, should
             be a tnode }
@@ -390,6 +391,7 @@ implementation
          inherited create(labelsym,n);
          used:=false;
          defined:=false;
+         nonlocal:=false;
          code:=nil;
       end;
 
@@ -399,6 +401,7 @@ implementation
          inherited ppuload(labelsym,ppufile);
          code:=nil;
          used:=false;
+         nonlocal:=false;
          defined:=true;
       end;
 
@@ -420,7 +423,10 @@ implementation
        if not(defined) then
          begin
            defined:=true;
-           current_asmdata.getjumplabel(asmblocklabel);
+           if nonlocal then
+             current_asmdata.getglobaljumplabel(asmblocklabel)
+           else
+             current_asmdata.getjumplabel(asmblocklabel);
          end;
        result:=asmblocklabel.name;
      end;