[clang] [clang] [Sema] Suggest [[noreturn]] for void functions that always throw (PR #146234)
Samarth Narang via cfe-commits
cfe-commits at lists.llvm.org
Sat Jun 28 12:34:02 PDT 2025
https://github.com/snarang181 created https://github.com/llvm/llvm-project/pull/146234
Fixes https://github.com/llvm/llvm-project/issues/146223.
>From 6f450c2686e4c4900234ac9aae9dd085966eff64 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] 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 | 6 +++++
.../SemaCXX/wmissing-noreturn-suggestion.cpp | 23 +++++++++++++++++++
3 files changed, 30 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..cadaddc2d5b6d 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1979,6 +1979,12 @@ 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
+}
More information about the cfe-commits
mailing list