https://gcc.gnu.org/g:4ff09eb3422c525d514c869c7e0366fd5b40b561

commit r16-1542-g4ff09eb3422c525d514c869c7e0366fd5b40b561
Author: Iain Sandoe <i...@sandoe.co.uk>
Date:   Mon Jun 9 11:26:01 2025 +0100

    c++,coroutines: Handle await expressions in assume attributes.
    
    Here we have an expression that is not evaluated but is still seen
    as potentially-evaluated.  We handle this by determining if the
    operand has side-effects, producing a warning that the assume has
    been ignored and eliding it.
    
    gcc/cp/ChangeLog:
    
            * coroutines.cc (analyze_expression_awaits): Elide assume
            attributes containing await expressions, since these have
            side effects.  Emit a diagnostic that this has been done.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/coroutines/assume.C: New test.

Diff:
---
 gcc/cp/coroutines.cc                     | 13 +++++++++++
 gcc/testsuite/g++.dg/coroutines/assume.C | 40 ++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index 276c6c40c785..f97bd9deae33 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -3479,6 +3479,19 @@ analyze_expression_awaits (tree *stmt, int *do_subtree, 
void *d)
                }
              *do_subtree = 0;
            }
+         else if (!fn && CALL_EXPR_IFN (*stmt) == IFN_ASSUME)
+           {
+             tree expr = CALL_EXPR_ARG (*stmt, 0);
+             if (TREE_SIDE_EFFECTS (expr))
+               {
+                 location_t loc_e = cp_expr_location (expr);
+                 location_t loc_s = cp_expr_location (*stmt);
+                 location_t loc_n = make_location (loc_e, loc_s, loc_s);
+                 warning_at (loc_n, OPT_Wattributes,"assumption ignored"
+                             " because it contains an await-expression");
+                 *stmt = build_empty_stmt (loc_n);
+               }
+           }
        }
        break;
       case CO_YIELD_EXPR:
diff --git a/gcc/testsuite/g++.dg/coroutines/assume.C 
b/gcc/testsuite/g++.dg/coroutines/assume.C
new file mode 100644
index 000000000000..d007386f6bcc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/coroutines/assume.C
@@ -0,0 +1,40 @@
+// { dg-additional-options "-fsyntax-only -Wattributes" }
+
+#include <coroutine>
+
+struct awaitable {
+    awaitable (int n) : delay{n} {}
+
+    constexpr bool await_ready () const noexcept { return false; }
+    auto await_suspend (std::coroutine_handle<> h) const {
+        __builtin_abort ();
+        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}; }
+    };
+};
+
+int h () { return 5; }
+
+Task foo() noexcept {
+    int x = 5;
+    [[assume (x == 5)]];
+    [[assume (co_await awaitable{10})]]; // { dg-warning {assumption ignored 
because it contains an await-expression} }
+    [[assume ((h(),co_await awaitable{11}))]]; // { dg-warning {assumption 
ignored because it contains an await-expression} }
+    co_return;
+}

Reply via email to