Skip to content

REQUIRE(co_await expr) unexpectedly repeats execution in GCC #2925

@Hackerl

Description

@Hackerl

Describe the bug
REQUIRE(co_await expr) unexpectedly repeats execution in GCC.

Expected behavior
The co_await expression should only be executed once

Reproduction steps
https://godbolt.org/z/h6jshrYs8

#include <iostream>
#include <coroutine>
#include <https://raw.githubusercontent.com/catchorg/Catch2/refs/tags/v3.7.1/extras/catch_amalgamated.hpp>
#include <https://raw.githubusercontent.com/catchorg/Catch2/refs/tags/v3.7.1/extras/catch_amalgamated.cpp>

struct promise;

struct coroutine : std::coroutine_handle<promise> {
    using promise_type = ::promise;
};

struct promise {
    coroutine get_return_object() { return {coroutine::from_promise(*this)}; }
    std::suspend_never initial_suspend() noexcept { return {}; }
    std::suspend_never final_suspend() noexcept { return {}; }

    void return_void() {
    }

    void unhandled_exception() {
    }
};

struct Awaitable {
    bool await_ready() {
        static int counter{};
        std::cout << ++counter << std::endl;
        return true;
    }

    void await_suspend(std::coroutine_handle<>) {
    }

    bool await_resume() {
        return true;
    }
};

coroutine test() {
    REQUIRE(co_await Awaitable{});
}

TEST_CASE("test") {
    test();
}

Platform information:

  • OS: Any
  • Compiler+version: GCC v14.x.x
  • Catch version: v3.7.1

Additional context
In GCC, __builtin_constant_p(co_await expr) is executed unexpectedly.
while ((void) 0, (false) && static_cast<const bool &>(!!(co_await expr))) is also.
I believe this is a compiler bug, but is there a way to avoid it with catch?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions