public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "oremanj at mit dot edu" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug c++/112360] New: [coroutines] unreachable 'co_await' still creates a suspension point Date: Fri, 03 Nov 2023 06:30:24 +0000 [thread overview] Message-ID: <bug-112360-4@http.gcc.gnu.org/bugzilla/> (raw) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112360 Bug ID: 112360 Summary: [coroutines] unreachable 'co_await' still creates a suspension point Product: gcc Version: 14.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: oremanj at mit dot edu Target Milestone: --- A coroutine function of the form: task example() { do { co_await awaitable{}; } while (false && co_await awaitable{}); co_return; } will execute the awaitable's await_ready() and await_suspend() methods twice, even though execution of the abstract machine only reaches one co_await statement. This reproduces on several tested versions from 11.1 to current master, at either of optimization level -O0 or -O2. While the construct may seem a bit nonsensical, it does show up in practice; it's simplified from something that appears after macro expansion when using the popular Catch2 testing library if you write an assertion about the value of a co_await expression. Compiler Explorer link: https://godbolt.org/z/EoP7EnEnf Full test case is below. On gcc it prints: ready suspend resume ready suspend returned final suspend clang (14 through 17) shows the more expected ready suspend resume returned final suspend command line: gcc -std=c++20 -Wall -Wextra t.c -o t --- test case follows --- #include <coroutine> extern "C" int puts(const char* s); struct task { struct promise_type { std::suspend_always initial_suspend() { return {}; } std::suspend_always final_suspend() noexcept { puts("final suspend"); return {}; } void return_void() { puts("returned"); } void unhandled_exception() {} task get_return_object() { return task{this}; } }; promise_type* promise; }; struct awaitable { bool await_ready() const noexcept { puts("ready"); return false; } void await_suspend(std::coroutine_handle<> h) { puts("suspend"); h.resume(); } bool await_resume() { puts("resume"); return false; } }; task example() { do { co_await awaitable{}; } while (false && co_await awaitable{}); co_return; } int main() { using handle = std::coroutine_handle<task::promise_type>; task t = example(); handle h = handle::from_promise(*t.promise); h.resume(); }
next reply other threads:[~2023-11-03 6:30 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2023-11-03 6:30 oremanj at mit dot edu [this message] 2023-11-03 19:04 ` [Bug c++/112360] [coroutines] unreachable 'co_await' still can suspend the coroutine pinskia at gcc dot gnu.org
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-112360-4@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).