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