My P0388R4 patch changed build_array_conv to create an identity conversion at the start of the conversion chain. That was a sound change but 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, " "}); } I considered fixing this when performing overload resolution (clang says "no matching function for call to 'f'"), but then it occured to me that we crash in different contexts too, so I'm just turning the assert into an early return. Bootstrapped/regtested on x86_64-linux, ok for trunk? 2020-02-13 Marek Polacek <pola...@redhat.com> PR c++/93712 - ICE with ill-formed array list-initialization. * call.c (convert_like_real): Turn an assert into a return. * g++.dg/cpp0x/initlist-array11.C: New test. --- gcc/cp/call.c | 2 +- gcc/testsuite/g++.dg/cpp0x/initlist-array11.C | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-array11.C diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 51621b7dd87..eba0ed8041d 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -7463,7 +7463,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum, else if (nelts == 1) expr = CONSTRUCTOR_ELT (expr, 0)->value; else - gcc_unreachable (); + return error_mark_node; } expr = mark_use (expr, /*rvalue_p=*/!convs->rvaluedness_matches_p, /*read_p=*/true, UNKNOWN_LOCATION, diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array11.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array11.C new file mode 100644 index 00000000000..7e76b588471 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array11.C @@ -0,0 +1,10 @@ +// 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 "invalid conversion" } + return f({1, "foo"}); // { dg-error "invalid conversion" } +} base-commit: 1d69147af203d4dcd2270429f90c93f1a37ddfff -- Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA