浏览代码

* fix for Mantis #31120: check current_genericdef only if the current_procinfo isn't used

+ added test

Note: the test is added to webtbs although it's right now still failing, cause I'll remove the restriction for nested procedures since the compiler now supports them correctly. Due to the way we handle generics we don't have problems with them unlike Delphi.

git-svn-id: trunk@35147 -
svenbarth 8 年之前
父节点
当前提交
d34acf3bc7
共有 3 个文件被更改,包括 61 次插入16 次删除
  1. 1 0
      .gitattributes
  2. 18 16
      compiler/pgenutil.pas
  3. 42 0
      tests/webtbs/tw31120.pp

+ 1 - 0
.gitattributes

@@ -15316,6 +15316,7 @@ tests/webtbs/tw3104.pp svneol=native#text/plain
 tests/webtbs/tw31076.pp svneol=native#text/pascal
 tests/webtbs/tw3109.pp svneol=native#text/plain
 tests/webtbs/tw3111.pp svneol=native#text/plain
+tests/webtbs/tw31120.pp svneol=native#text/pascal
 tests/webtbs/tw3113.pp svneol=native#text/plain
 tests/webtbs/tw3124.pp svneol=native#text/plain
 tests/webtbs/tw3131.pp svneol=native#text/plain

+ 18 - 16
compiler/pgenutil.pas

@@ -845,27 +845,29 @@ uses
         { decide in which symtable to put the specialization }
         if parse_generic and not assigned(result) then
           begin
-            if not assigned(current_genericdef) then
-              internalerror(2014050901);
             if assigned(current_procinfo) and (df_generic in current_procinfo.procdef.defoptions) then
               { if we are parsing the definition of a method we specialize into
                 the local symtable of it }
               specializest:=current_procinfo.procdef.getsymtable(gs_local)
             else
-              { we specialize the partial specialization into the symtable of the currently parsed
-                generic }
-              case current_genericdef.typ of
-                procvardef:
-                  specializest:=current_genericdef.getsymtable(gs_para);
-                procdef:
-                  specializest:=current_genericdef.getsymtable(gs_local);
-                objectdef,
-                recorddef:
-                  specializest:=current_genericdef.getsymtable(gs_record);
-                arraydef:
-                  specializest:=tarraydef(current_genericdef).symtable;
-                else
-                  internalerror(2014050902);
+              begin
+                if not assigned(current_genericdef) then
+                  internalerror(2014050901);
+                { we specialize the partial specialization into the symtable of the currently parsed
+                  generic }
+                case current_genericdef.typ of
+                  procvardef:
+                    specializest:=current_genericdef.getsymtable(gs_para);
+                  procdef:
+                    specializest:=current_genericdef.getsymtable(gs_local);
+                  objectdef,
+                  recorddef:
+                    specializest:=current_genericdef.getsymtable(gs_record);
+                  arraydef:
+                    specializest:=tarraydef(current_genericdef).symtable;
+                  else
+                    internalerror(2014050902);
+                end;
               end;
           end
         else

+ 42 - 0
tests/webtbs/tw31120.pp

@@ -0,0 +1,42 @@
+{ %NORUN }
+
+program tw31120;
+
+{$mode objfpc}
+
+type
+  TTest = class
+    generic class procedure PrintDefault<T>();
+  end;
+
+generic Function GetDefault<T>(): T;
+  Begin
+    result := default(T);
+  End;
+
+generic Procedure PrintDefault<T>();
+  procedure print();
+    begin
+      writeln(specialize GetDefault<T>())
+    end;
+
+  Begin
+    print()
+  End;
+
+generic class procedure TTest.PrintDefault<T>();
+  procedure print();
+    begin
+      writeln(specialize GetDefault<T>())
+    end;
+
+begin
+  print()
+end;
+
+Begin
+  specialize PrintDefault<LongInt>();
+  specialize PrintDefault<String>();
+  TTest.specialize PrintDefault<Boolean>();
+  TTest.specialize PrintDefault<Char>();
+End.