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> 2020-02-24 Jakub Jelinek <jakub@redhat.com>
P1937R2 - Fixing inconsistencies between const{expr,eval} functions P1937R2 - Fixing inconsistencies between const{expr,eval} functions
......
...@@ -117,13 +117,13 @@ struct conversion { ...@@ -117,13 +117,13 @@ struct conversion {
/* The next conversion in the chain. Since the conversions are /* The next conversion in the chain. Since the conversions are
arranged from outermost to innermost, the NEXT conversion will arranged from outermost to innermost, the NEXT conversion will
actually be performed before this conversion. This variant is 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 ck_list. Please use the next_conversion function instead
of using this field directly. */ of using this field directly. */
conversion *next; conversion *next;
/* The expression at the beginning of the conversion chain. This /* The expression at the beginning of the conversion chain. This
variant is used only if KIND is ck_identity or ck_ambig. You can variant is used only if KIND is ck_identity, ck_aggr, or ck_ambig.
use conv_get_original_expr to get this expression. */ You can use conv_get_original_expr to get this expression. */
tree expr; tree expr;
/* The array of conversions for an initializer_list, so this /* The array of conversions for an initializer_list, so this
variant is used only when KIN D is ck_list. */ variant is used only when KIN D is ck_list. */
...@@ -861,7 +861,8 @@ next_conversion (conversion *conv) ...@@ -861,7 +861,8 @@ next_conversion (conversion *conv)
if (conv == NULL if (conv == NULL
|| conv->kind == ck_identity || conv->kind == ck_identity
|| conv->kind == ck_ambig || conv->kind == ck_ambig
|| conv->kind == ck_list) || conv->kind == ck_list
|| conv->kind == ck_aggr)
return NULL; return NULL;
return conv->u.next; return conv->u.next;
} }
...@@ -1030,7 +1031,7 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) ...@@ -1030,7 +1031,7 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
c->rank = cr_exact; c->rank = cr_exact;
c->user_conv_p = true; c->user_conv_p = true;
c->check_narrowing = true; c->check_narrowing = true;
c->u.next = NULL; c->u.expr = ctor;
return c; return c;
} }
...@@ -1083,7 +1084,7 @@ build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) ...@@ -1083,7 +1084,7 @@ build_array_conv (tree type, tree ctor, int flags, tsubst_flags_t complain)
c->rank = rank; c->rank = rank;
c->user_conv_p = user; c->user_conv_p = user;
c->bad_p = bad; c->bad_p = bad;
c->u.next = build_identity_conv (TREE_TYPE (ctor), ctor); c->u.expr = ctor;
return c; return c;
} }
...@@ -1129,7 +1130,7 @@ build_complex_conv (tree type, tree ctor, int flags, ...@@ -1129,7 +1130,7 @@ build_complex_conv (tree type, tree ctor, int flags,
c->rank = rank; c->rank = rank;
c->user_conv_p = user; c->user_conv_p = user;
c->bad_p = bad; c->bad_p = bad;
c->u.next = NULL; c->u.expr = ctor;
return c; return c;
} }
...@@ -10500,7 +10501,7 @@ static tree ...@@ -10500,7 +10501,7 @@ static tree
conv_get_original_expr (conversion *c) conv_get_original_expr (conversion *c)
{ {
for (; c; c = next_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 c->u.expr;
return NULL_TREE; 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> 2020-02-20 Mark Eggleston <mark.eggleston@codethink.com>
PR fortran/93604 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