Browse Source

* fix for Mantis #30832: instead of checking a procdef's struct for df_generic check the procdef itself, this way global generic methods or generic methods that are part of non-generic classes or records are caught as well.
+ added test

git-svn-id: trunk@34914 -

svenbarth 8 năm trước cách đây
mục cha
commit
fc5ce63134
4 tập tin đã thay đổi với 40 bổ sung12 xóa
  1. 1 0
      .gitattributes
  2. 4 6
      compiler/i386/n386flw.pas
  3. 3 6
      compiler/x86_64/nx64flw.pas
  4. 32 0
      tests/webtbs/tw30832.pp

+ 1 - 0
.gitattributes

@@ -15252,6 +15252,7 @@ tests/webtbs/tw30706.pp svneol=native#text/plain
 tests/webtbs/tw3073.pp svneol=native#text/plain
 tests/webtbs/tw3082.pp svneol=native#text/plain
 tests/webtbs/tw3083.pp svneol=native#text/plain
+tests/webtbs/tw30832.pp svneol=native#text/pascal
 tests/webtbs/tw30889.pp svneol=native#text/pascal
 tests/webtbs/tw30923.pp svneol=native#text/pascal
 tests/webtbs/tw3093.pp svneol=native#text/plain

+ 4 - 6
compiler/i386/n386flw.pas

@@ -160,14 +160,13 @@ function copy_parasize(var n: tnode; arg: pointer): foreachnoderesult;
 constructor ti386tryfinallynode.create(l, r: TNode);
   begin
     inherited create(l,r);
-    if (target_info.system<>system_i386_win32) or (
+    if (target_info.system<>system_i386_win32) or
       { Don't create child procedures for generic methods, their nested-like
         behavior causes compilation errors because real nested procedures
         aren't allowed for generics. Not creating them doesn't harm because
         generic node tree is discarded without generating code. }
-        assigned(current_procinfo.procdef.struct) and
-        (df_generic in current_procinfo.procdef.struct.defoptions)
-      ) then
+      (df_generic in current_procinfo.procdef.defoptions)
+      then
       exit;
     finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));
     finalizepi.force_nested;
@@ -194,8 +193,7 @@ constructor ti386tryfinallynode.create_implicit(l, r, _t1: TNode);
     if implicitframe and (current_procinfo.procdef.proccalloption=pocall_safecall) then
       exit;
 
-    if assigned(current_procinfo.procdef.struct) and
-      (df_generic in current_procinfo.procdef.struct.defoptions) then
+    if df_generic in current_procinfo.procdef.defoptions then
       InternalError(2013012501);
 
     finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));

+ 3 - 6
compiler/x86_64/nx64flw.pas

@@ -154,14 +154,12 @@ constructor tx64tryfinallynode.create(l, r: TNode);
   begin
     inherited create(l,r);
     if (target_info.system=system_x86_64_win64) and
-       (
       { Don't create child procedures for generic methods, their nested-like
         behavior causes compilation errors because real nested procedures
         aren't allowed for generics. Not creating them doesn't harm because
         generic node tree is discarded without generating code. }
-        not assigned(current_procinfo.procdef.struct) or
-        not(df_generic in current_procinfo.procdef.struct.defoptions)
-       ) then
+       not (df_generic in current_procinfo.procdef.defoptions)
+       then
       begin
         finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));
         finalizepi.force_nested;
@@ -183,8 +181,7 @@ constructor tx64tryfinallynode.create_implicit(l, r, _t1: TNode);
     inherited create_implicit(l, r, _t1);
     if (target_info.system=system_x86_64_win64) then
       begin
-        if assigned(current_procinfo.procdef.struct) and
-          (df_generic in current_procinfo.procdef.struct.defoptions) then
+        if df_generic in current_procinfo.procdef.defoptions then
           InternalError(2013012501);
 
         finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));

+ 32 - 0
tests/webtbs/tw30832.pp

@@ -0,0 +1,32 @@
+{ %NORUN }
+
+program tw30832;
+
+{$mode objfpc}
+
+type
+  generic TTest<T> = class
+    procedure Test;
+  end;
+
+procedure TTest.Test;
+begin
+  try
+    Writeln(Default(T));
+  finally
+    Writeln('Finally');
+  end;
+end;
+
+generic procedure Test<T>;
+begin
+  try
+    Writeln(Default(T));
+  finally
+    Writeln('Finally');
+  end;
+end;
+
+begin
+  specialize Test<LongInt>;
+end.