[PATCH] D55039: [sema] Warn of mangling change if function parameters are noexcept.

Matt Davis via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 28 17:08:24 PST 2018


mattd created this revision.
mattd added reviewers: erik.pilkington, rsmith.

The flag: `-Wc++17-compat-mangling` was not emitting a warning diagnostic in all cases, specifically if a function has parameters that happen to have function pointers that have  noexecept parameters.  For example:

  void fn(void (*)(void (*)() noexcept)){}

That example will produce different symbol names between c++17 and earlier dialects.  I believe that clang should be emitting the compatibility warning in this case.  This patch modifies the existing logic to recursively check the parameters of a function and warn if they too are noexcept.

This fixes PR39656.


https://reviews.llvm.org/D55039

Files:
  lib/Sema/SemaDecl.cpp
  test/CXX/except/except.spec/p2-places.cpp
  test/SemaCXX/cxx1z-noexcept-function-type.cpp


Index: test/SemaCXX/cxx1z-noexcept-function-type.cpp
===================================================================
--- test/SemaCXX/cxx1z-noexcept-function-type.cpp
+++ test/SemaCXX/cxx1z-noexcept-function-type.cpp
@@ -83,14 +83,16 @@
   auto f5() -> void (*)() throw();
   auto f6() -> void (&)() throw();
   auto f7() -> void (X::*)() throw();
+  void f8(int, void (*)(int, void (*)() noexcept));
 #if __cplusplus <= 201402L && !defined(NO_COMPAT_MANGLING)
-  // expected-warning at -8 {{mangled name of 'f1' will change in C++17 due to non-throwing exception specification in function signature}}
-  // expected-warning at -8 {{mangled name of 'f2' will change in C++17 due to non-throwing exception specification in function signature}}
-  // expected-warning at -8 {{mangled name of 'f3' will change in C++17 due to non-throwing exception specification in function signature}}
-  // expected-warning at -8 {{mangled name of 'f4' will change in C++17 due to non-throwing exception specification in function signature}}
-  // expected-warning at -8 {{mangled name of 'f5' will change in C++17 due to non-throwing exception specification in function signature}}
-  // expected-warning at -8 {{mangled name of 'f6' will change in C++17 due to non-throwing exception specification in function signature}}
-  // expected-warning at -8 {{mangled name of 'f7' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f1' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f2' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f3' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f4' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f5' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f6' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f7' will change in C++17 due to non-throwing exception specification in function signature}}
+  // expected-warning at -9 {{mangled name of 'f8' will change in C++17 due to non-throwing exception specification in function signature}}
 #endif
 
   // An instantiation-dependent exception specification needs to be mangled in
Index: test/CXX/except/except.spec/p2-places.cpp
===================================================================
--- test/CXX/except/except.spec/p2-places.cpp
+++ test/CXX/except/except.spec/p2-places.cpp
@@ -55,7 +55,7 @@
 
   void (*h())() noexcept(false);
 
-  void (*i() noexcept(false))(void (*)() noexcept(true)) noexcept(false);
+  void (*i() noexcept(false))(void (*)() noexcept(true)) noexcept(false); // expected-warning {{mangled name of 'i' will change in C++17 due to non-throwing exception specification in function signature}}
 
   void (**k)(void pfa() noexcept(false)); // no-error
 
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -10209,7 +10209,7 @@
     // most cases, and exception specifications are not permitted in most other
     // contexts where they could make it into a mangling.)
     if (!getLangOpts().CPlusPlus17 && !NewFD->getPrimaryTemplate()) {
-      auto HasNoexcept = [&](QualType T) -> bool {
+      std::function<bool(QualType)> HasNoexcept = [&](QualType T) -> bool {
         // Strip off declarator chunks that could be between us and a function
         // type. We don't need to look far, exception specifications are very
         // restricted prior to C++17.
@@ -10219,9 +10219,12 @@
           T = T->getPointeeType();
         else if (auto *MPT = T->getAs<MemberPointerType>())
           T = MPT->getPointeeType();
-        if (auto *FPT = T->getAs<FunctionProtoType>())
-          if (FPT->isNothrow())
+        if (auto *FPT = T->getAs<FunctionProtoType>()) {
+          if (FPT->isNothrow() ||
+              llvm::any_of(FPT->param_types(),
+                           [&](QualType Q) { return HasNoexcept(Q); }))
             return true;
+        }
         return false;
       };
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D55039.175789.patch
Type: text/x-patch
Size: 4477 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20181129/e10fa92d/attachment.bin>


More information about the cfe-commits mailing list