Răsfoiți Sursa

* fixed several places where the interface crc could change:
o unsetting po_inline while parsing the implementation for various reasons
(interprocedural goto/label, accessing a local in a parent frame,
having nested procedures)
o instead handle this via the pio_inline_not_possible flag
o noreturn can no longer be specified only in the implementation

git-svn-id: trunk@40789 -

Jonas Maebe 6 ani în urmă
părinte
comite
51e68eb302

+ 0 - 7
compiler/nflw.pas

@@ -1969,7 +1969,6 @@ implementation
                     if assigned(labelsym.jumpbuf) then
                     if assigned(labelsym.jumpbuf) then
                       begin
                       begin
                         labelsym.nonlocal:=true;
                         labelsym.nonlocal:=true;
-                        exclude(current_procinfo.procdef.procoptions,po_inline);
                         result:=ccallnode.createintern('fpc_longjmp',
                         result:=ccallnode.createintern('fpc_longjmp',
                           ccallparanode.create(cordconstnode.create(1,sinttype,true),
                           ccallparanode.create(cordconstnode.create(1,sinttype,true),
                           ccallparanode.create(cloadnode.create(labelsym.jumpbuf,labelsym.jumpbuf.owner),
                           ccallparanode.create(cloadnode.create(labelsym.jumpbuf,labelsym.jumpbuf.owner),
@@ -2104,12 +2103,6 @@ implementation
 
 
         include(current_procinfo.flags,pi_has_label);
         include(current_procinfo.flags,pi_has_label);
 
 
-        if assigned(labsym) and labsym.nonlocal then
-          begin
-            include(current_procinfo.flags,pi_has_interproclabel);
-            exclude(current_procinfo.procdef.procoptions,po_inline);
-          end;
-
         if assigned(left) then
         if assigned(left) then
           firstpass(left);
           firstpass(left);
         if (m_non_local_goto in current_settings.modeswitches) and
         if (m_non_local_goto in current_settings.modeswitches) and

+ 1 - 1
compiler/nld.pas

@@ -332,7 +332,7 @@ implementation
                      internalerror(200309289);
                      internalerror(200309289);
                    left:=cloadparentfpnode.create(tprocdef(symtable.defowner),lpf_forload);
                    left:=cloadparentfpnode.create(tprocdef(symtable.defowner),lpf_forload);
                    { we can't inline the referenced parent procedure }
                    { we can't inline the referenced parent procedure }
-                   exclude(tprocdef(symtable.defowner).procoptions,po_inline);
+                   include(tprocdef(symtable.defowner).implprocoptions,pio_nested_access);
                    { reference in nested procedures, variable needs to be in memory }
                    { reference in nested procedures, variable needs to be in memory }
                    { and behaves as if its address escapes its parent block         }
                    { and behaves as if its address escapes its parent block         }
                    make_not_regable(self,[ra_different_scope]);
                    make_not_regable(self,[ra_different_scope]);

+ 1 - 1
compiler/pexpr.pas

@@ -3282,7 +3282,7 @@ implementation
                         if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
                         if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
                           begin
                           begin
                             tlabelsym(srsym).nonlocal:=true;
                             tlabelsym(srsym).nonlocal:=true;
-                            exclude(current_procinfo.procdef.procoptions,po_inline);
+                            include(current_procinfo.flags,pi_has_interproclabel);
                           end;
                           end;
                         if tlabelsym(srsym).nonlocal and
                         if tlabelsym(srsym).nonlocal and
                           (current_procinfo.procdef.proctypeoption in [potype_unitinit,potype_unitfinalize]) then
                           (current_procinfo.procdef.proctypeoption in [potype_unitinit,potype_unitfinalize]) then

+ 4 - 1
compiler/pparautl.pas

@@ -854,7 +854,10 @@ implementation
                         the interface version must also have it (otherwise we can
                         the interface version must also have it (otherwise we can
                         get annoying crashes due to interface crc changes) }
                         get annoying crashes due to interface crc changes) }
                       (not(po_overload in fwpd.procoptions) and
                       (not(po_overload in fwpd.procoptions) and
-                       (po_overload in currpd.procoptions)) then
+                       (po_overload in currpd.procoptions)) or
+                      { same with noreturn }
+                      (not(po_noreturn in fwpd.procoptions) and
+                       (po_noreturn in currpd.procoptions)) then
                      begin
                      begin
                        MessagePos1(currpd.fileinfo,parser_e_header_dont_match_forward,
                        MessagePos1(currpd.fileinfo,parser_e_header_dont_match_forward,
                                    fwpd.fullprocname(false));
                                    fwpd.fullprocname(false));

+ 1 - 1
compiler/pstatmnt.pas

@@ -1255,7 +1255,7 @@ implementation
                    if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
                    if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
                      begin
                      begin
                        tlabelsym(srsym).nonlocal:=true;
                        tlabelsym(srsym).nonlocal:=true;
-                       exclude(current_procinfo.procdef.procoptions,po_inline);
+                       include(current_procinfo.flags,pi_has_interproclabel);
                      end;
                      end;
                    if tlabelsym(srsym).nonlocal and
                    if tlabelsym(srsym).nonlocal and
                      (current_procinfo.procdef.proctypeoption in [potype_unitinit,potype_unitfinalize]) then
                      (current_procinfo.procdef.proctypeoption in [potype_unitinit,potype_unitfinalize]) then

+ 16 - 14
compiler/psub.pas

@@ -160,7 +160,8 @@ implementation
             _no_inline('assembler');
             _no_inline('assembler');
             exit;
             exit;
           end;
           end;
-        if pi_has_global_goto in current_procinfo.flags then
+        if (pi_has_global_goto in current_procinfo.flags) or
+           (pi_has_interproclabel in current_procinfo.flags) then
           begin
           begin
             _no_inline('global goto');
             _no_inline('global goto');
             exit;
             exit;
@@ -183,6 +184,20 @@ implementation
             _no_inline('inherited');
             _no_inline('inherited');
             exit;
             exit;
           end;
           end;
+        if pio_nested_access in procdef.implprocoptions then
+         begin
+           _no_inline('access to local from nested scope');
+           exit;
+         end;
+        { We can't support inlining for procedures that have nested
+          procedures because the nested procedures use a fixed offset
+          for accessing locals in the parent procedure (PFV) }
+        if current_procinfo.has_nestedprocs then
+          begin
+            _no_inline('nested procedures');
+            exit;
+          end;
+
         for i:=0 to procdef.paras.count-1 do
         for i:=0 to procdef.paras.count-1 do
           begin
           begin
             currpara:=tparavarsym(procdef.paras[i]);
             currpara:=tparavarsym(procdef.paras[i]);
@@ -2123,19 +2138,6 @@ implementation
         if (pd.proctypeoption=potype_constructor) then
         if (pd.proctypeoption=potype_constructor) then
           tokeninfo^[_FAIL].keyword:=oldfailtokenmode;
           tokeninfo^[_FAIL].keyword:=oldfailtokenmode;
 
 
-        { We can't support inlining for procedures that have nested
-          procedures because the nested procedures use a fixed offset
-          for accessing locals in the parent procedure (PFV) }
-        if current_procinfo.has_nestedprocs then
-          begin
-            if (po_inline in current_procinfo.procdef.procoptions) then
-              begin
-                Message1(parser_n_not_supported_for_inline,'nested procedures');
-                Message(parser_h_inlining_disabled);
-                exclude(current_procinfo.procdef.procoptions,po_inline);
-              end;
-          end;
-
         { When it's a nested procedure then defer the code generation,
         { When it's a nested procedure then defer the code generation,
           when back at normal function level then generate the code
           when back at normal function level then generate the code
           for all defered nested procedures and the current procedure }
           for all defered nested procedures and the current procedure }

+ 1 - 1
compiler/rautils.pas

@@ -1665,7 +1665,7 @@ Begin
           begin
           begin
             Tlabelsym(sym).nonlocal:=true;
             Tlabelsym(sym).nonlocal:=true;
             if emit then
             if emit then
-              exclude(current_procinfo.procdef.procoptions,po_inline);
+              include(current_procinfo.flags,pi_has_interproclabel);
           end;
           end;
         if not(assigned(tlabelsym(sym).asmblocklabel)) then
         if not(assigned(tlabelsym(sym).asmblocklabel)) then
           if Tlabelsym(sym).nonlocal then
           if Tlabelsym(sym).nonlocal then

+ 3 - 1
compiler/symconst.pas

@@ -425,7 +425,9 @@ type
     { the inline body of this routine is available }
     { the inline body of this routine is available }
     pio_has_inlininginfo,
     pio_has_inlininginfo,
     { inline is not possible (has assembler block, etc) }
     { inline is not possible (has assembler block, etc) }
-    pio_inline_not_possible
+    pio_inline_not_possible,
+    { a nested routine accesses a local variable from this routine }
+    pio_nested_access
   );
   );
   timplprocoptions = set of timplprocoption;
   timplprocoptions = set of timplprocoption;
 
 

+ 2 - 1
compiler/utils/ppuutils/ppudump.pp

@@ -2232,7 +2232,8 @@ const
   piopt : array[low(timplprocoption)..high(timplprocoption)] of tpiopt=(
   piopt : array[low(timplprocoption)..high(timplprocoption)] of tpiopt=(
     (mask:pio_empty; str:'IsEmpty'),
     (mask:pio_empty; str:'IsEmpty'),
     (mask:pio_has_inlininginfo; str:'HasInliningInfo'),
     (mask:pio_has_inlininginfo; str:'HasInliningInfo'),
-    (mask:pio_inline_not_possible; str:'InlineNotPossible')
+    (mask:pio_inline_not_possible; str:'InlineNotPossible'),
+    (mask:pio_nested_access; str:'NestedAccess')
   );
   );
 var
 var
   i: timplprocoption;
   i: timplprocoption;