[clang] [clang] [Sema] Suggest [[noreturn]] for void functions that always throw (PR #146234)
Samarth Narang via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 30 07:04:28 PDT 2025
https://github.com/snarang181 updated https://github.com/llvm/llvm-project/pull/146234
>From 588ae1c6c4b965a6cd57044284845a62c75da9c2 Mon Sep 17 00:00:00 2001
From: Samarth Narang <snarang at umass.edu>
Date: Sat, 28 Jun 2025 15:31:37 -0400
Subject: [PATCH 1/3] Emit a suggestion to explicitly mark the function with
[[noreturn]] if -Wmissing-noreturn is enabled.
---
clang/docs/ReleaseNotes.rst | 3 +--
clang/lib/Sema/SemaDeclAttr.cpp | 7 ++++++
.../SemaCXX/wmissing-noreturn-suggestion.cpp | 23 +++++++++++++++++++
3 files changed, 31 insertions(+), 2 deletions(-)
create mode 100644 clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index d9847fadc21e5..73a2618bb580c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -654,9 +654,8 @@ Improvements to Clang's diagnostics
a call to a function that is trivially known to always throw (i.e., its
body consists solely of a `throw` statement). This avoids certain
false positives in exception-heavy code, though only simple patterns
- are currently recognized.
+ are currently recognized. Additionally, if -Wmissing-noreturn is enabled, emit a suggestion to explicitly mark the function with [[noreturn]].
-
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 52313e6a15ff1..e7da8e673a9ec 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1979,6 +1979,13 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) {
if (!FD->hasAttr<NoReturnAttr>() && !FD->hasAttr<InferredNoReturnAttr>() &&
isKnownToAlwaysThrow(FD)) {
NonConstFD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context));
+
+ // Conditionally, emit the suggestion warning.
+ if (!Diags.isIgnored(diag::warn_suggest_noreturn_function,
+ FD->getLocation())) {
+ S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function)
+ << 0 << FD;
+ }
}
}
diff --git a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
new file mode 100644
index 0000000000000..7548ba8904a71
--- /dev/null
+++ b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -fexceptions -Wreturn-type -Wmissing-noreturn -verify %s
+
+namespace std {
+ class string {
+ public:
+ string(const char*);
+ };
+ class runtime_error {
+ public:
+ runtime_error(const string&);
+ };
+}
+
+// This function always throws. Suggest [[noreturn]].
+void throwError(const std::string& msg) { // expected-warning {{function 'throwError' could be declared with attribute 'noreturn'}}
+ throw std::runtime_error(msg);
+}
+
+// The non-void caller should not warn about missing return.
+int ensureZero(int i) {
+ if (i == 0) return 0;
+ throwError("ERROR"); // no-warning
+}
>From 8a0e8f8b12366048b69aa90d1ec0061de62cee73 Mon Sep 17 00:00:00 2001
From: Samarth Narang <snarang at umass.edu>
Date: Sun, 29 Jun 2025 11:15:34 -0400
Subject: [PATCH 2/3] Remove condition for emitting noreturn suggestion
---
clang/lib/Sema/SemaDeclAttr.cpp | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index e7da8e673a9ec..71b8347f4b890 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1980,12 +1980,8 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) {
isKnownToAlwaysThrow(FD)) {
NonConstFD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context));
- // Conditionally, emit the suggestion warning.
- if (!Diags.isIgnored(diag::warn_suggest_noreturn_function,
- FD->getLocation())) {
- S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function)
- << 0 << FD;
- }
+ // Emit a diagnostic suggesting the function being marked [[noreturn]].
+ S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function) << 0 << FD;
}
}
>From 3f02a489166909a9ed02595547b765b986c33869 Mon Sep 17 00:00:00 2001
From: Samarth Narang <samanara at qti.qualcomm.com>
Date: Mon, 30 Jun 2025 07:02:05 -0700
Subject: [PATCH 3/3] Add inline comment to clarify the purpose of the argument
---
clang/lib/Sema/SemaDeclAttr.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 71b8347f4b890..c5d5d03cc99c7 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1981,7 +1981,8 @@ void clang::inferNoReturnAttr(Sema &S, const Decl *D) {
NonConstFD->addAttr(InferredNoReturnAttr::CreateImplicit(S.Context));
// Emit a diagnostic suggesting the function being marked [[noreturn]].
- S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function) << 0 << FD;
+ S.Diag(FD->getLocation(), diag::warn_suggest_noreturn_function)
+ << /*isFunction=*/0 << FD;
}
}
More information about the cfe-commits
mailing list