forked from OSchip/llvm-project
Issue a good diagnostics when attempt to select
a type convesion function results in ambiguity. llvm-svn: 81812
This commit is contained in:
parent
f8122966a9
commit
19c7328881
|
@ -1619,6 +1619,8 @@ def err_type_defined_in_condition : Error<
|
|||
"types may not be defined in conditions">;
|
||||
def err_typecheck_bool_condition : Error<
|
||||
"value of type %0 is not contextually convertible to 'bool'">;
|
||||
def err_typecheck_ambiguous_bool_condition : Error<
|
||||
"conversion from %0 to 'bool' is ambiguous">;
|
||||
def err_expected_class_or_namespace : Error<"expected a class or namespace">;
|
||||
def err_invalid_declarator_scope : Error<
|
||||
"definition or redeclaration of %0 not in a namespace enclosing %1">;
|
||||
|
|
|
@ -772,6 +772,7 @@ public:
|
|||
bool IsQualificationConversion(QualType FromType, QualType ToType);
|
||||
bool IsUserDefinedConversion(Expr *From, QualType ToType,
|
||||
UserDefinedConversionSequence& User,
|
||||
OverloadCandidateSet& Conversions,
|
||||
bool AllowConversionFunctions,
|
||||
bool AllowExplicit, bool ForceRValue);
|
||||
|
||||
|
|
|
@ -410,10 +410,12 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
|
|||
bool AllowExplicit, bool ForceRValue,
|
||||
bool InOverloadResolution) {
|
||||
ImplicitConversionSequence ICS;
|
||||
OverloadCandidateSet Conversions;
|
||||
if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard))
|
||||
ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
else if (getLangOptions().CPlusPlus &&
|
||||
IsUserDefinedConversion(From, ToType, ICS.UserDefined,
|
||||
Conversions,
|
||||
!SuppressUserConversions, AllowExplicit,
|
||||
ForceRValue)) {
|
||||
ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
|
||||
|
@ -1355,9 +1357,9 @@ static void GetFunctionAndTemplate(AnyFunctionDecl Orig, T *&Function,
|
|||
/// for overload resolution.
|
||||
bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
|
||||
UserDefinedConversionSequence& User,
|
||||
OverloadCandidateSet& CandidateSet,
|
||||
bool AllowConversionFunctions,
|
||||
bool AllowExplicit, bool ForceRValue) {
|
||||
OverloadCandidateSet CandidateSet;
|
||||
if (const RecordType *ToRecordType = ToType->getAs<RecordType>()) {
|
||||
if (CXXRecordDecl *ToRecordDecl
|
||||
= dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
|
||||
|
@ -2097,9 +2099,19 @@ bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
|
|||
if (!PerformImplicitConversion(From, Context.BoolTy, ICS, "converting"))
|
||||
return false;
|
||||
|
||||
return Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_bool_condition)
|
||||
<< From->getType() << From->getSourceRange();
|
||||
OverloadCandidateSet CandidateSet;
|
||||
IsUserDefinedConversion(From, Context.BoolTy, ICS.UserDefined,
|
||||
CandidateSet,
|
||||
true, true, false);
|
||||
if (CandidateSet.begin() == CandidateSet.end())
|
||||
return Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_bool_condition)
|
||||
<< From->getType() << From->getSourceRange();
|
||||
Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_typecheck_ambiguous_bool_condition)
|
||||
<< From->getType() << From->getSourceRange();
|
||||
PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// AddOverloadCandidate - Adds the given function to the set of
|
||||
|
|
|
@ -79,16 +79,16 @@ void f(const C& c) {
|
|||
// Test. Conversion in base class is visible in derived class.
|
||||
class XB {
|
||||
public:
|
||||
operator int();
|
||||
operator int(); // expected-note {{candidate function}}
|
||||
};
|
||||
|
||||
class Yb : public XB {
|
||||
public:
|
||||
operator char();
|
||||
operator char(); // expected-note {{candidate function}}
|
||||
};
|
||||
|
||||
void f(Yb& a) {
|
||||
if (a) { } // expected-error {{value of type 'class Yb' is not contextually convertible to 'bool'}}
|
||||
if (a) { } // expected-error {{conversion from 'class Yb' to 'bool' is ambiguous}}
|
||||
int i = a; // OK. calls XB::operator int();
|
||||
char ch = a; // OK. calls Yb::operator char();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue