On 1/3/20 6:37 PM, Jakub Jelinek wrote:
On the following testcase since the split_nonconstant_init move
on the COND_EXPR with omitted middle-end operand we end up with
the operator bool called on a TARGET_EXPR in the first operand and
the same TARGET_EXPR appearing in INIT_EXPR in the second operand.
cp_gimplify_init_expr ICEs, because this is during gimplification
and when TARGET_EXPR is gimplified for the first time, the
TARGET_EXPR_SLOT VAR_DECL is initialized and TARGET_EXPR_INITIAL
is cleared and when we gimplify it for the second and following time,
we just use the TARGET_EXPR_SLOT.

Ah, and because I changed gimplify_cond_expr to use INIT_EXPR.

Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
trunk?

OK.

2010-01-04  Jakub Jelinek  <ja...@redhat.com>

        PR c++/93046
        * cp-gimplify.c (cp_gimplify_init_expr): Don't look through
        TARGET_EXPR if it has been gimplified already.

        * g++.dg/ext/cond4.C: New test.

--- gcc/cp/cp-gimplify.c.jj     2020-01-01 12:22:33.838478071 +0100
+++ gcc/cp/cp-gimplify.c        2020-01-03 13:28:49.714314467 +0100
@@ -523,7 +523,7 @@ cp_gimplify_init_expr (tree *expr_p, gim
       think that such code never uses the TARGET_EXPR as an initializer.  If
       I'm wrong, we'll abort because the temp won't have any RTL.  In that
       case, I guess we'll need to replace references somehow.  */
-  if (TREE_CODE (from) == TARGET_EXPR)
+  if (TREE_CODE (from) == TARGET_EXPR && TARGET_EXPR_INITIAL (from))
      from = TARGET_EXPR_INITIAL (from);
/* If we might need to clean up a partially constructed object, break down
--- gcc/testsuite/g++.dg/ext/cond4.C.jj 2020-01-03 13:48:09.630801029 +0100
+++ gcc/testsuite/g++.dg/ext/cond4.C    2020-01-03 13:47:10.408696206 +0100
@@ -0,0 +1,14 @@
+// PR c++/93046
+// { dg-do compile }
+// { dg-options "" }
+
+struct S {
+  S (int);
+  operator bool ();
+};
+
+S
+foo ()
+{
+  return S (1) ? : S (2);
+}

        Jakub


Reply via email to