diff options
author | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-01-06 20:35:56 +0000 |
---|---|---|
committer | jonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2019-01-06 20:35:56 +0000 |
commit | d4dad263a477bdbbc2161ce2c8d840ef70b8c291 (patch) | |
tree | 9ed7c55c60de306cdf38e560f4e3a16eeaae7020 /compiler | |
parent | 77938f251e1059bff6fbb30d2296034a8650c0a5 (diff) | |
download | fpc-d4dad263a477bdbbc2161ce2c8d840ef70b8c291.tar.gz |
* 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: https://svn.freepascal.org/svn/fpc/trunk@40789 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/nflw.pas | 7 | ||||
-rw-r--r-- | compiler/nld.pas | 2 | ||||
-rw-r--r-- | compiler/pexpr.pas | 2 | ||||
-rw-r--r-- | compiler/pparautl.pas | 5 | ||||
-rw-r--r-- | compiler/pstatmnt.pas | 2 | ||||
-rw-r--r-- | compiler/psub.pas | 30 | ||||
-rw-r--r-- | compiler/rautils.pas | 2 | ||||
-rw-r--r-- | compiler/symconst.pas | 4 | ||||
-rw-r--r-- | compiler/utils/ppuutils/ppudump.pp | 3 |
9 files changed, 29 insertions, 28 deletions
diff --git a/compiler/nflw.pas b/compiler/nflw.pas index dff5dd5eef..f8ebb671f9 100644 --- a/compiler/nflw.pas +++ b/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 diff --git a/compiler/nld.pas b/compiler/nld.pas index 798820174d..3549617e0b 100644 --- a/compiler/nld.pas +++ b/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]); diff --git a/compiler/pexpr.pas b/compiler/pexpr.pas index 8311dec546..e9a8058dce 100644 --- a/compiler/pexpr.pas +++ b/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 diff --git a/compiler/pparautl.pas b/compiler/pparautl.pas index 2e89b8441b..4f5335ab4f 100644 --- a/compiler/pparautl.pas +++ b/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)); diff --git a/compiler/pstatmnt.pas b/compiler/pstatmnt.pas index aba01c1b19..916d2f9bf1 100644 --- a/compiler/pstatmnt.pas +++ b/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 diff --git a/compiler/psub.pas b/compiler/psub.pas index 9fd729635c..88880662a9 100644 --- a/compiler/psub.pas +++ b/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 } diff --git a/compiler/rautils.pas b/compiler/rautils.pas index 33a63c2f3d..230f13509f 100644 --- a/compiler/rautils.pas +++ b/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 diff --git a/compiler/symconst.pas b/compiler/symconst.pas index bc738463a7..039b376679 100644 --- a/compiler/symconst.pas +++ b/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; diff --git a/compiler/utils/ppuutils/ppudump.pp b/compiler/utils/ppuutils/ppudump.pp index 3214ea85a6..ccf019fad1 100644 --- a/compiler/utils/ppuutils/ppudump.pp +++ b/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; |