瀏覽代碼

* generate an error if the type parameters of a generic routine's definition does not match with its interface or forward declaration
+ added tests

git-svn-id: trunk@39703 -

svenbarth 7 年之前
父節點
當前提交
46ef16ac11
共有 4 個文件被更改,包括 72 次插入0 次删除
  1. 2 0
      .gitattributes
  2. 30 0
      compiler/pdecsub.pas
  3. 20 0
      tests/test/tgenfunc17.pp
  4. 20 0
      tests/test/tgenfunc18.pp

+ 2 - 0
.gitattributes

@@ -13182,6 +13182,8 @@ tests/test/tgenfunc13.pp svneol=native#text/pascal
 tests/test/tgenfunc14.pp svneol=native#text/pascal
 tests/test/tgenfunc15.pp svneol=native#text/pascal
 tests/test/tgenfunc16.pp svneol=native#text/pascal
+tests/test/tgenfunc17.pp svneol=native#text/pascal
+tests/test/tgenfunc18.pp svneol=native#text/pascal
 tests/test/tgenfunc2.pp svneol=native#text/pascal
 tests/test/tgenfunc3.pp svneol=native#text/pascal
 tests/test/tgenfunc4.pp svneol=native#text/pascal

+ 30 - 0
compiler/pdecsub.pas

@@ -3540,6 +3540,29 @@ const
     function proc_add_definition(var currpd:tprocdef):boolean;
 
 
+      function check_generic_parameters(fwpd,currpd:tprocdef):boolean;
+        var
+          i : longint;
+          fwtype,
+          currtype : ttypesym;
+        begin
+          result:=true;
+          if fwpd.genericparas.count<>currpd.genericparas.count then
+            internalerror(2018090101);
+          for i:=0 to fwpd.genericparas.count-1 do
+            begin
+              fwtype:=ttypesym(fwpd.genericparas[i]);
+              currtype:=ttypesym(currpd.genericparas[i]);
+              if fwtype.name<>currtype.name then
+                begin
+                  messagepos1(currtype.fileinfo,sym_e_generic_type_param_mismatch,currtype.realname);
+                  messagepos1(fwtype.fileinfo,sym_e_generic_type_param_decl,fwtype.realname);
+                  result:=false;
+                end;
+            end;
+        end;
+
+
       function equal_generic_procdefs(fwpd,currpd:tprocdef):boolean;
         var
           i : longint;
@@ -3844,6 +3867,13 @@ const
                         inc(fwidx);
                       until false;
                     end;
+                   { check that the type parameter names for generic methods match;
+                     we check this here and not in equal_generic_procdefs as the defs
+                     might still be different due to their parameters, so we'd generate
+                     errors without any need }
+                   if currpd.is_generic and fwpd.is_generic then
+                     { an error here is recoverable, so we simply continue }
+                     check_generic_parameters(fwpd,currpd);
                    { Everything is checked, now we can update the forward declaration
                      with the new data from the implementation }
                    fwpd.forwarddef:=currpd.forwarddef;

+ 20 - 0
tests/test/tgenfunc17.pp

@@ -0,0 +1,20 @@
+{ %FAIL }
+
+{ the type parameters of the implementation need to match those in the interface }
+unit tgenfunc17;
+
+{$mode objfpc}{$H+}
+
+interface
+
+generic procedure Test<T>;
+
+implementation
+
+generic procedure Test<S>;
+begin
+
+end;
+
+end.
+

+ 20 - 0
tests/test/tgenfunc18.pp

@@ -0,0 +1,20 @@
+{ %FAIL }
+
+{ the type parameters of the implementation need to match those of the forward declaration }
+unit tgenfunc18;
+
+{$mode objfpc}{$H+}
+
+interface
+
+implementation
+
+generic procedure Test<T>; forward;
+
+generic procedure Test<S>;
+begin
+
+end;
+
+end.
+