mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 21:28:03 +02:00
Fix Mantis #21179
* defcmp.pas: + Extend compare_def_ext by the possiblity to specify whether strict or loose comparison of undefined defs should be applied. * in strict mode undefined defs are incompatible to all other defs except other undefined defs * in loose mode undefined defs are equal to anything (this is how FPC behaved up to now) + Enable the strict mode in compare_paras so that overloads with generic type parameters are possible * ptype.pas, single_type: If the generic dummy of the currently parsed generic is encountered in non-Delphi modes then we need to return the current genericdef. This condition needs to be checked using the ObjName of the def, because the link from the type symbol to the current def is not yet established + added test for bug report git-svn-id: trunk@20345 -
This commit is contained in:
parent
429af6f40b
commit
2a872978dc
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
22
tests/webtbs/tw21179.pp
Normal file
22
tests/webtbs/tw21179.pp
Normal file
@ -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.
|
Loading…
Reference in New Issue
Block a user