Author: rsmith Date: Mon Oct 31 20:31:23 2016 New Revision: 285663 URL: http://llvm.org/viewvc/llvm-project?rev=285663&view=rev Log: p0012: Teach resolving address of overloaded function with dependent exception specification to resolve the exception specification as part of the type check, in C++1z onwards. This is not actually part of P0012 / CWG1330 rules for when an exception specification is "needed", but is necessary for sanity.
Modified: cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=285663&r1=285662&r2=285663&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Oct 31 20:31:23 2016 @@ -1599,6 +1599,8 @@ static bool IsStandardConversion(Sema &S } // 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::ExtractUnqualifiedFunctio 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 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::ResolveSingleFunctionTemplateSpeci 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; Modified: cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp?rev=285663&r1=285662&r2=285663&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp (original) +++ cfe/trunk/lib/Sema/SemaTemplateDeduction.cpp Mon Oct 31 20:31:23 2016 @@ -3687,6 +3687,15 @@ Sema::DeduceTemplateArguments(FunctionTe 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. Modified: cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp?rev=285663&r1=285662&r2=285663&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp (original) +++ cfe/trunk/test/SemaCXX/cxx1z-noexcept-function-type.cpp Mon Oct 31 20:31:23 2016 @@ -17,7 +17,19 @@ template<typename A, typename B> void re 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; }; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits