Issue 143235
Summary Invalid exception object catch from nested lambda coroutines with clang 20.1.0 on windows
Labels clang
Assignees
Reporter ShirenY
    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
```
_______________________________________________
llvm-bugs mailing list
llvm-bugs@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-bugs

Reply via email to