Revert "[Clang] Do not treat Foo -> const Foo conversion sequences as perfect" (#149272)
Reverts llvm/llvm-project#148613 Considering object argument conversion qualifications perfect leads to situations where we prefer a non-template const qualified function over a non-qualified template function, which is very wrong indeed. I explored solutions to work around that, but instead, we might want to go the GCC road and prefer the friend overload in the #147374 example, as this seems a lot more consistent and reliable (cherry picked from commit 28e1e7e1b4b059a2e42f68061475cddb4ad0a6a3)
This commit is contained in:
parent
dd7710b7fd
commit
7ac3c62282
@ -350,11 +350,6 @@ class Sema;
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned BindsToRvalue : 1;
|
||||
|
||||
/// Whether this was an identity conversion with qualification
|
||||
/// conversion for the implicit object argument.
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
unsigned IsImplicitObjectArgumentQualificationConversion : 1;
|
||||
|
||||
/// Whether this binds an implicit object argument to a
|
||||
/// non-static member function without a ref-qualifier.
|
||||
LLVM_PREFERRED_TYPE(bool)
|
||||
@ -453,11 +448,11 @@ class Sema;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
if (!C.hasSameType(getFromType(), getToType(2)))
|
||||
return false;
|
||||
if (BindsToRvalue && IsLvalueReference)
|
||||
return false;
|
||||
if (IsImplicitObjectArgumentQualificationConversion)
|
||||
return C.hasSameUnqualifiedType(getFromType(), getToType(2));
|
||||
return C.hasSameType(getFromType(), getToType(2));
|
||||
return true;
|
||||
}
|
||||
|
||||
ImplicitConversionRank getRank() const;
|
||||
|
||||
@ -245,7 +245,6 @@ void StandardConversionSequence::setAsIdentityConversion() {
|
||||
IsLvalueReference = true;
|
||||
BindsToFunctionLvalue = false;
|
||||
BindsToRvalue = false;
|
||||
IsImplicitObjectArgumentQualificationConversion = false;
|
||||
BindsImplicitObjectArgumentWithoutRefQualifier = false;
|
||||
ObjCLifetimeConversionBinding = false;
|
||||
FromBracedInitList = false;
|
||||
@ -5318,7 +5317,6 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
|
||||
ICS.Standard.DirectBinding = BindsDirectly;
|
||||
ICS.Standard.IsLvalueReference = !isRValRef;
|
||||
ICS.Standard.BindsToFunctionLvalue = T2->isFunctionType();
|
||||
ICS.Standard.IsImplicitObjectArgumentQualificationConversion = false;
|
||||
ICS.Standard.BindsToRvalue = InitCategory.isRValue();
|
||||
ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
|
||||
ICS.Standard.ObjCLifetimeConversionBinding =
|
||||
@ -5498,7 +5496,6 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
|
||||
ICS.Standard.IsLvalueReference = !isRValRef;
|
||||
ICS.Standard.BindsToFunctionLvalue = false;
|
||||
ICS.Standard.BindsToRvalue = true;
|
||||
ICS.Standard.IsImplicitObjectArgumentQualificationConversion = false;
|
||||
ICS.Standard.BindsImplicitObjectArgumentWithoutRefQualifier = false;
|
||||
ICS.Standard.ObjCLifetimeConversionBinding = false;
|
||||
} else if (ICS.isUserDefined()) {
|
||||
@ -5521,8 +5518,6 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType,
|
||||
ICS.UserDefined.After.IsLvalueReference = !isRValRef;
|
||||
ICS.UserDefined.After.BindsToFunctionLvalue = false;
|
||||
ICS.UserDefined.After.BindsToRvalue = !LValRefType;
|
||||
ICS.UserDefined.After.IsImplicitObjectArgumentQualificationConversion =
|
||||
false;
|
||||
ICS.UserDefined.After.BindsImplicitObjectArgumentWithoutRefQualifier = false;
|
||||
ICS.UserDefined.After.ObjCLifetimeConversionBinding = false;
|
||||
ICS.UserDefined.After.FromBracedInitList = false;
|
||||
@ -5807,7 +5802,6 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
|
||||
StandardConversionSequence &SCS = Result.isStandard() ? Result.Standard :
|
||||
Result.UserDefined.After;
|
||||
SCS.ReferenceBinding = true;
|
||||
SCS.IsImplicitObjectArgumentQualificationConversion = false;
|
||||
SCS.IsLvalueReference = ToType->isLValueReferenceType();
|
||||
SCS.BindsToRvalue = true;
|
||||
SCS.BindsToFunctionLvalue = false;
|
||||
@ -6005,12 +5999,8 @@ static ImplicitConversionSequence TryObjectArgumentInitialization(
|
||||
// affects the conversion rank.
|
||||
QualType ClassTypeCanon = S.Context.getCanonicalType(ClassType);
|
||||
ImplicitConversionKind SecondKind;
|
||||
bool IsQualificationConversion = false;
|
||||
if (ImplicitParamType.getCanonicalType() == FromTypeCanon) {
|
||||
if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) {
|
||||
SecondKind = ICK_Identity;
|
||||
} else if (ClassTypeCanon == FromTypeCanon.getLocalUnqualifiedType()) {
|
||||
SecondKind = ICK_Identity;
|
||||
IsQualificationConversion = true;
|
||||
} else if (S.IsDerivedFrom(Loc, FromType, ClassType)) {
|
||||
SecondKind = ICK_Derived_To_Base;
|
||||
} else if (!Method->isExplicitObjectMemberFunction()) {
|
||||
@ -6051,8 +6041,6 @@ static ImplicitConversionSequence TryObjectArgumentInitialization(
|
||||
ICS.Standard.setFromType(FromType);
|
||||
ICS.Standard.setAllToTypes(ImplicitParamType);
|
||||
ICS.Standard.ReferenceBinding = true;
|
||||
ICS.Standard.IsImplicitObjectArgumentQualificationConversion =
|
||||
IsQualificationConversion;
|
||||
ICS.Standard.DirectBinding = true;
|
||||
ICS.Standard.IsLvalueReference = Method->getRefQualifier() != RQ_RValue;
|
||||
ICS.Standard.BindsToFunctionLvalue = false;
|
||||
|
||||
@ -283,31 +283,3 @@ void f() {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace GH147374 {
|
||||
|
||||
struct String {};
|
||||
template <typename T> void operator+(T, String &&) = delete;
|
||||
|
||||
struct Bar {
|
||||
void operator+(String) const; // expected-note {{candidate function}}
|
||||
friend void operator+(Bar, String) {}; // expected-note {{candidate function}}
|
||||
};
|
||||
|
||||
struct Baz {
|
||||
void operator+(String); // expected-note {{candidate function}}
|
||||
friend void operator+(Baz, String) {}; // expected-note {{candidate function}}
|
||||
};
|
||||
|
||||
void test() {
|
||||
Bar a;
|
||||
String b;
|
||||
a + b;
|
||||
//expected-error@-1 {{use of overloaded operator '+' is ambiguous (with operand types 'Bar' and 'String')}}
|
||||
|
||||
Baz z;
|
||||
z + b;
|
||||
//expected-error@-1 {{use of overloaded operator '+' is ambiguous (with operand types 'Baz' and 'String')}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user