Kaynağa Gözat

Fix for Mantis #27750.

pgenutil.pas:
  * parse_generic_parameters: create explicit undefineddefs for type parameters that don't have a constraint
  * insert_generic_parameter_types: move the created undefineddefs from the parent symtable to the generic's symtable
defcmp.pas, compare_defs_ext:
  * in case the flag for strict undefineddef checks is set don't consider two different undefineddefs as compatible
+ added tests

git-svn-id: trunk@30705 -
svenbarth 10 yıl önce
ebeveyn
işleme
19c6d72c7b

+ 2 - 0
.gitattributes

@@ -14405,6 +14405,8 @@ tests/webtbs/tw2767.pp svneol=native#text/plain
 tests/webtbs/tw27691.pp svneol=native#text/plain
 tests/webtbs/tw2771.pp svneol=native#text/plain
 tests/webtbs/tw2772.pp svneol=native#text/plain
+tests/webtbs/tw27750a.pp svneol=native#text/pascal
+tests/webtbs/tw27750b.pp svneol=native#text/pascal
 tests/webtbs/tw2776.pp svneol=native#text/plain
 tests/webtbs/tw2778.pp svneol=native#text/plain
 tests/webtbs/tw2779.pp svneol=native#text/plain

+ 3 - 3
compiler/defcmp.pas

@@ -247,12 +247,12 @@ implementation
 
          if cdo_strict_undefined_check in cdoptions then
            begin
-             { undefined defs are considered equal if both are undefined defs }
+             { two different undefined defs are not considered equal }
              if (def_from.typ=undefineddef) and
                 (def_to.typ=undefineddef) then
               begin
-                doconv:=tc_equal;
-                compare_defs_ext:=te_exact;
+                doconv:=tc_not_possible;
+                compare_defs_ext:=te_incompatible;
                 exit;
               end;
 

+ 27 - 3
compiler/pgenutil.pas

@@ -1132,10 +1132,26 @@ uses
               constraintdata.free;
             end
           else
-            if token=_SEMICOLON then
-              { a semicolon terminates a type parameter group }
-              firstidx:=result.count;
+            begin
+              if token=_SEMICOLON then
+                begin
+                  { two different typeless parameters are considered as incompatible }
+                  for i:=firstidx to result.count-1 do
+                    begin
+                      ttypesym(result[i]).typedef:=cundefineddef.create;
+                      ttypesym(result[i]).typedef.typesym:=ttypesym(result[i]);
+                    end;
+                  { a semicolon terminates a type parameter group }
+                  firstidx:=result.count;
+                end;
+            end;
         until not (try_to_consume(_COMMA) or try_to_consume(_SEMICOLON));
+        { two different typeless parameters are considered as incompatible }
+        for i:=firstidx to result.count-1 do
+          begin
+            ttypesym(result[i]).typedef:=cundefineddef.create;
+            ttypesym(result[i]).typedef.typesym:=ttypesym(result[i]);
+          end;
         block_type:=old_block_type;
       end;
 
@@ -1179,6 +1195,14 @@ uses
               end
             else
               begin
+                if (generictype.typedef.typ=undefineddef) and (generictype.typedef<>cundefinedtype) then
+                  begin
+                    { the generic parameters were parsed before the genericdef existed thus the
+                      undefineddefs were added as part of the parent symtable }
+                    if assigned(generictype.typedef.owner) then
+                      generictype.typedef.owner.DefList.Extract(generictype.typedef);
+                    generictype.typedef.changeowner(st);
+                  end;
                 st.insert(generictype);
                 include(generictype.symoptions,sp_generic_para);
               end;

+ 33 - 0
tests/webtbs/tw27750a.pp

@@ -0,0 +1,33 @@
+{ %NORUN }
+
+program tw27750a;
+
+{$MODE DELPHI}
+
+type
+
+  { TGeneric }
+
+  TGeneric<Foo, Bar> = record
+  public type
+    TGFB = TGeneric<Foo, Bar>;
+  public
+    class operator implicit(aFoo : Foo) : TGFB;
+    class operator implicit(aBar : Bar) : TGFB;
+  end;
+
+{ TGeneric }
+
+class operator TGeneric<Foo, Bar>.implicit(aFoo: Foo): TGFB;
+begin
+
+end;
+
+class operator TGeneric<Foo, Bar>.implicit(aBar: Bar): TGFB;
+begin
+
+end;
+
+begin
+end.
+

+ 34 - 0
tests/webtbs/tw27750b.pp

@@ -0,0 +1,34 @@
+{ %NORUN }
+
+program tw27750b;
+
+{$MODE OBJFPC}
+{$modeswitch advancedrecords}
+
+type
+
+  { TGeneric }
+
+  generic TGeneric<Foo, Bar> = record
+  public type
+    TGFB = specialize TGeneric<Foo, Bar>;
+  public
+    class operator :=(aFoo : Foo) : TGFB;
+    class operator :=(aBar : Bar) : TGFB;
+  end;
+
+{ TGeneric }
+
+class operator TGeneric.:=(aFoo: Foo): TGFB;
+begin
+
+end;
+
+class operator TGeneric.:=(aBar: Bar): TGFB;
+begin
+
+end;
+
+begin
+end.
+