diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 322 |
1 files changed, 198 insertions, 124 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 36f24fd9c463..268be9430a56 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -837,12 +837,13 @@ void OverloadCandidateSet::destroyCandidates() { } } -void OverloadCandidateSet::clear() { +void OverloadCandidateSet::clear(CandidateSetKind CSK) { destroyCandidates(); SlabAllocator.Reset(); NumInlineBytesUsed = 0; Candidates.clear(); Functions.clear(); + Kind = CSK; } namespace { @@ -1481,6 +1482,23 @@ bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, .getTypePtr()); Changed = true; } + + // Convert FromFPT's ExtParameterInfo if necessary. The conversion is valid + // only if the ExtParameterInfo lists of the two function prototypes can be + // merged and the merged list is identical to ToFPT's ExtParameterInfo list. + SmallVector<FunctionProtoType::ExtParameterInfo, 4> NewParamInfos; + bool CanUseToFPT, CanUseFromFPT; + if (Context.mergeExtParameterInfo(ToFPT, FromFPT, CanUseToFPT, + CanUseFromFPT, NewParamInfos) && + CanUseToFPT && !CanUseFromFPT) { + FunctionProtoType::ExtProtoInfo ExtInfo = FromFPT->getExtProtoInfo(); + ExtInfo.ExtParameterInfos = + NewParamInfos.empty() ? nullptr : NewParamInfos.data(); + QualType QT = Context.getFunctionType(FromFPT->getReturnType(), + FromFPT->getParamTypes(), ExtInfo); + FromFn = QT->getAs<FunctionType>(); + Changed = true; + } } if (!Changed) @@ -2663,8 +2681,12 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType, // Argument types are too different. Abort. return false; } - if (!Context.doFunctionTypesMatchOnExtParameterInfos(FromFunctionType, - ToFunctionType)) + + SmallVector<FunctionProtoType::ExtParameterInfo, 4> NewParamInfos; + bool CanUseToFPT, CanUseFromFPT; + if (!Context.mergeExtParameterInfo(ToFunctionType, FromFunctionType, + CanUseToFPT, CanUseFromFPT, + NewParamInfos)) return false; ConvertedType = ToType; @@ -3154,6 +3176,7 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, UserDefinedConversionSequence &User, OverloadCandidateSet &CandidateSet, bool AllowExplicit) { + CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); for (auto *D : S.LookupConstructors(To)) { auto Info = getConstructorInfo(D); if (!Info) @@ -3182,7 +3205,7 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, OverloadCandidateSet::iterator Best; switch (auto Result = CandidateSet.BestViableFunction(S, From->getLocStart(), - Best, true)) { + Best)) { case OR_Deleted: case OR_Success: { // Record the standard conversion we used and the conversion function. @@ -3229,6 +3252,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, bool AllowExplicit, bool AllowObjCConversionOnExplicit) { assert(AllowExplicit || !AllowObjCConversionOnExplicit); + CandidateSet.clear(OverloadCandidateSet::CSK_InitByUserDefinedConversion); // Whether we will only visit constructors. bool ConstructorsOnly = false; @@ -3264,7 +3288,8 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, if (Result != OR_No_Viable_Function) return Result; // Never mind. - CandidateSet.clear(); + CandidateSet.clear( + OverloadCandidateSet::CSK_InitByUserDefinedConversion); // If we're list-initializing, we pass the individual elements as // arguments, not the entire list. @@ -3354,7 +3379,7 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, OverloadCandidateSet::iterator Best; switch (auto Result = CandidateSet.BestViableFunction(S, From->getLocStart(), - Best, true)) { + Best)) { case OR_Success: case OR_Deleted: // Record the standard conversion we used and the conversion function. @@ -4288,7 +4313,8 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, CXXRecordDecl *T2RecordDecl = dyn_cast<CXXRecordDecl>(T2->getAs<RecordType>()->getDecl()); - OverloadCandidateSet CandidateSet(DeclLoc, OverloadCandidateSet::CSK_Normal); + OverloadCandidateSet CandidateSet( + DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion); const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions(); for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) { NamedDecl *D = *I; @@ -4358,7 +4384,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, bool HadMultipleCandidates = (CandidateSet.size() > 1); OverloadCandidateSet::iterator Best; - switch (CandidateSet.BestViableFunction(S, DeclLoc, Best, true)) { + switch (CandidateSet.BestViableFunction(S, DeclLoc, Best)) { case OR_Success: // C++ [over.ics.ref]p1: // @@ -6317,24 +6343,36 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, OverloadCandidateSet& CandidateSet, TemplateArgumentListInfo *ExplicitTemplateArgs, bool SuppressUserConversions, - bool PartialOverloading) { + bool PartialOverloading, + bool FirstArgumentIsBase) { for (UnresolvedSetIterator F = Fns.begin(), E = Fns.end(); F != E; ++F) { NamedDecl *D = F.getDecl()->getUnderlyingDecl(); if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + ArrayRef<Expr *> FunctionArgs = Args; if (isa<CXXMethodDecl>(FD) && !cast<CXXMethodDecl>(FD)->isStatic()) { QualType ObjectType; Expr::Classification ObjectClassification; - if (Expr *E = Args[0]) { - // Use the explit base to restrict the lookup: - ObjectType = E->getType(); - ObjectClassification = E->Classify(Context); - } // .. else there is an implit base. + if (Args.size() > 0) { + if (Expr *E = Args[0]) { + // Use the explit base to restrict the lookup: + ObjectType = E->getType(); + ObjectClassification = E->Classify(Context); + } // .. else there is an implit base. + FunctionArgs = Args.slice(1); + } AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), cast<CXXMethodDecl>(FD)->getParent(), ObjectType, - ObjectClassification, Args.slice(1), CandidateSet, + ObjectClassification, FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } else { - AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet, + // Slice the first argument (which is the base) when we access + // static method as non-static + if (Args.size() > 0 && (!Args[0] || (FirstArgumentIsBase && isa<CXXMethodDecl>(FD) && + !isa<CXXConstructorDecl>(FD)))) { + assert(cast<CXXMethodDecl>(FD)->isStatic()); + FunctionArgs = Args.slice(1); + } + AddOverloadCandidate(FD, F.getPair(), FunctionArgs, CandidateSet, SuppressUserConversions, PartialOverloading); } } else { @@ -6767,7 +6805,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, CXXRecordDecl *ActingContext, Expr *From, QualType ToType, OverloadCandidateSet& CandidateSet, - bool AllowObjCConversionOnExplicit) { + bool AllowObjCConversionOnExplicit, + bool AllowResultConversion) { assert(!Conversion->getDescribedFunctionTemplate() && "Conversion function templates use AddTemplateConversionCandidate"); QualType ConvType = Conversion->getConversionType().getNonReferenceType(); @@ -6782,6 +6821,12 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, ConvType = Conversion->getConversionType().getNonReferenceType(); } + // If we don't allow any conversion of the result type, ignore conversion + // functions that don't convert to exactly (possibly cv-qualified) T. + if (!AllowResultConversion && + !Context.hasSameUnqualifiedType(Conversion->getConversionType(), ToType)) + return; + // Per C++ [over.match.conv]p1, [over.match.ref]p1, an explicit conversion // operator is only a candidate if its return type is the target type or // can be converted to the target type with a qualification conversion. @@ -6935,7 +6980,8 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, CXXRecordDecl *ActingDC, Expr *From, QualType ToType, OverloadCandidateSet &CandidateSet, - bool AllowObjCConversionOnExplicit) { + bool AllowObjCConversionOnExplicit, + bool AllowResultConversion) { assert(isa<CXXConversionDecl>(FunctionTemplate->getTemplatedDecl()) && "Only conversion function templates permitted here"); @@ -6964,7 +7010,8 @@ Sema::AddTemplateConversionCandidate(FunctionTemplateDecl *FunctionTemplate, // template argument deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddConversionCandidate(Specialization, FoundDecl, ActingDC, From, ToType, - CandidateSet, AllowObjCConversionOnExplicit); + CandidateSet, AllowObjCConversionOnExplicit, + AllowResultConversion); } /// AddSurrogateCandidate - Adds a "surrogate" candidate function that @@ -7568,53 +7615,62 @@ class BuiltinOperatorOverloadBuilder { SmallVectorImpl<BuiltinCandidateTypeSet> &CandidateTypes; OverloadCandidateSet &CandidateSet; - // Define some constants used to index and iterate over the arithemetic types - // provided via the getArithmeticType() method below. - // The "promoted arithmetic types" are the arithmetic + static constexpr int ArithmeticTypesCap = 24; + SmallVector<CanQualType, ArithmeticTypesCap> ArithmeticTypes; + + // Define some indices used to iterate over the arithemetic types in + // ArithmeticTypes. The "promoted arithmetic types" are the arithmetic // types are that preserved by promotion (C++ [over.built]p2). - static const unsigned FirstIntegralType = 4; - static const unsigned LastIntegralType = 21; - static const unsigned FirstPromotedIntegralType = 4, - LastPromotedIntegralType = 12; - static const unsigned FirstPromotedArithmeticType = 0, - LastPromotedArithmeticType = 12; - static const unsigned NumArithmeticTypes = 21; - - /// \brief Get the canonical type for a given arithmetic type index. - CanQualType getArithmeticType(unsigned index) { - assert(index < NumArithmeticTypes); - static CanQualType ASTContext::* const - ArithmeticTypes[NumArithmeticTypes] = { - // Start of promoted types. - &ASTContext::FloatTy, - &ASTContext::DoubleTy, - &ASTContext::LongDoubleTy, - &ASTContext::Float128Ty, - - // Start of integral types. - &ASTContext::IntTy, - &ASTContext::LongTy, - &ASTContext::LongLongTy, - &ASTContext::Int128Ty, - &ASTContext::UnsignedIntTy, - &ASTContext::UnsignedLongTy, - &ASTContext::UnsignedLongLongTy, - &ASTContext::UnsignedInt128Ty, - // End of promoted types. - - &ASTContext::BoolTy, - &ASTContext::CharTy, - &ASTContext::WCharTy, - &ASTContext::Char16Ty, - &ASTContext::Char32Ty, - &ASTContext::SignedCharTy, - &ASTContext::ShortTy, - &ASTContext::UnsignedCharTy, - &ASTContext::UnsignedShortTy, - // End of integral types. - // FIXME: What about complex? What about half? - }; - return S.Context.*ArithmeticTypes[index]; + unsigned FirstIntegralType, + LastIntegralType; + unsigned FirstPromotedIntegralType, + LastPromotedIntegralType; + unsigned FirstPromotedArithmeticType, + LastPromotedArithmeticType; + unsigned NumArithmeticTypes; + + void InitArithmeticTypes() { + // Start of promoted types. + FirstPromotedArithmeticType = 0; + ArithmeticTypes.push_back(S.Context.FloatTy); + ArithmeticTypes.push_back(S.Context.DoubleTy); + ArithmeticTypes.push_back(S.Context.LongDoubleTy); + if (S.Context.getTargetInfo().hasFloat128Type()) + ArithmeticTypes.push_back(S.Context.Float128Ty); + + // Start of integral types. + FirstIntegralType = ArithmeticTypes.size(); + FirstPromotedIntegralType = ArithmeticTypes.size(); + ArithmeticTypes.push_back(S.Context.IntTy); + ArithmeticTypes.push_back(S.Context.LongTy); + ArithmeticTypes.push_back(S.Context.LongLongTy); + if (S.Context.getTargetInfo().hasInt128Type()) + ArithmeticTypes.push_back(S.Context.Int128Ty); + ArithmeticTypes.push_back(S.Context.UnsignedIntTy); + ArithmeticTypes.push_back(S.Context.UnsignedLongTy); + ArithmeticTypes.push_back(S.Context.UnsignedLongLongTy); + if (S.Context.getTargetInfo().hasInt128Type()) + ArithmeticTypes.push_back(S.Context.UnsignedInt128Ty); + LastPromotedIntegralType = ArithmeticTypes.size(); + LastPromotedArithmeticType = ArithmeticTypes.size(); + // End of promoted types. + + ArithmeticTypes.push_back(S.Context.BoolTy); + ArithmeticTypes.push_back(S.Context.CharTy); + ArithmeticTypes.push_back(S.Context.WCharTy); + ArithmeticTypes.push_back(S.Context.Char16Ty); + ArithmeticTypes.push_back(S.Context.Char32Ty); + ArithmeticTypes.push_back(S.Context.SignedCharTy); + ArithmeticTypes.push_back(S.Context.ShortTy); + ArithmeticTypes.push_back(S.Context.UnsignedCharTy); + ArithmeticTypes.push_back(S.Context.UnsignedShortTy); + LastIntegralType = ArithmeticTypes.size(); + NumArithmeticTypes = ArithmeticTypes.size(); + // End of integral types. + // FIXME: What about complex? What about half? + + assert(ArithmeticTypes.size() <= ArithmeticTypesCap && + "Enough inline storage for all arithmetic types."); } /// \brief Helper method to factor out the common pattern of adding overloads @@ -7673,18 +7729,8 @@ public: HasArithmeticOrEnumeralCandidateType), CandidateTypes(CandidateTypes), CandidateSet(CandidateSet) { - // Validate some of our static helper constants in debug builds. - assert(getArithmeticType(FirstPromotedIntegralType) == S.Context.IntTy && - "Invalid first promoted integral type"); - assert(getArithmeticType(LastPromotedIntegralType - 1) - == S.Context.UnsignedInt128Ty && - "Invalid last promoted integral type"); - assert(getArithmeticType(FirstPromotedArithmeticType) - == S.Context.FloatTy && - "Invalid first promoted arithmetic type"); - assert(getArithmeticType(LastPromotedArithmeticType - 1) - == S.Context.UnsignedInt128Ty && - "Invalid last promoted arithmetic type"); + + InitArithmeticTypes(); } // C++ [over.built]p3: @@ -7711,7 +7757,7 @@ public: for (unsigned Arith = (Op == OO_PlusPlus? 0 : 1); Arith < NumArithmeticTypes; ++Arith) { addPlusPlusMinusMinusStyleOverloads( - getArithmeticType(Arith), + ArithmeticTypes[Arith], VisibleTypeConversionsQuals.hasVolatile(), VisibleTypeConversionsQuals.hasRestrict()); } @@ -7784,7 +7830,7 @@ public: for (unsigned Arith = FirstPromotedArithmeticType; Arith < LastPromotedArithmeticType; ++Arith) { - QualType ArithTy = getArithmeticType(Arith); + QualType ArithTy = ArithmeticTypes[Arith]; S.AddBuiltinCandidate(&ArithTy, Args, CandidateSet); } @@ -7824,7 +7870,7 @@ public: for (unsigned Int = FirstPromotedIntegralType; Int < LastPromotedIntegralType; ++Int) { - QualType IntTy = getArithmeticType(Int); + QualType IntTy = ArithmeticTypes[Int]; S.AddBuiltinCandidate(&IntTy, Args, CandidateSet); } @@ -8052,8 +8098,8 @@ public: Left < LastPromotedArithmeticType; ++Left) { for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { - QualType LandR[2] = { getArithmeticType(Left), - getArithmeticType(Right) }; + QualType LandR[2] = { ArithmeticTypes[Left], + ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } @@ -8096,8 +8142,8 @@ public: Left < LastPromotedIntegralType; ++Left) { for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { - QualType LandR[2] = { getArithmeticType(Left), - getArithmeticType(Right) }; + QualType LandR[2] = { ArithmeticTypes[Left], + ArithmeticTypes[Right] }; S.AddBuiltinCandidate(LandR, Args, CandidateSet); } } @@ -8277,18 +8323,18 @@ public: for (unsigned Right = FirstPromotedArithmeticType; Right < LastPromotedArithmeticType; ++Right) { QualType ParamTypes[2]; - ParamTypes[1] = getArithmeticType(Right); + ParamTypes[1] = ArithmeticTypes[Right]; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = - S.Context.getLValueReferenceType(getArithmeticType(Left)); + S.Context.getLValueReferenceType(ArithmeticTypes[Left]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); // Add this built-in operator as a candidate (VQ is 'volatile'). if (VisibleTypeConversionsQuals.hasVolatile()) { ParamTypes[0] = - S.Context.getVolatileType(getArithmeticType(Left)); + S.Context.getVolatileType(ArithmeticTypes[Left]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet, /*IsAssigmentOperator=*/isEqualOp); @@ -8343,15 +8389,15 @@ public: for (unsigned Right = FirstPromotedIntegralType; Right < LastPromotedIntegralType; ++Right) { QualType ParamTypes[2]; - ParamTypes[1] = getArithmeticType(Right); + ParamTypes[1] = ArithmeticTypes[Right]; // Add this built-in operator as a candidate (VQ is empty). ParamTypes[0] = - S.Context.getLValueReferenceType(getArithmeticType(Left)); + S.Context.getLValueReferenceType(ArithmeticTypes[Left]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); if (VisibleTypeConversionsQuals.hasVolatile()) { // Add this built-in operator as a candidate (VQ is 'volatile'). - ParamTypes[0] = getArithmeticType(Left); + ParamTypes[0] = ArithmeticTypes[Left]; ParamTypes[0] = S.Context.getVolatileType(ParamTypes[0]); ParamTypes[0] = S.Context.getLValueReferenceType(ParamTypes[0]); S.AddBuiltinCandidate(ParamTypes, Args, CandidateSet); @@ -8646,6 +8692,9 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, OpBuilder.addGenericBinaryArithmeticOverloads(); break; + case OO_Spaceship: + llvm_unreachable("<=> expressions not supported yet"); + case OO_Percent: case OO_Caret: case OO_Pipe: @@ -8823,10 +8872,9 @@ static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1, /// isBetterOverloadCandidate - Determines whether the first overload /// candidate is a better candidate than the second (C++ 13.3.3p1). -bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, - const OverloadCandidate &Cand2, - SourceLocation Loc, - bool UserDefinedConversion) { +bool clang::isBetterOverloadCandidate( + Sema &S, const OverloadCandidate &Cand1, const OverloadCandidate &Cand2, + SourceLocation Loc, OverloadCandidateSet::CandidateSetKind Kind) { // Define viable functions to be better candidates than non-viable // functions. if (!Cand2.Viable) @@ -8908,7 +8956,8 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, // the type of the entity being initialized) is a better // conversion sequence than the standard conversion sequence // from the return type of F2 to the destination type. - if (UserDefinedConversion && Cand1.Function && Cand2.Function && + if (Kind == OverloadCandidateSet::CSK_InitByUserDefinedConversion && + Cand1.Function && Cand2.Function && isa<CXXConversionDecl>(Cand1.Function) && isa<CXXConversionDecl>(Cand2.Function)) { // First check whether we prefer one of the conversion functions over the @@ -8930,11 +8979,17 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, // C++14 [over.match.best]p1 section 2 bullet 3. } - // -- F1 is generated from a deduction-guide and F2 is not - auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function); - auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function); - if (Guide1 && Guide2 && Guide1->isImplicit() != Guide2->isImplicit()) - return Guide2->isImplicit(); + // FIXME: Work around a defect in the C++17 guaranteed copy elision wording, + // as combined with the resolution to CWG issue 243. + // + // When the context is initialization by constructor ([over.match.ctor] or + // either phase of [over.match.list]), a constructor is preferred over + // a conversion function. + if (Kind == OverloadCandidateSet::CSK_InitByConstructor && NumArgs == 1 && + Cand1.Function && Cand2.Function && + isa<CXXConstructorDecl>(Cand1.Function) != + isa<CXXConstructorDecl>(Cand2.Function)) + return isa<CXXConstructorDecl>(Cand1.Function); // -- F1 is a non-template function and F2 is a function template // specialization, or, if not that, @@ -8980,6 +9035,21 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, // Inherited from sibling base classes: still ambiguous. } + // Check C++17 tie-breakers for deduction guides. + { + auto *Guide1 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand1.Function); + auto *Guide2 = dyn_cast_or_null<CXXDeductionGuideDecl>(Cand2.Function); + if (Guide1 && Guide2) { + // -- F1 is generated from a deduction-guide and F2 is not + if (Guide1->isImplicit() != Guide2->isImplicit()) + return Guide2->isImplicit(); + + // -- F1 is the copy deduction candidate(16.3.1.8) and F2 is not + if (Guide1->isCopyDeductionCandidate()) + return true; + } + } + // Check for enable_if value-based overload resolution. if (Cand1.Function && Cand2.Function) { Comparison Cmp = compareEnableIfAttrs(S, Cand1.Function, Cand2.Function); @@ -9079,8 +9149,7 @@ void Sema::diagnoseEquivalentInternalLinkageDeclarations( /// \returns The result of overload resolution. OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, - iterator &Best, - bool UserDefinedConversion) { + iterator &Best) { llvm::SmallVector<OverloadCandidate *, 16> Candidates; std::transform(begin(), end(), std::back_inserter(Candidates), [](OverloadCandidate &Cand) { return &Cand; }); @@ -9114,8 +9183,8 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, Best = end(); for (auto *Cand : Candidates) if (Cand->Viable) - if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc, - UserDefinedConversion)) + if (Best == end() || + isBetterOverloadCandidate(S, *Cand, *Best, Loc, Kind)) Best = Cand; // If we didn't find any viable functions, abort. @@ -9127,10 +9196,8 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, // Make sure that this function is better than every other viable // function. If not, we have an ambiguity. for (auto *Cand : Candidates) { - if (Cand->Viable && - Cand != Best && - !isBetterOverloadCandidate(S, *Best, *Cand, Loc, - UserDefinedConversion)) { + if (Cand->Viable && Cand != Best && + !isBetterOverloadCandidate(S, *Best, *Cand, Loc, Kind)) { if (S.isEquivalentInternalLinkageDeclaration(Best->Function, Cand->Function)) { EquivalentCands.push_back(Cand->Function); @@ -10222,9 +10289,12 @@ struct CompareOverloadCandidatesForDisplay { Sema &S; SourceLocation Loc; size_t NumArgs; + OverloadCandidateSet::CandidateSetKind CSK; - CompareOverloadCandidatesForDisplay(Sema &S, SourceLocation Loc, size_t nArgs) - : S(S), NumArgs(nArgs) {} + CompareOverloadCandidatesForDisplay( + Sema &S, SourceLocation Loc, size_t NArgs, + OverloadCandidateSet::CandidateSetKind CSK) + : S(S), NumArgs(NArgs), CSK(CSK) {} bool operator()(const OverloadCandidate *L, const OverloadCandidate *R) { @@ -10238,8 +10308,10 @@ struct CompareOverloadCandidatesForDisplay { // TODO: introduce a tri-valued comparison for overload // candidates. Would be more worthwhile if we had a sort // that could exploit it. - if (isBetterOverloadCandidate(S, *L, *R, SourceLocation())) return true; - if (isBetterOverloadCandidate(S, *R, *L, SourceLocation())) return false; + if (isBetterOverloadCandidate(S, *L, *R, SourceLocation(), CSK)) + return true; + if (isBetterOverloadCandidate(S, *R, *L, SourceLocation(), CSK)) + return false; } else if (R->Viable) return false; @@ -10446,8 +10518,8 @@ void OverloadCandidateSet::NoteCandidates( } } - std::sort(Cands.begin(), Cands.end(), - CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size())); + std::stable_sort(Cands.begin(), Cands.end(), + CompareOverloadCandidatesForDisplay(S, OpLoc, Args.size(), Kind)); bool ReportedAmbiguousConversions = false; @@ -10627,7 +10699,7 @@ static bool completeFunctionType(Sema &S, FunctionDecl *FD, SourceLocation Loc, return true; auto *FPT = FD->getType()->castAs<FunctionProtoType>(); - if (S.getLangOpts().CPlusPlus1z && + if (S.getLangOpts().CPlusPlus17 && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) && !S.ResolveExceptionSpec(Loc, FPT)) return true; @@ -11878,7 +11950,7 @@ static bool IsOverloaded(const UnresolvedSetImpl &Functions) { ExprResult Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, - Expr *Input) { + Expr *Input, bool PerformADL) { OverloadedOperatorKind Op = UnaryOperator::getOverloadedOperator(Opc); assert(Op != OO_None && "Invalid opcode for overloaded unary operator"); DeclarationName OpName = Context.DeclarationNames.getCXXOperatorName(Op); @@ -11929,9 +12001,11 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, AddMemberOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); // Add candidates from ADL. - AddArgumentDependentLookupCandidates(OpName, OpLoc, ArgsArray, - /*ExplicitTemplateArgs*/nullptr, - CandidateSet); + if (PerformADL) { + AddArgumentDependentLookupCandidates(OpName, OpLoc, ArgsArray, + /*ExplicitTemplateArgs*/nullptr, + CandidateSet); + } // Add builtin operator candidates. AddBuiltinOperatorCandidates(Op, OpLoc, ArgsArray, CandidateSet); @@ -12069,7 +12143,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, - Expr *LHS, Expr *RHS) { + Expr *LHS, Expr *RHS, bool PerformADL) { Expr *Args[2] = { LHS, RHS }; LHS=RHS=nullptr; // Please use only Args instead of LHS/RHS couple @@ -12100,7 +12174,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, UnresolvedLookupExpr *Fn = UnresolvedLookupExpr::Create(Context, NamingClass, NestedNameSpecifierLoc(), OpNameInfo, - /*ADL*/ true, IsOverloaded(Fns), + /*ADL*/PerformADL, IsOverloaded(Fns), Fns.begin(), Fns.end()); return new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args, Context.DependentTy, @@ -12143,7 +12217,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // Add candidates from ADL. Per [over.match.oper]p2, this lookup is not // performed for an assignment operator (nor for operator[] nor operator->, // which don't get here). - if (Opc != BO_Assign) + if (Opc != BO_Assign && PerformADL) AddArgumentDependentLookupCandidates(OpName, OpLoc, Args, /*ExplicitTemplateArgs*/ nullptr, CandidateSet); @@ -12896,7 +12970,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, // Perform overload resolution. OverloadCandidateSet::iterator Best; switch (CandidateSet.BestViableFunction(*this, Object.get()->getLocStart(), - Best)) { + Best)) { case OR_Success: // Overload resolution succeeded; we'll build the appropriate call // below. @@ -13290,7 +13364,7 @@ Sema::BuildForRangeBeginEndCall(SourceLocation Loc, Expr *Range, ExprResult *CallExpr) { Scope *S = nullptr; - CandidateSet->clear(); + CandidateSet->clear(OverloadCandidateSet::CSK_Normal); if (!MemberLookup.empty()) { ExprResult MemberRef = BuildMemberReferenceExpr(Range, Range->getType(), Loc, |