[clang] a1d2611 - [c++17] Fix assert / wrong code when passing a noexcept pointer to

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Dec 4 18:55:35 PST 2019


Author: Richard Smith
Date: 2019-12-04T18:55:23-08:00
New Revision: a1d2611c046efa46cf32a10c9e9a8a7a8a06feba

URL: https://github.com/llvm/llvm-project/commit/a1d2611c046efa46cf32a10c9e9a8a7a8a06feba
DIFF: https://github.com/llvm/llvm-project/commit/a1d2611c046efa46cf32a10c9e9a8a7a8a06feba.diff

LOG: [c++17] Fix assert / wrong code when passing a noexcept pointer to
member function to a non-noexcept pointer to member non-type template
parameter.

Added: 
    

Modified: 
    clang/lib/Sema/SemaTemplate.cpp
    clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index a85fb6c1dc83..e800f7fe7424 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7004,15 +7004,21 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
 
       // We might need to perform a trailing qualification conversion, since
       // the element type on the parameter could be more qualified than the
-      // element type in the expression we constructed.
+      // element type in the expression we constructed, and likewise for a
+      // function conversion.
       bool ObjCLifetimeConversion;
-      if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
+      QualType Ignored;
+      if (IsFunctionConversion(RefExpr.get()->getType(), ParamType, Ignored) ||
+          IsQualificationConversion(RefExpr.get()->getType(),
                                     ParamType.getUnqualifiedType(), false,
                                     ObjCLifetimeConversion))
-        RefExpr = ImpCastExprToType(RefExpr.get(), ParamType.getUnqualifiedType(), CK_NoOp);
+        RefExpr = ImpCastExprToType(RefExpr.get(),
+                                    ParamType.getUnqualifiedType(), CK_NoOp);
 
+      // FIXME: We need to perform derived-to-base or base-to-derived
+      // pointer-to-member conversions here too.
       assert(!RefExpr.isInvalid() &&
-             Context.hasSameType(((Expr*) RefExpr.get())->getType(),
+             Context.hasSameType(RefExpr.get()->getType(),
                                  ParamType.getUnqualifiedType()));
       return RefExpr;
     }

diff  --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index d73a88777d0c..7a58dd5dcaed 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -393,3 +393,12 @@ namespace PR42362 {
   template<auto (&...F)()> struct Z<F...>::Q {};
   Z<f, f, f>::Q q;
 }
+
+namespace FunctionConversion {
+  struct a { void c(char *) noexcept; };
+  template<void (a::*f)(char*)> void g() {
+    using T = decltype(f);
+    using T = void (a::*)(char*); // (not 'noexcept')
+  }
+  template void g<&a::c>();
+}


        


More information about the cfe-commits mailing list