return cp_walk_tree (stmt, register_awaits, d, &visited);
}
-/* Lightweight callback to determine two key factors:
+/* Relatively lightweight callback to do initial assessment:
+ 0) Rewrite some await expressions.
1) If the statement/expression contains any await expressions.
2) If the statement/expression potentially requires a re-write to handle
TRUTH_{AND,OR}IF_EXPRs since, in most cases, they will need expansion
switch (TREE_CODE (*stmt))
{
default: return NULL_TREE;
+ case CALL_EXPR:
+ {
+ tree fn = cp_get_callee_fndecl_nofold (*stmt);
+ /* Special-cases where we want to re-write await expressions to some
+ other value before they are otherwise processed. */
+ if (fn && DECL_IS_BUILTIN_CONSTANT_P (fn))
+ {
+ gcc_checking_assert (call_expr_nargs (*stmt) == 1);
+ tree expr = CALL_EXPR_ARG (*stmt, 0);
+ if (cp_walk_tree (&expr, find_any_await, nullptr, NULL))
+ {
+ if (TREE_CONSTANT (maybe_constant_value (expr)))
+ *stmt = integer_one_node;
+ else
+ *stmt = integer_zero_node;
+ }
+ *do_subtree = 0;
+ }
+ }
+ break;
case CO_YIELD_EXPR:
/* co_yield is syntactic sugar, re-write it to co_await. */
*stmt = TREE_OPERAND (*stmt, 1);
--- /dev/null
+// { dg-additional-options "-fsyntax-only" }
+// PR116775
+#include <coroutine>
+#ifndef OUTPUT
+# define PRINT(X)
+# define PRINTF(...)
+#else
+#include <cstdio>
+# define PRINT(X) puts(X)
+# define PRINTF(...) printf(__VA_ARGS__)
+#endif
+
+struct awaitable {
+ awaitable(int n) : delay{n} {}
+
+ constexpr bool await_ready() const noexcept { return false; }
+ auto await_suspend(std::coroutine_handle<> h) const {
+ __builtin_trap ();
+ return false;
+ }
+ int await_resume() const noexcept {
+ return delay;
+ }
+
+ int delay;
+};
+
+struct Task {
+ struct promise_type {
+ promise_type() = default;
+ Task get_return_object() { return {}; }
+ std::suspend_never initial_suspend() { return {}; }
+ std::suspend_always final_suspend() noexcept { return {}; }
+ void unhandled_exception() {}
+ void return_void () {}
+ awaitable yield_value (int v) { return {v}; }
+ };
+};
+
+Task foo() noexcept {
+ if (__builtin_constant_p (true ? 1 : co_await awaitable{10}))
+ PRINT ("const OK");
+ else
+ {
+ PRINT ("failed : should be const");
+ __builtin_abort ();
+ }
+ if (__builtin_constant_p (false ? 1 : co_await awaitable{15}))
+ {
+ PRINT ("failed : should not be const");
+ __builtin_abort ();
+ }
+ else
+ PRINT ("not const, OK");
+ if (__builtin_constant_p (5 == (co_yield 42)))
+ {
+ PRINT ("failed : should not be const");
+ __builtin_abort ();
+ }
+ else
+ PRINT ("not const, OK");
+ co_return;
+}
+
+//call foo
+int main() {
+ foo();
+}