Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/branches?
-- >8 --
In c++/102990 we had a problem where massage_init_elt got {},
digest_nsdmi_init turned that {} into { .value = (int) 1.0e+0 },
and we crashed in the call to fold_non_dependent_init because
a FIX_TRUNC_EXPR/FLOAT_EXPR got into tsubst*. So we avoided
calling fold_non_dependent_init for a CONSTRUCTOR.
But that broke the following test, where we no longer fold the
CONST_DECL in
{ .type = ZERO }
to
{ .type = 0 }
and then process_init_constructor_array does:
if (next != error_mark_node
&& (initializer_constant_valid_p (next, TREE_TYPE (next))
!= null_pointer_node))
{
/* Use VEC_INIT_EXPR for non-constant initialization of
trailing elements with no explicit initializers. */
picflags |= PICFLAG_VEC_INIT;
because { .type = ZERO } isn't initializer_constant_valid_p. Then we
create a VEC_INIT_EXPR and say we can't convert the argument.
So we have to fold the elements of the CONSTRUCTOR. We just can't
instantiate the elements in a template.
This also fixes c++/118047.
PR c++/118047
PR c++/118355
gcc/cp/ChangeLog:
* typeck2.cc (massage_init_elt): Call fold_non_dependent_init
unless for a CONSTRUCTOR in a template.
gcc/testsuite/ChangeLog:
* g++.dg/cpp0x/nsdmi-list10.C: New test.
* g++.dg/cpp0x/nsdmi-list9.C: New test.
---
gcc/cp/typeck2.cc | 8 +++---
gcc/testsuite/g++.dg/cpp0x/nsdmi-list10.C | 35 +++++++++++++++++++++++
gcc/testsuite/g++.dg/cpp0x/nsdmi-list9.C | 34 ++++++++++++++++++++++
3 files changed, 73 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-list10.C
create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-list9.C
diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
index 5dae7fccf19..e2ab255a7d5 100644
--- a/gcc/cp/typeck2.cc
+++ b/gcc/cp/typeck2.cc
@@ -1568,10 +1568,10 @@ massage_init_elt (tree type, tree init, int nested, int
flags,
new_flags |= LOOKUP_AGGREGATE_PAREN_INIT;
init = digest_init_r (type, init, nested ? 2 : 1, new_flags, complain);
/* When we defer constant folding within a statement, we may want to
- defer this folding as well. Don't call this on CONSTRUCTORs because
- their elements have already been folded, and we must avoid folding
- the result of get_nsdmi. */
- if (TREE_CODE (init) != CONSTRUCTOR)
+ defer this folding as well. Don't call this on CONSTRUCTORs in
+ a template because their elements have already been folded, and
+ we must avoid folding the result of get_nsdmi. */
+ if (!(processing_template_decl && TREE_CODE (init) == CONSTRUCTOR))
{
tree t = fold_non_dependent_init (init, complain);
if (TREE_CONSTANT (t))
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-list10.C
b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list10.C
new file mode 100644
index 00000000000..36b74749cbf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list10.C
@@ -0,0 +1,35 @@
+// PR c++/118047
+// { dg-do compile { target c++11 } }
+
+typedef decltype(sizeof(char)) size_t;
+
+namespace std {
+template <typename T>
+struct initializer_list {
+ const T *_M_array;
+ size_t _M_len;
+ constexpr size_t size() const { return _M_len; }
+};
+}
+
+enum E {
+ One
+};
+
+struct A {
+ E e = One;
+};
+
+struct B {
+ A as[1] {};
+};
+
+struct V
+{
+ constexpr V(const std::initializer_list<B> &a) : size(a.size()){}
+ int size;
+};
+
+constexpr V a{{}};
+
+static_assert(a.size == 1, "");
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-list9.C
b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list9.C
new file mode 100644
index 00000000000..ae69ba0810d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-list9.C
@@ -0,0 +1,34 @@
+// PR c++/118355
+// { dg-do compile { target c++11 } }
+
+enum MY_ENUM
+{
+ ZERO,
+};
+
+struct FOO
+{
+ MY_ENUM type = ZERO;
+};
+
+struct ARR
+{
+ FOO array[1] = {};
+};
+
+template<typename>
+struct ARR2
+{
+ FOO array[1] = {};
+};
+
+void
+g ()
+{
+
+ ARR arr;
+ arr = {};
+
+ ARR2<int> arr2;
+ arr2 = {};
+}
base-commit: 22fe3c05d86b52c35850918bfb21e1f597e1b5c7
--
2.47.1