[clang] 93d759c - [Clang] suppress -Wmissing-noreturn for virtual methods with throw-only bodies (#167523)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 19 07:35:52 PST 2025
Author: Oleksandr T.
Date: 2025-11-19T17:35:47+02:00
New Revision: 93d759ce5a63cf74882087bad020825764043381
URL: https://github.com/llvm/llvm-project/commit/93d759ce5a63cf74882087bad020825764043381
DIFF: https://github.com/llvm/llvm-project/commit/93d759ce5a63cf74882087bad020825764043381.diff
LOG: [Clang] suppress -Wmissing-noreturn for virtual methods with throw-only bodies (#167523)
Fixes #167247
---
This PR addresses a case where Clang emitted `-Wmissing-noreturn` for
virtual methods whose body consists of a `throw` expression
```cpp
struct Base {
virtual void foo() {
throw std::runtime_error("error");
}
};
```
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index c2da61e4d066a..f8a8fc3c0f450 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -434,6 +434,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 bda7aa32a9348..c093052cf4035 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