Skip to content

[coroutines] Clang does not destroy coroutine object when throwing before first suspension #199627

@MeatBoy106

Description

@MeatBoy106

Executable version with step-by-step log: https://godbolt.org/z/z83bofdev

Minimum reproduction:

#include <exception>

bool g_coro_value_destroyed = false;

struct CoroValue {
    struct promise_type {
        auto get_return_object() -> CoroValue {
            return CoroValue{};
        }

        auto initial_suspend() -> std::suspend_never { return {}; }

        auto final_suspend() noexcept -> std::suspend_always { return {}; }

        void return_void() {}

        void unhandled_exception() {
            std::rethrow_exception(std::current_exception());
        }
    };

    ~CoroValue() {
        g_coro_value_destroyed = true;
    }
};

auto
failing_coro() -> CoroValue {
    throw 0;
    co_return;
}

auto
main() -> int {
    try {
        CoroValue value = failing_coro();
    } catch (...) {}

    if (g_coro_value_destroyed) {
        return 0;
    }
    return 1;
}

Observed behavior: Process exit status code is 1, indicating that the destructor of CoroValue was never called.
Expected behavior: Process exit status code is 0 after the destructor of CoroValue was called.

Investigation:

The standard (at least cppreference) states in the execution section of the coroutines page defines this step:

...
calls promise.get_return_object() and keeps the result in a local variable. The result of that call will be returned to the caller when the coroutine first suspends.
...

The observed behavior is that this local variable is not destroyed properly, as if the lifetime was immediately bound to the caller-side return value variable. However, if the flow never reaches this caller-side variable, then it is not destroyed during the stack unwinding triggered by the exception.

clang version:

$ clang --version
Ubuntu clang version 22.1.6 (++20260516103140+fc4aad7b5db3-1~exp1~20260516103204.74)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm-22/bin

Related issue: #61900

Metadata

Metadata

Assignees

No one assigned

    Labels

    clangClang issues not falling into any other categorycoroutinesC++20 coroutines

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions