r285663 - p0012: Teach resolving address of overloaded function with dependent exception
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Mon Oct 31 18:31:23 PDT 2016
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; };
More information about the cfe-commits
mailing list