diff options
Diffstat (limited to 'lib/Sema/SemaOverload.cpp')
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 648 |
1 files changed, 414 insertions, 234 deletions
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index d6a0ff7dc3d15..b025a397edca0 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -39,8 +39,8 @@ using namespace clang; using namespace sema; static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) { - return std::any_of(FD->param_begin(), FD->param_end(), - std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>)); + return llvm::any_of(FD->parameters(), + std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>)); } /// A convenience routine for creating a decayed reference to a function. @@ -293,6 +293,13 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, // A narrowing conversion is an implicit conversion ... QualType FromType = getToType(0); QualType ToType = getToType(1); + + // A conversion to an enumeration type is narrowing if the conversion to + // the underlying type is narrowing. This only arises for expressions of + // the form 'Enum{init}'. + if (auto *ET = ToType->getAs<EnumType>()) + ToType = ET->getDecl()->getIntegerType(); + switch (Second) { // 'bool' is an integral type; dispatch to the right place to handle it. case ICK_Boolean_Conversion: @@ -433,7 +440,7 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, /// dump - Print this standard conversion sequence to standard /// error. Useful for debugging overloading issues. -void StandardConversionSequence::dump() const { +LLVM_DUMP_METHOD void StandardConversionSequence::dump() const { raw_ostream &OS = llvm::errs(); bool PrintedSomething = false; if (First != ICK_Identity) { @@ -985,7 +992,7 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, } bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, - bool UseUsingDeclRules) { + bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs) { // C++ [basic.start.main]p2: This function shall not be overloaded. if (New->isMain()) return false; @@ -1041,7 +1048,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, // // However, we don't consider either of these when deciding whether // a member introduced by a shadow declaration is hidden. - if (!UseUsingDeclRules && NewTemplate && + if (!UseMemberUsingDeclRules && NewTemplate && (!TemplateParameterListsAreEqual(NewTemplate->getTemplateParameters(), OldTemplate->getTemplateParameters(), false, TPL_TemplateMatch) || @@ -1061,7 +1068,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, if (OldMethod && NewMethod && !OldMethod->isStatic() && !NewMethod->isStatic()) { if (OldMethod->getRefQualifier() != NewMethod->getRefQualifier()) { - if (!UseUsingDeclRules && + if (!UseMemberUsingDeclRules && (OldMethod->getRefQualifier() == RQ_None || NewMethod->getRefQualifier() == RQ_None)) { // C++0x [over.load]p2: @@ -1118,7 +1125,7 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, return true; } - if (getLangOpts().CUDA && getLangOpts().CUDATargetOverloads) { + if (getLangOpts().CUDA && ConsiderCudaAttrs) { CUDAFunctionTarget NewTarget = IdentifyCUDATarget(New), OldTarget = IdentifyCUDATarget(Old); if (NewTarget == CFT_InvalidTarget || NewTarget == CFT_Global) @@ -1129,7 +1136,10 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, // Don't allow mixing of HD with other kinds. This guarantees that // we have only one viable function with this signature on any // side of CUDA compilation . - if ((NewTarget == CFT_HostDevice) || (OldTarget == CFT_HostDevice)) + // __global__ functions can't be overloaded based on attribute + // difference because, like HD, they also exist on both sides. + if ((NewTarget == CFT_HostDevice) || (OldTarget == CFT_HostDevice) || + (NewTarget == CFT_Global) || (OldTarget == CFT_Global)) return false; // Allow overloading of functions with same signature, but @@ -1147,7 +1157,16 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, /// \returns true if \arg FD is unavailable and current context is inside /// an available function, false otherwise. bool Sema::isFunctionConsideredUnavailable(FunctionDecl *FD) { - return FD->isUnavailable() && !cast<Decl>(CurContext)->isUnavailable(); + if (!FD->isUnavailable()) + return false; + + // Walk up the context of the caller. + Decl *C = cast<Decl>(CurContext); + do { + if (C->isUnavailable()) + return false; + } while ((C = cast_or_null<Decl>(C->getDeclContext()))); + return true; } /// \brief Tries a user-defined conversion from From to ToType. @@ -1199,11 +1218,13 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, S.IsDerivedFrom(From->getLocStart(), FromCanon, ToCanon))) { // Turn this into a "standard" conversion sequence, so that it // gets ranked with standard conversion sequences. + DeclAccessPair Found = ICS.UserDefined.FoundConversionFunction; ICS.setStandard(); ICS.Standard.setAsIdentityConversion(); ICS.Standard.setFromType(From->getType()); ICS.Standard.setAllToTypes(ToType); ICS.Standard.CopyConstructor = Constructor; + ICS.Standard.FoundCopyConstructor = Found; if (ToCanon != FromCanon) ICS.Standard.Second = ICK_Derived_To_Base; } @@ -1217,7 +1238,7 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, for (OverloadCandidateSet::iterator Cand = Conversions.begin(); Cand != Conversions.end(); ++Cand) if (Cand->Viable) - ICS.Ambiguous.addConversion(Cand->Function); + ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); break; // Fall through. @@ -1652,6 +1673,20 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, SCS.Second = ICK_Complex_Real; FromType = ToType.getUnqualifiedType(); } else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) { + // FIXME: disable conversions between long double and __float128 if + // their representation is different until there is back end support + // We of course allow this conversion if long double is really double. + if (&S.Context.getFloatTypeSemantics(FromType) != + &S.Context.getFloatTypeSemantics(ToType)) { + bool Float128AndLongDouble = ((FromType == S.Context.Float128Ty && + ToType == S.Context.LongDoubleTy) || + (FromType == S.Context.LongDoubleTy && + ToType == S.Context.Float128Ty)); + if (Float128AndLongDouble && + (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) != + &llvm::APFloat::IEEEdouble)) + return false; + } // Floating point conversions (C++ 4.8). SCS.Second = ICK_Floating_Conversion; FromType = ToType.getUnqualifiedType(); @@ -1809,8 +1844,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { (FromType->isSignedIntegerType() || // We can promote any unsigned integer type whose size is // less than int to an int. - (!FromType->isSignedIntegerType() && - Context.getTypeSize(FromType) < Context.getTypeSize(ToType)))) { + Context.getTypeSize(FromType) < Context.getTypeSize(ToType))) { return To->getKind() == BuiltinType::Int; } @@ -1955,7 +1989,8 @@ bool Sema::IsFloatingPointPromotion(QualType FromType, QualType ToType) { if (!getLangOpts().CPlusPlus && (FromBuiltin->getKind() == BuiltinType::Float || FromBuiltin->getKind() == BuiltinType::Double) && - (ToBuiltin->getKind() == BuiltinType::LongDouble)) + (ToBuiltin->getKind() == BuiltinType::LongDouble || + ToBuiltin->getKind() == BuiltinType::Float128)) return true; // Half can be promoted to float. @@ -2538,9 +2573,8 @@ bool Sema::IsBlockPointerConversion(QualType FromType, QualType ToType, // Argument types are too different. Abort. return false; } - if (LangOpts.ObjCAutoRefCount && - !Context.FunctionTypesMatchOnNSConsumedAttrs(FromFunctionType, - ToFunctionType)) + if (!Context.doFunctionTypesMatchOnExtParameterInfos(FromFunctionType, + ToFunctionType)) return false; ConvertedType = ToType; @@ -2919,6 +2953,10 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType, Qualifiers FromQuals = FromType.getQualifiers(); Qualifiers ToQuals = ToType.getQualifiers(); + + // Ignore __unaligned qualifier if this type is void. + if (ToType.getUnqualifiedType()->isVoidType()) + FromQuals.removeUnaligned(); // Objective-C ARC: // Check Objective-C lifetime conversions. @@ -3015,39 +3053,26 @@ IsInitializerListConstructorConversion(Sema &S, Expr *From, QualType ToType, UserDefinedConversionSequence &User, OverloadCandidateSet &CandidateSet, bool AllowExplicit) { - DeclContext::lookup_result R = S.LookupConstructors(To); - for (DeclContext::lookup_iterator Con = R.begin(), ConEnd = R.end(); - Con != ConEnd; ++Con) { - NamedDecl *D = *Con; - DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); - - // Find the constructor (which may be a template). - CXXConstructorDecl *Constructor = nullptr; - FunctionTemplateDecl *ConstructorTmpl - = dyn_cast<FunctionTemplateDecl>(D); - if (ConstructorTmpl) - Constructor - = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl()); - else - Constructor = cast<CXXConstructorDecl>(D); + for (auto *D : S.LookupConstructors(To)) { + auto Info = getConstructorInfo(D); + if (!Info) + continue; - bool Usable = !Constructor->isInvalidDecl() && - S.isInitListConstructor(Constructor) && - (AllowExplicit || !Constructor->isExplicit()); + bool Usable = !Info.Constructor->isInvalidDecl() && + S.isInitListConstructor(Info.Constructor) && + (AllowExplicit || !Info.Constructor->isExplicit()); if (Usable) { // If the first argument is (a reference to) the target type, // suppress conversions. - bool SuppressUserConversions = - isFirstArgumentCompatibleWithType(S.Context, Constructor, ToType); - if (ConstructorTmpl) - S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, - /*ExplicitArgs*/ nullptr, - From, CandidateSet, - SuppressUserConversions); + bool SuppressUserConversions = isFirstArgumentCompatibleWithType( + S.Context, Info.Constructor, ToType); + if (Info.ConstructorTmpl) + S.AddTemplateOverloadCandidate(Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, From, + CandidateSet, SuppressUserConversions); else - S.AddOverloadCandidate(Constructor, FoundDecl, - From, CandidateSet, - SuppressUserConversions); + S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, From, + CandidateSet, SuppressUserConversions); } } @@ -3147,27 +3172,17 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, ListInitializing = true; } - DeclContext::lookup_result R = S.LookupConstructors(ToRecordDecl); - for (DeclContext::lookup_iterator Con = R.begin(), ConEnd = R.end(); - Con != ConEnd; ++Con) { - NamedDecl *D = *Con; - DeclAccessPair FoundDecl = DeclAccessPair::make(D, D->getAccess()); - - // Find the constructor (which may be a template). - CXXConstructorDecl *Constructor = nullptr; - FunctionTemplateDecl *ConstructorTmpl - = dyn_cast<FunctionTemplateDecl>(D); - if (ConstructorTmpl) - Constructor - = cast<CXXConstructorDecl>(ConstructorTmpl->getTemplatedDecl()); - else - Constructor = cast<CXXConstructorDecl>(D); + for (auto *D : S.LookupConstructors(ToRecordDecl)) { + auto Info = getConstructorInfo(D); + if (!Info) + continue; - bool Usable = !Constructor->isInvalidDecl(); + bool Usable = !Info.Constructor->isInvalidDecl(); if (ListInitializing) - Usable = Usable && (AllowExplicit || !Constructor->isExplicit()); + Usable = Usable && (AllowExplicit || !Info.Constructor->isExplicit()); else - Usable = Usable &&Constructor->isConvertingConstructor(AllowExplicit); + Usable = Usable && + Info.Constructor->isConvertingConstructor(AllowExplicit); if (Usable) { bool SuppressUserConversions = !ConstructorsOnly; if (SuppressUserConversions && ListInitializing) { @@ -3176,18 +3191,18 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType, // If the first argument is (a reference to) the target type, // suppress conversions. SuppressUserConversions = isFirstArgumentCompatibleWithType( - S.Context, Constructor, ToType); + S.Context, Info.Constructor, ToType); } } - if (ConstructorTmpl) - S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, - /*ExplicitArgs*/ nullptr, - llvm::makeArrayRef(Args, NumArgs), - CandidateSet, SuppressUserConversions); + if (Info.ConstructorTmpl) + S.AddTemplateOverloadCandidate( + Info.ConstructorTmpl, Info.FoundDecl, + /*ExplicitArgs*/ nullptr, llvm::makeArrayRef(Args, NumArgs), + CandidateSet, SuppressUserConversions); else // Allow one user-defined conversion when user specifies a // From->ToType conversion via an static cast (c-style, etc). - S.AddOverloadCandidate(Constructor, FoundDecl, + S.AddOverloadCandidate(Info.Constructor, Info.FoundDecl, llvm::makeArrayRef(Args, NumArgs), CandidateSet, SuppressUserConversions); } @@ -4127,6 +4142,10 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, T2Quals.removeObjCLifetime(); } + // MS compiler ignores __unaligned qualifier for references; do the same. + T1Quals.removeUnaligned(); + T2Quals.removeUnaligned(); + if (T1Quals == T2Quals) return Ref_Compatible; else if (T1Quals.compatiblyIncludes(T2Quals)) @@ -4248,7 +4267,7 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS, for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(); Cand != CandidateSet.end(); ++Cand) if (Cand->Viable) - ICS.Ambiguous.addConversion(Cand->Function); + ICS.Ambiguous.addConversion(Cand->FoundDecl, Cand->Function); return true; case OR_No_Viable_Function: @@ -4448,13 +4467,16 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, // initialization fails. // // Note that we only want to check address spaces and cvr-qualifiers here. - // ObjC GC and lifetime qualifiers aren't important. + // ObjC GC, lifetime and unaligned qualifiers aren't important. Qualifiers T1Quals = T1.getQualifiers(); Qualifiers T2Quals = T2.getQualifiers(); T1Quals.removeObjCGCAttr(); T1Quals.removeObjCLifetime(); T2Quals.removeObjCGCAttr(); T2Quals.removeObjCLifetime(); + // MS compiler ignores __unaligned qualifier for references; do the same. + T1Quals.removeUnaligned(); + T2Quals.removeUnaligned(); if (!T1Quals.compatiblyIncludes(T2Quals)) return ICS; } @@ -5838,12 +5860,12 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, } } -ObjCMethodDecl *Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, - bool IsInstance) { - SmallVector<ObjCMethodDecl*, 4> Methods; - if (!CollectMultipleMethodsInGlobalPool(Sel, Methods, IsInstance)) +ObjCMethodDecl * +Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, + SmallVectorImpl<ObjCMethodDecl *> &Methods) { + if (Methods.size() <= 1) return nullptr; - + for (unsigned b = 0, e = Methods.size(); b < e; b++) { bool Match = true; ObjCMethodDecl *Method = Methods[b]; @@ -5952,37 +5974,28 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, SFINAETrap Trap(*this); SmallVector<Expr *, 16> ConvertedArgs; bool InitializationFailed = false; - bool ContainsValueDependentExpr = false; // Convert the arguments. - for (unsigned i = 0, e = Args.size(); i != e; ++i) { - if (i == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) && + for (unsigned I = 0, E = Args.size(); I != E; ++I) { + ExprResult R; + if (I == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) && !cast<CXXMethodDecl>(Function)->isStatic() && !isa<CXXConstructorDecl>(Function)) { CXXMethodDecl *Method = cast<CXXMethodDecl>(Function); - ExprResult R = - PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr, - Method, Method); - if (R.isInvalid()) { - InitializationFailed = true; - break; - } - ContainsValueDependentExpr |= R.get()->isValueDependent(); - ConvertedArgs.push_back(R.get()); + R = PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr, + Method, Method); } else { - ExprResult R = - PerformCopyInitialization(InitializedEntity::InitializeParameter( - Context, - Function->getParamDecl(i)), - SourceLocation(), - Args[i]); - if (R.isInvalid()) { - InitializationFailed = true; - break; - } - ContainsValueDependentExpr |= R.get()->isValueDependent(); - ConvertedArgs.push_back(R.get()); + R = PerformCopyInitialization(InitializedEntity::InitializeParameter( + Context, Function->getParamDecl(I)), + SourceLocation(), Args[I]); } + + if (R.isInvalid()) { + InitializationFailed = true; + break; + } + + ConvertedArgs.push_back(R.get()); } if (InitializationFailed || Trap.hasErrorOccurred()) @@ -6002,7 +6015,6 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, InitializationFailed = true; break; } - ContainsValueDependentExpr |= R.get()->isValueDependent(); ConvertedArgs.push_back(R.get()); } @@ -6012,18 +6024,14 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, for (auto *EIA : EnableIfAttrs) { APValue Result; - if (EIA->getCond()->isValueDependent()) { - // Don't even try now, we'll examine it after instantiation. - continue; - } - + // FIXME: This doesn't consider value-dependent cases, because doing so is + // very difficult. Ideally, we should handle them more gracefully. if (!EIA->getCond()->EvaluateWithSubstitution( - Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) { - if (!ContainsValueDependentExpr) - return EIA; - } else if (!Result.isInt() || !Result.getInt().getBoolValue()) { + Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) + return EIA; + + if (!Result.isInt() || !Result.getInt().getBoolValue()) return EIA; - } } return nullptr; } @@ -6814,7 +6822,8 @@ namespace { /// enumeration types. class BuiltinCandidateTypeSet { /// TypeSet - A set of types. - typedef llvm::SmallPtrSet<QualType, 8> TypeSet; + typedef llvm::SetVector<QualType, SmallVector<QualType, 8>, + llvm::SmallPtrSet<QualType, 8>> TypeSet; /// PointerTypes - The set of pointer types that will be used in the /// built-in candidates. @@ -6913,7 +6922,7 @@ BuiltinCandidateTypeSet::AddPointerWithMoreQualifiedTypeVariants(QualType Ty, const Qualifiers &VisibleQuals) { // Insert this type. - if (!PointerTypes.insert(Ty).second) + if (!PointerTypes.insert(Ty)) return false; QualType PointeeTy; @@ -6981,7 +6990,7 @@ bool BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants( QualType Ty) { // Insert this type. - if (!MemberPointerTypes.insert(Ty).second) + if (!MemberPointerTypes.insert(Ty)) return false; const MemberPointerType *PointerTy = Ty->getAs<MemberPointerType>(); @@ -7187,13 +7196,13 @@ class BuiltinOperatorOverloadBuilder { // provided via the getArithmeticType() method below. // The "promoted arithmetic types" are the arithmetic // types are that preserved by promotion (C++ [over.built]p2). - static const unsigned FirstIntegralType = 3; - static const unsigned LastIntegralType = 20; - static const unsigned FirstPromotedIntegralType = 3, - LastPromotedIntegralType = 11; + static const unsigned FirstIntegralType = 4; + static const unsigned LastIntegralType = 21; + static const unsigned FirstPromotedIntegralType = 4, + LastPromotedIntegralType = 12; static const unsigned FirstPromotedArithmeticType = 0, - LastPromotedArithmeticType = 11; - static const unsigned NumArithmeticTypes = 20; + LastPromotedArithmeticType = 12; + static const unsigned NumArithmeticTypes = 21; /// \brief Get the canonical type for a given arithmetic type index. CanQualType getArithmeticType(unsigned index) { @@ -7204,6 +7213,7 @@ class BuiltinOperatorOverloadBuilder { &ASTContext::FloatTy, &ASTContext::DoubleTy, &ASTContext::LongDoubleTy, + &ASTContext::Float128Ty, // Start of integral types. &ASTContext::IntTy, @@ -7246,7 +7256,7 @@ class BuiltinOperatorOverloadBuilder { // (we could precompute SLL x UI for all known platforms, but it's // better not to make any assumptions). // We assume that int128 has a higher rank than long long on all platforms. - enum PromotedType { + enum PromotedType : int8_t { Dep=-1, Flt, Dbl, LDbl, SI, SL, SLL, S128, UI, UL, ULL, U128 }; @@ -8476,16 +8486,31 @@ Sema::AddArgumentDependentLookupCandidates(DeclarationName Name, } } -// Determines whether Cand1 is "better" in terms of its enable_if attrs than -// Cand2 for overloading. This function assumes that all of the enable_if attrs -// on Cand1 and Cand2 have conditions that evaluate to true. -// -// Cand1's set of enable_if attributes are said to be "better" than Cand2's iff -// Cand1's first N enable_if attributes have precisely the same conditions as -// Cand2's first N enable_if attributes (where N = the number of enable_if -// attributes on Cand2), and Cand1 has more than N enable_if attributes. -static bool hasBetterEnableIfAttrs(Sema &S, const FunctionDecl *Cand1, - const FunctionDecl *Cand2) { +namespace { +enum class Comparison { Equal, Better, Worse }; +} + +/// Compares the enable_if attributes of two FunctionDecls, for the purposes of +/// overload resolution. +/// +/// Cand1's set of enable_if attributes are said to be "better" than Cand2's iff +/// Cand1's first N enable_if attributes have precisely the same conditions as +/// Cand2's first N enable_if attributes (where N = the number of enable_if +/// attributes on Cand2), and Cand1 has more than N enable_if attributes. +/// +/// Note that you can have a pair of candidates such that Cand1's enable_if +/// attributes are worse than Cand2's, and Cand2's enable_if attributes are +/// worse than Cand1's. +static Comparison compareEnableIfAttrs(const Sema &S, const FunctionDecl *Cand1, + const FunctionDecl *Cand2) { + // Common case: One (or both) decls don't have enable_if attrs. + bool Cand1Attr = Cand1->hasAttr<EnableIfAttr>(); + bool Cand2Attr = Cand2->hasAttr<EnableIfAttr>(); + if (!Cand1Attr || !Cand2Attr) { + if (Cand1Attr == Cand2Attr) + return Comparison::Equal; + return Cand1Attr ? Comparison::Better : Comparison::Worse; + } // FIXME: The next several lines are just // specific_attr_iterator<EnableIfAttr> but going in declaration order, @@ -8493,10 +8518,10 @@ static bool hasBetterEnableIfAttrs(Sema &S, const FunctionDecl *Cand1, auto Cand1Attrs = getOrderedEnableIfAttrs(Cand1); auto Cand2Attrs = getOrderedEnableIfAttrs(Cand2); - // Candidate 1 is better if it has strictly more attributes and - // the common sequence is identical. - if (Cand1Attrs.size() <= Cand2Attrs.size()) - return false; + // It's impossible for Cand1 to be better than (or equal to) Cand2 if Cand1 + // has fewer enable_if attributes than Cand2. + if (Cand1Attrs.size() < Cand2Attrs.size()) + return Comparison::Worse; auto Cand1I = Cand1Attrs.begin(); llvm::FoldingSetNodeID Cand1ID, Cand2ID; @@ -8508,10 +8533,10 @@ static bool hasBetterEnableIfAttrs(Sema &S, const FunctionDecl *Cand1, Cand1A->getCond()->Profile(Cand1ID, S.getASTContext(), true); Cand2A->getCond()->Profile(Cand2ID, S.getASTContext(), true); if (Cand1ID != Cand2ID) - return false; + return Comparison::Worse; } - return true; + return Cand1I == Cand1Attrs.end() ? Comparison::Equal : Comparison::Better; } /// isBetterOverloadCandidate - Determines whether the first overload @@ -8621,14 +8646,33 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, return BetterTemplate == Cand1.Function->getPrimaryTemplate(); } + // FIXME: Work around a defect in the C++17 inheriting constructor wording. + // A derived-class constructor beats an (inherited) base class constructor. + bool Cand1IsInherited = + dyn_cast_or_null<ConstructorUsingShadowDecl>(Cand1.FoundDecl.getDecl()); + bool Cand2IsInherited = + dyn_cast_or_null<ConstructorUsingShadowDecl>(Cand2.FoundDecl.getDecl()); + if (Cand1IsInherited != Cand2IsInherited) + return Cand2IsInherited; + else if (Cand1IsInherited) { + assert(Cand2IsInherited); + auto *Cand1Class = cast<CXXRecordDecl>(Cand1.Function->getDeclContext()); + auto *Cand2Class = cast<CXXRecordDecl>(Cand2.Function->getDeclContext()); + if (Cand1Class->isDerivedFrom(Cand2Class)) + return true; + if (Cand2Class->isDerivedFrom(Cand1Class)) + return false; + // Inherited from sibling base classes: still ambiguous. + } + // Check for enable_if value-based overload resolution. - if (Cand1.Function && Cand2.Function && - (Cand1.Function->hasAttr<EnableIfAttr>() || - Cand2.Function->hasAttr<EnableIfAttr>())) - return hasBetterEnableIfAttrs(S, Cand1.Function, Cand2.Function); + if (Cand1.Function && Cand2.Function) { + Comparison Cmp = compareEnableIfAttrs(S, Cand1.Function, Cand2.Function); + if (Cmp != Comparison::Equal) + return Cmp == Comparison::Better; + } - if (S.getLangOpts().CUDA && S.getLangOpts().CUDATargetOverloads && - Cand1.Function && Cand2.Function) { + if (S.getLangOpts().CUDA && Cand1.Function && Cand2.Function) { FunctionDecl *Caller = dyn_cast<FunctionDecl>(S.CurContext); return S.IdentifyCUDAPreference(Caller, Cand1.Function) > S.IdentifyCUDAPreference(Caller, Cand2.Function); @@ -8722,14 +8766,44 @@ OverloadingResult OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, iterator &Best, bool UserDefinedConversion) { + llvm::SmallVector<OverloadCandidate *, 16> Candidates; + std::transform(begin(), end(), std::back_inserter(Candidates), + [](OverloadCandidate &Cand) { return &Cand; }); + + // [CUDA] HD->H or HD->D calls are technically not allowed by CUDA + // but accepted by both clang and NVCC. However during a particular + // compilation mode only one call variant is viable. We need to + // exclude non-viable overload candidates from consideration based + // only on their host/device attributes. Specifically, if one + // candidate call is WrongSide and the other is SameSide, we ignore + // the WrongSide candidate. + if (S.getLangOpts().CUDA) { + const FunctionDecl *Caller = dyn_cast<FunctionDecl>(S.CurContext); + bool ContainsSameSideCandidate = + llvm::any_of(Candidates, [&](OverloadCandidate *Cand) { + return Cand->Function && + S.IdentifyCUDAPreference(Caller, Cand->Function) == + Sema::CFP_SameSide; + }); + if (ContainsSameSideCandidate) { + auto IsWrongSideCandidate = [&](OverloadCandidate *Cand) { + return Cand->Function && + S.IdentifyCUDAPreference(Caller, Cand->Function) == + Sema::CFP_WrongSide; + }; + Candidates.erase(std::remove_if(Candidates.begin(), Candidates.end(), + IsWrongSideCandidate), + Candidates.end()); + } + } + // Find the best viable function. Best = end(); - for (iterator Cand = begin(); Cand != end(); ++Cand) { + for (auto *Cand : Candidates) if (Cand->Viable) if (Best == end() || isBetterOverloadCandidate(S, *Cand, *Best, Loc, UserDefinedConversion)) Best = Cand; - } // If we didn't find any viable functions, abort. if (Best == end()) @@ -8739,7 +8813,7 @@ 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 (iterator Cand = begin(); Cand != end(); ++Cand) { + for (auto *Cand : Candidates) { if (Cand->Viable && Cand != Best && !isBetterOverloadCandidate(S, *Best, *Cand, Loc, @@ -8782,10 +8856,12 @@ enum OverloadCandidateKind { oc_implicit_move_constructor, oc_implicit_copy_assignment, oc_implicit_move_assignment, - oc_implicit_inherited_constructor + oc_inherited_constructor, + oc_inherited_constructor_template }; OverloadCandidateKind ClassifyOverloadCandidate(Sema &S, + NamedDecl *Found, FunctionDecl *Fn, std::string &Description) { bool isTemplate = false; @@ -8797,11 +8873,13 @@ OverloadCandidateKind ClassifyOverloadCandidate(Sema &S, } if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn)) { - if (!Ctor->isImplicit()) - return isTemplate ? oc_constructor_template : oc_constructor; - - if (Ctor->getInheritedConstructor()) - return oc_implicit_inherited_constructor; + if (!Ctor->isImplicit()) { + if (isa<ConstructorUsingShadowDecl>(Found)) + return isTemplate ? oc_inherited_constructor_template + : oc_inherited_constructor; + else + return isTemplate ? oc_constructor_template : oc_constructor; + } if (Ctor->isDefaultConstructor()) return oc_implicit_default_constructor; @@ -8833,14 +8911,13 @@ OverloadCandidateKind ClassifyOverloadCandidate(Sema &S, return isTemplate ? oc_function_template : oc_function; } -void MaybeEmitInheritedConstructorNote(Sema &S, Decl *Fn) { - const CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Fn); - if (!Ctor) return; - - Ctor = Ctor->getInheritedConstructor(); - if (!Ctor) return; - - S.Diag(Ctor->getLocation(), diag::note_ovl_candidate_inherited_constructor); +void MaybeEmitInheritedConstructorNote(Sema &S, Decl *FoundDecl) { + // FIXME: It'd be nice to only emit a note once per using-decl per overload + // set. + if (auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl)) + S.Diag(FoundDecl->getLocation(), + diag::note_ovl_candidate_inherited_constructor) + << Shadow->getNominatedBaseClass(); } } // end anonymous namespace @@ -8879,8 +8956,8 @@ static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD, return false; } - auto I = std::find_if(FD->param_begin(), FD->param_end(), - std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>)); + auto I = llvm::find_if( + FD->parameters(), std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>)); if (I == FD->param_end()) return true; @@ -8914,19 +8991,19 @@ bool Sema::checkAddressOfFunctionIsAvailable(const FunctionDecl *Function, } // Notes the location of an overload candidate. -void Sema::NoteOverloadCandidate(FunctionDecl *Fn, QualType DestType, - bool TakingAddress) { +void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, + QualType DestType, bool TakingAddress) { if (TakingAddress && !checkAddressOfCandidateIsAvailable(*this, Fn)) return; std::string FnDesc; - OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Fn, FnDesc); + OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc); PartialDiagnostic PD = PDiag(diag::note_ovl_candidate) << (unsigned) K << FnDesc; HandleFunctionTypeMismatch(PD, Fn->getType(), DestType); Diag(Fn->getLocation(), PD); - MaybeEmitInheritedConstructorNote(*this, Fn); + MaybeEmitInheritedConstructorNote(*this, Found); } // Notes the location of all overload candidates designated through @@ -8943,11 +9020,11 @@ void Sema::NoteAllOverloadCandidates(Expr *OverloadedExpr, QualType DestType, I != IEnd; ++I) { if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>((*I)->getUnderlyingDecl()) ) { - NoteOverloadCandidate(FunTmpl->getTemplatedDecl(), DestType, + NoteOverloadCandidate(*I, FunTmpl->getTemplatedDecl(), DestType, TakingAddress); } else if (FunctionDecl *Fun = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl()) ) { - NoteOverloadCandidate(Fun, DestType, TakingAddress); + NoteOverloadCandidate(*I, Fun, DestType, TakingAddress); } } } @@ -8971,7 +9048,7 @@ void ImplicitConversionSequence::DiagnoseAmbiguousConversion( if (CandsShown >= 4 && ShowOverloads == Ovl_Best) break; ++CandsShown; - S.NoteOverloadCandidate(*I); + S.NoteOverloadCandidate(I->first, I->second); } if (I != E) S.Diag(SourceLocation(), diag::note_ovl_too_many_candidates) << int(E - I); @@ -8996,7 +9073,8 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, } std::string FnDesc; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); Expr *FromExpr = Conv.Bad.FromExpr; QualType FromTy = Conv.Bad.getFromType(); @@ -9013,7 +9091,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << (unsigned) FnKind << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << ToTy << Name << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9026,8 +9104,10 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, else { // TODO: detect and diagnose the full richness of const mismatches. if (CanQual<PointerType> FromPT = CFromTy->getAs<PointerType>()) - if (CanQual<PointerType> ToPT = CToTy->getAs<PointerType>()) - CFromTy = FromPT->getPointeeType(), CToTy = ToPT->getPointeeType(); + if (CanQual<PointerType> ToPT = CToTy->getAs<PointerType>()) { + CFromTy = FromPT->getPointeeType(); + CToTy = ToPT->getPointeeType(); + } } if (CToTy.getUnqualifiedType() == CFromTy.getUnqualifiedType() && @@ -9042,7 +9122,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << FromTy << FromQs.getAddressSpace() << ToQs.getAddressSpace() << (unsigned) isObjectArgument << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9053,7 +9133,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << FromTy << FromQs.getObjCLifetime() << ToQs.getObjCLifetime() << (unsigned) isObjectArgument << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9064,7 +9144,16 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << FromTy << FromQs.getObjCGCAttr() << ToQs.getObjCGCAttr() << (unsigned) isObjectArgument << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); + return; + } + + if (FromQs.hasUnaligned() != ToQs.hasUnaligned()) { + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_unaligned) + << (unsigned) FnKind << FnDesc + << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) + << FromTy << FromQs.hasUnaligned() << I+1; + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9082,7 +9171,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << (CVR - 1) << I+1; } - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9093,7 +9182,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << (unsigned) FnKind << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned) isObjectArgument << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9104,11 +9193,14 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, if (const PointerType *PTy = TempFromTy->getAs<PointerType>()) TempFromTy = PTy->getPointeeType(); if (TempFromTy->isIncompleteType()) { + // Emit the generic diagnostic and, optionally, add the hints to it. S.Diag(Fn->getLocation(), diag::note_ovl_candidate_bad_conv_incomplete) << (unsigned) FnKind << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) - << FromTy << ToTy << (unsigned) isObjectArgument << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + << FromTy << ToTy << (unsigned) isObjectArgument << I+1 + << (unsigned) (Cand->Fix.Kind); + + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9147,7 +9239,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << (unsigned) FnKind << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << (unsigned) isObjectArgument << I + 1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } } @@ -9159,7 +9251,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << (BaseToDerivedConversion - 1) << FromTy << ToTy << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } @@ -9172,7 +9264,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, << (unsigned) FnKind << FnDesc << (FromExpr ? FromExpr->getSourceRange() : SourceRange()) << FromTy << ToTy << (unsigned) isObjectArgument << I+1; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } } @@ -9194,7 +9286,7 @@ static void DiagnoseBadConversion(Sema &S, OverloadCandidate *Cand, FDiag << *HI; S.Diag(Fn->getLocation(), FDiag); - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); } /// Additional arity mismatch diagnosis specific to a function overload @@ -9228,7 +9320,8 @@ static bool CheckArityMismatch(Sema &S, OverloadCandidate *Cand, } /// General arity mismatch diagnosis over a candidate in a candidate set. -static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) { +static void DiagnoseArityMismatch(Sema &S, NamedDecl *Found, Decl *D, + unsigned NumFormalArgs) { assert(isa<FunctionDecl>(D) && "The templated declaration should at least be a function" " when diagnosing bad template argument deduction due to too many" @@ -9258,7 +9351,8 @@ static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) { } std::string Description; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, Description); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Found, Fn, Description); if (modeCount == 1 && Fn->getParamDecl(0)->getDeclName()) S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity_one) @@ -9268,28 +9362,25 @@ static void DiagnoseArityMismatch(Sema &S, Decl *D, unsigned NumFormalArgs) { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_arity) << (unsigned) FnKind << (Fn->getDescribedFunctionTemplate() != nullptr) << mode << modeCount << NumFormalArgs; - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Found); } /// Arity mismatch diagnosis specific to a function overload candidate. static void DiagnoseArityMismatch(Sema &S, OverloadCandidate *Cand, unsigned NumFormalArgs) { if (!CheckArityMismatch(S, Cand, NumFormalArgs)) - DiagnoseArityMismatch(S, Cand->Function, NumFormalArgs); + DiagnoseArityMismatch(S, Cand->FoundDecl, Cand->Function, NumFormalArgs); } static TemplateDecl *getDescribedTemplate(Decl *Templated) { - if (FunctionDecl *FD = dyn_cast<FunctionDecl>(Templated)) - return FD->getDescribedFunctionTemplate(); - else if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Templated)) - return RD->getDescribedClassTemplate(); - + if (TemplateDecl *TD = Templated->getDescribedTemplate()) + return TD; llvm_unreachable("Unsupported: Getting the described template declaration" " for bad deduction diagnosis"); } /// Diagnose a failed template-argument deduction. -static void DiagnoseBadDeduction(Sema &S, Decl *Templated, +static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, DeductionFailureInfo &DeductionFailure, unsigned NumArgs, bool TakingCandidateAddress) { @@ -9307,7 +9398,7 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, S.Diag(Templated->getLocation(), diag::note_ovl_candidate_incomplete_deduction) << ParamD->getDeclName(); - MaybeEmitInheritedConstructorNote(S, Templated); + MaybeEmitInheritedConstructorNote(S, Found); return; } @@ -9332,7 +9423,7 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, S.Diag(Templated->getLocation(), diag::note_ovl_candidate_underqualified) << ParamD->getDeclName() << Arg << NonCanonParam; - MaybeEmitInheritedConstructorNote(S, Templated); + MaybeEmitInheritedConstructorNote(S, Found); return; } @@ -9351,7 +9442,7 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, diag::note_ovl_candidate_inconsistent_deduction) << which << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg(); - MaybeEmitInheritedConstructorNote(S, Templated); + MaybeEmitInheritedConstructorNote(S, Found); return; } @@ -9374,18 +9465,18 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, diag::note_ovl_candidate_explicit_arg_mismatch_unnamed) << (index + 1); } - MaybeEmitInheritedConstructorNote(S, Templated); + MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: - DiagnoseArityMismatch(S, Templated, NumArgs); + DiagnoseArityMismatch(S, Found, Templated, NumArgs); return; case Sema::TDK_InstantiationDepth: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_instantiation_depth); - MaybeEmitInheritedConstructorNote(S, Templated); + MaybeEmitInheritedConstructorNote(S, Found); return; case Sema::TDK_SubstitutionFailure: { @@ -9423,7 +9514,7 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, S.Diag(Templated->getLocation(), diag::note_ovl_candidate_substitution_failure) << TemplateArgString << SFINAEArgString << R; - MaybeEmitInheritedConstructorNote(S, Templated); + MaybeEmitInheritedConstructorNote(S, Found); return; } @@ -9495,7 +9586,7 @@ static void DiagnoseBadDeduction(Sema &S, Decl *Templated, // note_ovl_candidate_bad_deduction, which is uselessly vague. case Sema::TDK_MiscellaneousDeductionFailure: S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_deduction); - MaybeEmitInheritedConstructorNote(S, Templated); + MaybeEmitInheritedConstructorNote(S, Found); return; } } @@ -9509,7 +9600,7 @@ static void DiagnoseBadDeduction(Sema &S, OverloadCandidate *Cand, if (CheckArityMismatch(S, Cand, NumArgs)) return; } - DiagnoseBadDeduction(S, Cand->Function, // pattern + DiagnoseBadDeduction(S, Cand->FoundDecl, Cand->Function, // pattern Cand->DeductionFailure, NumArgs, TakingCandidateAddress); } @@ -9522,7 +9613,8 @@ static void DiagnoseBadTarget(Sema &S, OverloadCandidate *Cand) { CalleeTarget = S.IdentifyCUDATarget(Callee); std::string FnDesc; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Callee, FnDesc); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Cand->FoundDecl, Callee, FnDesc); S.Diag(Callee->getLocation(), diag::note_ovl_candidate_bad_target) << (unsigned)FnKind << CalleeTarget << CallerTarget; @@ -9599,18 +9691,19 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, if (Cand->Viable && (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn))) { std::string FnDesc; - OverloadCandidateKind FnKind = ClassifyOverloadCandidate(S, Fn, FnDesc); + OverloadCandidateKind FnKind = + ClassifyOverloadCandidate(S, Cand->FoundDecl, Fn, FnDesc); S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) << FnKind << FnDesc << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0); - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } // We don't really have anything else to say about viable candidates. if (Cand->Viable) { - S.NoteOverloadCandidate(Fn); + S.NoteOverloadCandidate(Cand->FoundDecl, Fn); return; } @@ -9620,19 +9713,20 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, return DiagnoseArityMismatch(S, Cand, NumArgs); case ovl_fail_bad_deduction: - return DiagnoseBadDeduction(S, Cand, NumArgs, TakingCandidateAddress); + return DiagnoseBadDeduction(S, Cand, NumArgs, + TakingCandidateAddress); case ovl_fail_illegal_constructor: { S.Diag(Fn->getLocation(), diag::note_ovl_candidate_illegal_constructor) << (Fn->getPrimaryTemplate() ? 1 : 0); - MaybeEmitInheritedConstructorNote(S, Fn); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); return; } case ovl_fail_trivial_conversion: case ovl_fail_bad_final_conversion: case ovl_fail_final_conversion_not_exact: - return S.NoteOverloadCandidate(Fn); + return S.NoteOverloadCandidate(Cand->FoundDecl, Fn); case ovl_fail_bad_conversion: { unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); @@ -9643,7 +9737,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, // FIXME: this currently happens when we're called from SemaInit // when user-conversion overload fails. Figure out how to handle // those conditions and diagnose them well. - return S.NoteOverloadCandidate(Fn); + return S.NoteOverloadCandidate(Cand->FoundDecl, Fn); } case ovl_fail_bad_target: @@ -9691,7 +9785,6 @@ static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { S.Diag(Cand->Surrogate->getLocation(), diag::note_ovl_surrogate_cand) << FnType; - MaybeEmitInheritedConstructorNote(S, Cand->Surrogate); } static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, @@ -9721,8 +9814,8 @@ static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, if (ICS.isBad()) break; // all meaningless after first invalid if (!ICS.isAmbiguous()) continue; - ICS.DiagnoseAmbiguousConversion(S, OpLoc, - S.PDiag(diag::note_ambiguous_type_conversion)); + ICS.DiagnoseAmbiguousConversion( + S, OpLoc, S.PDiag(diag::note_ambiguous_type_conversion)); } } @@ -10089,7 +10182,7 @@ struct CompareTemplateSpecCandidatesForDisplay { /// deductions. void TemplateSpecCandidate::NoteDeductionFailure(Sema &S, bool ForTakingAddress) { - DiagnoseBadDeduction(S, Specialization, // pattern + DiagnoseBadDeduction(S, FoundDecl, Specialization, // pattern DeductionFailure, /*NumArgs=*/0, ForTakingAddress); } @@ -10252,21 +10345,32 @@ public: } } - if (S.getLangOpts().CUDA && S.getLangOpts().CUDATargetOverloads && - Matches.size() > 1) + if (S.getLangOpts().CUDA && Matches.size() > 1) EliminateSuboptimalCudaMatches(); } bool hasComplained() const { return HasComplained; } private: - // Is A considered a better overload candidate for the desired type than B? + bool candidateHasExactlyCorrectType(const FunctionDecl *FD) { + QualType Discard; + return Context.hasSameUnqualifiedType(TargetFunctionType, FD->getType()) || + S.IsNoReturnConversion(FD->getType(), TargetFunctionType, Discard); + } + + /// \return true if A is considered a better overload candidate for the + /// desired type than B. bool isBetterCandidate(const FunctionDecl *A, const FunctionDecl *B) { - return hasBetterEnableIfAttrs(S, A, B); + // If A doesn't have exactly the correct type, we don't want to classify it + // as "better" than anything else. This way, the user is required to + // disambiguate for us if there are multiple candidates and no exact match. + return candidateHasExactlyCorrectType(A) && + (!candidateHasExactlyCorrectType(B) || + compareEnableIfAttrs(S, A, B) == Comparison::Better); } - // Returns true if we've eliminated any (read: all but one) candidates, false - // otherwise. + /// \return true if we were able to eliminate all but one overload candidate, + /// false otherwise. bool eliminiateSuboptimalOverloadCandidates() { // Same algorithm as overload resolution -- one pass to pick the "best", // another pass to be sure that nothing is better than the best. @@ -10331,7 +10435,7 @@ private: Info, /*InOverloadResolution=*/true)) { // Make a note of the failed deduction for diagnostics. FailedCandidates.addCandidate() - .set(FunctionTemplate->getTemplatedDecl(), + .set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); return false; } @@ -10339,7 +10443,6 @@ private: // Template argument deduction ensures that we have an exact match or // compatible pointer-to-function arguments that would be adjusted by ICS. // This function template specicalization works. - Specialization = cast<FunctionDecl>(Specialization->getCanonicalDecl()); assert(S.isSameOrCompatibleFunctionType( Context.getCanonicalType(Specialization->getType()), Context.getCanonicalType(TargetFunctionType))); @@ -10380,12 +10483,9 @@ private: if (!S.checkAddressOfFunctionIsAvailable(FunDecl)) return false; - QualType ResultTy; - if (Context.hasSameUnqualifiedType(TargetFunctionType, - FunDecl->getType()) || - S.IsNoReturnConversion(FunDecl->getType(), TargetFunctionType, - ResultTy) || - (!S.getLangOpts().CPlusPlus && TargetType->isVoidPointerType())) { + // If we're in C, we need to support types that aren't exactly identical. + if (!S.getLangOpts().CPlusPlus || + candidateHasExactlyCorrectType(FunDecl)) { Matches.push_back(std::make_pair( CurAccessFunPair, cast<FunctionDecl>(FunDecl->getCanonicalDecl()))); FoundNonTemplateFunction = true; @@ -10451,9 +10551,10 @@ private: UnresolvedSetIterator Result = S.getMostSpecialized( MatchesCopy.begin(), MatchesCopy.end(), FailedCandidates, SourceExpr->getLocStart(), S.PDiag(), - S.PDiag(diag::err_addr_ovl_ambiguous) << Matches[0] - .second->getDeclName(), - S.PDiag(diag::note_ovl_candidate) << (unsigned)oc_function_template, + S.PDiag(diag::err_addr_ovl_ambiguous) + << Matches[0].second->getDeclName(), + S.PDiag(diag::note_ovl_candidate) + << (unsigned)oc_function_template, Complain, TargetFunctionType); if (Result != MatchesCopy.end()) { @@ -10501,7 +10602,7 @@ public: if (FunctionDecl *Fun = dyn_cast<FunctionDecl>((*I)->getUnderlyingDecl())) if (!functionHasPassObjectSizeParams(Fun)) - S.NoteOverloadCandidate(Fun, TargetFunctionType, + S.NoteOverloadCandidate(*I, Fun, TargetFunctionType, /*TakingAddress=*/true); FailedCandidates.NoteCandidates(S, OvlExpr->getLocStart()); } @@ -10614,6 +10715,72 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, } /// \brief Given an expression that refers to an overloaded function, try to +/// resolve that function to a single function that can have its address taken. +/// This will modify `Pair` iff it returns non-null. +/// +/// This routine can only realistically succeed if all but one candidates in the +/// overload set for SrcExpr cannot have their addresses taken. +FunctionDecl * +Sema::resolveAddressOfOnlyViableOverloadCandidate(Expr *E, + DeclAccessPair &Pair) { + OverloadExpr::FindResult R = OverloadExpr::find(E); + OverloadExpr *Ovl = R.Expression; + FunctionDecl *Result = nullptr; + DeclAccessPair DAP; + // Don't use the AddressOfResolver because we're specifically looking for + // cases where we have one overload candidate that lacks + // enable_if/pass_object_size/... + for (auto I = Ovl->decls_begin(), E = Ovl->decls_end(); I != E; ++I) { + auto *FD = dyn_cast<FunctionDecl>(I->getUnderlyingDecl()); + if (!FD) + return nullptr; + + if (!checkAddressOfFunctionIsAvailable(FD)) + continue; + + // We have more than one result; quit. + if (Result) + return nullptr; + DAP = I.getPair(); + Result = FD; + } + + if (Result) + Pair = DAP; + return Result; +} + +/// \brief Given an overloaded function, tries to turn it into a non-overloaded +/// function reference using resolveAddressOfOnlyViableOverloadCandidate. This +/// will perform access checks, diagnose the use of the resultant decl, and, if +/// necessary, perform a function-to-pointer decay. +/// +/// Returns false if resolveAddressOfOnlyViableOverloadCandidate fails. +/// Otherwise, returns true. This may emit diagnostics and return true. +bool Sema::resolveAndFixAddressOfOnlyViableOverloadCandidate( + ExprResult &SrcExpr) { + Expr *E = SrcExpr.get(); + assert(E->getType() == Context.OverloadTy && "SrcExpr must be an overload"); + + DeclAccessPair DAP; + FunctionDecl *Found = resolveAddressOfOnlyViableOverloadCandidate(E, DAP); + if (!Found) + return false; + + // Emitting multiple diagnostics for a function that is both inaccessible and + // unavailable is consistent with our behavior elsewhere. So, always check + // for both. + DiagnoseUseOfDecl(Found, E->getExprLoc()); + CheckAddressOfMemberAccess(E, DAP); + Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found); + if (Fixed->getType()->isFunctionType()) + SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false); + else + SrcExpr = Fixed; + return true; +} + +/// \brief Given an expression that refers to an overloaded function, try to /// resolve that overloaded function expression down to a single function. /// /// This routine can only resolve template-ids that refer to a single function @@ -10671,7 +10838,7 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, // Make a note of the failed deduction for diagnostics. // TODO: Actually use the failed-deduction info? FailedCandidates.addCandidate() - .set(FunctionTemplate->getTemplatedDecl(), + .set(I.getPair(), FunctionTemplate->getTemplatedDecl(), MakeDeductionFailureInfo(Context, Result, Info)); continue; } @@ -12236,6 +12403,16 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, << MD->getDeclName(); } } + + if (CXXDestructorDecl *DD = + dyn_cast<CXXDestructorDecl>(TheCall->getMethodDecl())) { + // a->A::f() doesn't go through the vtable, except in AppleKext mode. + bool CallCanBeVirtual = !MemExpr->hasQualifier() || getLangOpts().AppleKext; + CheckVirtualDtorCall(DD, MemExpr->getLocStart(), /*IsDelete=*/false, + CallCanBeVirtual, /*WarnOnNonAbstractTypes=*/true, + MemExpr->getMemberLoc()); + } + return MaybeBindToTemporary(TheCall); } @@ -12843,6 +13020,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, = Context.getTypeDeclType(cast<RecordDecl>(Method->getDeclContext())); QualType MemPtrType = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr()); + // Under the MS ABI, lock down the inheritance model now. + if (Context.getTargetInfo().getCXXABI().isMicrosoft()) + (void)isCompleteType(UnOp->getOperatorLoc(), MemPtrType); return new (Context) UnaryOperator(SubExpr, UO_AddrOf, MemPtrType, VK_RValue, OK_Ordinary, |