Skip to content

Commit 74d55f9

Browse files
committed
[Clang] Warn about [[noreturn]] on coroutines
1 parent 6273877 commit 74d55f9

File tree

3 files changed

+32
-2
lines changed

3 files changed

+32
-2
lines changed

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10606,6 +10606,9 @@ def warn_noreturn_function_has_return_expr : Warning<
1060610606
def warn_falloff_noreturn_function : Warning<
1060710607
"function declared 'noreturn' should not return">,
1060810608
InGroup<InvalidNoreturn>;
10609+
def warn_noreturn_coroutine : Warning<
10610+
"coroutines cannot be declared 'noreturn' as they always return a coroutine handle">,
10611+
InGroup<InvalidNoreturn>;
1060910612
def err_noreturn_block_has_return_expr : Error<
1061010613
"block declared 'noreturn' should not return">;
1061110614
def err_carries_dependency_missing_on_first_decl : Error<

clang/lib/Sema/AnalysisBasedWarnings.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -588,10 +588,10 @@ struct CheckFallThroughDiagnostics {
588588
static CheckFallThroughDiagnostics MakeForCoroutine(const Decl *Func) {
589589
CheckFallThroughDiagnostics D;
590590
D.FuncLoc = Func->getLocation();
591-
D.diag_MaybeFallThrough_HasNoReturn = 0;
591+
D.diag_MaybeFallThrough_HasNoReturn = diag::warn_noreturn_coroutine;
592592
D.diag_MaybeFallThrough_ReturnsNonVoid =
593593
diag::warn_maybe_falloff_nonvoid_coroutine;
594-
D.diag_AlwaysFallThrough_HasNoReturn = 0;
594+
D.diag_AlwaysFallThrough_HasNoReturn = diag::warn_noreturn_coroutine;
595595
D.diag_AlwaysFallThrough_ReturnsNonVoid =
596596
diag::warn_falloff_nonvoid_coroutine;
597597
D.diag_NeverFallThroughOrReturn = 0;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -Winvalid-noreturn -verify
2+
3+
#include "Inputs/std-coroutine.h"
4+
5+
struct Promise;
6+
7+
struct Awaitable {
8+
bool await_ready();
9+
void await_suspend(std::coroutine_handle<>);
10+
void await_resume();
11+
};
12+
13+
struct Coro : std::coroutine_handle<> {
14+
using promise_type = Promise;
15+
};
16+
17+
struct Promise {
18+
Coro get_return_object();
19+
std::suspend_always initial_suspend() noexcept;
20+
std::suspend_always final_suspend() noexcept;
21+
void return_void();
22+
void unhandled_exception();
23+
};
24+
25+
[[noreturn]] Coro test() { // expected-warning {{function 'test' declared 'noreturn' should not return}}
26+
co_await Awaitable{};
27+
} // expected-warning {{coroutines cannot be declared 'noreturn' as they always return a coroutine handle}}

0 commit comments

Comments
 (0)