return NULL_TREE;
}
+/* Given a CO_AWAIT_EXPR AWAIT_EXPR, return its resume call. */
+
+tree*
+co_await_get_resume_call (tree await_expr)
+{
+ gcc_checking_assert (TREE_CODE (await_expr) == CO_AWAIT_EXPR);
+ tree vec = TREE_OPERAND (await_expr, 3);
+ if (!vec)
+ return nullptr;
+ return &TREE_VEC_ELT (vec, 2);
+}
+
+
/* These functions assumes that the caller has verified that the state for
the decl has been initialized, we try to minimize work here. */
param_info *parm_i = param_uses->get (arg);
if (parm_i->trivial_dtor)
continue;
- add_decl_expr (parm_i->guard_var);;
+ add_decl_expr (parm_i->guard_var);
}
add_decl_expr (coro_promise_live);
add_decl_expr (coro_gro_live);
extern tree coro_get_destroy_function (tree);
extern tree coro_get_ramp_function (tree);
+extern tree* co_await_get_resume_call (tree await_expr);
+
+
/* contracts.cc */
extern tree make_postcondition_variable (cp_expr);
extern tree make_postcondition_variable (cp_expr, tree);
maybe_warn_nodiscard (expr, implicit);
break;
+ case CO_AWAIT_EXPR:
+ {
+ auto awr = co_await_get_resume_call (expr);
+ if (awr && *awr)
+ *awr = convert_to_void (*awr, implicit, complain);
+ break;
+ }
+
default:;
}
expr = resolve_nondeduced_context (expr, complain);
--- /dev/null
+// { dg-do compile }
+#include <coroutine>
+
+struct must_check_result
+{
+ bool await_ready() { return false; }
+ void await_suspend(std::coroutine_handle<>) {}
+ [[nodiscard]] bool await_resume() { return {}; }
+};
+
+struct task {};
+
+namespace std
+{
+ template<typename... Args>
+ struct coroutine_traits<task, Args...>
+ {
+ struct promise_type
+ {
+ task get_return_object() { return {}; }
+ suspend_always initial_suspend() noexcept { return {}; }
+ suspend_always final_suspend() noexcept { return {}; }
+ void return_void() {}
+ void unhandled_exception() {}
+ };
+ };
+}
+
+task example(auto)
+{
+ co_await must_check_result(); // { dg-warning "-Wunused-result" }
+}
+
+void f() { example(1); }
--- /dev/null
+// { dg-do compile }
+#include <coroutine>
+
+struct must_check_result
+{
+ bool await_ready() { return false; }
+ void await_suspend(std::coroutine_handle<>) {}
+ [[nodiscard]] bool await_resume() { return {}; }
+};
+
+struct task {};
+
+namespace std
+{
+ template<typename... Args>
+ struct coroutine_traits<task, Args...>
+ {
+ struct promise_type
+ {
+ task get_return_object() { return {}; }
+ suspend_always initial_suspend() noexcept { return {}; }
+ suspend_always final_suspend() noexcept { return {}; }
+ void return_void() {}
+ void unhandled_exception() {}
+ };
+ };
+}
+
+task example()
+{
+ co_await must_check_result(); // { dg-warning "-Wunused-result" }
+}