https://github.com/Nerixyz updated https://github.com/llvm/llvm-project/pull/127623
>From a7924a05880d6f96c27b169a709327275d3eb9f3 Mon Sep 17 00:00:00 2001 From: Nerixyz <nerix...@outlook.de> Date: Tue, 18 Feb 2025 12:56:05 +0100 Subject: [PATCH] [Clang] Warn about `[[noreturn]]` on coroutines --- .../clang/Basic/DiagnosticSemaKinds.td | 3 +++ clang/lib/Sema/AnalysisBasedWarnings.cpp | 8 +++--- clang/lib/Sema/SemaStmt.cpp | 9 +++++-- clang/test/SemaCXX/coroutine-noreturn.cpp | 27 +++++++++++++++++++ 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 clang/test/SemaCXX/coroutine-noreturn.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index f10af8f5bd6b2..ee1ad214d81df 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -10606,6 +10606,9 @@ def warn_noreturn_function_has_return_expr : Warning< def warn_falloff_noreturn_function : Warning< "function declared 'noreturn' should not return">, InGroup<InvalidNoreturn>; +def warn_noreturn_coroutine : Warning< + "coroutine %0 cannot be declared 'noreturn' as it always returns a coroutine handle">, + InGroup<InvalidNoreturn>; def err_noreturn_block_has_return_expr : Error< "block declared 'noreturn' should not return">; def err_carries_dependency_missing_on_first_decl : Error< diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp index 589869d018657..ce7d9be8d2faa 100644 --- a/clang/lib/Sema/AnalysisBasedWarnings.cpp +++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp @@ -697,10 +697,12 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, return; SourceLocation LBrace = Body->getBeginLoc(), RBrace = Body->getEndLoc(); auto EmitDiag = [&](SourceLocation Loc, unsigned DiagID) { - if (IsCoroutine) - S.Diag(Loc, DiagID) << FSI->CoroutinePromise->getType(); - else + if (IsCoroutine) { + if (DiagID != 0) + S.Diag(Loc, DiagID) << FSI->CoroutinePromise->getType(); + } else { S.Diag(Loc, DiagID); + } }; // cpu_dispatch functions permit empty function bodies for ICC compatibility. diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ec38674a2c3e7..389c08768a2ed 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -3910,8 +3910,13 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, FnRetType = FD->getReturnType(); if (FD->hasAttrs()) Attrs = &FD->getAttrs(); - if (FD->isNoReturn()) - Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD; + if (FD->isNoReturn()) { + const FunctionScopeInfo *Scope = getEnclosingFunction(); + if (Scope && Scope->isCoroutine()) + Diag(ReturnLoc, diag::warn_noreturn_coroutine) << FD; + else + Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD; + } if (FD->isMain() && RetValExp) if (isa<CXXBoolLiteralExpr>(RetValExp)) Diag(ReturnLoc, diag::warn_main_returns_bool_literal) diff --git a/clang/test/SemaCXX/coroutine-noreturn.cpp b/clang/test/SemaCXX/coroutine-noreturn.cpp new file mode 100644 index 0000000000000..bb23e2adcd5c6 --- /dev/null +++ b/clang/test/SemaCXX/coroutine-noreturn.cpp @@ -0,0 +1,27 @@ +// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -Winvalid-noreturn -verify + +#include "Inputs/std-coroutine.h" + +struct Promise; + +struct Awaitable { + bool await_ready(); + void await_suspend(std::coroutine_handle<>); + void await_resume(); +}; + +struct Coro : std::coroutine_handle<> { + using promise_type = Promise; +}; + +struct Promise { + Coro get_return_object(); + std::suspend_always initial_suspend() noexcept; + std::suspend_always final_suspend() noexcept; + void return_void(); + void unhandled_exception(); +}; + +[[noreturn]] Coro test() { // expected-warning {{coroutine 'test' cannot be declared 'noreturn' as it always returns a coroutine handle}} + co_await Awaitable{}; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits