summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-01-06 20:35:56 +0000
committerjonas <jonas@3ad0048d-3df7-0310-abae-a5850022a9f2>2019-01-06 20:35:56 +0000
commitd4dad263a477bdbbc2161ce2c8d840ef70b8c291 (patch)
tree9ed7c55c60de306cdf38e560f4e3a16eeaae7020 /compiler
parent77938f251e1059bff6fbb30d2296034a8650c0a5 (diff)
downloadfpc-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.pas7
-rw-r--r--compiler/nld.pas2
-rw-r--r--compiler/pexpr.pas2
-rw-r--r--compiler/pparautl.pas5
-rw-r--r--compiler/pstatmnt.pas2
-rw-r--r--compiler/psub.pas30
-rw-r--r--compiler/rautils.pas2
-rw-r--r--compiler/symconst.pas4
-rw-r--r--compiler/utils/ppuutils/ppudump.pp3
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;