diff options
| author | 2017-01-24 08:32:59 +0000 | |
|---|---|---|
| committer | 2017-01-24 08:32:59 +0000 | |
| commit | 53d771aafdbe5b919f264f53cba3788e2c4cffd2 (patch) | |
| tree | 7eca39498be0ff1e3a6daf583cd9ca5886bb2636 /gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp | |
| parent | In preparation of compiling our kernels with -ffreestanding, explicitly map (diff) | |
| download | wireguard-openbsd-53d771aafdbe5b919f264f53cba3788e2c4cffd2.tar.xz wireguard-openbsd-53d771aafdbe5b919f264f53cba3788e2c4cffd2.zip | |
Import LLVM 4.0.0 rc1 including clang and lld to help the current
development effort on OpenBSD/arm64.
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp | 1234 |
1 files changed, 885 insertions, 349 deletions
diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp index 40d6e910f1f..afdae4ed6d7 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaOverload.cpp @@ -29,6 +29,7 @@ #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" @@ -39,8 +40,9 @@ using namespace clang; using namespace sema; static bool functionHasPassObjectSizeParams(const FunctionDecl *FD) { - return llvm::any_of(FD->parameters(), - std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>)); + return llvm::any_of(FD->parameters(), [](const ParmVarDecl *P) { + return P->hasAttr<PassObjectSizeAttr>(); + }); } /// A convenience routine for creating a decayed reference to a function. @@ -59,6 +61,8 @@ CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, NamedDecl *FoundDecl, // being used. if (FoundDecl != Fn && S.DiagnoseUseOfDecl(Fn, Loc)) return ExprError(); + if (auto *FPT = Fn->getType()->getAs<FunctionProtoType>()) + S.ResolveExceptionSpec(Loc, FPT); DeclRefExpr *DRE = new (S.Context) DeclRefExpr(Fn, false, Fn->getType(), VK_LValue, Loc, LocInfo); if (HadMultipleCandidates) @@ -135,7 +139,8 @@ ImplicitConversionRank clang::GetConversionRank(ImplicitConversionKind Kind) { ICR_Exact_Match, // NOTE(gbiv): This may not be completely right -- // it was omitted by the patch that added // ICK_Zero_Event_Conversion - ICR_C_Conversion + ICR_C_Conversion, + ICR_C_Conversion_Extension }; return Rank[(int)Kind]; } @@ -148,7 +153,7 @@ static const char* GetImplicitConversionName(ImplicitConversionKind Kind) { "Lvalue-to-rvalue", "Array-to-pointer", "Function-to-pointer", - "Noreturn adjustment", + "Function pointer conversion", "Qualification", "Integral promotion", "Floating point promotion", @@ -169,7 +174,8 @@ static const char* GetImplicitConversionName(ImplicitConversionKind Kind) { "Transparent Union Conversion", "Writeback conversion", "OpenCL Zero Event Conversion", - "C specific type conversion" + "C specific type conversion", + "Incompatible pointer conversion" }; return Name[Kind]; } @@ -324,6 +330,11 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, } else if (FromType->isIntegralType(Ctx) && ToType->isRealFloatingType()) { llvm::APSInt IntConstantValue; const Expr *Initializer = IgnoreNarrowingConversion(Converted); + + // If it's value-dependent, we can't tell whether it's narrowing. + if (Initializer->isValueDependent()) + return NK_Dependent_Narrowing; + if (Initializer && Initializer->isIntegerConstantExpr(IntConstantValue, Ctx)) { // Convert the integer to the floating type. @@ -357,6 +368,11 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, Ctx.getFloatingTypeOrder(FromType, ToType) == 1) { // FromType is larger than ToType. const Expr *Initializer = IgnoreNarrowingConversion(Converted); + + // If it's value-dependent, we can't tell whether it's narrowing. + if (Initializer->isValueDependent()) + return NK_Dependent_Narrowing; + if (Initializer->isCXX11ConstantExpr(Ctx, &ConstantValue)) { // Constant! assert(ConstantValue.isFloat()); @@ -398,6 +414,11 @@ StandardConversionSequence::getNarrowingKind(ASTContext &Ctx, // Not all values of FromType can be represented in ToType. llvm::APSInt InitializerValue; const Expr *Initializer = IgnoreNarrowingConversion(Converted); + + // If it's value-dependent, we can't tell whether it's narrowing. + if (Initializer->isValueDependent()) + return NK_Dependent_Narrowing; + if (!Initializer->isIntegerConstantExpr(InitializerValue, Ctx)) { // Such conversions on variables are always narrowing. return NK_Variable_Narrowing; @@ -569,12 +590,12 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, Result.Result = static_cast<unsigned>(TDK); Result.HasDiagnostic = false; switch (TDK) { - case Sema::TDK_Success: case Sema::TDK_Invalid: case Sema::TDK_InstantiationDepth: case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_MiscellaneousDeductionFailure: + case Sema::TDK_CUDATargetMismatch: Result.Data = nullptr; break; @@ -583,7 +604,8 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, Result.Data = Info.Param.getOpaqueValue(); break; - case Sema::TDK_DeducedMismatch: { + case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: { // FIXME: Should allocate from normal heap so that we can free this later. auto *Saved = new (Context) DFIDeducedMismatchArgs; Saved->FirstArg = Info.FirstArg; @@ -624,9 +646,9 @@ clang::MakeDeductionFailureInfo(ASTContext &Context, } break; - case Sema::TDK_FailedOverloadResolution: - Result.Data = Info.Expression; - break; + case Sema::TDK_Success: + case Sema::TDK_NonDependentConversionFailure: + llvm_unreachable("not a deduction failure"); } return Result; @@ -641,12 +663,14 @@ void DeductionFailureInfo::Destroy() { case Sema::TDK_TooManyArguments: case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_CUDATargetMismatch: + case Sema::TDK_NonDependentConversionFailure: break; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: // FIXME: Destroy the data? Data = nullptr; @@ -682,8 +706,10 @@ TemplateParameter DeductionFailureInfo::getTemplateParameter() { case Sema::TDK_TooFewArguments: case Sema::TDK_SubstitutionFailure: case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_CUDATargetMismatch: + case Sema::TDK_NonDependentConversionFailure: return TemplateParameter(); case Sema::TDK_Incomplete: @@ -714,10 +740,12 @@ TemplateArgumentList *DeductionFailureInfo::getTemplateArgumentList() { case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_NonDeducedMismatch: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_CUDATargetMismatch: + case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: return static_cast<DFIDeducedMismatchArgs*>(Data)->TemplateArgs; case Sema::TDK_SubstitutionFailure: @@ -741,12 +769,14 @@ const TemplateArgument *DeductionFailureInfo::getFirstArg() { case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_CUDATargetMismatch: + case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: return &static_cast<DFIArguments*>(Data)->FirstArg; @@ -768,12 +798,14 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { case Sema::TDK_TooFewArguments: case Sema::TDK_InvalidExplicitArguments: case Sema::TDK_SubstitutionFailure: - case Sema::TDK_FailedOverloadResolution: + case Sema::TDK_CUDATargetMismatch: + case Sema::TDK_NonDependentConversionFailure: return nullptr; case Sema::TDK_Inconsistent: case Sema::TDK_Underqualified: case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: return &static_cast<DFIArguments*>(Data)->SecondArg; @@ -785,26 +817,21 @@ const TemplateArgument *DeductionFailureInfo::getSecondArg() { return nullptr; } -Expr *DeductionFailureInfo::getExpr() { - if (static_cast<Sema::TemplateDeductionResult>(Result) == - Sema::TDK_FailedOverloadResolution) - return static_cast<Expr*>(Data); - - return nullptr; -} - llvm::Optional<unsigned> DeductionFailureInfo::getCallArgIndex() { - if (static_cast<Sema::TemplateDeductionResult>(Result) == - Sema::TDK_DeducedMismatch) + switch (static_cast<Sema::TemplateDeductionResult>(Result)) { + case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: return static_cast<DFIDeducedMismatchArgs*>(Data)->CallArgIndex; - return llvm::None; + default: + return llvm::None; + } } void OverloadCandidateSet::destroyCandidates() { for (iterator i = begin(), e = end(); i != e; ++i) { - for (unsigned ii = 0, ie = i->NumConversions; ii != ie; ++ii) - i->Conversions[ii].~ImplicitConversionSequence(); + for (auto &C : i->Conversions) + C.~ImplicitConversionSequence(); if (!i->Viable && i->FailureKind == ovl_fail_bad_deduction) i->DeductionFailure.Destroy(); } @@ -812,11 +839,20 @@ void OverloadCandidateSet::destroyCandidates() { void OverloadCandidateSet::clear() { destroyCandidates(); - NumInlineSequences = 0; + // DiagnoseIfAttrs are just pointers, so we don't need to destroy them. + SlabAllocator.Reset(); + NumInlineBytesUsed = 0; Candidates.clear(); Functions.clear(); } +DiagnoseIfAttr ** +OverloadCandidateSet::addDiagnoseIfComplaints(ArrayRef<DiagnoseIfAttr *> CA) { + auto *DIA = slabAllocate<DiagnoseIfAttr *>(CA.size()); + std::uninitialized_copy(CA.begin(), CA.end(), DIA); + return DIA; +} + namespace { class UnbridgedCastsSet { struct Entry { @@ -969,16 +1005,23 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old, Match = *I; return Ovl_Match; } - } else if (isa<UsingDecl>(OldD)) { + } else if (isa<UsingDecl>(OldD) || isa<UsingPackDecl>(OldD)) { // We can overload with these, which can show up when doing // redeclaration checks for UsingDecls. assert(Old.getLookupKind() == LookupUsingDeclName); } else if (isa<TagDecl>(OldD)) { // We can always overload with tags by hiding them. - } else if (isa<UnresolvedUsingValueDecl>(OldD)) { + } else if (auto *UUD = dyn_cast<UnresolvedUsingValueDecl>(OldD)) { // Optimistically assume that an unresolved using decl will // overload; if it doesn't, we'll have to diagnose during // template instantiation. + // + // Exception: if the scope is dependent and this is not a class + // member, the using declaration can only introduce an enumerator. + if (UUD->getQualifier()->isDependent() && !UUD->isCXXClassMember()) { + Match = *I; + return Ovl_NonFunction; + } } else { // (C++ 13p1): // Only function declarations can be overloaded; object and type @@ -1126,24 +1169,20 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, } if (getLangOpts().CUDA && ConsiderCudaAttrs) { + // Don't allow overloading of destructors. (In theory we could, but it + // would be a giant change to clang.) + if (isa<CXXDestructorDecl>(New)) + return false; + CUDAFunctionTarget NewTarget = IdentifyCUDATarget(New), OldTarget = IdentifyCUDATarget(Old); - if (NewTarget == CFT_InvalidTarget || NewTarget == CFT_Global) + if (NewTarget == CFT_InvalidTarget) return false; assert((OldTarget != CFT_InvalidTarget) && "Unexpected invalid target."); - // 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 . - // __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 - // different CUDA target attributes. + // Allow overloading of functions with same signature and different CUDA + // target attributes. return NewTarget != OldTarget; } @@ -1199,7 +1238,6 @@ TryUserDefinedConversion(Sema &S, Expr *From, QualType ToType, case OR_Success: case OR_Deleted: ICS.setUserDefined(); - ICS.UserDefined.Before.setAsIdentityConversion(); // 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 @@ -1383,17 +1421,20 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType, } /// \brief Determine whether the conversion from FromType to ToType is a valid -/// conversion that strips "noreturn" off the nested function type. -bool Sema::IsNoReturnConversion(QualType FromType, QualType ToType, +/// conversion that strips "noexcept" or "noreturn" off the nested function +/// type. +bool Sema::IsFunctionConversion(QualType FromType, QualType ToType, QualType &ResultTy) { if (Context.hasSameUnqualifiedType(FromType, ToType)) return false; // Permit the conversion F(t __attribute__((noreturn))) -> F(t) + // or F(t noexcept) -> F(t) // where F adds one of the following at most once: // - a pointer // - a member pointer // - a block pointer + // Changes here need matching changes in FindCompositePointerType. CanQualType CanTo = Context.getCanonicalType(ToType); CanQualType CanFrom = Context.getCanonicalType(FromType); Type::TypeClass TyClass = CanTo->getTypeClass(); @@ -1406,8 +1447,13 @@ bool Sema::IsNoReturnConversion(QualType FromType, QualType ToType, CanTo = CanTo.getAs<BlockPointerType>()->getPointeeType(); CanFrom = CanFrom.getAs<BlockPointerType>()->getPointeeType(); } else if (TyClass == Type::MemberPointer) { - CanTo = CanTo.getAs<MemberPointerType>()->getPointeeType(); - CanFrom = CanFrom.getAs<MemberPointerType>()->getPointeeType(); + auto ToMPT = CanTo.getAs<MemberPointerType>(); + auto FromMPT = CanFrom.getAs<MemberPointerType>(); + // A function pointer conversion cannot change the class of the function. + if (ToMPT->getClass() != FromMPT->getClass()) + return false; + CanTo = ToMPT->getPointeeType(); + CanFrom = FromMPT->getPointeeType(); } else { return false; } @@ -1418,11 +1464,37 @@ bool Sema::IsNoReturnConversion(QualType FromType, QualType ToType, return false; } - const FunctionType *FromFn = cast<FunctionType>(CanFrom); - FunctionType::ExtInfo EInfo = FromFn->getExtInfo(); - if (!EInfo.getNoReturn()) return false; + const auto *FromFn = cast<FunctionType>(CanFrom); + FunctionType::ExtInfo FromEInfo = FromFn->getExtInfo(); + + const auto *ToFn = cast<FunctionType>(CanTo); + FunctionType::ExtInfo ToEInfo = ToFn->getExtInfo(); + + bool Changed = false; + + // Drop 'noreturn' if not present in target type. + if (FromEInfo.getNoReturn() && !ToEInfo.getNoReturn()) { + FromFn = Context.adjustFunctionType(FromFn, FromEInfo.withNoReturn(false)); + Changed = true; + } + + // Drop 'noexcept' if not present in target type. + if (const auto *FromFPT = dyn_cast<FunctionProtoType>(FromFn)) { + const auto *ToFPT = cast<FunctionProtoType>(ToFn); + if (FromFPT->isNothrow(Context) && !ToFPT->isNothrow(Context)) { + FromFn = cast<FunctionType>( + Context.getFunctionType(FromFPT->getReturnType(), + FromFPT->getParamTypes(), + FromFPT->getExtProtoInfo().withExceptionSpec( + FunctionProtoType::ExceptionSpecInfo())) + .getTypePtr()); + Changed = true; + } + } + + if (!Changed) + return false; - FromFn = Context.adjustFunctionType(FromFn, EInfo.withNoReturn(false)); assert(QualType(FromFn, 0).isCanonical()); if (QualType(FromFn, 0) != CanTo) return false; @@ -1527,7 +1599,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, S.ExtractUnqualifiedFunctionType(ToType), FromType)) { QualType resultTy; // if the function type matches except for [[noreturn]], it's ok - if (!S.IsNoReturnConversion(FromType, + if (!S.IsFunctionConversion(FromType, S.ExtractUnqualifiedFunctionType(ToType), resultTy)) // otherwise, only a boolean conversion is standard if (!ToType->isBooleanType()) @@ -1556,6 +1628,8 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, } // Check that we've computed the proper type after overload resolution. + // FIXME: FixOverloadedFunctionReference has side-effects; we shouldn't + // be calling it from within an NDEBUG block. assert(S.Context.hasSameType( FromType, S.FixOverloadedFunctionReference(From, AccessPair, Fn)->getType())); @@ -1684,7 +1758,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, ToType == S.Context.Float128Ty)); if (Float128AndLongDouble && (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) != - &llvm::APFloat::IEEEdouble)) + &llvm::APFloat::IEEEdouble())) return false; } // Floating point conversions (C++ 4.8). @@ -1720,9 +1794,6 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, // Compatible conversions (Clang extension for C function overloading) SCS.Second = ICK_Compatible_Conversion; FromType = ToType.getUnqualifiedType(); - } else if (S.IsNoReturnConversion(FromType, ToType, FromType)) { - // Treat a conversion that strips "noreturn" as an identity conversion. - SCS.Second = ICK_NoReturn_Adjustment; } else if (IsTransparentUnionStandardConversion(S, From, ToType, InOverloadResolution, SCS, CStyle)) { @@ -1738,40 +1809,47 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, From->EvaluateKnownConstInt(S.getASTContext()) == 0) { SCS.Second = ICK_Zero_Event_Conversion; FromType = ToType; + } else if (ToType->isQueueT() && + From->isIntegerConstantExpr(S.getASTContext()) && + (From->EvaluateKnownConstInt(S.getASTContext()) == 0)) { + SCS.Second = ICK_Zero_Queue_Conversion; + FromType = ToType; } else { // No second conversion required. SCS.Second = ICK_Identity; } SCS.setToType(1, FromType); - QualType CanonFrom; - QualType CanonTo; - // The third conversion can be a qualification conversion (C++ 4p1). + // The third conversion can be a function pointer conversion or a + // qualification conversion (C++ [conv.fctptr], [conv.qual]). bool ObjCLifetimeConversion; - if (S.IsQualificationConversion(FromType, ToType, CStyle, - ObjCLifetimeConversion)) { + if (S.IsFunctionConversion(FromType, ToType, FromType)) { + // Function pointer conversions (removing 'noexcept') including removal of + // 'noreturn' (Clang extension). + SCS.Third = ICK_Function_Conversion; + } else if (S.IsQualificationConversion(FromType, ToType, CStyle, + ObjCLifetimeConversion)) { SCS.Third = ICK_Qualification; SCS.QualificationIncludesObjCLifetime = ObjCLifetimeConversion; FromType = ToType; - CanonFrom = S.Context.getCanonicalType(FromType); - CanonTo = S.Context.getCanonicalType(ToType); } else { // No conversion required SCS.Third = ICK_Identity; + } - // C++ [over.best.ics]p6: - // [...] Any difference in top-level cv-qualification is - // subsumed by the initialization itself and does not constitute - // a conversion. [...] - CanonFrom = S.Context.getCanonicalType(FromType); - CanonTo = S.Context.getCanonicalType(ToType); - if (CanonFrom.getLocalUnqualifiedType() - == CanonTo.getLocalUnqualifiedType() && - CanonFrom.getLocalQualifiers() != CanonTo.getLocalQualifiers()) { - FromType = ToType; - CanonFrom = CanonTo; - } + // C++ [over.best.ics]p6: + // [...] Any difference in top-level cv-qualification is + // subsumed by the initialization itself and does not constitute + // a conversion. [...] + QualType CanonFrom = S.Context.getCanonicalType(FromType); + QualType CanonTo = S.Context.getCanonicalType(ToType); + if (CanonFrom.getLocalUnqualifiedType() + == CanonTo.getLocalUnqualifiedType() && + CanonFrom.getLocalQualifiers() != CanonTo.getLocalQualifiers()) { + FromType = ToType; + CanonFrom = CanonTo; } + SCS.setToType(2, FromType); if (CanonFrom == CanonTo) @@ -1783,22 +1861,43 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, return false; ExprResult ER = ExprResult{From}; - auto Conv = S.CheckSingleAssignmentConstraints(ToType, ER, - /*Diagnose=*/false, - /*DiagnoseCFAudited=*/false, - /*ConvertRHS=*/false); - if (Conv != Sema::Compatible) + Sema::AssignConvertType Conv = + S.CheckSingleAssignmentConstraints(ToType, ER, + /*Diagnose=*/false, + /*DiagnoseCFAudited=*/false, + /*ConvertRHS=*/false); + ImplicitConversionKind SecondConv; + switch (Conv) { + case Sema::Compatible: + SecondConv = ICK_C_Only_Conversion; + break; + // For our purposes, discarding qualifiers is just as bad as using an + // incompatible pointer. Note that an IncompatiblePointer conversion can drop + // qualifiers, as well. + case Sema::CompatiblePointerDiscardsQualifiers: + case Sema::IncompatiblePointer: + case Sema::IncompatiblePointerSign: + SecondConv = ICK_Incompatible_Pointer_Conversion; + break; + default: return false; + } - SCS.setAllToTypes(ToType); - // We need to set all three because we want this conversion to rank terribly, - // and we don't know what conversions it may overlap with. - SCS.First = ICK_C_Only_Conversion; - SCS.Second = ICK_C_Only_Conversion; - SCS.Third = ICK_C_Only_Conversion; + // First can only be an lvalue conversion, so we pretend that this was the + // second conversion. First should already be valid from earlier in the + // function. + SCS.Second = SecondConv; + SCS.setToType(1, ToType); + + // Third is Identity, because Second should rank us worse than any other + // conversion. This could also be ICK_Qualification, but it's simpler to just + // lump everything in with the second conversion, and we don't gain anything + // from making this ICK_Qualification. + SCS.Third = ICK_Identity; + SCS.setToType(2, ToType); return true; } - + static bool IsTransparentUnionStandardConversion(Sema &S, Expr* From, QualType &ToType, @@ -2587,7 +2686,8 @@ enum { ft_parameter_arity, ft_parameter_mismatch, ft_return_type, - ft_qualifer_mismatch + ft_qualifer_mismatch, + ft_noexcept }; /// Attempts to get the FunctionProtoType from a Type. Handles @@ -2687,6 +2787,16 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, return; } + // Handle exception specification differences on canonical type (in C++17 + // onwards). + if (cast<FunctionProtoType>(FromFunction->getCanonicalTypeUnqualified()) + ->isNothrow(Context) != + cast<FunctionProtoType>(ToFunction->getCanonicalTypeUnqualified()) + ->isNothrow(Context)) { + PDiag << ft_noexcept; + return; + } + // Unable to find a difference, so add no extra info. PDiag << ft_default; } @@ -4098,6 +4208,7 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, DerivedToBase = false; ObjCConversion = false; ObjCLifetimeConversion = false; + QualType ConvertedT2; if (UnqualT1 == UnqualT2) { // Nothing to do. } else if (isCompleteType(Loc, OrigT2) && @@ -4108,6 +4219,15 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, UnqualT2->isObjCObjectOrInterfaceType() && Context.canBindObjCObjectType(UnqualT1, UnqualT2)) ObjCConversion = true; + else if (UnqualT2->isFunctionType() && + IsFunctionConversion(UnqualT2, UnqualT1, ConvertedT2)) + // C++1z [dcl.init.ref]p4: + // cv1 T1" is reference-compatible with "cv2 T2" if [...] T2 is "noexcept + // function" and T1 is "function" + // + // We extend this to also apply to 'noreturn', so allow any function + // conversion between function types. + return Ref_Compatible; else return Ref_Incompatible; @@ -4146,10 +4266,8 @@ Sema::CompareReferenceRelationship(SourceLocation Loc, T1Quals.removeUnaligned(); T2Quals.removeUnaligned(); - if (T1Quals == T2Quals) + if (T1Quals.compatiblyIncludes(T2Quals)) return Ref_Compatible; - else if (T1Quals.compatiblyIncludes(T2Quals)) - return Ref_Compatible_With_Added_Qualification; else return Ref_Related; } @@ -4327,8 +4445,7 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, // reference-compatible with "cv2 T2," or // // Per C++ [over.ics.ref]p4, we don't check the bit-field property here. - if (InitCategory.isLValue() && - RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification) { + if (InitCategory.isLValue() && RefRelationship == Sema::Ref_Compatible) { // C++ [over.ics.ref]p1: // When a parameter of reference type binds directly (8.5.3) // to an argument expression, the implicit conversion sequence @@ -4390,10 +4507,10 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, // // -- is an xvalue, class prvalue, array prvalue or function // lvalue and "cv1 T1" is reference-compatible with "cv2 T2", or - if (RefRelationship >= Sema::Ref_Compatible_With_Added_Qualification && + if (RefRelationship == Sema::Ref_Compatible && (InitCategory.isXValue() || - (InitCategory.isPRValue() && (T2->isRecordType() || T2->isArrayType())) || - (InitCategory.isLValue() && T2->isFunctionType()))) { + (InitCategory.isPRValue() && (T2->isRecordType() || T2->isArrayType())) || + (InitCategory.isLValue() && T2->isFunctionType()))) { ICS.setStandard(); ICS.Standard.First = ICK_Identity; ICS.Standard.Second = DerivedToBase? ICK_Derived_To_Base @@ -4540,7 +4657,6 @@ TryReferenceInit(Sema &S, Expr *Init, QualType DeclType, return ICS; } - ICS.UserDefined.Before.setAsIdentityConversion(); ICS.UserDefined.After.ReferenceBinding = true; ICS.UserDefined.After.IsLvalueReference = !isRValRef; ICS.UserDefined.After.BindsToFunctionLvalue = false; @@ -4693,6 +4809,9 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType, // Type is an aggregate, argument is an init list. At this point it comes // down to checking whether the initialization works. // FIXME: Find out whether this parameter is consumed or not. + // FIXME: Expose SemaInit's aggregate initialization code so that we don't + // need to call into the initialization code here; overload resolution + // should not be doing that. InitializedEntity Entity = InitializedEntity::InitializeParameter(S.Context, ToType, /*Consumed=*/false); @@ -4896,7 +5015,7 @@ TryObjectArgumentInitialization(Sema &S, SourceLocation Loc, QualType FromType, // cv-qualification on the member function declaration. // // However, when finding an implicit conversion sequence for the argument, we - // are not allowed to create temporaries or perform user-defined conversions + // are not allowed to perform user-defined conversions // (C++ [over.match.funcs]p5). We perform a simplified version of // reference binding here, that allows class rvalues to bind to // non-constant references. @@ -5069,9 +5188,10 @@ static bool CheckConvertedConstantConversions(Sema &S, // conversions are fine. switch (SCS.Second) { case ICK_Identity: - case ICK_NoReturn_Adjustment: + case ICK_Function_Conversion: case ICK_Integral_Promotion: case ICK_Integral_Conversion: // Narrowing conversions are checked elsewhere. + case ICK_Zero_Queue_Conversion: return true; case ICK_Boolean_Conversion: @@ -5106,6 +5226,7 @@ static bool CheckConvertedConstantConversions(Sema &S, case ICK_Writeback_Conversion: case ICK_Zero_Event_Conversion: case ICK_C_Only_Conversion: + case ICK_Incompatible_Pointer_Conversion: return false; case ICK_Lvalue_To_Rvalue: @@ -5141,12 +5262,18 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, // implicitly converted to type T, where the converted // expression is a constant expression and the implicit conversion // sequence contains only [... list of conversions ...]. + // C++1z [stmt.if]p2: + // If the if statement is of the form if constexpr, the value of the + // condition shall be a contextually converted constant expression of type + // bool. ImplicitConversionSequence ICS = - TryCopyInitialization(S, From, T, - /*SuppressUserConversions=*/false, - /*InOverloadResolution=*/false, - /*AllowObjcWritebackConversion=*/false, - /*AllowExplicit=*/false); + CCE == Sema::CCEK_ConstexprIf + ? TryContextuallyConvertToBool(S, From) + : TryCopyInitialization(S, From, T, + /*SuppressUserConversions=*/false, + /*InOverloadResolution=*/false, + /*AllowObjcWritebackConversion=*/false, + /*AllowExplicit=*/false); StandardConversionSequence *SCS = nullptr; switch (ICS.getKind()) { case ImplicitConversionSequence::StandardConversion: @@ -5192,6 +5319,9 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, QualType PreNarrowingType; switch (SCS->getNarrowingKind(S.Context, Result.get(), PreNarrowingValue, PreNarrowingType)) { + case NK_Dependent_Narrowing: + // Implicit conversion to a narrower type, but the expression is + // value-dependent so we can't tell whether it's actually narrowing. case NK_Variable_Narrowing: // Implicit conversion to a narrower type, and the value is not a constant // expression. We'll diagnose this in a moment. @@ -5210,6 +5340,11 @@ static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, break; } + if (Result.get()->isValueDependent()) { + Value = APValue(); + return Result; + } + // Check the expression is a constant expression. SmallVector<PartialDiagnosticAt, 8> Notes; Expr::EvalResult Eval; @@ -5256,7 +5391,7 @@ ExprResult Sema::CheckConvertedConstantExpression(Expr *From, QualType T, APValue V; auto R = ::CheckConvertedConstantExpression(*this, From, T, V, CCE, true); - if (!R.isInvalid()) + if (!R.isInvalid() && !R.get()->isValueDependent()) Value = V.getInt(); return R; } @@ -5310,6 +5445,7 @@ TryContextuallyConvertToObjCPointer(Sema &S, Expr *From) { /// PerformContextuallyConvertToObjCPointer - Perform a contextual /// conversion of the expression From to an Objective-C pointer type. +/// Returns a valid but null ExprResult if no conversion sequence exists. ExprResult Sema::PerformContextuallyConvertToObjCPointer(Expr *From) { if (checkPlaceholderForOverload(*this, From)) return ExprError(); @@ -5319,7 +5455,7 @@ ExprResult Sema::PerformContextuallyConvertToObjCPointer(Expr *From) { TryContextuallyConvertToObjCPointer(*this, From); if (!ICS.isBad()) return PerformImplicitConversion(From, Ty, ICS, AA_Converting); - return ExprError(); + return ExprResult(); } /// Determine whether the provided type is an integral type, or an enumeration @@ -5695,6 +5831,28 @@ static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context, return false; } +static void initDiagnoseIfComplaint(Sema &S, OverloadCandidateSet &CandidateSet, + OverloadCandidate &Candidate, + FunctionDecl *Function, + ArrayRef<Expr *> Args, + bool MissingImplicitThis = false, + Expr *ExplicitThis = nullptr) { + SmallVector<DiagnoseIfAttr *, 8> Results; + if (DiagnoseIfAttr *DIA = S.checkArgDependentDiagnoseIf( + Function, Args, Results, MissingImplicitThis, ExplicitThis)) { + Results.clear(); + Results.push_back(DIA); + } + + Candidate.NumTriggeredDiagnoseIfs = Results.size(); + if (Results.empty()) + Candidate.DiagnoseIfInfo = nullptr; + else if (Results.size() == 1) + Candidate.DiagnoseIfInfo = Results[0]; + else + Candidate.DiagnoseIfInfo = CandidateSet.addDiagnoseIfComplaints(Results); +} + /// AddOverloadCandidate - Adds the given function to the set of /// candidate functions, using the given function call arguments. If /// @p SuppressUserConversions, then don't allow user-defined @@ -5710,7 +5868,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, bool PartialOverloading, - bool AllowExplicit) { + bool AllowExplicit, + ConversionSequenceList EarlyConversions) { const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(Function->getType()->getAs<FunctionType>()); assert(Proto && "Functions without a prototype cannot be overloaded"); @@ -5726,10 +5885,11 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // function, e.g., X::f(). We use an empty type for the implied // object argument (C++ [over.call.func]p3), and the acting context // is irrelevant. - AddMethodCandidate(Method, FoundDecl, Method->getParent(), - QualType(), Expr::Classification::makeSimpleLValue(), - Args, CandidateSet, SuppressUserConversions, - PartialOverloading); + AddMethodCandidate(Method, FoundDecl, Method->getParent(), QualType(), + Expr::Classification::makeSimpleLValue(), + /*ThisArg=*/nullptr, Args, CandidateSet, + SuppressUserConversions, PartialOverloading, + EarlyConversions); return; } // We treat a constructor like a non-member function, since its object @@ -5762,7 +5922,8 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); // Add this candidate - OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size()); + OverloadCandidate &Candidate = + CandidateSet.addCandidate(Args.size(), EarlyConversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = Function; Candidate.Viable = true; @@ -5817,7 +5978,7 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // case we may not yet know what the member's target is; the target is // inferred for the member automatically, based on the bases and fields of // the class. - if (!Caller->isImplicit() && CheckCUDATarget(Caller, Function)) { + if (!Caller->isImplicit() && !IsAllowedCUDACall(Caller, Function)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_target; return; @@ -5826,7 +5987,10 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { - if (ArgIdx < NumParams) { + if (Candidate.Conversions[ArgIdx].isInitialized()) { + // We already formed a conversion sequence for this parameter during + // template argument deduction. + } else if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding @@ -5852,12 +6016,45 @@ Sema::AddOverloadCandidate(FunctionDecl *Function, } } + // C++ [over.best.ics]p4+: (proposed DR resolution) + // If the target is the first parameter of an inherited constructor when + // constructing an object of type C with an argument list that has exactly + // one expression, an implicit conversion sequence cannot be formed if C is + // reference-related to the type that the argument would have after the + // application of the user-defined conversion (if any) and before the final + // standard conversion sequence. + auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl.getDecl()); + if (Shadow && Args.size() == 1 && !isa<InitListExpr>(Args.front())) { + bool DerivedToBase, ObjCConversion, ObjCLifetimeConversion; + QualType ConvertedArgumentType = Args.front()->getType(); + if (Candidate.Conversions[0].isUserDefined()) + ConvertedArgumentType = + Candidate.Conversions[0].UserDefined.After.getFromType(); + if (CompareReferenceRelationship(Args.front()->getLocStart(), + Context.getRecordType(Shadow->getParent()), + ConvertedArgumentType, DerivedToBase, + ObjCConversion, + ObjCLifetimeConversion) >= Ref_Related) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_inhctor_slice; + return; + } + } + if (EnableIfAttr *FailedAttr = CheckEnableIf(Function, Args)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_enable_if; Candidate.DeductionFailure.Data = FailedAttr; return; } + + if (LangOpts.OpenCL && isOpenCLDisabledDecl(Function)) { + Candidate.Viable = false; + Candidate.FailureKind = ovl_fail_ext_disabled; + return; + } + + initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Function, Args); } ObjCMethodDecl * @@ -5907,10 +6104,15 @@ Sema::SelectBestMethod(Selector Sel, MultiExprArg Args, bool IsInstance, /*AllowObjCWritebackConversion=*/ getLangOpts().ObjCAutoRefCount, /*AllowExplicit*/false); - if (ConversionState.isBad()) { - Match = false; - break; - } + // This function looks for a reasonably-exact match, so we consider + // incompatible pointer conversions to be a failure here. + if (ConversionState.isBad() || + (ConversionState.isStandard() && + ConversionState.Standard.Second == + ICK_Incompatible_Pointer_Conversion)) { + Match = false; + break; + } } // Promote additional arguments to variadic methods. if (Match && Method->isVariadic()) { @@ -5965,66 +6167,87 @@ getOrderedEnableIfAttrs(const FunctionDecl *Function) { return Result; } -EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, - bool MissingImplicitThis) { - auto EnableIfAttrs = getOrderedEnableIfAttrs(Function); - if (EnableIfAttrs.empty()) - return nullptr; - - SFINAETrap Trap(*this); - SmallVector<Expr *, 16> ConvertedArgs; - bool InitializationFailed = false; +static bool +convertArgsForAvailabilityChecks(Sema &S, FunctionDecl *Function, Expr *ThisArg, + ArrayRef<Expr *> Args, Sema::SFINAETrap &Trap, + bool MissingImplicitThis, Expr *&ConvertedThis, + SmallVectorImpl<Expr *> &ConvertedArgs) { + if (ThisArg) { + CXXMethodDecl *Method = cast<CXXMethodDecl>(Function); + assert(!isa<CXXConstructorDecl>(Method) && + "Shouldn't have `this` for ctors!"); + assert(!Method->isStatic() && "Shouldn't have `this` for static methods!"); + ExprResult R = S.PerformObjectArgumentInitialization( + ThisArg, /*Qualifier=*/nullptr, Method, Method); + if (R.isInvalid()) + return false; + ConvertedThis = R.get(); + } else { + if (auto *MD = dyn_cast<CXXMethodDecl>(Function)) { + (void)MD; + assert((MissingImplicitThis || MD->isStatic() || + isa<CXXConstructorDecl>(MD)) && + "Expected `this` for non-ctor instance methods"); + } + ConvertedThis = nullptr; + } - // Ignore any variadic parameters. Converting them is pointless, since the - // user can't refer to them in the enable_if condition. + // Ignore any variadic arguments. Converting them is pointless, since the + // user can't refer to them in the function condition. unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size()); // Convert the arguments. for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) { ExprResult R; - if (I == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) && - !cast<CXXMethodDecl>(Function)->isStatic() && - !isa<CXXConstructorDecl>(Function)) { - CXXMethodDecl *Method = cast<CXXMethodDecl>(Function); - R = PerformObjectArgumentInitialization(Args[0], /*Qualifier=*/nullptr, - Method, Method); - } else { - R = PerformCopyInitialization(InitializedEntity::InitializeParameter( - Context, Function->getParamDecl(I)), + R = S.PerformCopyInitialization(InitializedEntity::InitializeParameter( + S.Context, Function->getParamDecl(I)), SourceLocation(), Args[I]); - } - if (R.isInvalid()) { - InitializationFailed = true; - break; - } + if (R.isInvalid()) + return false; ConvertedArgs.push_back(R.get()); } - if (InitializationFailed || Trap.hasErrorOccurred()) - return EnableIfAttrs[0]; + if (Trap.hasErrorOccurred()) + return false; // Push default arguments if needed. if (!Function->isVariadic() && Args.size() < Function->getNumParams()) { for (unsigned i = Args.size(), e = Function->getNumParams(); i != e; ++i) { ParmVarDecl *P = Function->getParamDecl(i); - ExprResult R = PerformCopyInitialization( - InitializedEntity::InitializeParameter(Context, + ExprResult R = S.PerformCopyInitialization( + InitializedEntity::InitializeParameter(S.Context, Function->getParamDecl(i)), SourceLocation(), P->hasUninstantiatedDefaultArg() ? P->getUninstantiatedDefaultArg() : P->getDefaultArg()); - if (R.isInvalid()) { - InitializationFailed = true; - break; - } + if (R.isInvalid()) + return false; ConvertedArgs.push_back(R.get()); } - if (InitializationFailed || Trap.hasErrorOccurred()) - return EnableIfAttrs[0]; + if (Trap.hasErrorOccurred()) + return false; } + return true; +} + +EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, + bool MissingImplicitThis) { + SmallVector<EnableIfAttr *, 4> EnableIfAttrs = + getOrderedEnableIfAttrs(Function); + if (EnableIfAttrs.empty()) + return nullptr; + + SFINAETrap Trap(*this); + SmallVector<Expr *, 16> ConvertedArgs; + // FIXME: We should look into making enable_if late-parsed. + Expr *DiscardedThis; + if (!convertArgsForAvailabilityChecks( + *this, Function, /*ThisArg=*/nullptr, Args, Trap, + /*MissingImplicitThis=*/true, DiscardedThis, ConvertedArgs)) + return EnableIfAttrs[0]; for (auto *EIA : EnableIfAttrs) { APValue Result; @@ -6040,6 +6263,87 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args, return nullptr; } +static bool gatherDiagnoseIfAttrs(FunctionDecl *Function, bool ArgDependent, + SmallVectorImpl<DiagnoseIfAttr *> &Errors, + SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal) { + for (auto *DIA : Function->specific_attrs<DiagnoseIfAttr>()) + if (ArgDependent == DIA->getArgDependent()) { + if (DIA->isError()) + Errors.push_back(DIA); + else + Nonfatal.push_back(DIA); + } + + return !Errors.empty() || !Nonfatal.empty(); +} + +template <typename CheckFn> +static DiagnoseIfAttr * +checkDiagnoseIfAttrsWith(const SmallVectorImpl<DiagnoseIfAttr *> &Errors, + SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal, + CheckFn &&IsSuccessful) { + // Note that diagnose_if attributes are late-parsed, so they appear in the + // correct order (unlike enable_if attributes). + auto ErrAttr = llvm::find_if(Errors, IsSuccessful); + if (ErrAttr != Errors.end()) + return *ErrAttr; + + llvm::erase_if(Nonfatal, [&](DiagnoseIfAttr *A) { return !IsSuccessful(A); }); + return nullptr; +} + +DiagnoseIfAttr * +Sema::checkArgDependentDiagnoseIf(FunctionDecl *Function, ArrayRef<Expr *> Args, + SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal, + bool MissingImplicitThis, + Expr *ThisArg) { + SmallVector<DiagnoseIfAttr *, 4> Errors; + if (!gatherDiagnoseIfAttrs(Function, /*ArgDependent=*/true, Errors, Nonfatal)) + return nullptr; + + SFINAETrap Trap(*this); + SmallVector<Expr *, 16> ConvertedArgs; + Expr *ConvertedThis; + if (!convertArgsForAvailabilityChecks(*this, Function, ThisArg, Args, Trap, + MissingImplicitThis, ConvertedThis, + ConvertedArgs)) + return nullptr; + + return checkDiagnoseIfAttrsWith(Errors, Nonfatal, [&](DiagnoseIfAttr *DIA) { + APValue Result; + // It's sane to use the same ConvertedArgs for any redecl of this function, + // since EvaluateWithSubstitution only cares about the position of each + // argument in the arg list, not the ParmVarDecl* it maps to. + if (!DIA->getCond()->EvaluateWithSubstitution( + Result, Context, DIA->getParent(), ConvertedArgs, ConvertedThis)) + return false; + return Result.isInt() && Result.getInt().getBoolValue(); + }); +} + +DiagnoseIfAttr *Sema::checkArgIndependentDiagnoseIf( + FunctionDecl *Function, SmallVectorImpl<DiagnoseIfAttr *> &Nonfatal) { + SmallVector<DiagnoseIfAttr *, 4> Errors; + if (!gatherDiagnoseIfAttrs(Function, /*ArgDependent=*/false, Errors, + Nonfatal)) + return nullptr; + + return checkDiagnoseIfAttrsWith(Errors, Nonfatal, [&](DiagnoseIfAttr *DIA) { + bool Result; + return DIA->getCond()->EvaluateAsBooleanCondition(Result, Context) && + Result; + }); +} + +void Sema::emitDiagnoseIfDiagnostic(SourceLocation Loc, + const DiagnoseIfAttr *DIA) { + auto Code = DIA->isError() ? diag::err_diagnose_if_succeeded + : diag::warn_diagnose_if_succeeded; + Diag(Loc, Code) << DIA->getMessage(); + Diag(DIA->getLocation(), diag::note_from_diagnose_if) + << DIA->getParent() << DIA->getCond()->getSourceRange(); +} + /// \brief Add all of the function declarations in the given function set to /// the overload candidate set. void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, @@ -6055,7 +6359,7 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, AddMethodCandidate(cast<CXXMethodDecl>(FD), F.getPair(), cast<CXXMethodDecl>(FD)->getParent(), Args[0]->getType(), Args[0]->Classify(Context), - Args.slice(1), CandidateSet, + Args[0], Args.slice(1), CandidateSet, SuppressUserConversions, PartialOverloading); else AddOverloadCandidate(FD, F.getPair(), Args, CandidateSet, @@ -6064,13 +6368,12 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, FunctionTemplateDecl *FunTmpl = cast<FunctionTemplateDecl>(D); if (isa<CXXMethodDecl>(FunTmpl->getTemplatedDecl()) && !cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())->isStatic()) - AddMethodTemplateCandidate(FunTmpl, F.getPair(), - cast<CXXRecordDecl>(FunTmpl->getDeclContext()), - ExplicitTemplateArgs, - Args[0]->getType(), - Args[0]->Classify(Context), Args.slice(1), - CandidateSet, SuppressUserConversions, - PartialOverloading); + AddMethodTemplateCandidate( + FunTmpl, F.getPair(), + cast<CXXRecordDecl>(FunTmpl->getDeclContext()), + ExplicitTemplateArgs, Args[0]->getType(), + Args[0]->Classify(Context), Args[0], Args.slice(1), CandidateSet, + SuppressUserConversions, PartialOverloading); else AddTemplateOverloadCandidate(FunTmpl, F.getPair(), ExplicitTemplateArgs, Args, @@ -6085,6 +6388,7 @@ void Sema::AddFunctionCandidates(const UnresolvedSetImpl &Fns, void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, QualType ObjectType, Expr::Classification ObjectClassification, + Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions) { @@ -6100,12 +6404,12 @@ void Sema::AddMethodCandidate(DeclAccessPair FoundDecl, AddMethodTemplateCandidate(TD, FoundDecl, ActingContext, /*ExplicitArgs*/ nullptr, ObjectType, ObjectClassification, - Args, CandidateSet, + ThisArg, Args, CandidateSet, SuppressUserConversions); } else { AddMethodCandidate(cast<CXXMethodDecl>(Decl), FoundDecl, ActingContext, ObjectType, ObjectClassification, - Args, + ThisArg, Args, CandidateSet, SuppressUserConversions); } } @@ -6121,10 +6425,11 @@ void Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, CXXRecordDecl *ActingContext, QualType ObjectType, Expr::Classification ObjectClassification, - ArrayRef<Expr *> Args, + Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions, - bool PartialOverloading) { + bool PartialOverloading, + ConversionSequenceList EarlyConversions) { const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(Method->getType()->getAs<FunctionType>()); assert(Proto && "Methods without a prototype cannot be overloaded"); @@ -6145,7 +6450,8 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); // Add this candidate - OverloadCandidate &Candidate = CandidateSet.addCandidate(Args.size() + 1); + OverloadCandidate &Candidate = + CandidateSet.addCandidate(Args.size() + 1, EarlyConversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = Method; Candidate.IsSurrogate = false; @@ -6198,7 +6504,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, // (CUDA B.1): Check for invalid calls between targets. if (getLangOpts().CUDA) if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) - if (CheckCUDATarget(Caller, Method)) { + if (!IsAllowedCUDACall(Caller, Method)) { Candidate.Viable = false; Candidate.FailureKind = ovl_fail_bad_target; return; @@ -6207,7 +6513,10 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, // Determine the implicit conversion sequences for each of the // arguments. for (unsigned ArgIdx = 0; ArgIdx < Args.size(); ++ArgIdx) { - if (ArgIdx < NumParams) { + if (Candidate.Conversions[ArgIdx + 1].isInitialized()) { + // We already formed a conversion sequence for this parameter during + // template argument deduction. + } else if (ArgIdx < NumParams) { // (C++ 13.3.2p3): for F to be a viable function, there shall // exist for each argument an implicit conversion sequence // (13.3.3.1) that converts that argument to the corresponding @@ -6238,6 +6547,9 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl, Candidate.DeductionFailure.Data = FailedAttr; return; } + + initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Method, Args, + /*MissingImplicitThis=*/!ThisArg, ThisArg); } /// \brief Add a C++ member function template as a candidate to the candidate @@ -6250,6 +6562,7 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, TemplateArgumentListInfo *ExplicitTemplateArgs, QualType ObjectType, Expr::Classification ObjectClassification, + Expr *ThisArg, ArrayRef<Expr *> Args, OverloadCandidateSet& CandidateSet, bool SuppressUserConversions, @@ -6268,19 +6581,32 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; - if (TemplateDeductionResult Result - = DeduceTemplateArguments(MethodTmpl, ExplicitTemplateArgs, Args, - Specialization, Info, PartialOverloading)) { - OverloadCandidate &Candidate = CandidateSet.addCandidate(); + ConversionSequenceList Conversions; + if (TemplateDeductionResult Result = DeduceTemplateArguments( + MethodTmpl, ExplicitTemplateArgs, Args, Specialization, Info, + PartialOverloading, [&](ArrayRef<QualType> ParamTypes) { + return CheckNonDependentConversions( + MethodTmpl, ParamTypes, Args, CandidateSet, Conversions, + SuppressUserConversions, ActingContext, ObjectType, + ObjectClassification); + })) { + OverloadCandidate &Candidate = + CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = MethodTmpl->getTemplatedDecl(); Candidate.Viable = false; - Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; + Candidate.IgnoreObjectArgument = + cast<CXXMethodDecl>(Candidate.Function)->isStatic() || + ObjectType.isNull(); Candidate.ExplicitCallArguments = Args.size(); - Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, - Info); + if (Result == TDK_NonDependentConversionFailure) + Candidate.FailureKind = ovl_fail_bad_conversion; + else { + Candidate.FailureKind = ovl_fail_bad_deduction; + Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, + Info); + } return; } @@ -6290,8 +6616,9 @@ Sema::AddMethodTemplateCandidate(FunctionTemplateDecl *MethodTmpl, assert(isa<CXXMethodDecl>(Specialization) && "Specialization is not a member function?"); AddMethodCandidate(cast<CXXMethodDecl>(Specialization), FoundDecl, - ActingContext, ObjectType, ObjectClassification, Args, - CandidateSet, SuppressUserConversions, PartialOverloading); + ActingContext, ObjectType, ObjectClassification, + /*ThisArg=*/ThisArg, Args, CandidateSet, + SuppressUserConversions, PartialOverloading, Conversions); } /// \brief Add a C++ function template specialization as a candidate @@ -6319,19 +6646,33 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, // functions. TemplateDeductionInfo Info(CandidateSet.getLocation()); FunctionDecl *Specialization = nullptr; - if (TemplateDeductionResult Result - = DeduceTemplateArguments(FunctionTemplate, ExplicitTemplateArgs, Args, - Specialization, Info, PartialOverloading)) { - OverloadCandidate &Candidate = CandidateSet.addCandidate(); + ConversionSequenceList Conversions; + if (TemplateDeductionResult Result = DeduceTemplateArguments( + FunctionTemplate, ExplicitTemplateArgs, Args, Specialization, Info, + PartialOverloading, [&](ArrayRef<QualType> ParamTypes) { + return CheckNonDependentConversions(FunctionTemplate, ParamTypes, + Args, CandidateSet, Conversions, + SuppressUserConversions); + })) { + OverloadCandidate &Candidate = + CandidateSet.addCandidate(Conversions.size(), Conversions); Candidate.FoundDecl = FoundDecl; Candidate.Function = FunctionTemplate->getTemplatedDecl(); Candidate.Viable = false; - Candidate.FailureKind = ovl_fail_bad_deduction; Candidate.IsSurrogate = false; - Candidate.IgnoreObjectArgument = false; + // Ignore the object argument if there is one, since we don't have an object + // type. + Candidate.IgnoreObjectArgument = + isa<CXXMethodDecl>(Candidate.Function) && + !isa<CXXConstructorDecl>(Candidate.Function); Candidate.ExplicitCallArguments = Args.size(); - Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, - Info); + if (Result == TDK_NonDependentConversionFailure) + Candidate.FailureKind = ovl_fail_bad_conversion; + else { + Candidate.FailureKind = ovl_fail_bad_deduction; + Candidate.DeductionFailure = MakeDeductionFailureInfo(Context, Result, + Info); + } return; } @@ -6339,7 +6680,64 @@ Sema::AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, // deduction as a candidate. assert(Specialization && "Missing function template specialization?"); AddOverloadCandidate(Specialization, FoundDecl, Args, CandidateSet, - SuppressUserConversions, PartialOverloading); + SuppressUserConversions, PartialOverloading, + /*AllowExplicit*/false, Conversions); +} + +/// Check that implicit conversion sequences can be formed for each argument +/// whose corresponding parameter has a non-dependent type, per DR1391's +/// [temp.deduct.call]p10. +bool Sema::CheckNonDependentConversions( + FunctionTemplateDecl *FunctionTemplate, ArrayRef<QualType> ParamTypes, + ArrayRef<Expr *> Args, OverloadCandidateSet &CandidateSet, + ConversionSequenceList &Conversions, bool SuppressUserConversions, + CXXRecordDecl *ActingContext, QualType ObjectType, + Expr::Classification ObjectClassification) { + // FIXME: The cases in which we allow explicit conversions for constructor + // arguments never consider calling a constructor template. It's not clear + // that is correct. + const bool AllowExplicit = false; + + auto *FD = FunctionTemplate->getTemplatedDecl(); + auto *Method = dyn_cast<CXXMethodDecl>(FD); + bool HasThisConversion = Method && !isa<CXXConstructorDecl>(Method); + unsigned ThisConversions = HasThisConversion ? 1 : 0; + + Conversions = + CandidateSet.allocateConversionSequences(ThisConversions + Args.size()); + + // Overload resolution is always an unevaluated context. + EnterExpressionEvaluationContext Unevaluated(*this, Sema::Unevaluated); + + // For a method call, check the 'this' conversion here too. DR1391 doesn't + // require that, but this check should never result in a hard error, and + // overload resolution is permitted to sidestep instantiations. + if (HasThisConversion && !cast<CXXMethodDecl>(FD)->isStatic() && + !ObjectType.isNull()) { + Conversions[0] = TryObjectArgumentInitialization( + *this, CandidateSet.getLocation(), ObjectType, ObjectClassification, + Method, ActingContext); + if (Conversions[0].isBad()) + return true; + } + + for (unsigned I = 0, N = std::min(ParamTypes.size(), Args.size()); I != N; + ++I) { + QualType ParamType = ParamTypes[I]; + if (!ParamType->isDependentType()) { + Conversions[ThisConversions + I] + = TryCopyInitialization(*this, Args[I], ParamType, + SuppressUserConversions, + /*InOverloadResolution=*/true, + /*AllowObjCWritebackConversion=*/ + getLangOpts().ObjCAutoRefCount, + AllowExplicit); + if (Conversions[ThisConversions + I].isBad()) + return true; + } + } + + return false; } /// Determine whether this is an allowable conversion from the result @@ -6547,6 +6945,8 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, Candidate.DeductionFailure.Data = FailedAttr; return; } + + initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Conversion, None, false, From); } /// \brief Adds a conversion function template specialization @@ -6699,6 +7099,8 @@ void Sema::AddSurrogateCandidate(CXXConversionDecl *Conversion, Candidate.DeductionFailure.Data = FailedAttr; return; } + + initDiagnoseIfComplaint(*this, CandidateSet, Candidate, Conversion, None); } /// \brief Add overload candidates for overloaded operators that are @@ -6747,10 +7149,8 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op, Oper != OperEnd; ++Oper) AddMethodCandidate(Oper.getPair(), Args[0]->getType(), - Args[0]->Classify(Context), - Args.slice(1), - CandidateSet, - /* SuppressUserConversions = */ false); + Args[0]->Classify(Context), Args[0], Args.slice(1), + CandidateSet, /*SuppressUserConversions=*/false); } } @@ -7538,12 +7938,12 @@ public: } // C++ [over.match.oper]p16: - // For every pointer to member type T, there exist candidate operator - // functions of the form + // For every pointer to member type T or type std::nullptr_t, there + // exist candidate operator functions of the form // // bool operator==(T,T); // bool operator!=(T,T); - void addEqualEqualOrNotEqualMemberPointerOverloads() { + void addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads() { /// Set of (canonical) types that we've already handled. llvm::SmallPtrSet<QualType, 8> AddedTypes; @@ -7560,13 +7960,22 @@ public: QualType ParamTypes[2] = { *MemPtr, *MemPtr }; S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } + + if (CandidateTypes[ArgIdx].hasNullPtrType()) { + CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy); + if (AddedTypes.insert(NullPtrTy).second) { + QualType ParamTypes[2] = { NullPtrTy, NullPtrTy }; + S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, + CandidateSet); + } + } } } // C++ [over.built]p15: // - // For every T, where T is an enumeration type, a pointer type, or - // std::nullptr_t, there exist candidate operator functions of the form + // For every T, where T is an enumeration type or a pointer type, + // there exist candidate operator functions of the form // // bool operator<(T, T); // bool operator>(T, T); @@ -7651,17 +8060,6 @@ public: QualType ParamTypes[2] = { *Enum, *Enum }; S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet); } - - if (CandidateTypes[ArgIdx].hasNullPtrType()) { - CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy); - if (AddedTypes.insert(NullPtrTy).second && - !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy, - NullPtrTy))) { - QualType ParamTypes[2] = { NullPtrTy, NullPtrTy }; - S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, - CandidateSet); - } - } } } @@ -8357,7 +8755,7 @@ void Sema::AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, case OO_EqualEqual: case OO_ExclaimEqual: - OpBuilder.addEqualEqualOrNotEqualMemberPointerOverloads(); + OpBuilder.addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads(); // Fall through. case OO_Less: @@ -8566,13 +8964,40 @@ bool clang::isBetterOverloadCandidate(Sema &S, const OverloadCandidate &Cand1, if (Cand1.IgnoreObjectArgument || Cand2.IgnoreObjectArgument) StartArg = 1; + auto IsIllFormedConversion = [&](const ImplicitConversionSequence &ICS) { + // We don't allow incompatible pointer conversions in C++. + if (!S.getLangOpts().CPlusPlus) + return ICS.isStandard() && + ICS.Standard.Second == ICK_Incompatible_Pointer_Conversion; + + // The only ill-formed conversion we allow in C++ is the string literal to + // char* conversion, which is only considered ill-formed after C++11. + return S.getLangOpts().CPlusPlus11 && !S.getLangOpts().WritableStrings && + hasDeprecatedStringLiteralToCharPtrConversion(ICS); + }; + + // Define functions that don't require ill-formed conversions for a given + // argument to be better candidates than functions that do. + unsigned NumArgs = Cand1.Conversions.size(); + assert(Cand2.Conversions.size() == NumArgs && "Overload candidate mismatch"); + bool HasBetterConversion = false; + for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { + bool Cand1Bad = IsIllFormedConversion(Cand1.Conversions[ArgIdx]); + bool Cand2Bad = IsIllFormedConversion(Cand2.Conversions[ArgIdx]); + if (Cand1Bad != Cand2Bad) { + if (Cand1Bad) + return false; + HasBetterConversion = true; + } + } + + if (HasBetterConversion) + return true; + // C++ [over.match.best]p1: // A viable function F1 is defined to be a better function than another // viable function F2 if for all arguments i, ICSi(F1) is not a worse // conversion sequence than ICSi(F2), and then... - unsigned NumArgs = Cand1.NumConversions; - assert(Cand2.NumConversions == NumArgs && "Overload candidate mismatch"); - bool HasBetterConversion = false; for (unsigned ArgIdx = StartArg; ArgIdx < NumArgs; ++ArgIdx) { switch (CompareImplicitConversionSequences(S, Loc, Cand1.Conversions[ArgIdx], @@ -8756,6 +9181,17 @@ void Sema::diagnoseEquivalentInternalLinkageDeclarations( } } +static bool isCandidateUnavailableDueToDiagnoseIf(const OverloadCandidate &OC) { + ArrayRef<DiagnoseIfAttr *> Info = OC.getDiagnoseIfInfo(); + if (!Info.empty() && Info[0]->isError()) + return true; + + assert(llvm::all_of(Info, + [](const DiagnoseIfAttr *A) { return !A->isError(); }) && + "DiagnoseIf info shouldn't have mixed warnings and errors."); + return false; +} + /// \brief Computes the best viable function (C++ 13.3.3) /// within an overload candidate set. /// @@ -8774,8 +9210,8 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, 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 + // [CUDA] HD->H or HD->D calls are technically not allowed by CUDA but + // are 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 @@ -8795,9 +9231,7 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, S.IdentifyCUDAPreference(Caller, Cand->Function) == Sema::CFP_WrongSide; }; - Candidates.erase(std::remove_if(Candidates.begin(), Candidates.end(), - IsWrongSideCandidate), - Candidates.end()); + llvm::erase_if(Candidates, IsWrongSideCandidate); } } @@ -8836,13 +9270,19 @@ OverloadCandidateSet::BestViableFunction(Sema &S, SourceLocation Loc, // Best is the best viable function. if (Best->Function && (Best->Function->isDeleted() || - S.isFunctionConsideredUnavailable(Best->Function))) + S.isFunctionConsideredUnavailable(Best->Function) || + isCandidateUnavailableDueToDiagnoseIf(*Best))) return OR_Deleted; if (!EquivalentCands.empty()) S.diagnoseEquivalentInternalLinkageDeclarations(Loc, Best->Function, EquivalentCands); + for (const auto *W : Best->getDiagnoseIfInfo()) { + assert(W->isWarning() && "Errors should've been caught earlier!"); + S.emitDiagnoseIfDiagnostic(Loc, W); + } + return OR_Success; } @@ -8864,10 +9304,9 @@ enum OverloadCandidateKind { oc_inherited_constructor_template }; -OverloadCandidateKind ClassifyOverloadCandidate(Sema &S, - NamedDecl *Found, - FunctionDecl *Fn, - std::string &Description) { +static OverloadCandidateKind +ClassifyOverloadCandidate(Sema &S, NamedDecl *Found, FunctionDecl *Fn, + std::string &Description) { bool isTemplate = false; if (FunctionTemplateDecl *FunTmpl = Fn->getPrimaryTemplate()) { @@ -8960,8 +9399,9 @@ static bool checkAddressOfFunctionIsAvailable(Sema &S, const FunctionDecl *FD, return false; } - auto I = llvm::find_if( - FD->parameters(), std::mem_fn(&ParmVarDecl::hasAttr<PassObjectSizeAttr>)); + auto I = llvm::find_if(FD->parameters(), [](const ParmVarDecl *P) { + return P->hasAttr<PassObjectSizeAttr>(); + }); if (I == FD->param_end()) return true; @@ -9003,7 +9443,7 @@ void Sema::NoteOverloadCandidate(NamedDecl *Found, FunctionDecl *Fn, std::string FnDesc; OverloadCandidateKind K = ClassifyOverloadCandidate(*this, Found, Fn, FnDesc); PartialDiagnostic PD = PDiag(diag::note_ovl_candidate) - << (unsigned) K << FnDesc; + << (unsigned) K << Fn << FnDesc; HandleFunctionTypeMismatch(PD, Fn->getType(), DestType); Diag(Fn->getLocation(), PD); @@ -9436,9 +9876,25 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, int which = 0; if (isa<TemplateTypeParmDecl>(ParamD)) which = 0; - else if (isa<NonTypeTemplateParmDecl>(ParamD)) + else if (isa<NonTypeTemplateParmDecl>(ParamD)) { + // Deduction might have failed because we deduced arguments of two + // different types for a non-type template parameter. + // FIXME: Use a different TDK value for this. + QualType T1 = + DeductionFailure.getFirstArg()->getNonTypeTemplateArgumentType(); + QualType T2 = + DeductionFailure.getSecondArg()->getNonTypeTemplateArgumentType(); + if (!S.Context.hasSameType(T1, T2)) { + S.Diag(Templated->getLocation(), + diag::note_ovl_candidate_inconsistent_deduction_types) + << ParamD->getDeclName() << *DeductionFailure.getFirstArg() << T1 + << *DeductionFailure.getSecondArg() << T2; + MaybeEmitInheritedConstructorNote(S, Found); + return; + } + which = 1; - else { + } else { which = 2; } @@ -9522,15 +9978,8 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, return; } - case Sema::TDK_FailedOverloadResolution: { - OverloadExpr::FindResult R = OverloadExpr::find(DeductionFailure.getExpr()); - S.Diag(Templated->getLocation(), - diag::note_ovl_candidate_failed_overload_resolution) - << R.Expression->getName(); - return; - } - - case Sema::TDK_DeducedMismatch: { + case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: { // Format the template argument list into the argument string. SmallString<128> TemplateArgString; if (TemplateArgumentList *Args = @@ -9543,7 +9992,8 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, S.Diag(Templated->getLocation(), diag::note_ovl_candidate_deduced_mismatch) << (*DeductionFailure.getCallArgIndex() + 1) << *DeductionFailure.getFirstArg() << *DeductionFailure.getSecondArg() - << TemplateArgString; + << TemplateArgString + << (DeductionFailure.Result == Sema::TDK_DeducedMismatchNested); break; } @@ -9592,6 +10042,10 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl *Found, Decl *Templated, S.Diag(Templated->getLocation(), diag::note_ovl_candidate_bad_deduction); MaybeEmitInheritedConstructorNote(S, Found); return; + case Sema::TDK_CUDATargetMismatch: + S.Diag(Templated->getLocation(), + diag::note_cuda_ovl_candidate_target_mismatch); + return; } } @@ -9669,10 +10123,17 @@ static void DiagnoseFailedEnableIfAttr(Sema &S, OverloadCandidate *Cand) { EnableIfAttr *Attr = static_cast<EnableIfAttr*>(Cand->DeductionFailure.Data); S.Diag(Callee->getLocation(), - diag::note_ovl_candidate_disabled_by_enable_if_attr) + diag::note_ovl_candidate_disabled_by_function_cond_attr) << Attr->getCond()->getSourceRange() << Attr->getMessage(); } +static void DiagnoseOpenCLExtensionDisabled(Sema &S, OverloadCandidate *Cand) { + FunctionDecl *Callee = Cand->Function; + + S.Diag(Callee->getLocation(), + diag::note_ovl_candidate_disabled_by_extension); +} + /// Generates a 'note' diagnostic for an overload candidate. We've /// already generated a primary error at the call site. /// @@ -9692,21 +10153,28 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, FunctionDecl *Fn = Cand->Function; // Note deleted candidates, but only if they're viable. - if (Cand->Viable && (Fn->isDeleted() || - S.isFunctionConsideredUnavailable(Fn))) { - std::string FnDesc; - OverloadCandidateKind FnKind = + if (Cand->Viable) { + if (Fn->isDeleted() || S.isFunctionConsideredUnavailable(Fn)) { + std::string 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, Cand->FoundDecl); - return; - } + S.Diag(Fn->getLocation(), diag::note_ovl_candidate_deleted) + << FnKind << FnDesc + << (Fn->isDeleted() ? (Fn->isDeletedAsWritten() ? 1 : 2) : 0); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); + return; + } + if (isCandidateUnavailableDueToDiagnoseIf(*Cand)) { + auto *A = Cand->DiagnoseIfInfo.get<DiagnoseIfAttr *>(); + assert(A->isError() && "Non-error diagnose_if disables a candidate?"); + S.Diag(Cand->Function->getLocation(), + diag::note_ovl_candidate_disabled_by_function_cond_attr) + << A->getCond()->getSourceRange() << A->getMessage(); + return; + } - // We don't really have anything else to say about viable candidates. - if (Cand->Viable) { + // We don't really have anything else to say about viable candidates. S.NoteOverloadCandidate(Cand->FoundDecl, Fn); return; } @@ -9734,7 +10202,7 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, case ovl_fail_bad_conversion: { unsigned I = (Cand->IgnoreObjectArgument ? 1 : 0); - for (unsigned N = Cand->NumConversions; I != N; ++I) + for (unsigned N = Cand->Conversions.size(); I != N; ++I) if (Cand->Conversions[I].isBad()) return DiagnoseBadConversion(S, Cand, I, TakingCandidateAddress); @@ -9750,6 +10218,15 @@ static void NoteFunctionCandidate(Sema &S, OverloadCandidate *Cand, case ovl_fail_enable_if: return DiagnoseFailedEnableIfAttr(S, Cand); + case ovl_fail_ext_disabled: + return DiagnoseOpenCLExtensionDisabled(S, Cand); + + case ovl_fail_inhctor_slice: + S.Diag(Fn->getLocation(), + diag::note_ovl_candidate_inherited_constructor_slice); + MaybeEmitInheritedConstructorNote(S, Cand->FoundDecl); + return; + case ovl_fail_addr_not_available: { bool Available = checkAddressOfCandidateIsAvailable(S, Cand->Function); (void)Available; @@ -9794,12 +10271,12 @@ static void NoteSurrogateCandidate(Sema &S, OverloadCandidate *Cand) { static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, SourceLocation OpLoc, OverloadCandidate *Cand) { - assert(Cand->NumConversions <= 2 && "builtin operator is not binary"); + assert(Cand->Conversions.size() <= 2 && "builtin operator is not binary"); std::string TypeStr("operator"); TypeStr += Opc; TypeStr += "("; TypeStr += Cand->BuiltinTypes.ParamTypes[0].getAsString(); - if (Cand->NumConversions == 1) { + if (Cand->Conversions.size() == 1) { TypeStr += ")"; S.Diag(OpLoc, diag::note_ovl_builtin_unary_candidate) << TypeStr; } else { @@ -9812,9 +10289,7 @@ static void NoteBuiltinOperatorCandidate(Sema &S, StringRef Opc, static void NoteAmbiguousUserConversions(Sema &S, SourceLocation OpLoc, OverloadCandidate *Cand) { - unsigned NoOperands = Cand->NumConversions; - for (unsigned ArgIdx = 0; ArgIdx < NoOperands; ++ArgIdx) { - const ImplicitConversionSequence &ICS = Cand->Conversions[ArgIdx]; + for (const ImplicitConversionSequence &ICS : Cand->Conversions) { if (ICS.isBad()) break; // all meaningless after first invalid if (!ICS.isAmbiguous()) continue; @@ -9834,7 +10309,8 @@ static SourceLocation GetLocationForCandidate(const OverloadCandidate *Cand) { static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { switch ((Sema::TemplateDeductionResult)DFI.Result) { case Sema::TDK_Success: - llvm_unreachable("TDK_success while diagnosing bad deduction"); + case Sema::TDK_NonDependentConversionFailure: + llvm_unreachable("non-deduction failure while diagnosing bad deduction"); case Sema::TDK_Invalid: case Sema::TDK_Incomplete: @@ -9846,12 +10322,13 @@ static unsigned RankDeductionFailure(const DeductionFailureInfo &DFI) { case Sema::TDK_SubstitutionFailure: case Sema::TDK_DeducedMismatch: + case Sema::TDK_DeducedMismatchNested: case Sema::TDK_NonDeducedMismatch: case Sema::TDK_MiscellaneousDeductionFailure: + case Sema::TDK_CUDATargetMismatch: return 3; case Sema::TDK_InstantiationDepth: - case Sema::TDK_FailedOverloadResolution: return 4; case Sema::TDK_InvalidExplicitArguments: @@ -9936,11 +10413,11 @@ struct CompareOverloadCandidatesForDisplay { // If there's any ordering between the defined conversions... // FIXME: this might not be transitive. - assert(L->NumConversions == R->NumConversions); + assert(L->Conversions.size() == R->Conversions.size()); int leftBetter = 0; unsigned I = (L->IgnoreObjectArgument || R->IgnoreObjectArgument); - for (unsigned E = L->NumConversions; I != E; ++I) { + for (unsigned E = L->Conversions.size(); I != E; ++I) { switch (CompareImplicitConversionSequences(S, Loc, L->Conversions[I], R->Conversions[I])) { @@ -9989,7 +10466,8 @@ struct CompareOverloadCandidatesForDisplay { } /// CompleteNonViableCandidate - Normally, overload resolution only -/// computes up to the first. Produces the FixIt set if possible. +/// computes up to the first bad conversion. Produces the FixIt set if +/// possible. static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, ArrayRef<Expr *> Args) { assert(!Cand->Viable); @@ -10002,71 +10480,67 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, // Use a implicit copy initialization to check conversion fixes. Cand->Fix.setConversionChecker(TryCopyInitialization); - // Skip forward to the first bad conversion. - unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); - unsigned ConvCount = Cand->NumConversions; - while (true) { + // Attempt to fix the bad conversion. + unsigned ConvCount = Cand->Conversions.size(); + for (unsigned ConvIdx = (Cand->IgnoreObjectArgument ? 1 : 0); /**/; + ++ConvIdx) { assert(ConvIdx != ConvCount && "no bad conversion in candidate"); - ConvIdx++; - if (Cand->Conversions[ConvIdx - 1].isBad()) { - Unfixable = !Cand->TryToFixBadConversion(ConvIdx - 1, S); + if (Cand->Conversions[ConvIdx].isInitialized() && + Cand->Conversions[ConvIdx].isBad()) { + Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); break; } } - if (ConvIdx == ConvCount) - return; - - assert(!Cand->Conversions[ConvIdx].isInitialized() && - "remaining conversion is initialized?"); - // FIXME: this should probably be preserved from the overload // operation somehow. bool SuppressUserConversions = false; - const FunctionProtoType* Proto; - unsigned ArgIdx = ConvIdx; + unsigned ConvIdx = 0; + ArrayRef<QualType> ParamTypes; if (Cand->IsSurrogate) { QualType ConvType = Cand->Surrogate->getConversionType().getNonReferenceType(); if (const PointerType *ConvPtrType = ConvType->getAs<PointerType>()) ConvType = ConvPtrType->getPointeeType(); - Proto = ConvType->getAs<FunctionProtoType>(); - ArgIdx--; + ParamTypes = ConvType->getAs<FunctionProtoType>()->getParamTypes(); + // Conversion 0 is 'this', which doesn't have a corresponding argument. + ConvIdx = 1; } else if (Cand->Function) { - Proto = Cand->Function->getType()->getAs<FunctionProtoType>(); + ParamTypes = + Cand->Function->getType()->getAs<FunctionProtoType>()->getParamTypes(); if (isa<CXXMethodDecl>(Cand->Function) && - !isa<CXXConstructorDecl>(Cand->Function)) - ArgIdx--; + !isa<CXXConstructorDecl>(Cand->Function)) { + // Conversion 0 is 'this', which doesn't have a corresponding argument. + ConvIdx = 1; + } } else { - // Builtin binary operator with a bad first conversion. + // Builtin operator. assert(ConvCount <= 3); - for (; ConvIdx != ConvCount; ++ConvIdx) - Cand->Conversions[ConvIdx] - = TryCopyInitialization(S, Args[ConvIdx], - Cand->BuiltinTypes.ParamTypes[ConvIdx], - SuppressUserConversions, - /*InOverloadResolution*/ true, - /*AllowObjCWritebackConversion=*/ - S.getLangOpts().ObjCAutoRefCount); - return; + ParamTypes = Cand->BuiltinTypes.ParamTypes; } // Fill in the rest of the conversions. - unsigned NumParams = Proto->getNumParams(); - for (; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) { - if (ArgIdx < NumParams) { - Cand->Conversions[ConvIdx] = TryCopyInitialization( - S, Args[ArgIdx], Proto->getParamType(ArgIdx), SuppressUserConversions, - /*InOverloadResolution=*/true, - /*AllowObjCWritebackConversion=*/ - S.getLangOpts().ObjCAutoRefCount); - // Store the FixIt in the candidate if it exists. - if (!Unfixable && Cand->Conversions[ConvIdx].isBad()) - Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); - } - else + for (unsigned ArgIdx = 0; ConvIdx != ConvCount; ++ConvIdx, ++ArgIdx) { + if (Cand->Conversions[ConvIdx].isInitialized()) { + // We've already checked this conversion. + } else if (ArgIdx < ParamTypes.size()) { + if (ParamTypes[ArgIdx]->isDependentType()) + Cand->Conversions[ConvIdx].setAsIdentityConversion( + Args[ArgIdx]->getType()); + else { + Cand->Conversions[ConvIdx] = + TryCopyInitialization(S, Args[ArgIdx], ParamTypes[ArgIdx], + SuppressUserConversions, + /*InOverloadResolution=*/true, + /*AllowObjCWritebackConversion=*/ + S.getLangOpts().ObjCAutoRefCount); + // Store the FixIt in the candidate if it exists. + if (!Unfixable && Cand->Conversions[ConvIdx].isBad()) + Unfixable = !Cand->TryToFixBadConversion(ConvIdx, S); + } + } else Cand->Conversions[ConvIdx].setEllipsis(); } } @@ -10074,16 +10548,17 @@ static void CompleteNonViableCandidate(Sema &S, OverloadCandidate *Cand, /// PrintOverloadCandidates - When overload resolution fails, prints /// diagnostic messages containing the candidates in the candidate /// set. -void OverloadCandidateSet::NoteCandidates(Sema &S, - OverloadCandidateDisplayKind OCD, - ArrayRef<Expr *> Args, - StringRef Opc, - SourceLocation OpLoc) { +void OverloadCandidateSet::NoteCandidates( + Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef<Expr *> Args, + StringRef Opc, SourceLocation OpLoc, + llvm::function_ref<bool(OverloadCandidate &)> Filter) { // Sort the candidates by viability and position. Sorting directly would // be prohibitive, so we make a set of pointers and sort those. SmallVector<OverloadCandidate*, 32> Cands; if (OCD == OCD_AllCandidates) Cands.reserve(size()); for (iterator Cand = begin(), LastCand = end(); Cand != LastCand; ++Cand) { + if (!Filter(*Cand)) + continue; if (Cand->Viable) Cands.push_back(Cand); else if (OCD == OCD_AllCandidates) { @@ -10269,6 +10744,21 @@ QualType Sema::ExtractUnqualifiedFunctionType(QualType PossiblyAFunctionType) { return Ret; } +static bool completeFunctionType(Sema &S, FunctionDecl *FD, SourceLocation Loc, + bool Complain = true) { + if (S.getLangOpts().CPlusPlus14 && FD->getReturnType()->isUndeducedType() && + S.DeduceReturnType(FD, Loc, Complain)) + return true; + + auto *FPT = FD->getType()->castAs<FunctionProtoType>(); + if (S.getLangOpts().CPlusPlus1z && + isUnresolvedExceptionSpec(FPT->getExceptionSpecType()) && + !S.ResolveExceptionSpec(Loc, FPT)) + return true; + + return false; +} + namespace { // A helper class to help with address of function resolution // - allows us to avoid passing around all those ugly parameters @@ -10359,7 +10849,7 @@ private: bool candidateHasExactlyCorrectType(const FunctionDecl *FD) { QualType Discard; return Context.hasSameUnqualifiedType(TargetFunctionType, FD->getType()) || - S.IsNoReturnConversion(FD->getType(), TargetFunctionType, Discard); + S.IsFunctionConversion(FD->getType(), TargetFunctionType, Discard); } /// \return true if A is considered a better overload candidate for the @@ -10436,7 +10926,7 @@ private: = S.DeduceTemplateArguments(FunctionTemplate, &OvlExplicitTemplateArgs, TargetFunctionType, Specialization, - Info, /*InOverloadResolution=*/true)) { + Info, /*IsAddressOfFunction*/true)) { // Make a note of the failed deduction for diagnostics. FailedCandidates.addCandidate() .set(CurAccessFunPair, FunctionTemplate->getTemplatedDecl(), @@ -10472,14 +10962,13 @@ private: if (FunctionDecl *FunDecl = dyn_cast<FunctionDecl>(Fn)) { if (S.getLangOpts().CUDA) if (FunctionDecl *Caller = dyn_cast<FunctionDecl>(S.CurContext)) - if (!Caller->isImplicit() && S.CheckCUDATarget(Caller, FunDecl)) + if (!Caller->isImplicit() && !S.IsAllowedCUDACall(Caller, FunDecl)) return false; // If any candidate has a placeholder return type, trigger its deduction // now. - if (S.getLangOpts().CPlusPlus14 && - FunDecl->getReturnType()->isUndeducedType() && - S.DeduceReturnType(FunDecl, SourceExpr->getLocStart(), Complain)) { + if (completeFunctionType(S, FunDecl, SourceExpr->getLocStart(), + Complain)) { HasComplained |= Complain; return false; } @@ -10704,6 +11193,8 @@ Sema::ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, else if (NumMatches == 1) { Fn = Resolver.getMatchingFunctionDecl(); assert(Fn); + if (auto *FPT = Fn->getType()->getAs<FunctionProtoType>()) + ResolveExceptionSpec(AddressOfExpr->getExprLoc(), FPT); FoundResult = *Resolver.getMatchingFunctionAccessPair(); if (Complain) { if (Resolver.IsStaticMemberFunctionFromBoundPointer()) @@ -10838,7 +11329,7 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, if (TemplateDeductionResult Result = DeduceTemplateArguments(FunctionTemplate, &ExplicitTemplateArgs, Specialization, Info, - /*InOverloadResolution=*/true)) { + /*IsAddressOfFunction*/true)) { // Make a note of the failed deduction for diagnostics. // TODO: Actually use the failed-deduction info? FailedCandidates.addCandidate() @@ -10863,9 +11354,8 @@ Sema::ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl, if (FoundResult) *FoundResult = I.getPair(); } - if (Matched && getLangOpts().CPlusPlus14 && - Matched->getReturnType()->isUndeducedType() && - DeduceReturnType(Matched, ovl->getExprLoc(), Complain)) + if (Matched && + completeFunctionType(*this, Matched, ovl->getExprLoc(), Complain)) return nullptr; return Matched; @@ -11255,6 +11745,12 @@ BuildRecoveryCallExpr(Sema &SemaRef, Scope *S, Expr *Fn, assert(!R.empty() && "lookup results empty despite recovery"); + // If recovery created an ambiguity, just bail out. + if (R.isAmbiguous()) { + R.suppressDiagnostics(); + return ExprError(); + } + // Build an implicit member call if appropriate. Just drop the // casts and such from the call, we don't really care. ExprResult NewFn = ExprError(); @@ -12229,6 +12725,16 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, TemplateArgs = &TemplateArgsBuffer; } + // Poor-programmer's Lazy<Expr *>; isImplicitAccess requires stripping + // parens/casts, which would be nice to avoid potentially doing multiple + // times. + llvm::Optional<Expr *> UnresolvedBase; + auto GetUnresolvedBase = [&] { + if (!UnresolvedBase.hasValue()) + UnresolvedBase = + UnresExpr->isImplicitAccess() ? nullptr : UnresExpr->getBase(); + return *UnresolvedBase; + }; for (UnresolvedMemberExpr::decls_iterator I = UnresExpr->decls_begin(), E = UnresExpr->decls_end(); I != E; ++I) { @@ -12249,14 +12755,15 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, continue; AddMethodCandidate(Method, I.getPair(), ActingDC, ObjectType, - ObjectClassification, Args, CandidateSet, + ObjectClassification, + /*ThisArg=*/GetUnresolvedBase(), Args, CandidateSet, /*SuppressUserConversions=*/false); } else { - AddMethodTemplateCandidate(cast<FunctionTemplateDecl>(Func), - I.getPair(), ActingDC, TemplateArgs, - ObjectType, ObjectClassification, - Args, CandidateSet, - /*SuppressUsedConversions=*/false); + AddMethodTemplateCandidate( + cast<FunctionTemplateDecl>(Func), I.getPair(), ActingDC, + TemplateArgs, ObjectType, ObjectClassification, + /*ThisArg=*/GetUnresolvedBase(), Args, CandidateSet, + /*SuppressUsedConversions=*/false); } } @@ -12331,18 +12838,6 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, new (Context) CXXMemberCallExpr(Context, MemExprE, Args, ResultType, VK, RParenLoc); - // (CUDA B.1): Check for invalid calls between targets. - if (getLangOpts().CUDA) { - if (const FunctionDecl *Caller = dyn_cast<FunctionDecl>(CurContext)) { - if (CheckCUDATarget(Caller, Method)) { - Diag(MemExpr->getMemberLoc(), diag::err_ref_bad_target) - << IdentifyCUDATarget(Method) << Method->getIdentifier() - << IdentifyCUDATarget(Caller); - return ExprError(); - } - } - } - // Check for a valid return type. if (CheckCallReturnType(Method->getReturnType(), MemExpr->getMemberLoc(), TheCall, Method)) @@ -12374,17 +12869,27 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, // In the case the method to call was not selected by the overloading // resolution process, we still need to handle the enable_if attribute. Do - // that here, so it will not hide previous -- and more relevant -- errors - if (isa<MemberExpr>(NakedMemExpr)) { + // that here, so it will not hide previous -- and more relevant -- errors. + if (auto *MemE = dyn_cast<MemberExpr>(NakedMemExpr)) { if (const EnableIfAttr *Attr = CheckEnableIf(Method, Args, true)) { - Diag(MemExprE->getLocStart(), + Diag(MemE->getMemberLoc(), diag::err_ovl_no_viable_member_function_in_call) << Method << Method->getSourceRange(); Diag(Method->getLocation(), - diag::note_ovl_candidate_disabled_by_enable_if_attr) + diag::note_ovl_candidate_disabled_by_function_cond_attr) << Attr->getCond()->getSourceRange() << Attr->getMessage(); return ExprError(); } + + SmallVector<DiagnoseIfAttr *, 4> Nonfatal; + if (const DiagnoseIfAttr *Attr = checkArgDependentDiagnoseIf( + Method, Args, Nonfatal, false, MemE->getBase())) { + emitDiagnoseIfDiagnostic(MemE->getMemberLoc(), Attr); + return ExprError(); + } + + for (const auto *Attr : Nonfatal) + emitDiagnoseIfDiagnostic(MemE->getMemberLoc(), Attr); } if ((isa<CXXConstructorDecl>(CurContext) || @@ -12464,7 +12969,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Object.get()->getType(), Object.get()->Classify(Context), - Args, CandidateSet, + Object.get(), Args, CandidateSet, /*SuppressUserConversions=*/ false); } @@ -12619,9 +13124,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, // Build the full argument list for the method call (the implicit object // parameter is placed at the beginning of the list). - std::unique_ptr<Expr * []> MethodArgs(new Expr *[Args.size() + 1]); + SmallVector<Expr *, 8> MethodArgs(Args.size() + 1); MethodArgs[0] = Object.get(); - std::copy(Args.begin(), Args.end(), &MethodArgs[1]); + std::copy(Args.begin(), Args.end(), MethodArgs.begin() + 1); // Once we've built TheCall, all of the expressions are properly // owned. @@ -12630,10 +13135,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj, ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = new (Context) - CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), - llvm::makeArrayRef(MethodArgs.get(), Args.size() + 1), - ResultTy, VK, RParenLoc, false); - MethodArgs.reset(); + CXXOperatorCallExpr(Context, OO_Call, NewFn.get(), MethodArgs, ResultTy, + VK, RParenLoc, false); if (CheckCallReturnType(Method->getReturnType(), LParenLoc, TheCall, Method)) return true; @@ -12742,7 +13245,8 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end(); Oper != OperEnd; ++Oper) { AddMethodCandidate(Oper.getPair(), Base->getType(), Base->Classify(Context), - None, CandidateSet, /*SuppressUserConversions=*/false); + Base, None, CandidateSet, + /*SuppressUserConversions=*/false); } bool HadMultipleCandidates = (CandidateSet.size() > 1); @@ -12996,6 +13500,31 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, ICE->getValueKind()); } + if (auto *GSE = dyn_cast<GenericSelectionExpr>(E)) { + if (!GSE->isResultDependent()) { + Expr *SubExpr = + FixOverloadedFunctionReference(GSE->getResultExpr(), Found, Fn); + if (SubExpr == GSE->getResultExpr()) + return GSE; + + // Replace the resulting type information before rebuilding the generic + // selection expression. + ArrayRef<Expr *> A = GSE->getAssocExprs(); + SmallVector<Expr *, 4> AssocExprs(A.begin(), A.end()); + unsigned ResultIdx = GSE->getResultIndex(); + AssocExprs[ResultIdx] = SubExpr; + + return new (Context) GenericSelectionExpr( + Context, GSE->getGenericLoc(), GSE->getControllingExpr(), + GSE->getAssocTypeSourceInfos(), AssocExprs, GSE->getDefaultLoc(), + GSE->getRParenLoc(), GSE->containsUnexpandedParameterPack(), + ResultIdx); + } + // Rather than fall through to the unreachable, return the original generic + // selection expression. + return GSE; + } + if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(E)) { assert(UnOp->getOpcode() == UO_AddrOf && "Can only take the address of an overloaded function"); @@ -13044,6 +13573,13 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, UnOp->getOperatorLoc()); } + // C++ [except.spec]p17: + // An exception-specification is considered to be needed when: + // - in an expression the function is the unique lookup result or the + // selected member of a set of overloaded functions + if (auto *FPT = Fn->getType()->getAs<FunctionProtoType>()) + ResolveExceptionSpec(E->getExprLoc(), FPT); + if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E)) { // FIXME: avoid copy. TemplateArgumentListInfo TemplateArgsBuffer, *TemplateArgs = nullptr; |
