tree awaiter_calls = make_tree_vec (3);
TREE_VEC_ELT (awaiter_calls, 0) = awrd_call; /* await_ready(). */
TREE_VEC_ELT (awaiter_calls, 1) = awsp_call; /* await_suspend(). */
+ tree te = NULL_TREE;
+ if (TREE_CODE (awrs_call) == TARGET_EXPR)
+ {
+ te = awrs_call;
+ awrs_call = TREE_OPERAND (awrs_call, 1);
+ }
TREE_VEC_ELT (awaiter_calls, 2) = awrs_call; /* await_resume(). */
tree await_expr = build5_loc (loc, CO_AWAIT_EXPR,
a, e_proxy, o, awaiter_calls,
build_int_cst (integer_type_node,
(int) suspend_kind));
- return convert_from_reference (await_expr);
+ if (te)
+ {
+ TREE_OPERAND (te, 1) = await_expr;
+ await_expr = te;
+ }
+ tree t = convert_from_reference (await_expr);
+ return t;
}
tree
tree op = build_co_await (kw, yield_call, CO_YIELD_SUSPEND_POINT);
if (op != error_mark_node)
{
- op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
+ if (REFERENCE_REF_P (op))
+ op = TREE_OPERAND (op, 0);
+ /* If the await expression is wrapped in a TARGET_EXPR, then transfer
+ that wrapper to the CO_YIELD_EXPR, since this is just a proxy for
+ its contained await. Otherwise, just build the CO_YIELD_EXPR. */
+ if (TREE_CODE (op) == TARGET_EXPR)
+ {
+ tree t = TREE_OPERAND (op, 1);
+ t = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (t), expr, t);
+ TREE_OPERAND (op, 1) = t;
+ }
+ else
+ op = build2_loc (kw, CO_YIELD_EXPR, TREE_TYPE (op), expr, op);
TREE_SIDE_EFFECTS (op) = 1;
+ op = convert_from_reference (op);
}
return op;
--- /dev/null
+#if __has_include (<coroutine>)
+#include <coroutine>
+using namespace std;
+#elif defined (__clang__) && __has_include (<experimental/coroutine>)
+#include <experimental/coroutine>
+using namespace std::experimental;
+#endif
+#include <utility>
+
+struct ret_type
+{
+ ret_type () = default;
+ ret_type (const ret_type&) = delete;
+ //ret_type (ret_type&&) = default;
+ ~ret_type() {}
+};
+
+struct task
+{
+ struct promise_type
+ {
+ auto get_return_object () -> task { return {}; }
+ auto initial_suspend () -> suspend_always { return {}; }
+ auto final_suspend () -> suspend_always { return {}; }
+ void return_void () {}
+ void unhandled_exception () { }
+ void thing (ret_type x) {}
+ };
+};
+
+struct awaiter
+{
+ bool await_ready() const { return true; }
+ void await_suspend (coroutine_handle<>) {}
+ ret_type await_resume() { return {}; }
+};
+
+task
+my_coro ()
+{
+ ret_type r2{co_await awaiter{}};
+ //ret_type r3 (std::move(r2));
+}
+
+int main()
+{
+ auto x = my_coro ();
+ return 0;
+}