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 {};
+}