c++: assignment from {} with array member NSDMI [PR127016]
can_convert_array only accepts a CONSTRUCTOR or a string literal as a valid
way to aggregate initialize an array. When the element type needs a loop to
initialize, the digested NSDMI of an array member is a VEC_INIT_EXPR
instead, so we returned false and discarded the implicit assignment
operators as non-viable. Look through it to VEC_INIT_EXPR_INIT.
PR c++/127016
gcc/cp/ChangeLog:
* call.cc (can_convert_array): Handle a VEC_INIT_EXPR FROM.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/initlist-array26.C: New test.
Signed-off-by: Sebastian Miles <sebastianmiles20@gmail.com>
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 45c108e..ecf1c87 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -1016,6 +1016,9 @@
&& TREE_CODE (tree_strip_any_location_wrapper (from)) == STRING_CST)
return array_string_literal_compatible_p (atype, from);
+ if (tree vi = (get_vec_init_expr (from)))
+ return can_convert_array (atype, VEC_INIT_EXPR_INIT (vi), flags, complain);
+
/* No other valid way to aggregate initialize an array. */
return false;
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array26.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array26.C
new file mode 100644
index 0000000..ee1f594
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array26.C
@@ -0,0 +1,39 @@
+// PR c++/127016
+// { dg-do compile { target c++14 } }
+// Assigning {} to an aggregate with an array member that has a default
+// member initializer, where the element type needs a loop to initialize.
+
+struct NonTrivial {
+ NonTrivial () {}
+ int v = 0;
+};
+
+struct Elem {
+ NonTrivial n;
+ int x{};
+};
+
+struct Bug {
+ bool flag{true};
+ Elem arr[2]{};
+};
+
+void
+f (Bug *p)
+{
+ *p = {};
+}
+
+void g (Bug);
+
+void
+h ()
+{
+ g ({});
+}
+
+Bug
+i ()
+{
+ return {};
+}