From 5f14029e74fdd316a8d5b8b1d54af4cb965956b9 Mon Sep 17 00:00:00 2001 From: Jonas Maebe <jonas@freepascal.org> Date: Sun, 20 Dec 2015 20:56:08 +0000 Subject: [PATCH] * if a function result has been migrated to the parentfpstruct because it is accessed by a nested routine, assign it back to the original funcretsym at the end because the code generator is hardcoded to use funcretsym. We can't replace funcretsym with an absolutevarsym that redirects to the parentfpstruct field, because the code generator can only handle simple variables git-svn-id: trunk@32687 - --- compiler/ngenutil.pas | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/compiler/ngenutil.pas b/compiler/ngenutil.pas index 4f5793a7e1..3e8050ba9b 100644 --- a/compiler/ngenutil.pas +++ b/compiler/ngenutil.pas @@ -117,7 +117,7 @@ implementation verbose,version,globals,cutils,constexp, scanner,systems,procinfo,fmodule, aasmbase,aasmtai,aasmcnst, - symbase,symtable,defutil, + symbase,symtable,defutil,symcreat, nadd,ncal,ncnv,ncon,nflw,ninl,nld,nmem,nobj,nutils, ppu, pass_1; @@ -313,7 +313,8 @@ implementation class function tnodeutils.wrap_proc_body(pd: tprocdef; n: tnode): tnode; var stat: tstatementnode; - block: tnode; + block, + target: tnode; psym: tsym; begin result:=maybe_insert_trashing(pd,n); @@ -384,6 +385,31 @@ implementation end; end; end; + if target_info.system in systems_fpnestedstruct then + begin + { if the funcretsym was moved to the parentfpstruct, move its value + back into the funcretsym now, as the code generator is hardcoded + to use the funcretsym when loading the value to be returned; + replacing it with an absolutevarsym that redirects to the field in + the parentfpstruct doesn't work, as the code generator cannot deal + with such symbols } + if assigned(pd.funcretsym) and + tabstractnormalvarsym(pd.funcretsym).inparentfpstruct then + begin + block:=internalstatements(stat); + addstatement(stat,result); + target:=cloadnode.create(pd.funcretsym,pd.funcretsym.owner); + { ensure the target of this assignment doesn't translate the + funcretsym also to its alias in the parentfpstruct } + include(target.flags,nf_internal); + addstatement(stat, + cassignmentnode.create( + target,cloadnode.create(pd.funcretsym,pd.funcretsym.owner) + ) + ); + result:=block; + end; + end; end;