From e9fab1bfee4c518859a68c0be8feb1670577ee74 Mon Sep 17 00:00:00 2001 From: svenbarth Date: Fri, 18 Mar 2016 16:31:23 +0000 Subject: [PATCH] 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 - --- .gitattributes | 1 + compiler/pgenutil.pas | 4 ++++ compiler/psub.pas | 9 +++++++- tests/webtbs/tw29080.pp | 47 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tests/webtbs/tw29080.pp diff --git a/.gitattributes b/.gitattributes index f10e94bea7..7ecdd3e439 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/compiler/pgenutil.pas b/compiler/pgenutil.pas index a67570fa71..8b0821ce52 100644 --- a/compiler/pgenutil.pas +++ b/compiler/pgenutil.pas @@ -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 } diff --git a/compiler/psub.pas b/compiler/psub.pas index 348ccad6c3..1f1804ef2b 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -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; diff --git a/tests/webtbs/tw29080.pp b/tests/webtbs/tw29080.pp new file mode 100644 index 0000000000..91edc434bc --- /dev/null +++ b/tests/webtbs/tw29080.pp @@ -0,0 +1,47 @@ +unit tw29080; + +{$mode delphi} + +interface + +function Min(const A, B: T): T; +function Max(const A, B: T): T; +procedure Test(const A, B: T); + +implementation + +function Min(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(const A, B: T): T; +begin + if A > B then + Result := A + else + Result := B; +end; + +procedure Test(const A, B: T); +var + Value: T; +begin + // This should be legal + Value := Min(A, B); + WriteLn('The Min of values, ', A, ' and ', B, ' are: ', Value); + // As well as this + Value := Max(A, B); + WriteLn('The Max of values, ', A, ' and ', B, ' are: ', Value); +end; + +procedure TestFix; +begin + Test(42, 21); +end; + +end.