Pārlūkot izejas kodu

Fix one problem type of Mantis #23546. A record must not contain a static array that uses itself as an element type (in can contain a dynamic array however) otherwise an infinite loop is encountered when checking whether the record needs special init/final code.

pdecvar.pas, read_record_fields:
  * if the def of the field is a static array then use the array's element def (the final element def if it is a multi dimensional array) to check for whether this is the current record type

+ added tests

git-svn-id: trunk@23352 -
svenbarth 12 gadi atpakaļ
vecāks
revīzija
359a228085
7 mainītis faili ar 110 papildinājumiem un 7 dzēšanām
  1. 5 0
      .gitattributes
  2. 26 7
      compiler/pdecvar.pas
  3. 12 0
      tests/tbf/tb0224.pp
  4. 19 0
      tests/tbf/tb0225.pp
  5. 12 0
      tests/tbs/tb0589.pp
  6. 19 0
      tests/tbs/tb0590.pp
  7. 17 0
      tests/webtbf/tw23546b.pp

+ 5 - 0
.gitattributes

@@ -9181,6 +9181,8 @@ tests/tbf/tb0220.pp svneol=native#text/plain
 tests/tbf/tb0221.pp svneol=native#text/plain
 tests/tbf/tb0222.pp svneol=native#text/plain
 tests/tbf/tb0223.pp svneol=native#text/pascal
+tests/tbf/tb0224.pp svneol=native#text/pascal
+tests/tbf/tb0225.pp svneol=native#text/pascal
 tests/tbf/ub0115.pp svneol=native#text/plain
 tests/tbf/ub0149.pp svneol=native#text/plain
 tests/tbf/ub0158a.pp svneol=native#text/plain
@@ -9768,6 +9770,8 @@ tests/tbs/tb0585.pp svneol=native#text/pascal
 tests/tbs/tb0586.pp svneol=native#text/pascal
 tests/tbs/tb0587.pp svneol=native#text/plain
 tests/tbs/tb0588.pp svneol=native#text/pascal
+tests/tbs/tb0589.pp svneol=native#text/pascal
+tests/tbs/tb0590.pp svneol=native#text/pascal
 tests/tbs/tb205.pp svneol=native#text/plain
 tests/tbs/ub0060.pp svneol=native#text/plain
 tests/tbs/ub0069.pp svneol=native#text/plain
@@ -12027,6 +12031,7 @@ tests/webtbf/tw2281.pp svneol=native#text/plain
 tests/webtbf/tw2285.pp svneol=native#text/plain
 tests/webtbf/tw22941.pp svneol=native#text/plain
 tests/webtbf/tw23110.pp svneol=native#text/plain
+tests/webtbf/tw23546b.pp svneol=native#text/pascal
 tests/webtbf/tw23547a.pp svneol=native#text/pascal
 tests/webtbf/tw23547b.pp svneol=native#text/pascal
 tests/webtbf/tw23547c.pp svneol=native#text/pascal

+ 26 - 7
compiler/pdecvar.pas

@@ -1558,7 +1558,7 @@ implementation
          sc : TFPObjectList;
          i  : longint;
          hs,sorg : string;
-         hdef,casetype : tdef;
+         hdef,casetype,tmpdef : tdef;
          { maxsize contains the max. size of a variant }
          { startvarrec contains the start of the variant part of a record }
          maxsize, startvarrecsize : longint;
@@ -1633,13 +1633,32 @@ implementation
              maybe_guarantee_record_typesym(hdef,symtablestack.top);
              block_type:=bt_var;
              { allow only static fields reference to struct where they are declared }
-             if not (vd_class in options) and
-               (is_object(hdef) or is_record(hdef)) and
-               is_owned_by(tabstractrecorddef(recst.defowner),tabstractrecorddef(hdef)) then
+             if not (vd_class in options) then
                begin
-                 Message1(type_e_type_is_not_completly_defined, tabstractrecorddef(hdef).RttiName);
-                 { for error recovery or compiler will crash later }
-                 hdef:=generrordef;
+                 if hdef.typ=arraydef then
+                   begin
+                     tmpdef:=hdef;
+                     while (tmpdef.typ=arraydef) do
+                       begin
+                         { dynamic arrays are allowed }
+                         if ado_IsDynamicArray in tarraydef(tmpdef).arrayoptions then
+                           begin
+                             tmpdef:=nil;
+                             break;
+                           end;
+                         tmpdef:=tarraydef(tmpdef).elementdef;
+                       end;
+                   end
+                 else
+                   tmpdef:=hdef;
+                 if assigned(tmpdef) and
+                     (is_object(tmpdef) or is_record(tmpdef)) and
+                     is_owned_by(tabstractrecorddef(recst.defowner),tabstractrecorddef(tmpdef)) then
+                   begin
+                     Message1(type_e_type_is_not_completly_defined, tabstractrecorddef(tmpdef).RttiName);
+                     { for error recovery or compiler will crash later }
+                     hdef:=generrordef;
+                   end;
                end;
 
              { Process procvar directives }

+ 12 - 0
tests/tbf/tb0224.pp

@@ -0,0 +1,12 @@
+{ %FAIL }
+
+program tb0224;
+
+type
+  TTest = record
+    f: array[0..0] of TTest;
+  end;
+
+begin
+
+end.

+ 19 - 0
tests/tbf/tb0225.pp

@@ -0,0 +1,19 @@
+{ %FAIL }
+
+program tb0225;
+
+{$modeswitch advancedrecords}
+
+type
+  TTest = record
+  public type
+    TTestSub = record
+      f: TTest;
+    end;
+  public
+    f: array of TTestSub;
+  end;
+
+begin
+
+end.

+ 12 - 0
tests/tbs/tb0589.pp

@@ -0,0 +1,12 @@
+{ %NORUN }
+
+program tb0589;
+
+type
+  TTest = record
+    f: array of TTest;
+  end;
+
+begin
+
+end.

+ 19 - 0
tests/tbs/tb0590.pp

@@ -0,0 +1,19 @@
+{ %NORUN }
+
+program tb0590;
+
+{$modeswitch advancedrecords}
+
+type
+  TTest = record
+  public type
+    TTestSub = record
+      f: Integer;
+    end;
+  public
+    f: array[0..0] of TTestSub;
+  end;
+
+begin
+
+end.

+ 17 - 0
tests/webtbf/tw23546b.pp

@@ -0,0 +1,17 @@
+{ %FAIL }
+
+{$MODE DELPHI}
+
+type
+  Wrapper<T> = record
+  strict private
+    type ThisWrapper = Wrapper<T>;  { #21539 }
+  public
+    FWrapper: array [0..0] of ThisWrapper;
+  end;
+
+var
+  wr: Wrapper<Byte>;
+
+begin
+end.