<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/143235>143235</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
Invalid exception object catch from nested lambda coroutines with clang 20.1.0 on windows
</td>
</tr>
<tr>
<th>Labels</th>
<td>
clang
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
ShirenY
</td>
</tr>
</table>
<pre>
The code below will trigger the **assert(err == message)** on windows with clang 20.1.0. While it will pass with gcc and msvc. Also the clang on linux does not have this issue.
This issue looks like https://github.com/llvm/llvm-project/issues/59723, which should had be fixed on the 20.1.0.
```
#include <cassert>
#include <coroutine>
#include <exception>
#include <iostream>
#include <stdexcept>
#include <string>
struct Task
{
struct promise_type;
using handle_type = std::coroutine_handle<promise_type>;
struct promise_type
{
std::exception_ptr exception;
handle_type continuation;
Task get_return_object()
{
return Task{handle_type::from_promise(*this)};
}
std::suspend_always initial_suspend() noexcept
{
return {};
}
auto final_suspend() noexcept
{
struct FinalAwaiter
{
bool await_ready() noexcept
{
return false;
}
void await_resume() noexcept
{
}
std::coroutine_handle<> await_suspend(handle_type h) noexcept
{
auto& promise = h.promise();
return promise.continuation ? std::coroutine_handle<>(promise.continuation) : std::noop_coroutine();
}
};
return FinalAwaiter{};
}
void unhandled_exception()
{
exception = std::current_exception();
}
void return_void()
{
}
};
handle_type handle;
explicit Task(handle_type h) : handle(h)
{
}
~Task()
{
if (handle)
handle.destroy();
}
bool await_ready() const noexcept
{
return false;
}
handle_type await_suspend(std::coroutine_handle<> continuation) noexcept
{
handle.promise().continuation =
handle_type::from_address(continuation.address());
return handle;
}
void await_resume()
{
rethrowIfAny();
}
void start()
{
if (handle && !handle.done())
{
handle.resume();
}
}
void rethrowIfAny()
{
if (handle.promise().exception)
{
// auto except = handle.promise().exception;
// handle.promise().exception = nullptr;
std::rethrow_exception(handle.promise().exception);
}
}
};
int main()
{
constexpr static char message[] = "test a very long message ~~~~~~~";
auto taskLambda = [&]() -> Task {
try
{
co_await []() -> Task {
co_await []() -> Task {
throw std::runtime_error(message);
}();
}();
}
catch (std::runtime_error e)
{
const std::string err = e.what();
std::cout << err << std::endl;
assert(err == message);
}
};
Task task = taskLambda();
task.start();
return 0;
}
```
Below is the command line execution record.
```
C:\Users\YXX\source\repos\TestNestedCoroutine>clang++ --version
clang version 20.1.0
Target: x86_64-pc-windows-msvc
Thread model: posix
InstalledDir: C:\Program Files\LLVM\bin
C:\Users\YXX\source\repos\TestNestedCoroutine>clang++ -std=c++20 -O0 -g -o test.exe TestNestedCoroutine.cpp
C:\Users\YXX\source\repos\TestNestedCoroutine>test.exe
Unknown exception
Assertion failed: err == message, file TestNestedCoroutine.cpp, line 124
```
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJysWEuP6joS_jVmUyIKDo9mwSINp6UjnXlI03fm3hUySUE87diR7QC9ub995MQQBwJ95sxYLTXxo-qrqq8qrjBj-EEirsjslcw2I1bbQunVPwquUf4x2qn8c_VeIGQqR9ihUCc4cSHAan44oAZbIBCaEpoyY1BbQl9QayDJhiQbKNEYdkBCl-0eUBJOXObqZODEbQGZYPIANI4mURzBvwouELhtVVTM-F2HLAMmcyjNMYsgFUY1etvDSoLgsj5DrtCAVBYKdkSwBTfAjakxAhKn79dHEEp9GBD8A6GwtjIkSQl9I_TtwG1R76JMlYS-CXG8_BtXWv0bM0voWyPBEPo2Wy5oQugaTgXPCjCFqkUOBcthh7DnZ8wdMIfSG0fi1P3NY_8Xp4QmXGaizhFIss68_5Jv90tKq9pyiUOLeM6wslzJoUWujNXIyqE1Y_P27PCi5vLgV-LUWF1nFt6Z-XATi1cSpwAAfr7SquQGt_azQpJcFmvD5QEKJnPRLjlWgLG5c3iSXq3atltIsu7L-daKeqKqXfFwroKvHtlWVkPgnwswN0JYfmRKWi5r1m12-53NcEC71WhrLbdq11LhxZG6k9f55DLa_a3PFq-BvhblXqty661ppKWOsU7oYtOH6iZaLFcTTW0qlPmWiRP7NMAlt5yJrZ9uwYFUPr4_gdItDOu9PLHaKthz-V-o8SF7c4fSE-MW9Y32ezxu7JQSwNyBrUaWfz5W9FxOYN-eCXOhZufPm3FUPL_qNXWJP634ochnbCfJN6-tc2hIy-LndLvAEDq_ZEaTZEUUMmvZj-uAe_zuKEwBIMnbV_gJfRk66oCTJOCrVKradmUsBNVnGXje3QH2QHtcCjl7F4EmmLVs0ebbrgx8nbnXvTcFq9Yapb0T9SBZQxy-drjfnf6-4s4PV6P8c48T3vnBMp4rwTPuq_MAhVwk_Dn6UnTGd_p7oP_0cu428j1cxfdd2KGMcjRWq89b1_Q0PMjvTEljbwnfd9JANt8KD82_za6vsvGWw8NYvKW9DLvNnE238bbmszzXaAyhL-GZqJtubks3tPKGh-Hvm_2gdj3yYqHV6fs-lU8C1Ug0lmn7RFTICSB07goRoZMLGdQ12YdSzu_q4X3wBrq3dcCIh2y9iVWQwM8LQXstbF997aG2uj4Xele7vJjnxxrJshaistqLuNLV29qrPF9bNuRK78egwnBpoWS8q4udG5qExHOlHQ0szyArmL7e6Zt-oUFNKLVoLDA4ov4EoeThsgv-bAehtFe0GpdaZj5-sHKXs1bM7NUxaLbx9WDsUrK5fnlIVn8-DVemtk0GQIvtkZib8Wun3GiCEkSplpaXuEWtlSb0JWh-uoR98D5-sNR_OWbMZgWEdaynEvArPrcVtrtFNpd88P0aYHQqmH2EMKidtUuDNUnW_mjzs7t-y1zcH_-iO3yS9iFtmoDYJirJJuBPD7SbjsLCFUrwhTT2k206BE3Za9PictM2mKosXd8puETAM2Z1k6kaM6Xz6Obk2pk_W_9mUBsyW__x--9ktjaq1hmS2Vpjpdz0Oxr7VzQW83XQ1TWdLKGvhL7CeHxEbVwOx2nb4fpn30m6ZpbpA1r3Xj-_zLfz6bjKxr6tHrseuel33asVSpWjcBsrZfiZxOl3aSwTAvMN127eo_67VgfNSnjjAh3MHz_--RcyW--4bF33fzOuockmax9pDOO_xTA-wFiBKyERnhEGpERZVf3vQC4aSJz-Jj-kOsmgO4zTtKGoc_SecYGOzjDE1jXsuXgMk65bvkzoNGTIKF8l-TJZshGuJovpki4WcTIfFaskwYROX9iE7pM5i9kEF0kyYQu6zLL9bjob8RWN6Syex4t4PllM5lG83M3j6XLG8lkW02RBpjGWjItIiGMZKX0YNZ8pVpNpQpPZSLAdCtN84KHUB4OS2WakV83XjV19MGQaC26s6URYbgWuvssjEzwPrsRt_-trkbvQgGycAKKt5Ner1cAXnuDzz6jWYvXrn1-8accV_U8AAAD__6FHdOw">