On 10/3/22 23:53, Jason Merrill wrote:
On 9/30/22 18:50, Iain Sandoe wrote:
Hi Jason,
On 30 Sep 2022, at 23:06, Jason Merrill <ja...@redhat.com> wrote:
You can't use CONVERT_EXPR to convert between two class types, and it
was
breaking copy elision.
Unfortunately, this patch breaks symmetric-transfer-00-basic.C, where
susp_type is Loopy<int>::handle_type. How is this supposed to work?
We are trying to save a type-erased handle (which the symmetric
transfer makes
and indirect call through, nothing else).
The problem is you're treating one class directly as another class here,
without the indirection involved in usual type-erasure idioms.
It does seem that the gimplifier handles this fine, but it doesn't
correspond to anything in the language and much of the front end assumes
that CONVERT_EXPR is only used for scalars. VIEW_CONVERT_EXPR would
better express that we're not doing anything to the value, just cheating
the type system. That's still dodgy from a language perspective, but
probably safe enough in this case.
So I'm applying this:
From 0cd9dafcfa8cf69b3a1eae91bea82d388c5328d2 Mon Sep 17 00:00:00 2001
From: Jason Merrill <ja...@redhat.com>
Date: Fri, 30 Sep 2022 10:04:22 -0400
Subject: [PATCH] c++: fix broken conversion in coroutines
To: gcc-patches@gcc.gnu.org
You can't use CONVERT_EXPR to convert between two class types.
VIEW_CONVERT_EXPR takes liberties with the C++ type system, but is probably
safe in this context. Let's also only use it when the type isn't already
what we want.
gcc/cp/ChangeLog:
* coroutines.cc (expand_one_await_expression): Change conversion
to VIEW_CONVERT_EXPR.
* cp-gimplify.cc (cp_genericize_r) [CONVERT_EXPR]: Add assert.
---
gcc/cp/coroutines.cc | 5 ++++-
gcc/cp/cp-gimplify.cc | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index eca01abcb7a..60b846600b9 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -1728,7 +1728,10 @@ expand_one_await_expression (tree *stmt, tree *await_expr, void *d)
}
else
{
- r = build1_loc (loc, CONVERT_EXPR, void_coro_handle_type, suspend);
+ r = suspend;
+ if (!same_type_ignoring_top_level_qualifiers_p (susp_type,
+ void_coro_handle_type))
+ r = build1_loc (loc, VIEW_CONVERT_EXPR, void_coro_handle_type, r);
r = build2_loc (loc, INIT_EXPR, void_coro_handle_type, data->conthand, r);
r = build1 (CONVERT_EXPR, void_type_node, r);
append_to_statement_list (r, &body_list);
diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index b4599fc34d8..5d26e59d098 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1589,6 +1589,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
break;
case CONVERT_EXPR:
+ gcc_checking_assert (!AGGREGATE_TYPE_P (TREE_TYPE (stmt)));
gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
break;
--
2.31.1