diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 29 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateDeduction.cpp | 9 | ||||
-rw-r--r-- | clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp | 14 |
3 files changed, 45 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 70a4c333f34..cdfb30b30a3 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1599,6 +1599,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())); @@ -10388,6 +10390,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 @@ -10596,9 +10613,8 @@ private: // 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; } @@ -10823,6 +10839,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()) @@ -10982,9 +11000,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; diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp index e61197b62ce..11d744b72bd 100644 --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -3687,6 +3687,15 @@ Sema::DeduceTemplateArguments(FunctionTemplateDecl *FunctionTemplate, DeduceReturnType(Specialization, Info.getLocation(), false)) return TDK_MiscellaneousDeductionFailure; + // If the function has a dependent exception specification, resolve it now, + // so we can check that the exception specification matches. + auto *SpecializationFPT = + Specialization->getType()->castAs<FunctionProtoType>(); + if (getLangOpts().CPlusPlus1z && + isUnresolvedExceptionSpec(SpecializationFPT->getExceptionSpecType()) && + !ResolveExceptionSpec(Info.getLocation(), SpecializationFPT)) + return TDK_MiscellaneousDeductionFailure; + // If the requested function type does not match the actual type of the // specialization with respect to arguments of compatible pointer to function // types, template argument deduction fails. diff --git a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp index 77d073f0109..72b28432ef0 100644 --- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp +++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp @@ -17,7 +17,19 @@ template<typename A, typename B> void redecl3() throw(B); typedef int I; template<bool B> void redecl4(I) noexcept(B); -template<bool B> void redecl4(I) noexcept(B); +template<bool B> void redecl4(I) noexcept(B); // expected-note {{failed template argument deduction}} + +void (*init_with_exact_type_a)(int) noexcept = redecl4<true>; +void (*init_with_mismatched_type_a)(int) = redecl4<true>; +auto deduce_auto_from_noexcept_function_ptr_a = redecl4<true>; +using DeducedType_a = decltype(deduce_auto_from_noexcept_function_ptr_a); +using DeducedType_a = void (*)(int) noexcept; + +void (*init_with_exact_type_b)(int) = redecl4<false>; +void (*init_with_mismatched_type_b)(int) noexcept = redecl4<false>; // expected-error {{does not match required type}} +auto deduce_auto_from_noexcept_function_ptr_b = redecl4<false>; +using DeducedType_b = decltype(deduce_auto_from_noexcept_function_ptr_b); +using DeducedType_b = void (*)(int); namespace DependentDefaultCtorExceptionSpec { template<typename> struct T { static const bool value = true; }; |