* 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 -
This commit is contained in:
svenbarth 2016-12-17 21:20:44 +00:00
parent 779799c406
commit d34acf3bc7
3 changed files with 61 additions and 16 deletions

1
.gitattributes vendored
View File

@ -15316,6 +15316,7 @@ tests/webtbs/tw3104.pp svneol=native#text/plain
tests/webtbs/tw31076.pp svneol=native#text/pascal tests/webtbs/tw31076.pp svneol=native#text/pascal
tests/webtbs/tw3109.pp svneol=native#text/plain tests/webtbs/tw3109.pp svneol=native#text/plain
tests/webtbs/tw3111.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/tw3113.pp svneol=native#text/plain
tests/webtbs/tw3124.pp svneol=native#text/plain tests/webtbs/tw3124.pp svneol=native#text/plain
tests/webtbs/tw3131.pp svneol=native#text/plain tests/webtbs/tw3131.pp svneol=native#text/plain

View File

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

42
tests/webtbs/tw31120.pp Normal file
View File

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