зеркало из https://github.com/microsoft/clang-1.git
Introduce a specific representation for the ambiguous implicit conversion
sequence. Lots of small relevant changes. Fixes some serious problems with ambiguous conversions; also possibly improves associated diagnostics. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@93214 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
1fc00e6e49
Коммит
1d31833450
|
@ -1044,6 +1044,9 @@ public:
|
|||
SourceLocation Loc = SourceLocation());
|
||||
|
||||
void NoteOverloadCandidate(FunctionDecl *Fn);
|
||||
void DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
|
||||
SourceLocation CaretLoc,
|
||||
const PartialDiagnostic &PDiag);
|
||||
|
||||
FunctionDecl *ResolveAddressOfOverloadedFunction(Expr *From, QualType ToType,
|
||||
bool Complain);
|
||||
|
|
|
@ -893,7 +893,7 @@ TryStaticImplicitCast(Sema &Self, Expr *&SrcExpr, QualType DestType,
|
|||
/*InOverloadResolution=*/false,
|
||||
/*one of user provided casts*/true);
|
||||
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion)
|
||||
if (ICS.isBad())
|
||||
return TC_NotApplicable;
|
||||
|
||||
// The conversion is possible, so commit to it.
|
||||
|
|
|
@ -4389,8 +4389,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
= CompareReferenceRelationship(DeclLoc, T1, T2, DerivedToBase);
|
||||
|
||||
// Most paths end in a failed conversion.
|
||||
if (ICS)
|
||||
ICS->ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
if (ICS) ICS->setBad();
|
||||
|
||||
// C++ [dcl.init.ref]p5:
|
||||
// A reference to type "cv1 T1" is initialized by an expression
|
||||
|
@ -4428,7 +4427,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
// has a type that is a derived class of the parameter type,
|
||||
// in which case the implicit conversion sequence is a
|
||||
// derived-to-base Conversion (13.3.3.1).
|
||||
ICS->ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
ICS->setStandard();
|
||||
ICS->Standard.First = ICK_Identity;
|
||||
ICS->Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
|
||||
ICS->Standard.Third = ICK_Identity;
|
||||
|
@ -4513,7 +4512,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
// conversion or, if the conversion function returns an
|
||||
// entity of a type that is a derived class of the parameter
|
||||
// type, a derived-to-base Conversion.
|
||||
ICS->ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
|
||||
ICS->setUserDefined();
|
||||
ICS->UserDefined.Before = Best->Conversions[0].Standard;
|
||||
ICS->UserDefined.After = Best->FinalConversion;
|
||||
ICS->UserDefined.ConversionFunction = Best->Function;
|
||||
|
@ -4539,10 +4538,11 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
|
||||
case OR_Ambiguous:
|
||||
if (ICS) {
|
||||
ICS->setAmbiguous();
|
||||
for (OverloadCandidateSet::iterator Cand = CandidateSet.begin();
|
||||
Cand != CandidateSet.end(); ++Cand)
|
||||
if (Cand->Viable)
|
||||
ICS->ConversionFunctionSet.push_back(Cand->Function);
|
||||
ICS->Ambiguous.addConversion(Cand->Function);
|
||||
break;
|
||||
}
|
||||
Diag(DeclLoc, diag::err_ref_init_ambiguous) << DeclType << Init->getType()
|
||||
|
@ -4616,7 +4616,7 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
if (InitLvalue != Expr::LV_Valid && T2->isRecordType() &&
|
||||
RefRelationship >= Ref_Compatible_With_Added_Qualification) {
|
||||
if (ICS) {
|
||||
ICS->ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
ICS->setStandard();
|
||||
ICS->Standard.First = ICK_Identity;
|
||||
ICS->Standard.Second = DerivedToBase? ICK_Derived_To_Base : ICK_Identity;
|
||||
ICS->Standard.Third = ICK_Identity;
|
||||
|
@ -4688,29 +4688,26 @@ Sema::CheckReferenceInit(Expr *&Init, QualType DeclType,
|
|||
/*InOverloadResolution=*/false);
|
||||
|
||||
// Of course, that's still a reference binding.
|
||||
if (ICS->ConversionKind == ImplicitConversionSequence::StandardConversion) {
|
||||
if (ICS->isStandard()) {
|
||||
ICS->Standard.ReferenceBinding = true;
|
||||
ICS->Standard.RRefBinding = isRValRef;
|
||||
} else if (ICS->ConversionKind ==
|
||||
ImplicitConversionSequence::UserDefinedConversion) {
|
||||
} else if (ICS->isUserDefined()) {
|
||||
ICS->UserDefined.After.ReferenceBinding = true;
|
||||
ICS->UserDefined.After.RRefBinding = isRValRef;
|
||||
}
|
||||
return ICS->ConversionKind == ImplicitConversionSequence::BadConversion;
|
||||
return ICS->isBad();
|
||||
} else {
|
||||
ImplicitConversionSequence Conversions;
|
||||
bool badConversion = PerformImplicitConversion(Init, T1, AA_Initializing,
|
||||
false, false,
|
||||
Conversions);
|
||||
if (badConversion) {
|
||||
if ((Conversions.ConversionKind ==
|
||||
ImplicitConversionSequence::BadConversion)
|
||||
&& !Conversions.ConversionFunctionSet.empty()) {
|
||||
if (Conversions.isAmbiguous()) {
|
||||
Diag(DeclLoc,
|
||||
diag::err_lvalue_to_rvalue_ambig_ref) << Init->getSourceRange();
|
||||
for (int j = Conversions.ConversionFunctionSet.size()-1;
|
||||
for (int j = Conversions.Ambiguous.conversions().size()-1;
|
||||
j >= 0; j--) {
|
||||
FunctionDecl *Func = Conversions.ConversionFunctionSet[j];
|
||||
FunctionDecl *Func = Conversions.Ambiguous.conversions()[j];
|
||||
NoteOverloadCandidate(Func);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1075,7 +1075,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
|
|||
AssignmentAction Action, bool AllowExplicit,
|
||||
bool Elidable,
|
||||
ImplicitConversionSequence& ICS) {
|
||||
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
ICS.setBad();
|
||||
if (Elidable && getLangOptions().CPlusPlus0x) {
|
||||
ICS = TryImplicitConversion(From, ToType,
|
||||
/*SuppressUserConversions=*/false,
|
||||
|
@ -1083,7 +1083,7 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
|
|||
/*ForceRValue=*/true,
|
||||
/*InOverloadResolution=*/false);
|
||||
}
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) {
|
||||
if (ICS.isBad()) {
|
||||
ICS = TryImplicitConversion(From, ToType,
|
||||
/*SuppressUserConversions=*/false,
|
||||
AllowExplicit,
|
||||
|
@ -1103,7 +1103,7 @@ bool
|
|||
Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
|
||||
const ImplicitConversionSequence &ICS,
|
||||
AssignmentAction Action, bool IgnoreBaseAccess) {
|
||||
switch (ICS.ConversionKind) {
|
||||
switch (ICS.getKind()) {
|
||||
case ImplicitConversionSequence::StandardConversion:
|
||||
if (PerformImplicitConversion(From, ToType, ICS.Standard, Action,
|
||||
IgnoreBaseAccess))
|
||||
|
@ -1158,6 +1158,12 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType,
|
|||
AA_Converting, IgnoreBaseAccess);
|
||||
}
|
||||
|
||||
case ImplicitConversionSequence::AmbiguousConversion:
|
||||
DiagnoseAmbiguousConversion(ICS, From->getExprLoc(),
|
||||
PDiag(diag::err_typecheck_ambiguous_condition)
|
||||
<< From->getSourceRange());
|
||||
return true;
|
||||
|
||||
case ImplicitConversionSequence::EllipsisConversion:
|
||||
assert(false && "Cannot perform an ellipsis conversion");
|
||||
return false;
|
||||
|
@ -1474,14 +1480,18 @@ QualType Sema::CheckPointerToMemberOperands(
|
|||
|
||||
/// \brief Get the target type of a standard or user-defined conversion.
|
||||
static QualType TargetType(const ImplicitConversionSequence &ICS) {
|
||||
assert((ICS.ConversionKind ==
|
||||
ImplicitConversionSequence::StandardConversion ||
|
||||
ICS.ConversionKind ==
|
||||
ImplicitConversionSequence::UserDefinedConversion) &&
|
||||
"function only valid for standard or user-defined conversions");
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::StandardConversion)
|
||||
return QualType::getFromOpaquePtr(ICS.Standard.ToTypePtr);
|
||||
return QualType::getFromOpaquePtr(ICS.UserDefined.After.ToTypePtr);
|
||||
switch (ICS.getKind()) {
|
||||
case ImplicitConversionSequence::StandardConversion:
|
||||
return ICS.Standard.getToType();
|
||||
case ImplicitConversionSequence::UserDefinedConversion:
|
||||
return ICS.UserDefined.After.getToType();
|
||||
case ImplicitConversionSequence::AmbiguousConversion:
|
||||
return ICS.Ambiguous.getToType();
|
||||
case ImplicitConversionSequence::EllipsisConversion:
|
||||
case ImplicitConversionSequence::BadConversion:
|
||||
llvm_unreachable("function not valid for ellipsis or bad conversions");
|
||||
}
|
||||
return QualType(); // silence warnings
|
||||
}
|
||||
|
||||
/// \brief Try to convert a type to another according to C++0x 5.16p3.
|
||||
|
@ -1511,19 +1521,16 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To,
|
|||
/*ForceRValue=*/false,
|
||||
&ICS))
|
||||
{
|
||||
assert((ICS.ConversionKind ==
|
||||
ImplicitConversionSequence::StandardConversion ||
|
||||
ICS.ConversionKind ==
|
||||
ImplicitConversionSequence::UserDefinedConversion) &&
|
||||
assert((ICS.isStandard() || ICS.isUserDefined()) &&
|
||||
"expected a definite conversion");
|
||||
bool DirectBinding =
|
||||
ICS.ConversionKind == ImplicitConversionSequence::StandardConversion ?
|
||||
ICS.Standard.DirectBinding : ICS.UserDefined.After.DirectBinding;
|
||||
ICS.isStandard() ? ICS.Standard.DirectBinding
|
||||
: ICS.UserDefined.After.DirectBinding;
|
||||
if (DirectBinding)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
ICS.setBad();
|
||||
// -- If E2 is an rvalue, or if the conversion above cannot be done:
|
||||
// -- if E1 and E2 have class type, and the underlying class types are
|
||||
// the same or one is a base class of the other:
|
||||
|
@ -1619,8 +1626,7 @@ static bool FindConditionalOverload(Sema &Self, Expr *&LHS, Expr *&RHS,
|
|||
/// handles the reference binding specially.
|
||||
static bool ConvertForConditional(Sema &Self, Expr *&E,
|
||||
const ImplicitConversionSequence &ICS) {
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::StandardConversion &&
|
||||
ICS.Standard.ReferenceBinding) {
|
||||
if (ICS.isStandard() && ICS.Standard.ReferenceBinding) {
|
||||
assert(ICS.Standard.DirectBinding &&
|
||||
"TryClassUnification should never generate indirect ref bindings");
|
||||
// FIXME: CheckReferenceInit should be able to reuse the ICS instead of
|
||||
|
@ -1632,8 +1638,7 @@ static bool ConvertForConditional(Sema &Self, Expr *&E,
|
|||
/*AllowExplicit=*/false,
|
||||
/*ForceRValue=*/false);
|
||||
}
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion &&
|
||||
ICS.UserDefined.After.ReferenceBinding) {
|
||||
if (ICS.isUserDefined() && ICS.UserDefined.After.ReferenceBinding) {
|
||||
assert(ICS.UserDefined.After.DirectBinding &&
|
||||
"TryClassUnification should never generate indirect ref bindings");
|
||||
return Self.CheckReferenceInit(E, Self.Context.getLValueReferenceType(
|
||||
|
@ -1721,10 +1726,8 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS,
|
|||
if (TryClassUnification(*this, RHS, LHS, QuestionLoc, ICSRightToLeft))
|
||||
return QualType();
|
||||
|
||||
bool HaveL2R = ICSLeftToRight.ConversionKind !=
|
||||
ImplicitConversionSequence::BadConversion;
|
||||
bool HaveR2L = ICSRightToLeft.ConversionKind !=
|
||||
ImplicitConversionSequence::BadConversion;
|
||||
bool HaveL2R = !ICSLeftToRight.isBad();
|
||||
bool HaveR2L = !ICSRightToLeft.isBad();
|
||||
// If both can be converted, [...] the program is ill-formed.
|
||||
if (HaveL2R && HaveR2L) {
|
||||
Diag(QuestionLoc, diag::err_conditional_ambiguous)
|
||||
|
@ -1938,8 +1941,8 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) {
|
|||
/*InOverloadResolution=*/false);
|
||||
|
||||
ImplicitConversionSequence E1ToC2, E2ToC2;
|
||||
E1ToC2.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
E2ToC2.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
E1ToC2.setBad();
|
||||
E2ToC2.setBad();
|
||||
if (Context.getCanonicalType(Composite1) !=
|
||||
Context.getCanonicalType(Composite2)) {
|
||||
E1ToC2 = TryImplicitConversion(E1, Composite2,
|
||||
|
@ -1954,14 +1957,8 @@ QualType Sema::FindCompositePointerType(Expr *&E1, Expr *&E2) {
|
|||
/*InOverloadResolution=*/false);
|
||||
}
|
||||
|
||||
bool ToC1Viable = E1ToC1.ConversionKind !=
|
||||
ImplicitConversionSequence::BadConversion
|
||||
&& E2ToC1.ConversionKind !=
|
||||
ImplicitConversionSequence::BadConversion;
|
||||
bool ToC2Viable = E1ToC2.ConversionKind !=
|
||||
ImplicitConversionSequence::BadConversion
|
||||
&& E2ToC2.ConversionKind !=
|
||||
ImplicitConversionSequence::BadConversion;
|
||||
bool ToC1Viable = !E1ToC1.isBad() && !E2ToC1.isBad();
|
||||
bool ToC2Viable = !E1ToC2.isBad() && !E2ToC2.isBad();
|
||||
if (ToC1Viable && !ToC2Viable) {
|
||||
if (!PerformImplicitConversion(E1, Composite1, E1ToC1, Sema::AA_Converting) &&
|
||||
!PerformImplicitConversion(E2, Composite1, E2ToC1, Sema::AA_Converting))
|
||||
|
|
|
@ -670,7 +670,7 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList,
|
|||
/*ForceRValue=*/false,
|
||||
/*InOverloadResolution=*/false);
|
||||
|
||||
if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion) {
|
||||
if (!ICS.isBad()) {
|
||||
if (SemaRef.PerformImplicitConversion(expr, ElemType, ICS,
|
||||
Sema::AA_Initializing))
|
||||
hadError = true;
|
||||
|
@ -2300,6 +2300,11 @@ static void TryReferenceInitialization(Sema &S,
|
|||
Sequence);
|
||||
if (ConvOvlResult == OR_Success)
|
||||
return;
|
||||
if (ConvOvlResult != OR_No_Viable_Function) {
|
||||
Sequence.SetOverloadFailure(
|
||||
InitializationSequence::FK_ReferenceInitOverloadFailed,
|
||||
ConvOvlResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2384,7 +2389,7 @@ static void TryReferenceInitialization(Sema &S,
|
|||
/*FIXME:InOverloadResolution=*/false,
|
||||
/*UserCast=*/Kind.isExplicitCast());
|
||||
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) {
|
||||
if (ICS.isBad()) {
|
||||
// FIXME: Use the conversion function set stored in ICS to turn
|
||||
// this into an overloading ambiguity diagnostic. However, we need
|
||||
// to keep that set as an OverloadCandidateSet rather than as some
|
||||
|
@ -2711,7 +2716,7 @@ static void TryUserDefinedConversion(Sema &S,
|
|||
if (Best->FinalConversion.First || Best->FinalConversion.Second ||
|
||||
Best->FinalConversion.Third) {
|
||||
ImplicitConversionSequence ICS;
|
||||
ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
ICS.setStandard();
|
||||
ICS.Standard = Best->FinalConversion;
|
||||
Sequence.AddConversionSequenceStep(ICS, DestType);
|
||||
}
|
||||
|
@ -2732,7 +2737,7 @@ static void TryImplicitConversion(Sema &S,
|
|||
/*FIXME:InOverloadResolution=*/false,
|
||||
/*UserCast=*/Kind.isExplicitCast());
|
||||
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion) {
|
||||
if (ICS.isBad()) {
|
||||
Sequence.SetFailed(InitializationSequence::FK_ConversionFailed);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -145,15 +145,12 @@ ImplicitConversionRank StandardConversionSequence::getRank() const {
|
|||
/// used as part of the ranking of standard conversion sequences
|
||||
/// (C++ 13.3.3.2p4).
|
||||
bool StandardConversionSequence::isPointerConversionToBool() const {
|
||||
QualType FromType = QualType::getFromOpaquePtr(FromTypePtr);
|
||||
QualType ToType = QualType::getFromOpaquePtr(ToTypePtr);
|
||||
|
||||
// Note that FromType has not necessarily been transformed by the
|
||||
// array-to-pointer or function-to-pointer implicit conversions, so
|
||||
// check for their presence as well as checking whether FromType is
|
||||
// a pointer.
|
||||
if (ToType->isBooleanType() &&
|
||||
(FromType->isPointerType() || FromType->isBlockPointerType() ||
|
||||
if (getToType()->isBooleanType() &&
|
||||
(getFromType()->isPointerType() || getFromType()->isBlockPointerType() ||
|
||||
First == ICK_Array_To_Pointer || First == ICK_Function_To_Pointer))
|
||||
return true;
|
||||
|
||||
|
@ -167,8 +164,8 @@ bool StandardConversionSequence::isPointerConversionToBool() const {
|
|||
bool
|
||||
StandardConversionSequence::
|
||||
isPointerConversionToVoidPointer(ASTContext& Context) const {
|
||||
QualType FromType = QualType::getFromOpaquePtr(FromTypePtr);
|
||||
QualType ToType = QualType::getFromOpaquePtr(ToTypePtr);
|
||||
QualType FromType = getFromType();
|
||||
QualType ToType = getToType();
|
||||
|
||||
// Note that FromType has not necessarily been transformed by the
|
||||
// array-to-pointer implicit conversion, so check for its presence
|
||||
|
@ -250,6 +247,9 @@ void ImplicitConversionSequence::DebugPrint() const {
|
|||
case EllipsisConversion:
|
||||
fprintf(stderr, "Ellipsis conversion");
|
||||
break;
|
||||
case AmbiguousConversion:
|
||||
fprintf(stderr, "Ambiguous conversion");
|
||||
break;
|
||||
case BadConversion:
|
||||
fprintf(stderr, "Bad conversion");
|
||||
break;
|
||||
|
@ -258,6 +258,22 @@ void ImplicitConversionSequence::DebugPrint() const {
|
|||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
void AmbiguousConversionSequence::construct() {
|
||||
new (&conversions()) ConversionSet();
|
||||
}
|
||||
|
||||
void AmbiguousConversionSequence::destruct() {
|
||||
conversions().~ConversionSet();
|
||||
}
|
||||
|
||||
void
|
||||
AmbiguousConversionSequence::copyFrom(const AmbiguousConversionSequence &O) {
|
||||
FromTypePtr = O.FromTypePtr;
|
||||
ToTypePtr = O.ToTypePtr;
|
||||
new (&conversions()) ConversionSet(O.conversions());
|
||||
}
|
||||
|
||||
|
||||
// IsOverload - Determine whether the given New declaration is an
|
||||
// overload of the declarations in Old. This routine returns false if
|
||||
// New and Old cannot be overloaded, e.g., if New has the same
|
||||
|
@ -432,14 +448,14 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
|
|||
OverloadCandidateSet Conversions;
|
||||
OverloadingResult UserDefResult = OR_Success;
|
||||
if (IsStandardConversion(From, ToType, InOverloadResolution, ICS.Standard))
|
||||
ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
ICS.setStandard();
|
||||
else if (getLangOptions().CPlusPlus &&
|
||||
(UserDefResult = IsUserDefinedConversion(From, ToType,
|
||||
ICS.UserDefined,
|
||||
Conversions,
|
||||
!SuppressUserConversions, AllowExplicit,
|
||||
ForceRValue, UserCast)) == OR_Success) {
|
||||
ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion;
|
||||
ICS.setUserDefined();
|
||||
// C++ [over.ics.user]p4:
|
||||
// A conversion of an expression of class type to the same class
|
||||
// type is given Exact Match rank, and a conversion of an
|
||||
|
@ -456,10 +472,10 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
|
|||
(FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon))) {
|
||||
// Turn this into a "standard" conversion sequence, so that it
|
||||
// gets ranked with standard conversion sequences.
|
||||
ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
ICS.setStandard();
|
||||
ICS.Standard.setAsIdentityConversion();
|
||||
ICS.Standard.FromTypePtr = From->getType().getAsOpaquePtr();
|
||||
ICS.Standard.ToTypePtr = ToType.getAsOpaquePtr();
|
||||
ICS.Standard.setFromType(From->getType());
|
||||
ICS.Standard.setToType(ToType);
|
||||
ICS.Standard.CopyConstructor = Constructor;
|
||||
if (ToCanon != FromCanon)
|
||||
ICS.Standard.Second = ICK_Derived_To_Base;
|
||||
|
@ -473,17 +489,18 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType,
|
|||
// of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or
|
||||
// 13.3.1.6 in all cases, only standard conversion sequences and
|
||||
// ellipsis conversion sequences are allowed.
|
||||
if (SuppressUserConversions &&
|
||||
ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion)
|
||||
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
} else {
|
||||
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
if (UserDefResult == OR_Ambiguous) {
|
||||
if (SuppressUserConversions && ICS.isUserDefined())
|
||||
ICS.setBad();
|
||||
} else if (UserDefResult == OR_Ambiguous) {
|
||||
ICS.setAmbiguous();
|
||||
ICS.Ambiguous.setFromType(From->getType());
|
||||
ICS.Ambiguous.setToType(ToType);
|
||||
for (OverloadCandidateSet::iterator Cand = Conversions.begin();
|
||||
Cand != Conversions.end(); ++Cand)
|
||||
if (Cand->Viable)
|
||||
ICS.ConversionFunctionSet.push_back(Cand->Function);
|
||||
}
|
||||
ICS.Ambiguous.addConversion(Cand->Function);
|
||||
} else {
|
||||
ICS.setBad();
|
||||
}
|
||||
|
||||
return ICS;
|
||||
|
@ -524,7 +541,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
|
|||
SCS.setAsIdentityConversion();
|
||||
SCS.Deprecated = false;
|
||||
SCS.IncompatibleObjC = false;
|
||||
SCS.FromTypePtr = FromType.getAsOpaquePtr();
|
||||
SCS.setFromType(FromType);
|
||||
SCS.CopyConstructor = 0;
|
||||
|
||||
// There are no standard conversions for class types in C++, so
|
||||
|
@ -573,7 +590,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
|
|||
// conversion (4.4). (C++ 4.2p2)
|
||||
SCS.Second = ICK_Identity;
|
||||
SCS.Third = ICK_Qualification;
|
||||
SCS.ToTypePtr = ToType.getAsOpaquePtr();
|
||||
SCS.setToType(ToType);
|
||||
return true;
|
||||
}
|
||||
} else if (FromType->isFunctionType() && argIsLvalue == Expr::LV_Valid) {
|
||||
|
@ -724,7 +741,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType,
|
|||
if (CanonFrom != CanonTo)
|
||||
return false;
|
||||
|
||||
SCS.ToTypePtr = FromType.getAsOpaquePtr();
|
||||
SCS.setToType(FromType);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1544,8 +1561,7 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
|
|||
// the argument of the constructor.
|
||||
//
|
||||
QualType ThisType = Constructor->getThisType(Context);
|
||||
if (Best->Conversions[0].ConversionKind ==
|
||||
ImplicitConversionSequence::EllipsisConversion)
|
||||
if (Best->Conversions[0].isEllipsis())
|
||||
User.EllipsisConversion = true;
|
||||
else {
|
||||
User.Before = Best->Conversions[0].Standard;
|
||||
|
@ -1553,9 +1569,9 @@ OverloadingResult Sema::IsUserDefinedConversion(Expr *From, QualType ToType,
|
|||
}
|
||||
User.ConversionFunction = Constructor;
|
||||
User.After.setAsIdentityConversion();
|
||||
User.After.FromTypePtr
|
||||
= ThisType->getAs<PointerType>()->getPointeeType().getAsOpaquePtr();
|
||||
User.After.ToTypePtr = ToType.getAsOpaquePtr();
|
||||
User.After.setFromType(
|
||||
ThisType->getAs<PointerType>()->getPointeeType());
|
||||
User.After.setToType(ToType);
|
||||
return OR_Success;
|
||||
} else if (CXXConversionDecl *Conversion
|
||||
= dyn_cast<CXXConversionDecl>(Best->Function)) {
|
||||
|
@ -1635,18 +1651,28 @@ Sema::CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1,
|
|||
// conversion sequence than an ellipsis conversion sequence
|
||||
// (13.3.3.1.3).
|
||||
//
|
||||
if (ICS1.ConversionKind < ICS2.ConversionKind)
|
||||
// C++0x [over.best.ics]p10:
|
||||
// For the purpose of ranking implicit conversion sequences as
|
||||
// described in 13.3.3.2, the ambiguous conversion sequence is
|
||||
// treated as a user-defined sequence that is indistinguishable
|
||||
// from any other user-defined conversion sequence.
|
||||
if (ICS1.getKind() < ICS2.getKind()) {
|
||||
if (!(ICS1.isUserDefined() && ICS2.isAmbiguous()))
|
||||
return ImplicitConversionSequence::Better;
|
||||
else if (ICS2.ConversionKind < ICS1.ConversionKind)
|
||||
} else if (ICS2.getKind() < ICS1.getKind()) {
|
||||
if (!(ICS2.isUserDefined() && ICS1.isAmbiguous()))
|
||||
return ImplicitConversionSequence::Worse;
|
||||
}
|
||||
|
||||
if (ICS1.isAmbiguous() || ICS2.isAmbiguous())
|
||||
return ImplicitConversionSequence::Indistinguishable;
|
||||
|
||||
// Two implicit conversion sequences of the same form are
|
||||
// indistinguishable conversion sequences unless one of the
|
||||
// following rules apply: (C++ 13.3.3.2p3):
|
||||
if (ICS1.ConversionKind == ImplicitConversionSequence::StandardConversion)
|
||||
if (ICS1.isStandard())
|
||||
return CompareStandardConversionSequences(ICS1.Standard, ICS2.Standard);
|
||||
else if (ICS1.ConversionKind ==
|
||||
ImplicitConversionSequence::UserDefinedConversion) {
|
||||
else if (ICS1.isUserDefined()) {
|
||||
// User-defined conversion sequence U1 is a better conversion
|
||||
// sequence than another user-defined conversion sequence U2 if
|
||||
// they contain the same user-defined conversion function or
|
||||
|
@ -1739,8 +1765,8 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
|
|||
// Both conversion sequences are conversions to void
|
||||
// pointers. Compare the source types to determine if there's an
|
||||
// inheritance relationship in their sources.
|
||||
QualType FromType1 = QualType::getFromOpaquePtr(SCS1.FromTypePtr);
|
||||
QualType FromType2 = QualType::getFromOpaquePtr(SCS2.FromTypePtr);
|
||||
QualType FromType1 = SCS1.getFromType();
|
||||
QualType FromType2 = SCS2.getFromType();
|
||||
|
||||
// Adjust the types we're converting from via the array-to-pointer
|
||||
// conversion, if we need to.
|
||||
|
@ -1796,8 +1822,8 @@ Sema::CompareStandardConversionSequences(const StandardConversionSequence& SCS1,
|
|||
// top-level cv-qualifiers, and the type to which the reference
|
||||
// initialized by S2 refers is more cv-qualified than the type
|
||||
// to which the reference initialized by S1 refers.
|
||||
QualType T1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr);
|
||||
QualType T2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr);
|
||||
QualType T1 = SCS1.getToType();
|
||||
QualType T2 = SCS2.getToType();
|
||||
T1 = Context.getCanonicalType(T1);
|
||||
T2 = Context.getCanonicalType(T2);
|
||||
Qualifiers T1Quals, T2Quals;
|
||||
|
@ -1927,10 +1953,10 @@ Sema::CompareQualificationConversions(const StandardConversionSequence& SCS1,
|
|||
ImplicitConversionSequence::CompareKind
|
||||
Sema::CompareDerivedToBaseConversions(const StandardConversionSequence& SCS1,
|
||||
const StandardConversionSequence& SCS2) {
|
||||
QualType FromType1 = QualType::getFromOpaquePtr(SCS1.FromTypePtr);
|
||||
QualType ToType1 = QualType::getFromOpaquePtr(SCS1.ToTypePtr);
|
||||
QualType FromType2 = QualType::getFromOpaquePtr(SCS2.FromTypePtr);
|
||||
QualType ToType2 = QualType::getFromOpaquePtr(SCS2.ToTypePtr);
|
||||
QualType FromType1 = SCS1.getFromType();
|
||||
QualType ToType1 = SCS1.getToType();
|
||||
QualType FromType2 = SCS2.getFromType();
|
||||
QualType ToType2 = SCS2.getToType();
|
||||
|
||||
// Adjust the types we're converting from via the array-to-pointer
|
||||
// conversion, if we need to.
|
||||
|
@ -2175,7 +2201,7 @@ Sema::TryObjectArgumentInitialization(QualType FromType,
|
|||
// to exit early.
|
||||
ImplicitConversionSequence ICS;
|
||||
ICS.Standard.setAsIdentityConversion();
|
||||
ICS.ConversionKind = ImplicitConversionSequence::BadConversion;
|
||||
ICS.setBad();
|
||||
|
||||
// We need to have an object of class type.
|
||||
if (const PointerType *PT = FromType->getAs<PointerType>())
|
||||
|
@ -2211,9 +2237,9 @@ Sema::TryObjectArgumentInitialization(QualType FromType,
|
|||
return ICS;
|
||||
|
||||
// Success. Mark this as a reference binding.
|
||||
ICS.ConversionKind = ImplicitConversionSequence::StandardConversion;
|
||||
ICS.Standard.FromTypePtr = FromType.getAsOpaquePtr();
|
||||
ICS.Standard.ToTypePtr = ImplicitParamType.getAsOpaquePtr();
|
||||
ICS.setStandard();
|
||||
ICS.Standard.setFromType(FromType);
|
||||
ICS.Standard.setToType(ImplicitParamType);
|
||||
ICS.Standard.ReferenceBinding = true;
|
||||
ICS.Standard.DirectBinding = true;
|
||||
ICS.Standard.RRefBinding = false;
|
||||
|
@ -2242,7 +2268,7 @@ Sema::PerformObjectArgumentInitialization(Expr *&From, CXXMethodDecl *Method) {
|
|||
ImplicitConversionSequence ICS
|
||||
= TryObjectArgumentInitialization(From->getType(), Method,
|
||||
Method->getParent());
|
||||
if (ICS.ConversionKind == ImplicitConversionSequence::BadConversion)
|
||||
if (ICS.isBad())
|
||||
return Diag(From->getSourceRange().getBegin(),
|
||||
diag::err_implicit_object_parameter_init)
|
||||
<< ImplicitParamRecordType << FromRecordType << From->getSourceRange();
|
||||
|
@ -2274,8 +2300,8 @@ ImplicitConversionSequence Sema::TryContextuallyConvertToBool(Expr *From) {
|
|||
/// of the expression From to bool (C++0x [conv]p3).
|
||||
bool Sema::PerformContextuallyConvertToBool(Expr *&From) {
|
||||
ImplicitConversionSequence ICS = TryContextuallyConvertToBool(From);
|
||||
if (!PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting))
|
||||
return false;
|
||||
if (!ICS.isBad())
|
||||
return PerformImplicitConversion(From, Context.BoolTy, ICS, AA_Converting);
|
||||
|
||||
if (!DiagnoseMultipleUserDefinedConversion(From, Context.BoolTy))
|
||||
return Diag(From->getSourceRange().getBegin(),
|
||||
|
@ -2388,35 +2414,15 @@ Sema::AddOverloadCandidate(FunctionDecl *Function,
|
|||
= TryCopyInitialization(Args[ArgIdx], ParamType,
|
||||
SuppressUserConversions, ForceRValue,
|
||||
/*InOverloadResolution=*/true);
|
||||
if (Candidate.Conversions[ArgIdx].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
// 13.3.3.1-p10 If several different sequences of conversions exist that
|
||||
// each convert the argument to the parameter type, the implicit conversion
|
||||
// sequence associated with the parameter is defined to be the unique conversion
|
||||
// sequence designated the ambiguous conversion sequence. For the purpose of
|
||||
// ranking implicit conversion sequences as described in 13.3.3.2, the ambiguous
|
||||
// conversion sequence is treated as a user-defined sequence that is
|
||||
// indistinguishable from any other user-defined conversion sequence
|
||||
if (!Candidate.Conversions[ArgIdx].ConversionFunctionSet.empty()) {
|
||||
Candidate.Conversions[ArgIdx].ConversionKind =
|
||||
ImplicitConversionSequence::UserDefinedConversion;
|
||||
// Set the conversion function to one of them. As due to ambiguity,
|
||||
// they carry the same weight and is needed for overload resolution
|
||||
// later.
|
||||
Candidate.Conversions[ArgIdx].UserDefined.ConversionFunction =
|
||||
Candidate.Conversions[ArgIdx].ConversionFunctionSet[0];
|
||||
}
|
||||
else {
|
||||
if (Candidate.Conversions[ArgIdx].isBad()) {
|
||||
Candidate.Viable = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// (C++ 13.3.2p2): For the purposes of overload resolution, any
|
||||
// argument for which there is no corresponding parameter is
|
||||
// considered to ""match the ellipsis" (C+ 13.3.3.1.3).
|
||||
Candidate.Conversions[ArgIdx].ConversionKind
|
||||
= ImplicitConversionSequence::EllipsisConversion;
|
||||
Candidate.Conversions[ArgIdx].setEllipsis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2552,8 +2558,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, CXXRecordDecl *ActingContext,
|
|||
// parameter.
|
||||
Candidate.Conversions[0]
|
||||
= TryObjectArgumentInitialization(ObjectType, Method, ActingContext);
|
||||
if (Candidate.Conversions[0].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
if (Candidate.Conversions[0].isBad()) {
|
||||
Candidate.Viable = false;
|
||||
return;
|
||||
}
|
||||
|
@ -2572,8 +2577,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, CXXRecordDecl *ActingContext,
|
|||
= TryCopyInitialization(Args[ArgIdx], ParamType,
|
||||
SuppressUserConversions, ForceRValue,
|
||||
/*InOverloadResolution=*/true);
|
||||
if (Candidate.Conversions[ArgIdx + 1].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
if (Candidate.Conversions[ArgIdx + 1].isBad()) {
|
||||
Candidate.Viable = false;
|
||||
break;
|
||||
}
|
||||
|
@ -2581,8 +2585,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, CXXRecordDecl *ActingContext,
|
|||
// (C++ 13.3.2p2): For the purposes of overload resolution, any
|
||||
// argument for which there is no corresponding parameter is
|
||||
// considered to ""match the ellipsis" (C+ 13.3.3.1.3).
|
||||
Candidate.Conversions[ArgIdx + 1].ConversionKind
|
||||
= ImplicitConversionSequence::EllipsisConversion;
|
||||
Candidate.Conversions[ArgIdx + 1].setEllipsis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2706,9 +2709,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
|
|||
Candidate.IsSurrogate = false;
|
||||
Candidate.IgnoreObjectArgument = false;
|
||||
Candidate.FinalConversion.setAsIdentityConversion();
|
||||
Candidate.FinalConversion.FromTypePtr
|
||||
= Conversion->getConversionType().getAsOpaquePtr();
|
||||
Candidate.FinalConversion.ToTypePtr = ToType.getAsOpaquePtr();
|
||||
Candidate.FinalConversion.setFromType(Conversion->getConversionType());
|
||||
Candidate.FinalConversion.setToType(ToType);
|
||||
|
||||
// Determine the implicit conversion sequence for the implicit
|
||||
// object parameter.
|
||||
|
@ -2722,8 +2724,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
|
|||
// in overload resolution.
|
||||
if (Candidate.Conversions[0].Standard.Second == ICK_Derived_To_Base)
|
||||
Candidate.Conversions[0].Standard.Second = ICK_Identity;
|
||||
if (Candidate.Conversions[0].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
if (Candidate.Conversions[0].isBad()) {
|
||||
Candidate.Viable = false;
|
||||
return;
|
||||
}
|
||||
|
@ -2766,7 +2767,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion,
|
|||
/*ForceRValue=*/false,
|
||||
/*InOverloadResolution=*/false);
|
||||
|
||||
switch (ICS.ConversionKind) {
|
||||
switch (ICS.getKind()) {
|
||||
case ImplicitConversionSequence::StandardConversion:
|
||||
Candidate.FinalConversion = ICS.Standard;
|
||||
break;
|
||||
|
@ -2844,7 +2845,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
|
|||
// object parameter.
|
||||
ImplicitConversionSequence ObjectInit
|
||||
= TryObjectArgumentInitialization(ObjectType, Conversion, ActingContext);
|
||||
if (ObjectInit.ConversionKind == ImplicitConversionSequence::BadConversion) {
|
||||
if (ObjectInit.isBad()) {
|
||||
Candidate.Viable = false;
|
||||
return;
|
||||
}
|
||||
|
@ -2852,8 +2853,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
|
|||
// The first conversion is actually a user-defined conversion whose
|
||||
// first conversion is ObjectInit's standard conversion (which is
|
||||
// effectively a reference binding). Record it as such.
|
||||
Candidate.Conversions[0].ConversionKind
|
||||
= ImplicitConversionSequence::UserDefinedConversion;
|
||||
Candidate.Conversions[0].setUserDefined();
|
||||
Candidate.Conversions[0].UserDefined.Before = ObjectInit.Standard;
|
||||
Candidate.Conversions[0].UserDefined.EllipsisConversion = false;
|
||||
Candidate.Conversions[0].UserDefined.ConversionFunction = Conversion;
|
||||
|
@ -2894,8 +2894,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
|
|||
/*SuppressUserConversions=*/false,
|
||||
/*ForceRValue=*/false,
|
||||
/*InOverloadResolution=*/false);
|
||||
if (Candidate.Conversions[ArgIdx + 1].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
if (Candidate.Conversions[ArgIdx + 1].isBad()) {
|
||||
Candidate.Viable = false;
|
||||
break;
|
||||
}
|
||||
|
@ -2903,8 +2902,7 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion,
|
|||
// (C++ 13.3.2p2): For the purposes of overload resolution, any
|
||||
// argument for which there is no corresponding parameter is
|
||||
// considered to ""match the ellipsis" (C+ 13.3.3.1.3).
|
||||
Candidate.Conversions[ArgIdx + 1].ConversionKind
|
||||
= ImplicitConversionSequence::EllipsisConversion;
|
||||
Candidate.Conversions[ArgIdx + 1].setEllipsis();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3038,8 +3036,7 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys,
|
|||
/*ForceRValue=*/false,
|
||||
/*InOverloadResolution=*/false);
|
||||
}
|
||||
if (Candidate.Conversions[ArgIdx].ConversionKind
|
||||
== ImplicitConversionSequence::BadConversion) {
|
||||
if (Candidate.Conversions[ArgIdx].isBad()) {
|
||||
Candidate.Viable = false;
|
||||
break;
|
||||
}
|
||||
|
@ -4304,11 +4301,22 @@ void Sema::NoteOverloadCandidate(FunctionDecl *Fn) {
|
|||
Diag(Fn->getLocation(), diag::note_ovl_candidate);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void NoteDeletedCandidate(Sema &S, OverloadCandidate *Cand) {
|
||||
/// Diagnoses an ambiguous conversion. The partial diagnostic is the
|
||||
/// "lead" diagnostic; it will be given two arguments, the source and
|
||||
/// target types of the conversion.
|
||||
void Sema::DiagnoseAmbiguousConversion(const ImplicitConversionSequence &ICS,
|
||||
SourceLocation CaretLoc,
|
||||
const PartialDiagnostic &PDiag) {
|
||||
Diag(CaretLoc, PDiag)
|
||||
<< ICS.Ambiguous.getFromType() << ICS.Ambiguous.getToType();
|
||||
for (AmbiguousConversionSequence::const_iterator
|
||||
I = ICS.Ambiguous.begin(), E = ICS.Ambiguous.end(); I != E; ++I) {
|
||||
NoteOverloadCandidate(*I);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) {
|
||||
// Note deleted candidates, but only if they're viable.
|
||||
if (Cand->Viable &&
|
||||
|
@ -4335,18 +4343,13 @@ void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand) {
|
|||
for (int i = Cand->Conversions.size()-1; i >= 0; i--) {
|
||||
const ImplicitConversionSequence &Conversion =
|
||||
Cand->Conversions[i];
|
||||
if ((Conversion.ConversionKind !=
|
||||
ImplicitConversionSequence::BadConversion) ||
|
||||
Conversion.ConversionFunctionSet.size() == 0)
|
||||
|
||||
if (!Conversion.isAmbiguous())
|
||||
continue;
|
||||
S.Diag(Cand->Function->getLocation(),
|
||||
diag::note_ovl_candidate_not_viable) << (i+1);
|
||||
|
||||
S.DiagnoseAmbiguousConversion(Conversion, Cand->Function->getLocation(),
|
||||
PDiag(diag::note_ovl_candidate_not_viable) << (i+1));
|
||||
errReported = true;
|
||||
for (int j = Conversion.ConversionFunctionSet.size()-1;
|
||||
j >= 0; j--) {
|
||||
FunctionDecl *Func = Conversion.ConversionFunctionSet[j];
|
||||
S.NoteOverloadCandidate(Func);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4411,21 +4414,11 @@ void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc,
|
|||
unsigned NoOperands = Cand->Conversions.size();
|
||||
for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) {
|
||||
const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx];
|
||||
if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion ||
|
||||
ICS.ConversionFunctionSet.empty())
|
||||
continue;
|
||||
if (CXXConversionDecl *Func = dyn_cast<CXXConversionDecl>(
|
||||
Cand->Conversions[ArgIdx].ConversionFunctionSet[0])) {
|
||||
QualType FromTy =
|
||||
QualType(static_cast<Type*>(ICS.UserDefined.Before.FromTypePtr),0);
|
||||
S.Diag(OpLoc, diag::note_ambiguous_type_conversion)
|
||||
<< FromTy << Func->getConversionType();
|
||||
}
|
||||
for (unsigned j = 0; j < ICS.ConversionFunctionSet.size(); j++) {
|
||||
FunctionDecl *Func =
|
||||
Cand->Conversions[ArgIdx].ConversionFunctionSet[j];
|
||||
S.NoteOverloadCandidate(Func);
|
||||
}
|
||||
if (ICS.isBad()) break; // all meaningless after first invalid
|
||||
if (!ICS.isAmbiguous()) continue;
|
||||
|
||||
S.DiagnoseAmbiguousConversion(ICS, OpLoc,
|
||||
PDiag(diag::note_ambiguous_type_conversion));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4479,7 +4472,7 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
|
|||
Cands.push_back(Cand);
|
||||
std::sort(Cands.begin(), Cands.end(), CompareOverloadCandidates(SourceMgr));
|
||||
|
||||
bool ReportedNonViableOperator = false;
|
||||
bool ReportedAmbiguousConversions = false;
|
||||
|
||||
llvm::SmallVectorImpl<OverloadCandidate*>::iterator I, E;
|
||||
for (I = Cands.begin(), E = Cands.end(); I != E; ++I) {
|
||||
|
@ -4492,16 +4485,20 @@ Sema::PrintOverloadCandidates(OverloadCandidateSet& CandidateSet,
|
|||
|
||||
// This a builtin candidate. We do not, in general, want to list
|
||||
// every possible builtin candidate.
|
||||
else if (Cand->Viable) {
|
||||
// Generally we only see ambiguities including viable builtin
|
||||
// operators if overload resolution got screwed up by an
|
||||
// ambiguous user-defined conversion.
|
||||
//
|
||||
// FIXME: It's quite possible for different conversions to see
|
||||
// different ambiguities, though.
|
||||
if (!ReportedAmbiguousConversions) {
|
||||
NoteAmbiguousUserConversions(*this, OpLoc, Cand);
|
||||
ReportedAmbiguousConversions = true;
|
||||
}
|
||||
|
||||
// If this is a viable builtin, print it.
|
||||
else if (Cand->Viable)
|
||||
NoteBuiltinOperatorCandidate(*this, Opc, OpLoc, Cand);
|
||||
|
||||
// Otherwise, non-viability might be due to ambiguous user-defined
|
||||
// conversions. Report them exactly once.
|
||||
else if (!ReportedNonViableOperator) {
|
||||
NoteAmbiguousUserConversions(*this, OpLoc, Cand);
|
||||
ReportedNonViableOperator = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,6 +149,15 @@ namespace clang {
|
|||
/// conversions.
|
||||
CXXConstructorDecl *CopyConstructor;
|
||||
|
||||
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
|
||||
void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
|
||||
QualType getFromType() const {
|
||||
return QualType::getFromOpaquePtr(FromTypePtr);
|
||||
}
|
||||
QualType getToType() const {
|
||||
return QualType::getFromOpaquePtr(ToTypePtr);
|
||||
}
|
||||
|
||||
void setAsIdentityConversion();
|
||||
ImplicitConversionRank getRank() const;
|
||||
bool isPointerConversionToBool() const;
|
||||
|
@ -190,6 +199,48 @@ namespace clang {
|
|||
void DebugPrint() const;
|
||||
};
|
||||
|
||||
/// Represents an ambiguous user-defined conversion sequence.
|
||||
struct AmbiguousConversionSequence {
|
||||
typedef llvm::SmallVector<FunctionDecl*, 4> ConversionSet;
|
||||
|
||||
void *FromTypePtr;
|
||||
void *ToTypePtr;
|
||||
char Buffer[sizeof(ConversionSet)];
|
||||
|
||||
QualType getFromType() const {
|
||||
return QualType::getFromOpaquePtr(FromTypePtr);
|
||||
}
|
||||
QualType getToType() const {
|
||||
return QualType::getFromOpaquePtr(ToTypePtr);
|
||||
}
|
||||
void setFromType(QualType T) { FromTypePtr = T.getAsOpaquePtr(); }
|
||||
void setToType(QualType T) { ToTypePtr = T.getAsOpaquePtr(); }
|
||||
|
||||
ConversionSet &conversions() {
|
||||
return *reinterpret_cast<ConversionSet*>(Buffer);
|
||||
}
|
||||
|
||||
const ConversionSet &conversions() const {
|
||||
return *reinterpret_cast<const ConversionSet*>(Buffer);
|
||||
}
|
||||
|
||||
void addConversion(FunctionDecl *D) {
|
||||
conversions().push_back(D);
|
||||
}
|
||||
|
||||
typedef ConversionSet::iterator iterator;
|
||||
iterator begin() { return conversions().begin(); }
|
||||
iterator end() { return conversions().end(); }
|
||||
|
||||
typedef ConversionSet::const_iterator const_iterator;
|
||||
const_iterator begin() const { return conversions().begin(); }
|
||||
const_iterator end() const { return conversions().end(); }
|
||||
|
||||
void construct();
|
||||
void destruct();
|
||||
void copyFrom(const AmbiguousConversionSequence &);
|
||||
};
|
||||
|
||||
/// ImplicitConversionSequence - Represents an implicit conversion
|
||||
/// sequence, which may be a standard conversion sequence
|
||||
/// (C++ 13.3.3.1.1), user-defined conversion sequence (C++ 13.3.3.1.2),
|
||||
|
@ -197,18 +248,26 @@ namespace clang {
|
|||
struct ImplicitConversionSequence {
|
||||
/// Kind - The kind of implicit conversion sequence. BadConversion
|
||||
/// specifies that there is no conversion from the source type to
|
||||
/// the target type. The enumerator values are ordered such that
|
||||
/// better implicit conversions have smaller values.
|
||||
/// the target type. AmbiguousConversion represents the unique
|
||||
/// ambiguous conversion (C++0x [over.best.ics]p10).
|
||||
enum Kind {
|
||||
StandardConversion = 0,
|
||||
UserDefinedConversion,
|
||||
AmbiguousConversion,
|
||||
EllipsisConversion,
|
||||
BadConversion
|
||||
};
|
||||
|
||||
private:
|
||||
/// ConversionKind - The kind of implicit conversion sequence.
|
||||
Kind ConversionKind;
|
||||
|
||||
void setKind(Kind K) {
|
||||
if (isAmbiguous()) Ambiguous.destruct();
|
||||
ConversionKind = K;
|
||||
}
|
||||
|
||||
public:
|
||||
union {
|
||||
/// When ConversionKind == StandardConversion, provides the
|
||||
/// details of the standard conversion sequence.
|
||||
|
@ -217,11 +276,53 @@ namespace clang {
|
|||
/// When ConversionKind == UserDefinedConversion, provides the
|
||||
/// details of the user-defined conversion sequence.
|
||||
UserDefinedConversionSequence UserDefined;
|
||||
|
||||
/// When ConversionKind == AmbiguousConversion, provides the
|
||||
/// details of the ambiguous conversion.
|
||||
AmbiguousConversionSequence Ambiguous;
|
||||
};
|
||||
|
||||
/// When ConversionKind == BadConversion due to multiple conversion
|
||||
/// functions, this will list those functions.
|
||||
llvm::SmallVector<FunctionDecl*, 4> ConversionFunctionSet;
|
||||
ImplicitConversionSequence() : ConversionKind(BadConversion) {}
|
||||
~ImplicitConversionSequence() {
|
||||
if (isAmbiguous()) Ambiguous.destruct();
|
||||
}
|
||||
ImplicitConversionSequence(const ImplicitConversionSequence &Other)
|
||||
: ConversionKind(Other.ConversionKind)
|
||||
{
|
||||
switch (ConversionKind) {
|
||||
case StandardConversion: Standard = Other.Standard; break;
|
||||
case UserDefinedConversion: UserDefined = Other.UserDefined; break;
|
||||
case AmbiguousConversion: Ambiguous.copyFrom(Other.Ambiguous); break;
|
||||
case EllipsisConversion: break;
|
||||
case BadConversion: break;
|
||||
}
|
||||
}
|
||||
|
||||
ImplicitConversionSequence &
|
||||
operator=(const ImplicitConversionSequence &Other) {
|
||||
if (isAmbiguous()) Ambiguous.destruct();
|
||||
new (this) ImplicitConversionSequence(Other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Kind getKind() const { return ConversionKind; }
|
||||
bool isBad() const { return ConversionKind == BadConversion; }
|
||||
bool isStandard() const { return ConversionKind == StandardConversion; }
|
||||
bool isEllipsis() const { return ConversionKind == EllipsisConversion; }
|
||||
bool isAmbiguous() const { return ConversionKind == AmbiguousConversion; }
|
||||
bool isUserDefined() const {
|
||||
return ConversionKind == UserDefinedConversion;
|
||||
}
|
||||
|
||||
void setBad() { setKind(BadConversion); }
|
||||
void setStandard() { setKind(StandardConversion); }
|
||||
void setEllipsis() { setKind(EllipsisConversion); }
|
||||
void setUserDefined() { setKind(UserDefinedConversion); }
|
||||
void setAmbiguous() {
|
||||
if (isAmbiguous()) return;
|
||||
ConversionKind = AmbiguousConversion;
|
||||
Ambiguous.construct();
|
||||
}
|
||||
|
||||
// The result of a comparison between implicit conversion
|
||||
// sequences. Use Sema::CompareImplicitConversionSequences to
|
||||
|
@ -280,6 +381,16 @@ namespace clang {
|
|||
/// after the call to the overload candidate to convert the result
|
||||
/// of calling the conversion function to the required type.
|
||||
StandardConversionSequence FinalConversion;
|
||||
|
||||
/// hasAmbiguousConversion - Returns whether this overload
|
||||
/// candidate requires an ambiguous conversion or not.
|
||||
bool hasAmbiguousConversion() const {
|
||||
for (llvm::SmallVectorImpl<ImplicitConversionSequence>::const_iterator
|
||||
I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
|
||||
if (I->isAmbiguous()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/// OverloadCandidateSet - A set of overload candidates, used in C++
|
||||
|
|
|
@ -21,6 +21,13 @@ namespace test0 {
|
|||
func(b1, f()); // expected-error {{call to 'func' is ambiguous}}
|
||||
return f(); // expected-error {{conversion from 'struct test0::B' to 'int const' is ambiguous}}
|
||||
}
|
||||
|
||||
// This used to crash when comparing the two operands.
|
||||
void func2(const char cc); // expected-note {{candidate function}}
|
||||
void func2(const int ci); // expected-note {{candidate function}}
|
||||
void Test2() {
|
||||
func2(b1); // expected-error {{call to 'func2' is ambiguous}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace test1 {
|
||||
|
|
|
@ -40,7 +40,7 @@ void foo1(C1 c1, int A::* pmf) {
|
|||
}
|
||||
|
||||
void foo1(C1 c1, int E::* pmf) {
|
||||
// FIXME. Error reporting needs much improvement here.
|
||||
int i = c1->*pmf; // expected-error {{left hand operand to ->* must be a pointer to class compatible with the right hand operand, but is 'struct C1'}} \
|
||||
// expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}}
|
||||
int i = c1->*pmf; // expected-error {{use of overloaded operator '->*' is ambiguous}} \
|
||||
// expected-note {{because of ambiguity in conversion of 'struct C1' to 'struct E *'}} \
|
||||
// expected-note 4 {{built-in candidate operator}}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
struct ToBool { explicit operator bool(); };
|
||||
|
||||
struct B;
|
||||
struct A { A(); A(const B&); };
|
||||
struct B { operator A() const; };
|
||||
struct A { A(); A(const B&); }; // expected-note 2 {{candidate constructor}}
|
||||
struct B { operator A() const; }; // expected-note 2 {{candidate function}}
|
||||
struct I { operator int(); };
|
||||
struct J { operator I(); };
|
||||
struct K { operator double(); };
|
||||
|
@ -50,8 +50,8 @@ struct MixedFieldsDerived : MixedFields {
|
|||
enum Enum { EVal };
|
||||
|
||||
struct Ambig {
|
||||
operator short();
|
||||
operator signed char();
|
||||
operator short(); // expected-note 2 {{candidate function}}
|
||||
operator signed char(); // expected-note 2 {{candidate function}}
|
||||
};
|
||||
|
||||
void test()
|
||||
|
@ -129,10 +129,10 @@ void test()
|
|||
vfn pfn = i1 ? F() : test;
|
||||
pfn = i1 ? test : F();
|
||||
// these are ambiguous - better messages would be nice
|
||||
(void)(i1 ? A() : B()); // expected-error {{incompatible operand types}}
|
||||
(void)(i1 ? B() : A()); // expected-error {{incompatible operand types}}
|
||||
(void)(i1 ? 1 : Ambig()); // expected-error {{incompatible operand types}}
|
||||
(void)(i1 ? Ambig() : 1); // expected-error {{incompatible operand types}}
|
||||
(void)(i1 ? A() : B()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}}
|
||||
(void)(i1 ? B() : A()); // expected-error {{conversion from 'struct B' to 'struct A' is ambiguous}}
|
||||
(void)(i1 ? 1 : Ambig()); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}}
|
||||
(void)(i1 ? Ambig() : 1); // expected-error {{conversion from 'struct Ambig' to 'int' is ambiguous}}
|
||||
// By the way, this isn't an lvalue:
|
||||
&(i1 ? i1 : i2); // expected-error {{address expression must be an lvalue or a function designator}}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче