From c37c485eb78f7e827cf5b66578935fe32080de5e Mon Sep 17 00:00:00 2001 From: florian Date: Wed, 7 Nov 2018 22:03:00 +0000 Subject: [PATCH] + check if initialization/finalization code uses implicitly thread vars git-svn-id: trunk@40269 - --- compiler/psub.pas | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/compiler/psub.pas b/compiler/psub.pas index 97810ab588..cdf3d98908 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -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;