* correctly handle inlined exits in dfa, resolves #38259

git-svn-id: trunk@47894 -
This commit is contained in:
florian 2020-12-29 22:35:33 +00:00
parent 6866b07266
commit edfbf2ce30
4 changed files with 41 additions and 5 deletions

1
.gitattributes vendored
View File

@ -18619,6 +18619,7 @@ tests/webtbs/tw38202.pp svneol=native#text/pascal
tests/webtbs/tw38225.pp svneol=native#text/pascal tests/webtbs/tw38225.pp svneol=native#text/pascal
tests/webtbs/tw38238.pp svneol=native#text/pascal tests/webtbs/tw38238.pp svneol=native#text/pascal
tests/webtbs/tw38249.pp svneol=native#text/pascal tests/webtbs/tw38249.pp svneol=native#text/pascal
tests/webtbs/tw38259.pp svneol=native#text/pascal
tests/webtbs/tw3827.pp svneol=native#text/plain tests/webtbs/tw3827.pp svneol=native#text/plain
tests/webtbs/tw3829.pp svneol=native#text/plain tests/webtbs/tw3829.pp svneol=native#text/plain
tests/webtbs/tw3833.pp svneol=native#text/plain tests/webtbs/tw3833.pp svneol=native#text/plain

View File

@ -508,20 +508,32 @@ unit optdfa;
exitn: exitn:
begin begin
if not(is_void(current_procinfo.procdef.returndef)) then { in case of inlining, an exit node can have a successor, in this case, we do not have to
use the faked resultnode }
if assigned(node.successor) then
begin
l:=node.optinfo^.life;
DFASetIncludeSet(l,node.successor.optinfo^.life);
UpdateLifeInfo(node,l);
end
else if assigned(resultnode) and (resultnode.nodetype<>nothingn) then
begin begin
if not(assigned(node.optinfo^.def)) and if not(assigned(node.optinfo^.def)) and
not(assigned(node.optinfo^.use)) then not(assigned(node.optinfo^.use)) then
begin begin
if assigned(texitnode(node).left) then if assigned(texitnode(node).left) then
begin begin
{ this should never happen as
texitnode.pass_typecheck converts the left node into a separate node already
node.optinfo^.def:=resultnode.optinfo^.def; node.optinfo^.def:=resultnode.optinfo^.def;
dfainfo.use:=@node.optinfo^.use; dfainfo.use:=@node.optinfo^.use;
dfainfo.def:=@node.optinfo^.def; dfainfo.def:=@node.optinfo^.def;
dfainfo.map:=map; dfainfo.map:=map;
foreachnodestatic(pm_postprocess,texitnode(node).left,@AddDefUse,@dfainfo); foreachnodestatic(pm_postprocess,texitnode(node).left,@AddDefUse,@dfainfo);
calclife(node); calclife(node); }
Internalerror(2020122901);
end end
else else
begin begin

View File

@ -163,11 +163,12 @@ unit optutils;
var var
Continuestack : TFPList; Continuestack : TFPList;
Breakstack : TFPList; Breakstack : TFPList;
Exitsuccessor: TNode;
{ sets the successor nodes of a node tree block { sets the successor nodes of a node tree block
returns the first node of the tree if it's a controll flow node } returns the first node of the tree if it's a controll flow node }
function DoSet(p : tnode;succ : tnode) : tnode; function DoSet(p : tnode;succ : tnode) : tnode;
var var
hp1,hp2 : tnode; hp1,hp2, oldexitsuccessor: tnode;
i : longint; i : longint;
begin begin
result:=nil; result:=nil;
@ -203,11 +204,15 @@ unit optutils;
blockn: blockn:
begin begin
result:=p; result:=p;
oldexitsuccessor:=Exitsuccessor;
if nf_block_with_exit in p.flags then
Exitsuccessor:=succ;
DoSet(tblocknode(p).statements,succ); DoSet(tblocknode(p).statements,succ);
if assigned(tblocknode(p).statements) then if assigned(tblocknode(p).statements) then
p.successor:=tblocknode(p).statements p.successor:=tblocknode(p).statements
else else
p.successor:=succ; p.successor:=succ;
Exitsuccessor:=oldexitsuccessor;
end; end;
forn: forn:
begin begin
@ -288,7 +293,7 @@ unit optutils;
exitn: exitn:
begin begin
result:=p; result:=p;
p.successor:=nil; p.successor:=Exitsuccessor;
end; end;
casen: casen:
begin begin
@ -337,6 +342,7 @@ unit optutils;
begin begin
Breakstack:=TFPList.Create; Breakstack:=TFPList.Create;
Continuestack:=TFPList.Create; Continuestack:=TFPList.Create;
Exitsuccessor:=nil;
DoSet(p,last); DoSet(p,last);
Continuestack.Free; Continuestack.Free;
Breakstack.Free; Breakstack.Free;

17
tests/webtbs/tw38259.pp Normal file
View File

@ -0,0 +1,17 @@
{ %OPT=-O3 -Sew -vw }
{$mode objfpc}
{$inline on}
procedure test; inline;
begin
exit;
end;
function f: longint;
begin
test; // tt.pp(11,3) Warning: Function result variable does not seem to be initialized
result:=4;
end;
begin
end.