Skip to content

Commit 93d759c

Browse files
authored
[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"); } }; ```
1 parent 4f3d68a commit 93d759c

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,8 @@ Improvements to Clang's diagnostics
434434
or continue (#GH166013)
435435
- Clang now emits a diagnostic in case `vector_size` or `ext_vector_type`
436436
attributes are used with a negative size (#GH165463).
437+
- Clang no longer emits ``-Wmissing-noreturn`` for virtual methods where
438+
the function body consists of a `throw` expression (#GH167247).
437439

438440
Improvements to Clang's time-trace
439441
----------------------------------

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,8 +1966,16 @@ static bool isKnownToAlwaysThrow(const FunctionDecl *FD) {
19661966
if (const auto *EWC = dyn_cast<ExprWithCleanups>(OnlyStmt)) {
19671967
OnlyStmt = EWC->getSubExpr();
19681968
}
1969-
// Check if the only statement is a throw expression.
1970-
return isa<CXXThrowExpr>(OnlyStmt);
1969+
1970+
if (isa<CXXThrowExpr>(OnlyStmt)) {
1971+
const auto *MD = dyn_cast<CXXMethodDecl>(FD);
1972+
if (MD && MD->isVirtual()) {
1973+
const auto *RD = MD->getParent();
1974+
return MD->hasAttr<FinalAttr>() || (RD && RD->isEffectivelyFinal());
1975+
}
1976+
return true;
1977+
}
1978+
return false;
19711979
}
19721980

19731981
void clang::inferNoReturnAttr(Sema &S, const Decl *D) {

clang/test/SemaCXX/wmissing-noreturn-suggestion.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,26 @@ int gnu_throws() {
5353
int cxx11_throws() {
5454
throw 0;
5555
}
56+
57+
namespace GH167247 {
58+
struct S1 {
59+
virtual ~S1() = default;
60+
virtual void m() {
61+
throw std::runtime_error("This method always throws");
62+
}
63+
};
64+
65+
struct S2 {
66+
virtual ~S2() = default;
67+
68+
virtual void m() final { // expected-warning {{function 'm' could be declared with attribute 'noreturn'}}
69+
throw std::runtime_error("This method always throws");
70+
}
71+
};
72+
73+
struct S3 final : S1 {
74+
void m() { // expected-warning {{function 'm' could be declared with attribute 'noreturn'}}
75+
throw std::runtime_error("This method always throws");
76+
}
77+
};
78+
}

0 commit comments

Comments
 (0)