| Issue |
56470
|
| Summary |
[bug] clang doesn't implement co_yield transformation correctly (can't defer to co_await support)
|
| Labels |
new issue
|
| Assignees |
|
| Reporter |
jacobsa
|
In N4868, [[expr.yield]/1](https://timsong-cpp.github.io/cppwp/n4868/expr.yield#1) says that `co_yield`ing an _expression_ `e` is equivalent to `co_await`ing the result of calling `yield_value(e)` on the coroutine's promise:
> A *yield-_expression_* shall appear only within a suspension context of a function ([expr.await]). Let *e* be the operand of the *yield-_expression_* and *p* be an lvalue naming the promise object of the enclosing coroutine ([dcl.fct.def.coroutine]), then the *yield-_expression_* is equivalent to the _expression_ `co_await` *p*`.yield_value(`*e*`)`.
Here is a minimal program that attempts to make use of this property, by returning a type that the promise supports `co_await`ing from its `yield_value` method ([Compiler Explorer](https://godbolt.org/z/r1sar6sP1)):
```c++
#include <coroutine>
// A type that the promise supports awaiting.
struct SomeAwaitableType {};
struct MyTask{
struct promise_type {
MyTask get_return_object() { return {}; }
std::suspend_never initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
void unhandled_exception();
// We support co_await'ing objects of type SomeAwaitableType.
std::suspend_always await_transform(SomeAwaitableType);
// We support yielding ints, and reuse our support for co_await'ing
// SomeAwaitableType to implement this.
auto yield_value(int) { return SomeAwaitableType{}; }
};
};
MyTask CoAwait() {
co_await SomeAwaitableType();
}
MyTask CoYield() {
co_yield 0;
}
```
Clang doesn't transform this correctly, instead giving an error about how `SomeAwaitableType` doesn't have an `await_ready` method:
```
<source>:27:3: error: no member named 'await_ready' in 'SomeAwaitableType'
co_yield 0;
^~~~~~~~
```
It appears that the result of `co_yield` isn't correctly fed to `await_transform`, and is instead treated as if it's the output of a previous call to `await_transform`.
_______________________________________________
llvm-bugs mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs