On 2/13/20 8:56 PM, Marek Polacek wrote:
My P0388R4 patch changed build_array_conv to create an identity conversion at the start of the conversion chain.
Hmm, an identity conversion of {} suggests that it has a type, which it doesn't in the language. I'm not strongly against it, but what was the reason for this change?
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 }
Right, this is assuming that any other {} will either be ill-formed or handled by ck_aggr or ck_list. How are we getting here without going through one of those?
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