mattd updated this revision to Diff 176515.
mattd added a comment.
- Move the HasNoexcept lambda to its own static function.
- Added an additional check in HasNoexcept to recursively check return values.
- Modified the parameter check in Sema::CheckFunctionDeclaration to use
llvm::any_of, all we need to know is if any of the parameters might have a
mangling change.
- Updated the test to include the example provided by @Rakete1111.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D55039/new/
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,18 @@
auto f5() -> void (*)() throw();
auto f6() -> void (&)() throw();
auto f7() -> void (X::*)() throw();
+ void f8(int, void (*)(int, void (*)() noexcept));
+ void f9(void (*g())() noexcept);
#if __cplusplus <= 201402L && !defined(NO_COMPAT_MANGLING)
- // expected-warning@-8 {{mangled name of 'f1' will change in C++17 due to non-throwing exception specification in function signature}}
- // expected-warning@-8 {{mangled name of 'f2' will change in C++17 due to non-throwing exception specification in function signature}}
- // expected-warning@-8 {{mangled name of 'f3' will change in C++17 due to non-throwing exception specification in function signature}}
- // expected-warning@-8 {{mangled name of 'f4' will change in C++17 due to non-throwing exception specification in function signature}}
- // expected-warning@-8 {{mangled name of 'f5' will change in C++17 due to non-throwing exception specification in function signature}}
- // expected-warning@-8 {{mangled name of 'f6' will change in C++17 due to non-throwing exception specification in function signature}}
- // expected-warning@-8 {{mangled name of 'f7' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f1' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f2' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f3' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f4' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f5' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f6' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f7' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f8' will change in C++17 due to non-throwing exception specification in function signature}}
+ // expected-warning@-10 {{mangled name of 'f9' 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
@@ -9914,6 +9914,28 @@
OldDecl, MergeTypeWithPrevious, Previous);
}
+/// Returns true if the type T is a function type that contains a noexcept specifier.
+/// This check recursively checks the params and return types of T if T happens
+/// to be a function.
+static bool hasNoexcept(QualType T) {
+ // 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.
+ if (auto *RT = T->getAs<ReferenceType>())
+ T = RT->getPointeeType();
+ else if (T->isAnyPointerType())
+ T = T->getPointeeType();
+ else if (auto *MPT = T->getAs<MemberPointerType>())
+ T = MPT->getPointeeType();
+ if (auto *FPT = T->getAs<FunctionProtoType>()) {
+ if (FPT->isNothrow() || hasNoexcept(FPT->getReturnType()) ||
+ llvm::any_of(FPT->param_types(),
+ [](QualType Q) { return hasNoexcept(Q); }))
+ return true;
+ }
+ return false;
+}
+
/// Perform semantic checking of a new function declaration.
///
/// Performs semantic analysis of the new function declaration
@@ -10240,30 +10262,14 @@
// 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 {
- // 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.
- if (auto *RT = T->getAs<ReferenceType>())
- T = RT->getPointeeType();
- else if (T->isAnyPointerType())
- T = T->getPointeeType();
- else if (auto *MPT = T->getAs<MemberPointerType>())
- T = MPT->getPointeeType();
- if (auto *FPT = T->getAs<FunctionProtoType>())
- if (FPT->isNothrow())
- return true;
- return false;
- };
-
auto *FPT = NewFD->getType()->castAs<FunctionProtoType>();
- bool AnyNoexcept = HasNoexcept(FPT->getReturnType());
- for (QualType T : FPT->param_types())
- AnyNoexcept |= HasNoexcept(T);
- if (AnyNoexcept)
+ if (hasNoexcept(FPT->getReturnType()) ||
+ llvm::any_of(FPT->param_types(),
+ [](QualType Q) { return hasNoexcept(Q); })) {
Diag(NewFD->getLocation(),
diag::warn_cxx17_compat_exception_spec_in_signature)
<< NewFD;
+ }
}
if (!Redeclaration && LangOpts.CUDA)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits