[clang] [clang] Make error for [[clang::coro_wrapper]] be downgradable to a warning (PR #172910)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 9 11:53:06 PST 2026
https://github.com/higher-performance updated https://github.com/llvm/llvm-project/pull/172910
>From 1bdfef90e07ae367adab4ddc94004c0cc653b748 Mon Sep 17 00:00:00 2001
From: higher-performance <higher.performance.github at gmail.com>
Date: Thu, 18 Dec 2025 16:50:59 -0500
Subject: [PATCH] [clang] Make error for [[clang::coro_wrapper]] be
downgradable to a warning
Given that both -Wreturn-type and -Wdangling are already warnings and not hard errors, it makes sense for this diagnostic to behave similarly.
This allows suppressing benign occurrences of the error in external headers whose source code is not in the user's direct control.
---
clang/include/clang/Basic/DiagnosticSemaKinds.td | 6 +++---
clang/lib/Sema/SemaDecl.cpp | 2 +-
.../SemaCXX/coro-return-type-and-wrapper.cpp | 16 ++++++++--------
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f3c13841c4bf0..1b299bf459657 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -12743,10 +12743,10 @@ def err_conflicting_aligned_options : Error <
def err_coro_invalid_addr_of_label : Error<
"the GNU address of label extension is not allowed in coroutines"
>;
-def err_coroutine_return_type : Error<
+def warn_coroutine_return_type : Warning<
"function returns a type %0 marked with [[clang::coro_return_type]] but is neither a coroutine nor a coroutine wrapper; "
- "non-coroutines should be marked with [[clang::coro_wrapper]] to allow returning coroutine return type"
->;
+ "non-coroutines should be marked with [[clang::coro_wrapper]] to allow returning coroutine return type">,
+ DefaultError;
def warn_coroutine_type_aware_allocator_ignored : Warning <
"type aware %0 will not be used for coroutine allocation">,
InGroup<CoroTypeAwareAllocationFunction>;
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6505bb6e5f7ed..c77f0e1c42cbb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -16440,7 +16440,7 @@ void Sema::CheckCoroutineWrapper(FunctionDecl *FD) {
if (CanBeGetReturnObject(FD) || CanBeGetReturnTypeOnAllocFailure(FD))
return;
if (!FD->hasAttr<CoroWrapperAttr>())
- Diag(FD->getLocation(), diag::err_coroutine_return_type) << RD;
+ Diag(FD->getLocation(), diag::warn_coroutine_return_type) << RD;
}
Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, bool IsInstantiation,
diff --git a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
index b08e1c9c065a0..3d88f181b5946 100644
--- a/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
+++ b/clang/test/SemaCXX/coro-return-type-and-wrapper.cpp
@@ -44,7 +44,7 @@ Gen<int> foo_coro(int b) { co_return b; }
[[clang::coro_wrapper]] Gen<int> marked_wrapper1(int b) { return foo_coro(b); }
-// expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+// expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
Gen<int> non_marked_wrapper(int b) { return foo_coro(b); }
namespace using_decl {
@@ -52,7 +52,7 @@ template <typename T> using Co = Gen<T>;
[[clang::coro_wrapper]] Co<int> marked_wrapper1(int b) { return foo_coro(b); }
-// expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+// expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
Co<int> non_marked_wrapper(int b) { return foo_coro(b); }
} // namespace using_decl
@@ -62,7 +62,7 @@ void foo() {
auto coro_lambda = []() -> Gen<int> {
co_return 1;
};
- // expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+ // expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
auto not_allowed_wrapper = []() -> Gen<int> {
return foo_coro(1);
};
@@ -72,7 +72,7 @@ void foo() {
}
Gen<int> coro_containing_lambda() {
- // expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+ // expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
auto wrapper_lambda = []() -> Gen<int> {
return foo_coro(1);
};
@@ -89,7 +89,7 @@ class function<ReturnValue(Args...)> {
public:
template <typename T> function &operator=(T) {}
template <typename T> function(T) {}
- // expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+ // expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
ReturnValue operator()(Args... args) const {
return callable_->Invoke(args...); // expected-note {{in instantiation of member}}
}
@@ -97,7 +97,7 @@ class function<ReturnValue(Args...)> {
private:
class Callable {
public:
- // expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+ // expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
ReturnValue Invoke(Args...) const { return {}; }
};
Callable* callable_;
@@ -106,7 +106,7 @@ class function<ReturnValue(Args...)> {
void use_std_function() {
std::function<int(bool)> foo = [](bool b) { return b ? 1 : 2; };
- // expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+ // expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
std::function<Gen<int>(bool)> test1 = [](bool b) {
return foo_coro(b);
};
@@ -137,5 +137,5 @@ template<> class coroutine_traits<Task, int> {
using promise_type = my_promise_type;
};
} // namespace std
-// expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+// expected-warning at +1 {{neither a coroutine nor a coroutine wrapper}}
Task foo(int) { return Task{}; }
More information about the cfe-commits
mailing list