diff --git a/.gitattributes b/.gitattributes
index 37e5d10909..114400011d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -12224,6 +12224,7 @@ tests/webtbs/tw2110.pp svneol=native#text/plain
 tests/webtbs/tw21146.pp svneol=native#text/pascal
 tests/webtbs/tw21151.pp svneol=native#text/plain
 tests/webtbs/tw21177.pp svneol=native#text/plain
+tests/webtbs/tw21179.pp svneol=native#text/pascal
 tests/webtbs/tw2128.pp svneol=native#text/plain
 tests/webtbs/tw2129.pp svneol=native#text/plain
 tests/webtbs/tw2129b.pp svneol=native#text/plain
diff --git a/compiler/defcmp.pas b/compiler/defcmp.pas
index 2922c7af3f..ec7f36f6e3 100644
--- a/compiler/defcmp.pas
+++ b/compiler/defcmp.pas
@@ -50,7 +50,15 @@ interface
 
        tcompare_paras_options = set of tcompare_paras_option;
 
-       tcompare_defs_option = (cdo_internal,cdo_explicit,cdo_check_operator,cdo_allow_variant,cdo_parameter,cdo_warn_incompatible_univ);
+       tcompare_defs_option = (
+          cdo_internal,
+          cdo_explicit,
+          cdo_check_operator,
+          cdo_allow_variant,
+          cdo_parameter,
+          cdo_warn_incompatible_univ,
+          cdo_strict_undefined_check  // undefined defs are incompatible to everything except other undefined defs
+       );
        tcompare_defs_options = set of tcompare_defs_option;
 
        tconverttype = (tc_none,
@@ -210,14 +218,38 @@ implementation
             exit;
           end;
 
-         { undefined def? then mark it as equal }
-         if (def_from.typ=undefineddef) or
-            (def_to.typ=undefineddef) then
-          begin
-            doconv:=tc_equal;
-            compare_defs_ext:=te_exact;
-            exit;
-          end;
+         if cdo_strict_undefined_check in cdoptions then
+           begin
+             { undefined defs are considered equal if both are undefined defs }
+             if (def_from.typ=undefineddef) and
+                (def_to.typ=undefineddef) then
+              begin
+                doconv:=tc_equal;
+                compare_defs_ext:=te_exact;
+                exit;
+              end;
+
+             { if only one def is a undefined def then they are not considered as
+               equal}
+             if (def_from.typ=undefineddef) or
+                (def_to.typ=undefineddef) then
+              begin
+                doconv:=tc_not_possible;
+                compare_defs_ext:=te_incompatible;
+                exit;
+              end;
+           end
+         else
+           begin
+             { undefined defs are considered equal }
+             if (def_from.typ=undefineddef) or
+                (def_to.typ=undefineddef) then
+              begin
+                doconv:=tc_equal;
+                compare_defs_ext:=te_exact;
+                exit;
+              end;
+           end;
 
          { we walk the wanted (def_to) types and check then the def_from
            types if there is a conversion possible }
@@ -1668,7 +1700,7 @@ implementation
         i1,i2     : byte;
       begin
          compare_paras:=te_incompatible;
-         cdoptions:=[cdo_parameter,cdo_check_operator,cdo_allow_variant];
+         cdoptions:=[cdo_parameter,cdo_check_operator,cdo_allow_variant,cdo_strict_undefined_check];
          { we need to parse the list from left-right so the
            not-default parameters are checked first }
          lowesteq:=high(tequaltype);
diff --git a/compiler/ptype.pas b/compiler/ptype.pas
index 038ce2f7f4..f3ae1f0be1 100644
--- a/compiler/ptype.pas
+++ b/compiler/ptype.pas
@@ -400,6 +400,13 @@ implementation
                 Message(parser_e_no_generics_as_types);
                 def:=generrordef;
               end
+            else if (def.typ=undefineddef) and (sp_generic_dummy in srsym.symoptions)
+                and parse_generic and
+                (current_genericdef.typ in [recorddef,objectdef]) and
+                (Pos(upper(srsym.realname),tabstractrecorddef(current_genericdef).objname^)=1) then
+              begin
+                def:=current_genericdef;
+              end
             else if is_classhelper(def) and
                 not (stoParseClassParent in options) then
               begin
diff --git a/tests/webtbs/tw21179.pp b/tests/webtbs/tw21179.pp
new file mode 100644
index 0000000000..0b858a5eb8
--- /dev/null
+++ b/tests/webtbs/tw21179.pp
@@ -0,0 +1,22 @@
+{ %NORUN }
+
+{$mode OBJFPC}
+{$modeswitch ADVANCEDRECORDS}
+program generic_record_op_bug;
+
+type generic GVec3<T> = record
+  D : Byte;
+  class operator *( const A, B : GVec3 ) : GVec3;
+  class operator *( const A : GVec3; Scalar : T ) : GVec3;
+end;
+
+class operator GVec3.*( const A, B : GVec3 ) : GVec3;
+begin
+end;
+
+class operator GVec3.*( const A : GVec3; Scalar : T ) : GVec3;
+begin
+end;
+
+begin
+end.