-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[clang] Avoid inheriting [[noreturn]] in explicit function template specializations #150003
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
[clang] Avoid inheriting [[noreturn]] in explicit function template specializations #150003
Conversation
…late specializations
@llvm/pr-subscribers-clang Author: Samarth Narang (snarang181) ChangesThis 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 #145166 Full diff: https://github.com/llvm/llvm-project/pull/150003.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 78f4804202ddc..a61d10c166578 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1970,6 +1970,9 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) {
if (!FD)
return;
+ if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+ return; // Don't infer noreturn for explicit specializations.
+
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..c307bc675c14b 100644
--- a/clang/test/SemaCXX/wreturn-always-throws.cpp
+++ b/clang/test/SemaCXX/wreturn-always-throws.cpp
@@ -44,3 +44,18 @@ 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();
+};
+
+template<typename T>
+void S<T>::f() { throw 0; }
+template<>
+void S<int>::f() {} // expected-no-diagnostics
+
+
|
I think we need to test partial specialization as well. |
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.
Thanks for the fix!
Add -Winvalid-noreturn diagnostic in LIT test
a2125f5
to
4db6e19
Compare
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.
The fix looks good now.
We might still want to revisit the original patch though (#145166 (comment)).
…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
This fixes cases that are broken on the 21.x release branch - see #151742. Therefore, this should probably be backported there. |
/cherry-pick 22fef00 |
/pull-request #151752 |
… specializations. (#151815) Addressing #150003 (comment)
…in explicit specializations. (#151815) Addressing llvm/llvm-project#150003 (comment)
…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)
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 #145166