浏览代码

* pgenutil.pas, generate_specialization:
When parsing an inline specialization inside a generic we need to
respect the "parsedtype" parameter which tells us whether the first
generic parameter was already parsed. This fixes Mantis #20871 .
+ added test for this

git-svn-id: trunk@20251 -

svenbarth 13 年之前
父节点
当前提交
ef10ce3bd0
共有 3 个文件被更改,包括 47 次插入3 次删除
  1. 1 0
      .gitattributes
  2. 8 3
      compiler/pgenutil.pas
  3. 38 0
      tests/webtbs/tw20871.pp

+ 1 - 0
.gitattributes

@@ -12174,6 +12174,7 @@ tests/webtbs/tw20821.pp svneol=native#text/pascal
 tests/webtbs/tw20827.pp svneol=native#text/plain
 tests/webtbs/tw20836.pp svneol=native#text/pascal
 tests/webtbs/tw20851.pp svneol=native#text/pascal
+tests/webtbs/tw20871.pp svneol=native#text/pascal
 tests/webtbs/tw20872a.pp svneol=native#text/pascal
 tests/webtbs/tw20872b.pp svneol=native#text/pascal
 tests/webtbs/tw20872c.pp svneol=native#text/pascal

+ 8 - 3
compiler/pgenutil.pas

@@ -106,12 +106,17 @@ uses
           for recording in genericbuf }
         if parse_generic then
           begin
-            if not try_to_consume(_LT) then
+            first:=assigned(parsedtype);
+            if not first and not try_to_consume(_LT) then
               consume(_LSHARPBRACKET);
             gencount:=0;
             repeat
-              pt2:=factor(false,true);
-              pt2.free;
+              if not first then
+                begin
+                  pt2:=factor(false,true);
+                  pt2.free;
+                end;
+              first:=false;
               inc(gencount);
             until not try_to_consume(_COMMA);
             if not try_to_consume(_GT) then

+ 38 - 0
tests/webtbs/tw20871.pp

@@ -0,0 +1,38 @@
+{ %NORUN }
+
+program tw20871;
+{$MODE delphi}
+{$DEFINE CAUSE_ERROR}
+
+type
+  TInterior<TValue> = class end;
+
+  TExterior<TValue> = class
+  strict private
+    FInterior: TInterior<TValue>;
+  public
+    constructor Create;
+    destructor Destroy; override;
+  end;
+
+constructor TExterior<TValue>.Create;
+{$IFDEF CAUSE_ERROR}
+begin
+  FInterior := TInterior<TValue>.Create;
+                             { ^ Compiler reports here that “<” is expected }
+{$ELSE}
+type
+  TSpecializedInterior = TInterior<TValue>;
+begin
+  FInterior := TSpecializedInterior.Create;
+{$ENDIF}
+end;
+
+destructor TExterior<TValue>.Destroy;
+begin
+  FInterior.Free;
+end;
+
+begin
+  TExterior<Integer>.Create.Free;
+end.