Fix for Mantis #29080.

psub.pas, tcgprocinfo.parse_body:
  * ensure that parse_generic and current_genericdef are set correctly when parsing a generic routine
pgenutil.pas, generate_specialization_phase2:
  * when we're specializing inside a generic we don't want to have the routine definitions, so let the compiler assume that the routine is no longer a forward definition

+ added test

git-svn-id: trunk@33275 -
This commit is contained in:
svenbarth 2016-03-18 16:31:23 +00:00
parent 570607b1d1
commit e9fab1bfee
4 changed files with 60 additions and 1 deletions

1
.gitattributes vendored
View File

@ -14945,6 +14945,7 @@ tests/webtbs/tw29053.pp svneol=native#text/pascal
tests/webtbs/tw29053b.pp svneol=native#text/pascal
tests/webtbs/tw29064.pp svneol=native#text/plain
tests/webtbs/tw2908.pp svneol=native#text/plain
tests/webtbs/tw29080.pp svneol=native#text/pascal
tests/webtbs/tw29086.pp -text svneol=native#text/plain
tests/webtbs/tw29096.pp svneol=native#text/plain
tests/webtbs/tw2911.pp svneol=native#text/plain

View File

@ -997,6 +997,10 @@ uses
begin
handle_calling_convention(tprocdef(result),hcc_all);
proc_add_definition(tprocdef(result));
{ for partial specializations we implicitely declare the routine as
having its implementation although we'll not specialize it in reality }
if parse_generic then
unset_forwarddef(result);
end;
else
{ parse hint directives for records and arrays }

View File

@ -1797,7 +1797,14 @@ implementation
current_procinfo:=self;
current_structdef:=procdef.struct;
if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
{ if the procdef is truly a generic (thus takes parameters itself) then
/that/ is our genericdef, not the - potentially - generic struct }
if procdef.is_generic then
begin
current_genericdef:=procdef;
parse_generic:=true;
end
else if assigned(current_structdef) and (df_generic in current_structdef.defoptions) then
begin
current_genericdef:=current_structdef;
parse_generic:=true;

47
tests/webtbs/tw29080.pp Normal file
View File

@ -0,0 +1,47 @@
unit tw29080;
{$mode delphi}
interface
function Min<T>(const A, B: T): T;
function Max<T>(const A, B: T): T;
procedure Test<T>(const A, B: T);
implementation
function Min<T>(const A, B: T): T;
// Error on line below, GenericTest.pas(14,1) Error: Internal error 200301231
begin
if A < B then
Result := A
else
Result := B;
end;
function Max<T>(const A, B: T): T;
begin
if A > B then
Result := A
else
Result := B;
end;
procedure Test<T>(const A, B: T);
var
Value: T;
begin
// This should be legal
Value := Min<T>(A, B);
WriteLn('The Min<T> of values, ', A, ' and ', B, ' are: ', Value);
// As well as this
Value := Max<T>(A, B);
WriteLn('The Max<T> of values, ', A, ' and ', B, ' are: ', Value);
end;
procedure TestFix;
begin
Test<LongInt>(42, 21);
end;
end.