* load the function result from the parentfpstruct to its original location

in exit nodes, because the wrapping code added in
    tnodeutils.wrap_proc_body() gets inserted before the exit label to which
    the exit node jumps

git-svn-id: trunk@34305 -
This commit is contained in:
Jonas Maebe 2016-08-13 14:47:50 +00:00
parent a31ca58593
commit 051317e82e
3 changed files with 60 additions and 2 deletions

1
.gitattributes vendored
View File

@ -11032,6 +11032,7 @@ tests/tbs/tb0618.pp svneol=native#text/plain
tests/tbs/tb0619.pp svneol=native#text/pascal
tests/tbs/tb0620.pp svneol=native#text/pascal
tests/tbs/tb0621.pp svneol=native#text/plain
tests/tbs/tb0622.pp svneol=native#text/plain
tests/tbs/tb205.pp svneol=native#text/plain
tests/tbs/tb610.pp svneol=native#text/pascal
tests/tbs/tb613.pp svneol=native#text/plain

View File

@ -242,7 +242,7 @@ implementation
globtype,systems,constexp,
cutils,verbose,globals,
symconst,symtable,paramgr,defcmp,defutil,htypechk,pass_1,
ncal,nadd,ncon,nmem,nld,ncnv,nbas,cgobj,nutils,ninl,nset,
ncal,nadd,ncon,nmem,nld,ncnv,nbas,cgobj,nutils,ninl,nset,ngenutil,
pdecsub,
{$ifdef state_tracking}
nstate,
@ -1597,15 +1597,40 @@ implementation
function texitnode.pass_typecheck:tnode;
var
pd: tprocdef;
newstatement : tstatementnode;
begin
result:=nil;
newstatement:=nil;
if assigned(left) then
begin
result:=internalstatements(newstatement);
addstatement(newstatement,left);
left:=nil;
addstatement(newstatement,self.getcopy);
end;
{ if the function result has been migrated to the parentfpstruct,
we have to load it back to the original location (from which the
code generator will load it into the function result location),
because the code to this that we add in tnodeutils.wrap_proc_body()
gets inserted before the exit label to which this node will jump }
if (target_info.system in systems_fpnestedstruct) and
not(nf_internal in flags) then
begin
pd:=current_procinfo.procdef;
if assigned(pd.funcretsym) and
tabstractnormalvarsym(pd.funcretsym).inparentfpstruct then
begin
if not assigned(result) then
result:=internalstatements(newstatement);
cnodeutils.load_parentfpstruct_nested_funcret(current_procinfo.procdef,newstatement);
end;
end;
if assigned(result) then
begin
addstatement(newstatement,self.getcopy);
{ ensure we don't insert the function result loading code again for
this node }
include(newstatement.left.flags,nf_internal);
end;
resultdef:=voidtype;
end;

32
tests/tbs/tb0622.pp Normal file
View File

@ -0,0 +1,32 @@
{$mode objfpc}
function test: longint;
var
l: longint;
procedure nest;
begin
if result<>111 then
halt(1);
if l<>222 then
halt(2);
l:=1231;
result:=555;
end;
begin
result:=111;
l:=222;
nest;
if l<>1231 then
halt(3);
if result=555 then
exit;
result:=666;
end;
begin
if test<>555 then
halt(4);
end.