+ check if initialization/finalization code uses implicitly thread vars

git-svn-id: trunk@40269 -
This commit is contained in:
florian 2018-11-07 22:03:00 +00:00
parent e949276d9d
commit c37c485eb7

View File

@ -1203,6 +1203,46 @@ implementation
procdef.has_inlininginfo:=true;
end;
procedure searchthreadvar(p: TObject; arg: pointer);
var
i : longint;
pd : tprocdef;
begin
case tsym(p).typ of
staticvarsym :
begin
{ local (procedure or unit) variables only need finalization
if they are used
}
if (vo_is_thread_var in tstaticvarsym(p).varoptions) and
((tstaticvarsym(p).refs>0) or
{ global (unit) variables always need finalization, since
they may also be used in another unit
}
(tstaticvarsym(p).owner.symtabletype=globalsymtable)) and
(
(tstaticvarsym(p).varspez<>vs_const) or
(vo_force_finalize in tstaticvarsym(p).varoptions)
) and
not(vo_is_funcret in tstaticvarsym(p).varoptions) and
not(vo_is_external in tstaticvarsym(p).varoptions) and
is_managed_type(tstaticvarsym(p).vardef) then
include(current_procinfo.flags,pi_uses_threadvar);
end;
procsym :
begin
for i:=0 to tprocsym(p).ProcdefList.Count-1 do
begin
pd:=tprocdef(tprocsym(p).ProcdefList[i]);
if assigned(pd.localst) and
(pd.procsym=tprocsym(p)) and
(pd.localst.symtabletype<>staticsymtable) then
pd.localst.SymList.ForEachCall(@searchthreadvar,arg);
end;
end;
end;
end;
function searchusercode(var n: tnode; arg: pointer): foreachnoderesult;
begin
@ -1229,6 +1269,19 @@ implementation
procedure tcgprocinfo.generate_code;
procedure check_for_threadvars_in_initfinal;
begin
if current_procinfo.procdef.proctypeoption=potype_unitfinalize then
begin
{ this is also used for initialization of variables in a
program which does not have a globalsymtable }
if assigned(current_module.globalsymtable) then
TSymtable(current_module.globalsymtable).SymList.ForEachCall(@searchthreadvar,nil);
TSymtable(current_module.localsymtable).SymList.ForEachCall(@searchthreadvar,nil);
end;
end;
var
old_current_procinfo : tprocinfo;
oldmaxfpuregisters : longint;
@ -1426,6 +1479,10 @@ implementation
(code.nodetype=blockn) and (tblocknode(code).statements=nil) then
procdef.isempty:=true;
{ unit static/global symtables might contain threadvars which are not explicitly used but which might
require a tls register, so check for such variables }
check_for_threadvars_in_initfinal;
{ add implicit entry and exit code }
add_entry_exit_code;