Pārlūkot izejas kodu

* 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 -

Jonas Maebe 9 gadi atpakaļ
vecāks
revīzija
5f14029e74
1 mainītis faili ar 28 papildinājumiem un 2 dzēšanām
  1. 28 2
      compiler/ngenutil.pas

+ 28 - 2
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;