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