-
Notifications
You must be signed in to change notification settings - Fork 14.7k
release/21.x: [clang] Avoid inheriting [[noreturn]] in explicit function template specializations (#150003) #151752
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@alexfh What do you think about merging this PR to the release branch? |
@llvm/pr-subscribers-clang Author: None (llvmbot) ChangesBackport 22fef00 Requested by: @mstorsjo Full diff: https://github.com/llvm/llvm-project/pull/151752.diff 3 Files Affected:
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 14403e65e8f42..bb412ef6788e7 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -3267,6 +3267,14 @@ void Sema::mergeDeclAttributes(NamedDecl *New, Decl *Old,
if (isa<UsedAttr>(I) || isa<RetainAttr>(I))
continue;
+ if (isa<InferredNoReturnAttr>(I)) {
+ if (auto *FD = dyn_cast<FunctionDecl>(New)) {
+ if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+ continue; // Don't propagate inferred noreturn attributes to explicit
+ // specializations.
+ }
+ }
+
if (mergeDeclAttribute(*this, New, I, LocalAMK))
foundAny = true;
}
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index eff5f9568236a..a7897bdfe6e0f 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1970,6 +1970,13 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) {
if (!FD)
return;
+ // Skip explicit specializations here as they may have
+ // a user-provided definition that may deliberately differ from the primary
+ // template. If an explicit specialization truly never returns, the user
+ // should explicitly mark it with [[noreturn]].
+ if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+ return;
+
auto *NonConstFD = const_cast<FunctionDecl *>(FD);
DiagnosticsEngine &Diags = S.getDiagnostics();
if (Diags.isIgnored(diag::warn_falloff_nonvoid, FD->getLocation()) &&
diff --git a/clang/test/SemaCXX/wreturn-always-throws.cpp b/clang/test/SemaCXX/wreturn-always-throws.cpp
index addcadd1183dc..df7689f7063cc 100644
--- a/clang/test/SemaCXX/wreturn-always-throws.cpp
+++ b/clang/test/SemaCXX/wreturn-always-throws.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wreturn-type -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wreturn-type -Winvalid-noreturn -verify %s
// expected-no-diagnostics
namespace std {
@@ -44,3 +44,22 @@ void testTemplates() {
throwErrorTemplate("ERROR");
(void)ensureZeroTemplate(42);
}
+
+// Ensure that explicit specialization of a member function does not inherit
+// the warning from the primary template.
+
+template<typename T>
+struct S {
+ void f();
+ void g();
+};
+
+template<typename T>
+void S<T>::f() { throw 0; }
+template<>
+void S<int>::f() {}
+
+template<typename T>
+void S<T>::g() {}
+template<>
+void S<int>::g() { throw 0; }
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
but main could be improved with an nfc commit
#150003 (review)
…pecializations (llvm#150003) This patch fixes incorrect behavior in Clang where [[noreturn]] (either spelled or inferred) was being inherited by explicit specializations of function templates or member function templates, even when those specializations returned normally. Follow up on llvm#145166 (cherry picked from commit 22fef00)
@mstorsjo (or anyone else). If you would like to add a note about this fix in the release notes (completely optional). Please reply to this comment with a one or two sentence description of the fix. When you are done, please add the release:note label to this PR. |
Backport 22fef00
Requested by: @mstorsjo