* new node flag nf_modify to mark nodes being read and then written by one load node

* dfa takes care of nf_modify to create better life information
o resolves #11846 and #11849

git-svn-id: trunk@11615 -
This commit is contained in:
florian 2008-08-20 21:35:05 +00:00
parent 1a3c4c04cb
commit 369ed493f2
8 changed files with 143 additions and 51 deletions

3
.gitattributes vendored
View File

@ -8105,6 +8105,7 @@ tests/webtbf/tw1157a.pp svneol=native#text/plain
tests/webtbf/tw11619b.pp svneol=native#text/plain
tests/webtbf/tw11632.pp svneol=native#text/plain
tests/webtbf/tw11848a.pp svneol=native#text/plain
tests/webtbf/tw11849a.pp svneol=native#text/plain
tests/webtbf/tw11862a.pp svneol=native#text/plain
tests/webtbf/tw1238.pp svneol=native#text/plain
tests/webtbf/tw1251a.pp svneol=native#text/plain
@ -8541,7 +8542,9 @@ tests/webtbs/tw1157.pp svneol=native#text/plain
tests/webtbs/tw1157b.pp svneol=native#text/plain
tests/webtbs/tw11619.pp svneol=native#text/plain
tests/webtbs/tw1181.pp svneol=native#text/plain
tests/webtbs/tw11846.pp svneol=native#text/plain
tests/webtbs/tw11848.pp svneol=native#text/plain
tests/webtbs/tw11849.pp svneol=native#text/plain
tests/webtbs/tw11852.pp svneol=native#text/plain
tests/webtbs/tw11861.pp svneol=native#text/plain
tests/webtbs/tw11862.pp svneol=native#text/plain

View File

@ -850,49 +850,56 @@ implementation
loadn :
begin
if (tloadnode(p).symtableentry.typ in [localvarsym,paravarsym,staticvarsym]) then
begin
hsym:=tabstractvarsym(tloadnode(p).symtableentry);
if (vsf_must_be_valid in varstateflags) and
(hsym.varstate in [vs_declared,vs_read_not_warned,vs_referred_not_inited]) then
begin
{ Give warning/note for uninitialized locals }
if assigned(hsym.owner) and
not(cs_opt_nodedfa in current_settings.optimizerswitches) and
not(vo_is_external in hsym.varoptions) and
(hsym.owner.symtabletype in [parasymtable,localsymtable,staticsymtable]) and
((hsym.owner=current_procinfo.procdef.localst) or
(hsym.owner=current_procinfo.procdef.parast)) then
begin
if (vo_is_funcret in hsym.varoptions) then
begin
if (vsf_use_hints in varstateflags) then
CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized)
else
CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized)
end
else
begin
if tloadnode(p).symtable.symtabletype=localsymtable then
begin
if (vsf_use_hints in varstateflags) then
CGMessagePos1(p.fileinfo,sym_h_uninitialized_local_variable,hsym.realname)
else
CGMessagePos1(p.fileinfo,sym_w_uninitialized_local_variable,hsym.realname);
end
else
begin
if (vsf_use_hints in varstateflags) then
CGMessagePos1(p.fileinfo,sym_h_uninitialized_variable,hsym.realname)
else
CGMessagePos1(p.fileinfo,sym_w_uninitialized_variable,hsym.realname);
end;
end;
end
else if (newstate = vs_read) then
newstate := vs_read_not_warned;
end;
hsym.varstate := vstrans[hsym.varstate,newstate];
end;
begin
hsym:=tabstractvarsym(tloadnode(p).symtableentry);
if (vsf_must_be_valid in varstateflags) and
(hsym.varstate in [vs_declared,vs_read_not_warned,vs_referred_not_inited]) then
begin
{ Give warning/note for uninitialized locals }
if assigned(hsym.owner) and
not(cs_opt_nodedfa in current_settings.optimizerswitches) and
not(vo_is_external in hsym.varoptions) and
(hsym.owner.symtabletype in [parasymtable,localsymtable,staticsymtable]) and
((hsym.owner=current_procinfo.procdef.localst) or
(hsym.owner=current_procinfo.procdef.parast)) then
begin
if (vo_is_funcret in hsym.varoptions) then
begin
if (vsf_use_hints in varstateflags) then
CGMessagePos(p.fileinfo,sym_h_function_result_uninitialized)
else
CGMessagePos(p.fileinfo,sym_w_function_result_uninitialized)
end
else
begin
if tloadnode(p).symtable.symtabletype=localsymtable then
begin
if (vsf_use_hints in varstateflags) then
CGMessagePos1(p.fileinfo,sym_h_uninitialized_local_variable,hsym.realname)
else
CGMessagePos1(p.fileinfo,sym_w_uninitialized_local_variable,hsym.realname);
end
else
begin
if (vsf_use_hints in varstateflags) then
CGMessagePos1(p.fileinfo,sym_h_uninitialized_variable,hsym.realname)
else
CGMessagePos1(p.fileinfo,sym_w_uninitialized_variable,hsym.realname);
end;
end;
end
else if (newstate = vs_read) then
newstate := vs_read_not_warned;
end;
hsym.varstate := vstrans[hsym.varstate,newstate];
end;
case newstate of
vs_written:
include(tloadnode(p).flags,nf_write);
vs_readwritten:
if not(nf_write in tloadnode(p).flags) then
include(tloadnode(p).flags,nf_modify);
end;
break;
end;
callparan :

View File

@ -561,10 +561,8 @@ implementation
function tsubscriptnode.dogetcopy : tnode;
var
p : tsubscriptnode;
begin
p:=tsubscriptnode(inherited dogetcopy);
p.vs:=vs;
@ -587,10 +585,10 @@ implementation
end;
procedure Tsubscriptnode.mark_write;
begin
include(flags,nf_write);
end;
begin
include(flags,nf_write);
end;
function tsubscriptnode.pass_1 : tnode;
begin

View File

@ -201,7 +201,8 @@ interface
{ general }
nf_pass1_done,
nf_write, { Node is written to }
nf_write, { Node is written to }
nf_modify, { Node is modified }
nf_is_funcret,
nf_isproperty,
nf_processing,

View File

@ -116,7 +116,12 @@ unit optdfa;
loadn:
begin
pdfainfo(arg)^.map.Add(n);
if nf_write in n.flags then
if nf_modify in n.flags then
begin
DFASetInclude(pdfainfo(arg)^.use^,n.optinfo^.index);
DFASetInclude(pdfainfo(arg)^.def^,n.optinfo^.index)
end
else if nf_write in n.flags then
DFASetInclude(pdfainfo(arg)^.def^,n.optinfo^.index)
else
DFASetInclude(pdfainfo(arg)^.use^,n.optinfo^.index);
@ -424,6 +429,7 @@ unit optdfa;
{ get info from faked resultnode }
node.optinfo^.use:=resultnode.optinfo^.use;
node.optinfo^.life:=node.optinfo^.use;
changed:=true;
end;
end;
end;
@ -524,14 +530,40 @@ unit optdfa;
procedure TDFABuilder.createdfainfo(node : tnode);
{
var
lastnode : tnode;
fakeexitnode : texitnode;
}
begin
if not(assigned(nodemap)) then
nodemap:=TIndexedNodeSet.Create;
{ add controll flow information }
SetNodeSucessors(node);
{
{ create an exit node for functions to get
the function result at the end handled properly }
if not(is_void(current_procinfo.procdef.returndef)) and
not(current_procinfo.procdef.proctypeoption=potype_constructor) then
begin
lastnode:=node;
while assigned(lastnode.successor) do
lastnode:=lastnode.successor;
fakeexitnode:=cexitnode.create(nil);
lastnode.successor:=fakeexitnode;
end
else
fakeexitnode:=nil;
}
{ now, collect life information }
CreateLifeInfo(node,nodemap);
{
if assigned(fakeexitnode) then
begin
lastnode.successor.free;
lastnode.successor:=nil;
end;
}
end;

19
tests/webtbf/tw11849a.pp Normal file
View File

@ -0,0 +1,19 @@
{ %OPT=-Sew -Oodfa }
{ %fail }
{$mode objfpc}
procedure GiveMe(var i: integer);
begin
i:=0;
end;
function Test(a: integer): integer;
var
i: integer;
begin
GiveMe(i);
Result:=i;
end;
begin
end.

13
tests/webtbs/tw11846.pp Normal file
View File

@ -0,0 +1,13 @@
{ %OPT=-Sew -Oodfa }
{ %NORUN }
{$mode objfpc}
function Test(a: integer): boolean;
var
i: Integer;
begin
for i:=1 to 2 do
Result:=true;
end;
begin
end.

19
tests/webtbs/tw11849.pp Normal file
View File

@ -0,0 +1,19 @@
{ %OPT=-Sew -Oodfa }
{ %norun }
{$mode objfpc}
procedure GiveMe(out i: integer);
begin
i:=0;
end;
function Test(a: integer): integer;
var
i: integer;
begin
GiveMe(i);
Result:=i;
end;
begin
end.