* 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 -
This commit is contained in:
svenbarth 2016-11-18 14:01:03 +00:00
parent 3f080ad23f
commit fc5ce63134
4 changed files with 40 additions and 12 deletions

1
.gitattributes vendored
View File

@ -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

View File

@ -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));

View File

@ -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
tests/webtbs/tw30832.pp Normal file
View File

@ -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.