llvm-project/clang/test/SemaCXX/coroutine-unevaluate.cpp
NewSigma 0cc8a63d0c
Forbid co_await and co_yield in invalid expr contexts (#130455)
Fix #78426 

C++26 introduced braced initializer lists as template arguments.
However, such contexts should be considered invalid for co_await and
co_yield. This commit explicitly rules out the possibility of using
these exprs in template arguments.

---------

Co-authored-by: cor3ntin <corentinjabot@gmail.com>
2025-03-10 16:59:44 +01:00

43 lines
1.3 KiB
C++

// RUN: %clang_cc1 %s -std=c++20 -fsyntax-only -verify
#include "Inputs/std-coroutine.h"
struct MyTask{
struct promise_type {
MyTask get_return_object();
std::suspend_always initial_suspend() { return {}; }
void unhandled_exception();
void return_void();
auto final_suspend() noexcept {
struct Awaiter {
bool await_ready() noexcept { return false; }
std::coroutine_handle<promise_type> await_suspend(std::coroutine_handle<promise_type> h) noexcept;
void await_resume() noexcept;
};
return Awaiter{};
}
// The coroutine to resume when we're done.
std::coroutine_handle<promise_type> resume_when_done;
};
};
MyTask DoSomething() {
static_assert(__is_same(void, decltype(co_await 0))); // expected-error {{'co_await' cannot be used in an unevaluated context}}
co_return;
}
MyTask DoAnotherthing() {
static_assert(__is_same(void, decltype(co_yield 0))); // expected-error {{'co_yield' cannot be used in an unevaluated context}}
co_return;
}
template<class>
struct Task {};
void BracedInitListCXX26() {
[]() -> Task<{ co_await 1 }> {}; // expected-error {{'co_await' cannot be used in an unevaluated context}}
[]() -> Task<{ co_yield 1 }> {}; // expected-error {{'co_yield' cannot be used in an unevaluated context}}
}