Browse Source

complier: fix for-in array loop. use a temp variable for the loop expression only if loop is not an open array loop

git-svn-id: branches/paul/features@13935 -
paul 16 years ago
parent
commit
1b2121c652
1 changed files with 29 additions and 4 deletions
  1. 29 4
      compiler/pstatmnt.pas

+ 29 - 4
compiler/pstatmnt.pas

@@ -563,12 +563,33 @@ implementation
         function create_array_loop(hloopvar, hloopbody, expr: tnode): tnode;
         var
           loopstatement, loopbodystatement: tstatementnode;
-          loopvar: ttempcreatenode;
-          arrayindex, loopbody, forloopnode: tnode;
+          loopvar, arrayvar: ttempcreatenode;
+          arrayindex, lowbound, highbound, loopbody, forloopnode: tnode;
         begin
           { result is a block of statements }
           result:=internalstatements(loopstatement);
 
+          if not is_open_array(expr.resultdef) then
+          begin
+            { create a temp variable for expression }
+            arrayvar := ctempcreatenode.create(
+              expr.resultdef,
+              expr.resultdef.size,
+              tt_persistent,true);
+
+            lowbound:=cinlinenode.create(in_low_x,false,ctemprefnode.create(arrayvar));
+            highbound:=cinlinenode.create(in_high_x,false,ctemprefnode.create(arrayvar));
+
+            addstatement(loopstatement,arrayvar);
+            addstatement(loopstatement,cassignmentnode.create(ctemprefnode.create(arrayvar),expr.getcopy));
+          end
+          else
+          begin
+            arrayvar:=nil;
+            lowbound:=cinlinenode.create(in_low_x,false,expr.getcopy);
+            highbound:=cinlinenode.create(in_high_x,false,expr.getcopy);
+          end;
+
           { create a loop counter }
           loopvar := ctempcreatenode.create(
             tarraydef(expr.resultdef).rangedef,
@@ -577,6 +598,7 @@ implementation
 
           addstatement(loopstatement,loopvar);
 
+
           arrayindex:=ctemprefnode.create(loopvar);
 
           loopbody:=internalstatements(loopbodystatement);
@@ -588,14 +610,17 @@ implementation
           addstatement(loopbodystatement,hloopbody);
           
           forloopnode:=cfornode.create(ctemprefnode.create(loopvar),
-             cinlinenode.create(in_low_x,false,expr.getcopy),
-             cinlinenode.create(in_high_x,false,expr.getcopy),
+             lowbound,
+             highbound,
              loopbody,
              false);
 
           addstatement(loopstatement,forloopnode);
           { free the loop counter }
           addstatement(loopstatement,ctempdeletenode.create(loopvar));
+          { free the temp variable for expression if needed }
+          if arrayvar<>nil then
+            addstatement(loopstatement,ctempdeletenode.create(arrayvar));
         end;
 
         function create_set_loop(hloopvar, hloopbody, expr: tnode): tnode;