diff --git a/compiler/optdfa.pas b/compiler/optdfa.pas index 0b2e0e3a72..d9adc62bb8 100644 --- a/compiler/optdfa.pas +++ b/compiler/optdfa.pas @@ -329,7 +329,7 @@ unit optdfa; dfainfo.map:=map; foreachnodestatic(pm_postprocess,tifnode(node).left,@AddDefUse,@dfainfo); end; - { create life info for left and right node } + { create life info for then and else node } CreateInfo(tifnode(node).right); CreateInfo(tifnode(node).t1); @@ -418,10 +418,22 @@ unit optdfa; calclife(node); end; + calln: + begin + if not(assigned(node.optinfo^.def)) and + not(assigned(node.optinfo^.use)) then + begin + dfainfo.use:=@node.optinfo^.use; + dfainfo.def:=@node.optinfo^.def; + dfainfo.map:=map; + foreachnodestatic(pm_postprocess,node,@AddDefUse,@dfainfo); + end; + calclife(node); + end; + tempcreaten, tempdeleten, inlinen, - calln, nothingn, continuen, goton, @@ -484,17 +496,14 @@ unit optdfa; procedure createdfainfo(node : tnode); - var - map : TIndexedNodeSet; begin - map:=TIndexedNodeSet.Create; + if not(assigned(current_procinfo.nodemap)) then + current_procinfo.nodemap:=TIndexedNodeSet.Create; { add controll flow information } SetNodeSucessors(node); { now, collect life information } - CreateLifeInfo(node,map); - - map.free; + CreateLifeInfo(node,current_procinfo.nodemap); end; end. diff --git a/compiler/optutils.pas b/compiler/optutils.pas index af9f1ecb4e..a02adb8f8b 100644 --- a/compiler/optutils.pas +++ b/compiler/optutils.pas @@ -266,6 +266,8 @@ unit optutils; result:=p; p.successor:=succ; end; + tempcreaten, + tempdeleten, nothingn: begin result:=p; diff --git a/compiler/procinfo.pas b/compiler/procinfo.pas index 3243e1cc08..e4ef0d0785 100644 --- a/compiler/procinfo.pas +++ b/compiler/procinfo.pas @@ -34,7 +34,8 @@ unit procinfo; symconst,symtype,symdef,symsym, { aasm } cpubase,cpuinfo,cgbase,cgutils, - aasmbase,aasmtai,aasmdata + aasmbase,aasmtai,aasmdata, + optutils ; const @@ -102,6 +103,9 @@ unit procinfo; { max. of space need for parameters } maxpushedparasize : aint; + { node to index mapping for the node level optimizer } + nodemap : TIndexedNodeSet; + constructor create(aparent:tprocinfo);virtual; destructor destroy;override; diff --git a/compiler/psub.pas b/compiler/psub.pas index a1cff593e0..4665129950 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -102,9 +102,11 @@ implementation { codegen } tgobj,cgbase,cgobj,dbgbase, ncgutil,regvars, + optbase, opttail, optcse, - optdfa + optdfa, + optutils {$if defined(arm) or defined(powerpc) or defined(powerpc64)} ,aasmcpu {$endif arm} @@ -692,6 +694,8 @@ implementation oldfilepos : tfileposinfo; templist : TAsmList; headertai : tai; + i : integer; + varsym : tabstractnormalvarsym; begin { the initialization procedure can be empty, then we don't need to generate anything. When it was an empty @@ -763,6 +767,33 @@ implementation pi_needs_stackframe])=[]) then begin createdfainfo(code); + { when life info is available, we can give more sophisticated warning about unintialized + variables } + + { iterate through life info of the first node } + for i:=0 to nodemap.count-1 do + begin + if DFASetIn(code.optinfo^.life,i) then + case tnode(nodemap[i]).nodetype of + loadn: + begin + varsym:=tabstractnormalvarsym(tloadnode(nodemap[i]).symtableentry); + + { Give warning/note for living locals } + if assigned(varsym.owner) and + not(vo_is_external in varsym.varoptions) then + begin + if (vo_is_funcret in varsym.varoptions) then + CGMessage(sym_w_function_result_uninitialized) + else + begin + if varsym.owner=procdef.localst then + CGMessage1(sym_w_uninitialized_local_variable,varsym.realname); + end; + end; + end; + end; + end; end; if cs_opt_nodecse in current_settings.optimizerswitches then