diff --git a/.gitattributes b/.gitattributes index 373181cceb..2e66040084 100644 --- a/.gitattributes +++ b/.gitattributes @@ -18619,6 +18619,7 @@ tests/webtbs/tw38202.pp svneol=native#text/pascal tests/webtbs/tw38225.pp svneol=native#text/pascal tests/webtbs/tw38238.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/tw3829.pp svneol=native#text/plain tests/webtbs/tw3833.pp svneol=native#text/plain diff --git a/compiler/optdfa.pas b/compiler/optdfa.pas index c5c2759625..bf772b423c 100644 --- a/compiler/optdfa.pas +++ b/compiler/optdfa.pas @@ -508,20 +508,32 @@ unit optdfa; exitn: 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 if not(assigned(node.optinfo^.def)) and not(assigned(node.optinfo^.use)) then begin if assigned(texitnode(node).left) then begin - node.optinfo^.def:=resultnode.optinfo^.def; +{ this should never happen as + texitnode.pass_typecheck converts the left node into a separate node already + + node.optinfo^.def:=resultnode.optinfo^.def; dfainfo.use:=@node.optinfo^.use; dfainfo.def:=@node.optinfo^.def; dfainfo.map:=map; foreachnodestatic(pm_postprocess,texitnode(node).left,@AddDefUse,@dfainfo); - calclife(node); + calclife(node); } + Internalerror(2020122901); end else begin diff --git a/compiler/optutils.pas b/compiler/optutils.pas index a1bf0315a3..cfcf66958a 100644 --- a/compiler/optutils.pas +++ b/compiler/optutils.pas @@ -163,11 +163,12 @@ unit optutils; var Continuestack : TFPList; Breakstack : TFPList; + Exitsuccessor: TNode; { sets the successor nodes of a node tree block returns the first node of the tree if it's a controll flow node } function DoSet(p : tnode;succ : tnode) : tnode; var - hp1,hp2 : tnode; + hp1,hp2, oldexitsuccessor: tnode; i : longint; begin result:=nil; @@ -203,11 +204,15 @@ unit optutils; blockn: begin result:=p; + oldexitsuccessor:=Exitsuccessor; + if nf_block_with_exit in p.flags then + Exitsuccessor:=succ; DoSet(tblocknode(p).statements,succ); if assigned(tblocknode(p).statements) then p.successor:=tblocknode(p).statements else p.successor:=succ; + Exitsuccessor:=oldexitsuccessor; end; forn: begin @@ -288,7 +293,7 @@ unit optutils; exitn: begin result:=p; - p.successor:=nil; + p.successor:=Exitsuccessor; end; casen: begin @@ -337,6 +342,7 @@ unit optutils; begin Breakstack:=TFPList.Create; Continuestack:=TFPList.Create; + Exitsuccessor:=nil; DoSet(p,last); Continuestack.Free; Breakstack.Free; diff --git a/tests/webtbs/tw38259.pp b/tests/webtbs/tw38259.pp new file mode 100644 index 0000000000..33b88d6051 --- /dev/null +++ b/tests/webtbs/tw38259.pp @@ -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.