Przeglądaj źródła

* 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 lat temu
rodzic
commit
51e68eb302

+ 0 - 7
compiler/nflw.pas

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

+ 1 - 1
compiler/nld.pas

@@ -332,7 +332,7 @@ implementation
                      internalerror(200309289);
                    left:=cloadparentfpnode.create(tprocdef(symtable.defowner),lpf_forload);
                    { 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 }
                    { and behaves as if its address escapes its parent block         }
                    make_not_regable(self,[ra_different_scope]);

+ 1 - 1
compiler/pexpr.pas

@@ -3282,7 +3282,7 @@ implementation
                         if symtablestack.top.symtablelevel<>srsymtable.symtablelevel then
                           begin
                             tlabelsym(srsym).nonlocal:=true;
-                            exclude(current_procinfo.procdef.procoptions,po_inline);
+                            include(current_procinfo.flags,pi_has_interproclabel);
                           end;
                         if tlabelsym(srsym).nonlocal and
                           (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
                         get annoying crashes due to interface crc changes) }
                       (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
                        MessagePos1(currpd.fileinfo,parser_e_header_dont_match_forward,
                                    fwpd.fullprocname(false));

+ 1 - 1
compiler/pstatmnt.pas

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

+ 16 - 14
compiler/psub.pas

@@ -160,7 +160,8 @@ implementation
             _no_inline('assembler');
             exit;
           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
             _no_inline('global goto');
             exit;
@@ -183,6 +184,20 @@ implementation
             _no_inline('inherited');
             exit;
           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
           begin
             currpara:=tparavarsym(procdef.paras[i]);
@@ -2123,19 +2138,6 @@ implementation
         if (pd.proctypeoption=potype_constructor) then
           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 back at normal function level then generate the code
           for all defered nested procedures and the current procedure }

+ 1 - 1
compiler/rautils.pas

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

+ 3 - 1
compiler/symconst.pas

@@ -425,7 +425,9 @@ type
     { the inline body of this routine is available }
     pio_has_inlininginfo,
     { 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;
 

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

@@ -2232,7 +2232,8 @@ const
   piopt : array[low(timplprocoption)..high(timplprocoption)] of tpiopt=(
     (mask:pio_empty; str:'IsEmpty'),
     (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
   i: timplprocoption;