mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-19 20:39:25 +02:00
* 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:
parent
1a3c4c04cb
commit
369ed493f2
3
.gitattributes
vendored
3
.gitattributes
vendored
@ -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
|
||||
|
@ -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 :
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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
19
tests/webtbf/tw11849a.pp
Normal 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
13
tests/webtbs/tw11846.pp
Normal 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
19
tests/webtbs/tw11849.pp
Normal 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.
|
Loading…
Reference in New Issue
Block a user