mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 13:59:07 +02:00
* assume that compilerprocs never capture the addresses of their arguments
git-svn-id: trunk@31489 -
This commit is contained in:
parent
2b551d0241
commit
ee3f89246c
@ -1306,7 +1306,12 @@ implementation
|
|||||||
{ uninitialized warnings (tbs/tb0542) }
|
{ uninitialized warnings (tbs/tb0542) }
|
||||||
set_varstate(left,vs_written,[]);
|
set_varstate(left,vs_written,[]);
|
||||||
set_varstate(left,vs_readwritten,[]);
|
set_varstate(left,vs_readwritten,[]);
|
||||||
make_not_regable(left,[ra_addr_regable,ra_addr_taken]);
|
{ compilerprocs never capture the address of their
|
||||||
|
parameters }
|
||||||
|
if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
|
||||||
|
make_not_regable(left,[ra_addr_regable,ra_addr_taken])
|
||||||
|
else
|
||||||
|
make_not_regable(left,[ra_addr_regable])
|
||||||
end;
|
end;
|
||||||
vs_var,
|
vs_var,
|
||||||
vs_constref:
|
vs_constref:
|
||||||
@ -1315,7 +1320,12 @@ implementation
|
|||||||
{ constref takes also the address, but storing it is actually the compiler
|
{ constref takes also the address, but storing it is actually the compiler
|
||||||
is not supposed to expect }
|
is not supposed to expect }
|
||||||
if parasym.varspez=vs_var then
|
if parasym.varspez=vs_var then
|
||||||
make_not_regable(left,[ra_addr_regable,ra_addr_taken]);
|
{ compilerprocs never capture the address of their
|
||||||
|
parameters }
|
||||||
|
if not(po_compilerproc in aktcallnode.procdefinition.procoptions) then
|
||||||
|
make_not_regable(left,[ra_addr_regable,ra_addr_taken])
|
||||||
|
else
|
||||||
|
make_not_regable(left,[ra_addr_regable])
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
||||||
@ -2885,7 +2895,12 @@ implementation
|
|||||||
(procdefinition.parast.symtablelevel=normal_function_level) and
|
(procdefinition.parast.symtablelevel=normal_function_level) and
|
||||||
{ must be a local variable, a value para or a hidden function result }
|
{ must be a local variable, a value para or a hidden function result }
|
||||||
{ parameter (which can be passed by address, but in that case it got }
|
{ parameter (which can be passed by address, but in that case it got }
|
||||||
{ through these same checks at the caller side and is thus safe }
|
{ through these same checks at the caller side and is thus safe ) }
|
||||||
|
{ other option: we're calling a compilerproc, because those don't
|
||||||
|
rely on global state
|
||||||
|
}
|
||||||
|
((po_compilerproc in procdefinition.procoptions) or
|
||||||
|
(
|
||||||
(
|
(
|
||||||
(tloadnode(realassignmenttarget).symtableentry.typ=localvarsym) or
|
(tloadnode(realassignmenttarget).symtableentry.typ=localvarsym) or
|
||||||
(
|
(
|
||||||
@ -2900,6 +2915,8 @@ implementation
|
|||||||
(
|
(
|
||||||
not(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).addr_taken) and
|
not(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).addr_taken) and
|
||||||
(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).varregable in [vr_none,vr_addr])
|
(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).varregable in [vr_none,vr_addr])
|
||||||
|
)
|
||||||
|
)
|
||||||
) then
|
) then
|
||||||
begin
|
begin
|
||||||
{ If the funcret is also used as a parameter we can't optimize because the funcret
|
{ If the funcret is also used as a parameter we can't optimize because the funcret
|
||||||
@ -4050,7 +4067,8 @@ implementation
|
|||||||
function result" is not something which can be stored
|
function result" is not something which can be stored
|
||||||
persistently by the callee (it becomes invalid when the callee
|
persistently by the callee (it becomes invalid when the callee
|
||||||
returns) }
|
returns) }
|
||||||
if not(vo_is_funcret in hp.parasym.varoptions) then
|
if not(vo_is_funcret in hp.parasym.varoptions) and
|
||||||
|
not(po_compilerproc in procdefinition.procoptions) then
|
||||||
make_not_regable(hp.left,[ra_addr_regable,ra_addr_taken])
|
make_not_regable(hp.left,[ra_addr_regable,ra_addr_taken])
|
||||||
else
|
else
|
||||||
make_not_regable(hp.left,[ra_addr_regable]);
|
make_not_regable(hp.left,[ra_addr_regable]);
|
||||||
|
Loading…
Reference in New Issue
Block a user