ソースを参照

compiler: fix for-in loop for arrays. delphi does not copy arrays to a temp variable and it is possible to change array during loop. + test

git-svn-id: branches/paul/features@13943 -
paul 15 年 前
コミット
88a9db5217
6 ファイル変更67 行追加7 行削除
  1. 1 0
      .gitattributes
  2. 7 4
      compiler/pstatmnt.pas
  3. 1 1
      tests/test/tforin1.pp
  4. 1 1
      tests/test/tforin2.pp
  5. 1 1
      tests/test/tforin3.pp
  6. 56 0
      tests/test/tforin4.pp

+ 1 - 0
.gitattributes

@@ -8212,6 +8212,7 @@ tests/test/tfinal2.pp svneol=native#text/pascal
 tests/test/tforin1.pp svneol=native#text/pascal
 tests/test/tforin2.pp svneol=native#text/pascal
 tests/test/tforin3.pp svneol=native#text/pascal
+tests/test/tforin4.pp svneol=native#text/pascal
 tests/test/tfpu1.pp svneol=native#text/plain
 tests/test/tfpu2.pp svneol=native#text/plain
 tests/test/tfpu3.pp svneol=native#text/plain

+ 7 - 4
compiler/pstatmnt.pas

@@ -569,7 +569,7 @@ implementation
           { result is a block of statements }
           result:=internalstatements(loopstatement);
 
-          if not is_open_array(expr.resultdef) then
+          if (node_complexity(expr) > 1) and not is_open_array(expr.resultdef) then
           begin
             { create a temp variable for expression }
             arrayvar := ctempcreatenode.create(
@@ -598,13 +598,16 @@ implementation
 
           addstatement(loopstatement,loopvar);
 
-
           arrayindex:=ctemprefnode.create(loopvar);
 
           loopbody:=internalstatements(loopbodystatement);
           // for-in loop variable := array_expression[index]
-          addstatement(loopbodystatement,
-              cassignmentnode.create(hloopvar,cvecnode.create(expr.getcopy,arrayindex)));
+          if assigned(arrayvar) then
+            addstatement(loopbodystatement,
+                cassignmentnode.create(hloopvar,cvecnode.create(ctemprefnode.create(arrayvar),arrayindex)))
+          else
+            addstatement(loopbodystatement,
+                cassignmentnode.create(hloopvar,cvecnode.create(expr.getcopy,arrayindex)));
 
           { add the actual statement to the loop }
           addstatement(loopbodystatement,hloopbody);

+ 1 - 1
tests/test/tforin1.pp

@@ -1,4 +1,4 @@
-program project1;
+program tforin1;
 
 {$mode objfpc}{$H+}
 {$apptype console}

+ 1 - 1
tests/test/tforin2.pp

@@ -1,4 +1,4 @@
-program project1;
+program tforin2;
 
 {$mode objfpc}{$H+}
 {$apptype console}

+ 1 - 1
tests/test/tforin3.pp

@@ -1,4 +1,4 @@
-program Project18;
+program tforin3;
 
 {$APPTYPE CONSOLE}
 

+ 56 - 0
tests/test/tforin4.pp

@@ -0,0 +1,56 @@
+program tforin4;
+
+{$APPTYPE CONSOLE}
+
+type
+  TMyArray = array of integer;
+
+function return_array: TMyArray;
+begin
+  SetLength(result, 3);
+  result[0] := 1;
+  result[1] := 2;
+  result[2] := 3;
+end;
+
+procedure TestArrayReturn;
+var
+  i: integer;
+begin
+  for i in return_array do
+    WriteLn(i);
+end;
+
+procedure TestDynamicArray;
+var
+  i: integer;
+  a: array of integer;
+begin
+  setlength(a, 3);
+  a[0]:=1;
+  a[1]:=2;
+  a[2]:=3;
+  for i in a do
+  begin
+    WriteLn(i);
+    a[2] := -1;
+  end;
+end;
+
+procedure TestOpenArray(a: array of integer);
+var
+  i: integer;
+begin
+  for i in a do
+  begin
+    WriteLn(i);
+    a[2] := -1;
+  end;
+end;
+
+begin
+  TestOpenArray([1,2,3]);
+  TestDynamicArray;
+  TestArrayReturn;
+end.
+