Przeglądaj źródła

* read array initializations in generic subroutines without fixed limits, resolves #25602

git-svn-id: trunk@29598 -
florian 10 lat temu
rodzic
commit
461821d1a5
3 zmienionych plików z 58 dodań i 12 usunięć
  1. 1 0
      .gitattributes
  2. 31 12
      compiler/ngtcon.pas
  3. 26 0
      tests/webtbs/tw25602.pp

+ 1 - 0
.gitattributes

@@ -14125,6 +14125,7 @@ tests/webtbs/tw2540.pp svneol=native#text/plain
 tests/webtbs/tw25551.pp svneol=native#text/plain
 tests/webtbs/tw25551.pp svneol=native#text/plain
 tests/webtbs/tw25598.pp svneol=native#text/plain
 tests/webtbs/tw25598.pp svneol=native#text/plain
 tests/webtbs/tw25600.pp svneol=native#text/pascal
 tests/webtbs/tw25600.pp svneol=native#text/pascal
+tests/webtbs/tw25602.pp svneol=native#text/pascal
 tests/webtbs/tw25603.pp svneol=native#text/pascal
 tests/webtbs/tw25603.pp svneol=native#text/pascal
 tests/webtbs/tw25604.pp svneol=native#text/pascal
 tests/webtbs/tw25604.pp svneol=native#text/pascal
 tests/webtbs/tw25605.pp svneol=native#text/pascal
 tests/webtbs/tw25605.pp svneol=native#text/pascal

+ 31 - 12
compiler/ngtcon.pas

@@ -1109,21 +1109,40 @@ function get_next_varsym(def: tabstractrecorddef; const SymList:TFPHashObjectLis
           begin
           begin
             oldoffset:=curoffset;
             oldoffset:=curoffset;
             curoffset:=0;
             curoffset:=0;
-            for i:=def.lowrange to def.highrange-1 do
+            { in case of a generic subroutine, it might be we cannot
+              determine the size yet }
+            if assigned(current_procinfo) and (df_generic in current_procinfo.procdef.defoptions) then
               begin
               begin
-                read_typed_const_data(def.elementdef);
-                Inc(curoffset,def.elementdef.size);
-                if token=_RKLAMMER then
+                while true do
                   begin
                   begin
-                    Message1(parser_e_more_array_elements_expected,tostr(def.highrange-i));
-                    consume(_RKLAMMER);
-                    exit;
-                  end
-                else
-                  consume(_COMMA);
+                    read_typed_const_data(def.elementdef);
+                    if token=_RKLAMMER then
+                      begin
+                        consume(_RKLAMMER);
+                        break;
+                      end
+                    else
+                      consume(_COMMA);
+                  end;
+              end
+            else
+              begin
+                for i:=def.lowrange to def.highrange-1 do
+                  begin
+                    read_typed_const_data(def.elementdef);
+                    Inc(curoffset,def.elementdef.size);
+                    if token=_RKLAMMER then
+                      begin
+                        Message1(parser_e_more_array_elements_expected,tostr(def.highrange-i));
+                        consume(_RKLAMMER);
+                        exit;
+                      end
+                    else
+                      consume(_COMMA);
+                  end;
+                read_typed_const_data(def.elementdef);
+                consume(_RKLAMMER);
               end;
               end;
-            read_typed_const_data(def.elementdef);
-            consume(_RKLAMMER);
             curoffset:=oldoffset;
             curoffset:=oldoffset;
           end
           end
         { if array of char then we allow also a string }
         { if array of char then we allow also a string }

+ 26 - 0
tests/webtbs/tw25602.pp

@@ -0,0 +1,26 @@
+{$MODE DELPHI}
+
+type
+  TA = class
+    const C = 1;
+  end;
+
+  TB<T> = object
+    procedure Foo;
+  end;
+
+procedure TB<T>.Foo;
+var
+  // X: array[0..T.C] of byte = (0); // Error: Expected another 1 array elements
+  X: array[0..T.C] of byte = (0, 2); // Fatal: Syntax error, ")" expected but "," found
+begin
+  if high(x)<>1 then
+    halt(1);
+  writeln('ok');
+end;
+
+var
+  x: TB<TA>;
+begin
+  x.Foo;
+end.