[clang] [Clang] suppress -Wmissing-noreturn for virtual methods with throw-only bodies (PR #167523)
Oleksandr T. via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 14 08:51:55 PST 2025
https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/167523
>From 390454f7d1f0ce899b7ef11cce39f446bc98f3f1 Mon Sep 17 00:00:00 2001
From: Oleksandr Tarasiuk <oleksandr.tarasiuk at outlook.com>
Date: Tue, 11 Nov 2025 17:26:54 +0200
Subject: [PATCH] [Clang] suppress -Wmissing-noreturn for virtual methods with
throw-only bodies
---
clang/docs/ReleaseNotes.rst | 2 ++
clang/lib/Sema/SemaDeclAttr.cpp | 12 ++++++++--
.../SemaCXX/wmissing-noreturn-suggestion.cpp | 23 +++++++++++++++++++
3 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 980dbf1ff2cf6..e847af0dbbadf 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -417,6 +417,8 @@ Improvements to Clang's diagnostics
or continue (#GH166013)
- Clang now emits a diagnostic in case `vector_size` or `ext_vector_type`
attributes are used with a negative size (#GH165463).
+- Clang no longer emits ``-Wmissing-noreturn`` for virtual methods where
+ the function body consists of a `throw` expression (#GH167247).
Improvements to Clang's time-trace
----------------------------------
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index a9e7b44ac9d73..32707925b951c 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1966,8 +1966,16 @@ static bool isKnownToAlwaysThrow(const FunctionDecl *FD) {
if (const auto *EWC = dyn_cast<ExprWithCleanups>(OnlyStmt)) {
OnlyStmt = EWC->getSubExpr();
}
- // Check if the only statement is a throw expression.
- return isa<CXXThrowExpr>(OnlyStmt);
+
+ if (isa<CXXThrowExpr>(OnlyStmt)) {
+ const auto *MD = dyn_cast<CXXMethodDecl>(FD);
+ if (MD && MD->isVirtual()) {
+ const auto *RD = MD->getParent();
+ return MD->hasAttr<FinalAttr>() || (RD && RD->isEffectivelyFinal());
+ }
+ return true;
+ }
+ return false;
}
void clang::inferNoReturnAttr(Sema &S, const Decl *D) {
diff --git a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
index 06db972118d1c..2520c97cd0aee 100644
--- a/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
+++ b/clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
@@ -53,3 +53,26 @@ int gnu_throws() {
int cxx11_throws() {
throw 0;
}
+
+namespace GH167247 {
+struct S1 {
+ virtual ~S1() = default;
+ virtual void m() {
+ throw std::runtime_error("This method always throws");
+ }
+};
+
+struct S2 {
+ virtual ~S2() = default;
+
+ virtual void m() final { // expected-warning {{function 'm' could be declared with attribute 'noreturn'}}
+ throw std::runtime_error("This method always throws");
+ }
+};
+
+struct S3 final : S1 {
+ void m() { // expected-warning {{function 'm' could be declared with attribute 'noreturn'}}
+ throw std::runtime_error("This method always throws");
+ }
+};
+}
More information about the cfe-commits
mailing list