Browse Source

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 -
svenbarth 9 years ago
parent
commit
e9fab1bfee
4 changed files with 60 additions and 1 deletions
  1. 1 0
      .gitattributes
  2. 4 0
      compiler/pgenutil.pas
  3. 8 1
      compiler/psub.pas
  4. 47 0
      tests/webtbs/tw29080.pp

+ 1 - 0
.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

+ 4 - 0
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 }

+ 8 - 1
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;

+ 47 - 0
tests/webtbs/tw29080.pp

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