On Tue, May 7, 2019 at 4:43 PM Jason Merrill <ja...@redhat.com> wrote: > > * typeck.c (build_static_cast_1): Use cp_build_addr_expr. > > For GCC 9 I fixed this bug with a patch to gimplify_cond_expr, but this > function was also doing the wrong thing. > > Using build_address does not push the ADDR_EXPR down into the arms of a > COND_EXPR, which we need for proper handling of conversion of an lvalue ?: > to another reference type.
Yet another tweak that would have fixed this bug: we should treat INIT_EXPR and MODIFY_EXPR differently for determining whether this is a simple empty class copy, since a TARGET_EXPR on the RHS is direct initialization if INIT_EXPR but copy if MODIFY_EXPR. * cp-gimplify.c (simple_empty_class_p): Also true for MODIFY_EXPR.
commit 4ee9e054cba31bd532061bd357477e757b5b284a Author: Jason Merrill <ja...@redhat.com> Date: Sat Mar 2 01:07:41 2019 -0500 PR c++/86485 - simple_empty_class_p Yet another tweak that would have fixed this bug: we should treat INIT_EXPR and MODIFY_EXPR differently for determining whether this is a simple empty class copy, since a TARGET_EXPR on the RHS is direct initialization if INIT_EXPR but copy if MODIFY_EXPR. * cp-gimplify.c (simple_empty_class_p): Also true for MODIFY_EXPR. diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c index e8c22c071c2..30937b1a1a3 100644 --- a/gcc/cp/cp-gimplify.c +++ b/gcc/cp/cp-gimplify.c @@ -594,19 +594,20 @@ gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p) return slot optimization alone because it isn't a copy. */ static bool -simple_empty_class_p (tree type, tree op) +simple_empty_class_p (tree type, tree op, tree_code code) { + if (TREE_CODE (op) == COMPOUND_EXPR) + return simple_empty_class_p (type, TREE_OPERAND (op, 1), code); return - ((TREE_CODE (op) == COMPOUND_EXPR - && simple_empty_class_p (type, TREE_OPERAND (op, 1))) - || TREE_CODE (op) == EMPTY_CLASS_EXPR + (TREE_CODE (op) == EMPTY_CLASS_EXPR + || code == MODIFY_EXPR || is_gimple_lvalue (op) || INDIRECT_REF_P (op) || (TREE_CODE (op) == CONSTRUCTOR - && CONSTRUCTOR_NELTS (op) == 0 - && !TREE_CLOBBER_P (op)) + && CONSTRUCTOR_NELTS (op) == 0) || (TREE_CODE (op) == CALL_EXPR && !CALL_EXPR_RETURN_SLOT_OPT (op))) + && !TREE_CLOBBER_P (op) && is_really_empty_class (type, /*ignore_vptr*/true); } @@ -715,7 +716,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (op0), op1); - else if (simple_empty_class_p (TREE_TYPE (op0), op1)) + else if (simple_empty_class_p (TREE_TYPE (op0), op1, code)) { /* Remove any copies of empty classes. Also drop volatile variables on the RHS to avoid infinite recursion from