2
0
Эх сурвалжийг харах

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

Jonas Maebe 9 жил өмнө
parent
commit
051317e82e

+ 1 - 0
.gitattributes

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

+ 27 - 2
compiler/nflw.pas

@@ -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 - 0
tests/tbs/tb0622.pp

@@ -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.