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 years ago
parent
commit
fc5ce63134
4 changed files with 40 additions and 12 deletions
  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/tw3073.pp svneol=native#text/plain
 tests/webtbs/tw3082.pp svneol=native#text/plain
 tests/webtbs/tw3082.pp svneol=native#text/plain
 tests/webtbs/tw3083.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/tw30889.pp svneol=native#text/pascal
 tests/webtbs/tw30923.pp svneol=native#text/pascal
 tests/webtbs/tw30923.pp svneol=native#text/pascal
 tests/webtbs/tw3093.pp svneol=native#text/plain
 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);
 constructor ti386tryfinallynode.create(l, r: TNode);
   begin
   begin
     inherited create(l,r);
     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
       { Don't create child procedures for generic methods, their nested-like
         behavior causes compilation errors because real nested procedures
         behavior causes compilation errors because real nested procedures
         aren't allowed for generics. Not creating them doesn't harm because
         aren't allowed for generics. Not creating them doesn't harm because
         generic node tree is discarded without generating code. }
         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;
       exit;
     finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));
     finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));
     finalizepi.force_nested;
     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
     if implicitframe and (current_procinfo.procdef.proccalloption=pocall_safecall) then
       exit;
       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);
       InternalError(2013012501);
 
 
     finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));
     finalizepi:=tcgprocinfo(cprocinfo.create(current_procinfo));

+ 3 - 6
compiler/x86_64/nx64flw.pas

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