Commit b07c0855 by Marek Polacek

c++: Fix ICE with ill-formed array list-initialization [PR93712]

My P0388R4 patch changed build_array_conv to create an identity
conversion at the start of the conversion chain and now we crash
in convert_like_real:

 7457     case ck_identity:
 7458       if (BRACE_ENCLOSED_INITIALIZER_P (expr))
 7459         {
 7460           int nelts = CONSTRUCTOR_NELTS (expr);
 7461           if (nelts == 0)
 7462             expr = build_value_init (totype, complain);
 7463           else if (nelts == 1)
 7464             expr = CONSTRUCTOR_ELT (expr, 0)->value;
 7465           else
 7466             gcc_unreachable ();  // HERE
 7467         }

in a test like this

  int f (int const (&)[2])
  { return f({1, "M"}); }

Instead of creating a ck_identity at the start of the conversion chain,
so that conv_get_original_expr can be used with a ck_aggr, let's set
u.expr for a ck_aggr, and adjust next_conversion not to try to see
what's next in the chain if it gets a ck_aggr.

2020-02-24  Marek Polacek  <polacek@redhat.com>

	PR c++/93712 - ICE with ill-formed array list-initialization.
	* call.c (next_conversion): Return NULL for ck_aggr.
	(build_aggr_conv): Set u.expr instead of u.next.
	(build_array_conv): Likewise.
	(build_complex_conv): Likewise.
	(conv_get_original_expr): Handle ck_aggr.

	* g++.dg/cpp0x/initlist-array11.C: New test.
parent 85c143d0
2020-02-24 Marek Polacek <polacek@redhat.com>
PR c++/93712 - ICE with ill-formed array list-initialization.
* call.c (next_conversion): Return NULL for ck_aggr.
(build_aggr_conv): Set u.expr instead of u.next.
(build_array_conv): Likewise.
(build_complex_conv): Likewise.
(conv_get_original_expr): Handle ck_aggr.
2020-02-24 Jakub Jelinek <jakub@redhat.com>
P1937R2 - Fixing inconsistencies between const{expr,eval} functions
......
......@@ -117,13 +117,13 @@ struct conversion {
/* The next conversion in the chain. Since the conversions are
arranged from outermost to innermost, the NEXT conversion will
actually be performed before this conversion. This variant is
used only when KIND is neither ck_identity, ck_ambig nor
used only when KIND is neither ck_identity, ck_aggr, ck_ambig nor
ck_list. Please use the next_conversion function instead
of using this field directly. */
conversion *next;
/* The expression at the beginning of the conversion chain. This
variant is used only if KIND is ck_identity or ck_ambig. You can
use conv_get_original_expr to get this expression. */
variant is used only if KIND is ck_identity, ck_aggr, or ck_ambig.
You can use conv_get_original_expr to get this expression. */
tree expr;
/* The array of conversions for an initializer_list, so this
variant is used only when KIN D is ck_list. */
......@@ -861,7 +861,8 @@ next_conversion (conversion *conv)
if (conv == NULL
|| conv->kind == ck_identity
|| conv->kind == ck_ambig
|| conv->kind == ck_list)
|| conv->kind == ck_list
|| conv->kind == ck_aggr)
return NULL;
return conv->u.next;
}
......@@ -1030,7 +1031,7 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
c->rank = cr_exact;
c->user_conv_p = true;
c->check_narrowing = true;
c->u.next = NULL;
c->u.expr = ctor;
return c;
}
......@@ -1083,7 +1084,7 @@ build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
c->rank = rank;
c->user_conv_p = user;
c->bad_p = bad;
c->u.next = build_identity_conv (TREE_TYPE (ctor), ctor);
c->u.expr = ctor;
return c;
}
......@@ -1129,7 +1130,7 @@ build_complex_conv (tree type, tree ctor, int flags,
c->rank = rank;
c->user_conv_p = user;
c->bad_p = bad;
c->u.next = NULL;
c->u.expr = ctor;
return c;
}
......@@ -10500,7 +10501,7 @@ static tree
conv_get_original_expr (conversion *c)
{
for (; c; c = next_conversion (c))
if (c->kind == ck_identity || c->kind == ck_ambig)
if (c->kind == ck_identity || c->kind == ck_ambig || c->kind == ck_aggr)
return c->u.expr;
return NULL_TREE;
}
......
2020-02-24 Marek Polacek <polacek@redhat.com>
PR c++/93712 - ICE with ill-formed array list-initialization.
* g++.dg/cpp0x/initlist-array11.C: New test.
2020-02-20 Mark Eggleston <mark.eggleston@codethink.com>
PR fortran/93604
......
// PR c++/93712 - ICE with ill-formed array list-initialization.
// { dg-do compile { target c++11 } }
int f (const int (&)[2]);
int g ()
{
const int (&r)[2] = {1, "foo"}; // { dg-error "conversion" }
return f({1, "foo"}); // { dg-error "conversion" }
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment