<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/78290>78290</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
link error when compiling coroutine code.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang,
c++20,
coroutines
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
hokein
</td>
</tr>
</table>
<pre>
See https://godbolt.org/z/rc37E78EM for a minimal testcase.
The following code is compiled with gcc, but clang emits a link error (`in function Foo::CoroutineBody(): <source>:60: undefined reference to CoroutinePromise<void>::CoroutinePromise<Foo&>(Foo&)`) when linking to a binary. We seem to miss a symbol.
```cpp
#include <coroutine>
template <typename Final>
class Gen;
template <typename Final>
class CoroutinePromise final {
public:
template <typename... Args>
explicit CoroutinePromise(Args&&... args) {}
Gen<Final> get_return_object() { return Gen<Final>(my_handle()); }
std::coroutine_handle<CoroutinePromise> my_handle() {
return std::coroutine_handle<CoroutinePromise>::from_promise(*this);
}
void unhandled_exception() {}
void return_void() {}
template <typename U>
auto await_transform(Gen<U> gen) {
struct Awaitable {
bool await_ready() { return false; }
std::coroutine_handle<> await_suspend(
const std::coroutine_handle<> handle_in) {
return handle_in;
}
decltype(auto) await_resume() {}
};
return Awaitable();
}
std::suspend_always initial_suspend() { return {}; }
std::suspend_always final_suspend() noexcept { return {}; }
};
template <typename Final>
class Gen final {
public:
using final_result_type = Final;
using promise_type =CoroutinePromise<Final>;
explicit Gen(const std::coroutine_handle<promise_type> handle)
: handle_(handle) {}
std::coroutine_handle<promise_type> handle_;
};
class Foo {
public:
Gen<void> TestBody2() {
auto s =
[&]() -> Gen<void> { co_await this->CoroutineBody(); co_return; };
return s();
}
private:
Gen<void> CoroutineBody();
};
Gen<void> Foo ::CoroutineBody() {
if constexpr (0) // remove it will make clang compile.
co_await []() -> Gen<void> { co_return; }();
}
int main() {
return 0;
}
```
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJycVkuP4jgQ_jXmUhoUHALhwIFHs6eVVtoZ7TFynAp4x7Ej22ma_fUrx0kIr27NoBZNnKqvqr56uJi14qgQ1yTZkmQ_YY07abM-6Z8o1CTXxWX9NyKcnKstiTeEHgg9HHWRa-mm2hwJPfxH6MHwePm2TN_-hFIbYFAJJSomwaF1nFmckmhPok34_n5CKLWU-izUEbguEIQFrqtaSCzgLNwJjpwTuoO8ccAlU0fASjgLDKRQPwGN0QYITckiEgrKRnEntIKD1t7JeLPTRjdOKNzq4uLl6IrEGyDxzurGcCTxG4k3i8gfNqrAUigswGCJBhVHcBoGiL-MroRFEu_etSiC5tjE9b03Txdegqbdb7oii4jQFZxPqFrnfcxOA4NcKGYuU_gHwSJW_rAS1sdoL1Wu5Q1n3fciCn-8rrsTGgvFZVOgD473PnkfRnoOq1oy18q4S42KVQgHoZgcBLlk1sIfqEi8_S3Vez6g9EJAlh0c1E0uBffkhWd4Bj2dTmFjjnYAB8CPWgou3GNGaNqKepoXXpG1T6vW5nI_jiIEtuv9hiO6zKBrjMp0_i9yF2rEa0I4v9MgNK0u2YmpQmJXT76ktnBvyLoi1MeQi14r3j2WzBvcoY74Auhd-UXMIFsaXWX1wBShG3cSNnjdWxicB1_a0KgAW2T4wbH2LTXyapANwh19bU88Cn2WY_gxyi5rfDOcmXCZM0zZUpuK0DSw_yPkSj0QY51puION12O5xNu3ALnWskM1yPoRME5vyaQna5TAT2n2jgQ829gaVRvzyKD_cK2s-xIlPGTiMahRxq9CQ7JG_PtPgVx6QglNPYUerI_XNhU-zVtIePxYYAOP_ah8rJD-YAiv4yFj8swuFoQSTjA5pueW8M6VG8ZforWz4w5L6VCVX4COQ_zdGfj17Gqsn-PBTc-4dJkHBRLve9DtrWzXioPYs_uj9-aqOww_3xA0_brExmau5eaTOioef-11JUZoOog87eBfN5b5fMCrbASSD1rDZ_yG_u8uXPiO1vmbnD4bku0EsS3zfaskW38pJPtO_JvHuEX0NcR11rYM-MHoZZ5uDa1cKLe-zob09PP5ddtAbcQ7c_gytOc2X5F3q-tJfLnvjEkSZRhO-FG3a1O7kYRdDgxW-h1BODgLKaFiP7FbubqNbHqlemAsbItf0ntL22Nwo8iEclAxoR6d70iOnmj269AYaFKs42IVr9gE17NllMxnySxOJqc1Ukxn-Xwex4uELVmSp7N5xHjMkpznrEgmYk0jOo9ms8VsTpM4mS5XZV6mBceoXKbRqiDzCCsm5FTK98pvvxNhbYPrZUpX0USyHKVtF2lKWwYJpYTu_BOhW0K3NLqe9Amz_ijZT8zag37Lm6Ml80gK6-zVjBNO4nq0-rbbZMhP2KE7tHabnk4aI9d3K7twpyafcl0RevC43b9vtdFh_zm0sVhCD204_wcAAP__2R6azQ">