mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 21:09:24 +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) }
|
||||
set_varstate(left,vs_written,[]);
|
||||
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;
|
||||
vs_var,
|
||||
vs_constref:
|
||||
@ -1315,7 +1320,12 @@ implementation
|
||||
{ constref takes also the address, but storing it is actually the compiler
|
||||
is not supposed to expect }
|
||||
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;
|
||||
else
|
||||
set_varstate(left,vs_read,[vsf_must_be_valid]);
|
||||
@ -2885,21 +2895,28 @@ implementation
|
||||
(procdefinition.parast.symtablelevel=normal_function_level) and
|
||||
{ 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 }
|
||||
{ through these same checks at the caller side and is thus safe }
|
||||
(
|
||||
(tloadnode(realassignmenttarget).symtableentry.typ=localvarsym) or
|
||||
{ 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=paravarsym) and
|
||||
((tparavarsym(tloadnode(realassignmenttarget).symtableentry).varspez = vs_value) or
|
||||
(vo_is_funcret in tparavarsym(tloadnode(realassignmenttarget).symtableentry).varoptions))
|
||||
(
|
||||
(tloadnode(realassignmenttarget).symtableentry.typ=localvarsym) or
|
||||
(
|
||||
(tloadnode(realassignmenttarget).symtableentry.typ=paravarsym) and
|
||||
((tparavarsym(tloadnode(realassignmenttarget).symtableentry).varspez = vs_value) or
|
||||
(vo_is_funcret in tparavarsym(tloadnode(realassignmenttarget).symtableentry).varoptions))
|
||||
)
|
||||
) and
|
||||
{ the address may not have been taken of the variable/parameter, because }
|
||||
{ otherwise it's possible that the called function can access it via a }
|
||||
{ global variable or other stored state }
|
||||
(
|
||||
not(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).addr_taken) and
|
||||
(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).varregable in [vr_none,vr_addr])
|
||||
)
|
||||
)
|
||||
) and
|
||||
{ the address may not have been taken of the variable/parameter, because }
|
||||
{ otherwise it's possible that the called function can access it via a }
|
||||
{ global variable or other stored state }
|
||||
(
|
||||
not(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).addr_taken) and
|
||||
(tabstractvarsym(tloadnode(realassignmenttarget).symtableentry).varregable in [vr_none,vr_addr])
|
||||
) then
|
||||
begin
|
||||
{ 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
|
||||
persistently by the callee (it becomes invalid when the callee
|
||||
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])
|
||||
else
|
||||
make_not_regable(hp.left,[ra_addr_regable]);
|
||||
|
Loading…
Reference in New Issue
Block a user