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 <[email protected]>
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