]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Fix ({ ... }) array mem-initializer.
authorJason Merrill <jason@redhat.com>
Mon, 2 Mar 2020 19:42:47 +0000 (14:42 -0500)
committerJason Merrill <jason@redhat.com>
Mon, 2 Mar 2020 20:49:58 +0000 (15:49 -0500)
Here, we were going down the wrong path in perform_member_init because of
the incorrect parens around the mem-initializer for the array.  And then
cxx_eval_vec_init_1 didn't know what to do with a CONSTRUCTOR as the
initializer.  For GCC 9, let's just fix the latter issue.

gcc/cp/ChangeLog
2020-03-02  Jason Merrill  <jason@redhat.com>

PR c++/86917
* constexpr.c (cxx_eval_vec_init_1): Handle CONSTRUCTOR.

gcc/cp/ChangeLog
gcc/cp/constexpr.c
gcc/testsuite/g++.dg/cpp0x/constexpr-array23.C [new file with mode: 0644]

index 7692a8f1903fcb7e481555a1e906fc22d3bfbbb9..614844ef9061ceb1073e65f3694b1fc043ff33fd 100644 (file)
@@ -1,3 +1,8 @@
+2020-03-02  Jason Merrill  <jason@redhat.com>
+
+       PR c++/86917
+       * constexpr.c (cxx_eval_vec_init_1): Handle CONSTRUCTOR.
+
 2020-03-02  Jason Merrill  <jason@redhat.com>
 
        PR c++/91953
index 2006ad9f45eec6966f44d4e2f0eb482b3e9ea317..8fd5e4f2126ac23785f65989f2147ac60dde2318 100644 (file)
@@ -3135,6 +3135,10 @@ cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
   unsigned HOST_WIDE_INT i;
   tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
 
+  if (init && TREE_CODE (init) == CONSTRUCTOR)
+    return cxx_eval_bare_aggregate (ctx, init, lval,
+                                   non_constant_p, overflow_p);
+
   /* For the default constructor, build up a call to the default
      constructor of the element type.  We only need to handle class types
      here, as for a constructor to be constexpr, all members must be
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-array23.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-array23.C
new file mode 100644 (file)
index 0000000..e94695e
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/86917
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  constexpr A () : c (0) {}
+  static const A z;
+  unsigned c;
+};
+
+struct B
+{                              // This should really be target { ! c++2a }
+  typedef A W[4];              // { dg-error "paren" "" { xfail *-*-* } .+1 }
+  constexpr B () : w ({ A::z, A::z, A::z, A::z }) {} // { dg-error "constant" "" { xfail *-*-* } }
+  W w;
+};
+
+struct C
+{
+  C ();
+  B w[1];
+};
+
+C::C () { }