From 054aeaef276572c2ccbedbd7aa86046be338603c Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 2 Mar 2020 14:42:47 -0500 Subject: [PATCH] c++: Fix ({ ... }) array mem-initializer. 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 PR c++/86917 * constexpr.c (cxx_eval_vec_init_1): Handle CONSTRUCTOR. --- gcc/cp/ChangeLog | 5 ++++ gcc/cp/constexpr.c | 4 ++++ .../g++.dg/cpp0x/constexpr-array23.C | 24 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/constexpr-array23.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7692a8f1903f..614844ef9061 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2020-03-02 Jason Merrill + + PR c++/86917 + * constexpr.c (cxx_eval_vec_init_1): Handle CONSTRUCTOR. + 2020-03-02 Jason Merrill PR c++/91953 diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 2006ad9f45ee..8fd5e4f2126a 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -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 index 000000000000..e94695efa2ae --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-array23.C @@ -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 () { } -- 2.47.2