mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-07 05:27:13 +01:00
* 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 -
This commit is contained in:
parent
50e7e66201
commit
51e68eb302
@ -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
|
||||
|
||||
@ -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]);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user