aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2017-09-18 14:33:58 -0400
committerJason Merrill <jason@gcc.gnu.org>2017-09-18 14:33:58 -0400
commit6df911fd1d0f8d697b3a133a8c48a2ecb46f1dd0 (patch)
tree1370b34e7078c924719ba198c6fe52a77ea8a686
parent3632267ff2d567e12f4a77d28488733d480340f8 (diff)
downloadgcc-6df911fd1d0f8d697b3a133a8c48a2ecb46f1dd0.zip
gcc-6df911fd1d0f8d697b3a133a8c48a2ecb46f1dd0.tar.gz
gcc-6df911fd1d0f8d697b3a133a8c48a2ecb46f1dd0.tar.bz2
PR c++/72457 - ICE with list-value-initialized base.
* init.c (expand_aggr_init_1): Only handle value-init of bases. * constexpr.c (build_data_member_initialization): Handle multiple initializers for the same field. From-SVN: r252938
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/constexpr.c7
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-list1.C15
4 files changed, 29 insertions, 4 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f8c3a89..f78bce6 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,10 @@
2017-09-18 Jason Merrill <jason@redhat.com>
+ PR c++/72457
+ * init.c (expand_aggr_init_1): Only handle value-init of bases.
+ * constexpr.c (build_data_member_initialization): Handle multiple
+ initializers for the same field.
+
PR c++/55922
PR c++/63151
* init.c (expand_aggr_init_1): Handle list-initialization from {}.
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index b996e98..3f37cd5 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -401,7 +401,12 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
gcc_assert (TREE_TYPE (member) == vtbl_ptr_type_node);
}
- CONSTRUCTOR_APPEND_ELT (*vec, member, init);
+ /* Value-initialization can produce multiple initializers for the
+ same field; use the last one. */
+ if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member)
+ (*vec)->last().value = init;
+ else
+ CONSTRUCTOR_APPEND_ELT (*vec, member, init);
return true;
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 98caa95..841afbd 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1811,9 +1811,9 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
}
/* List-initialization from {} becomes value-initialization for non-aggregate
- classes with default constructors. Handle this here so protected access
- works. */
- if (init && TREE_CODE (init) == TREE_LIST)
+ classes with default constructors. Handle this here when we're
+ initializing a base, so protected access works. */
+ if (exp != true_exp && init && TREE_CODE (init) == TREE_LIST)
{
tree elt = TREE_VALUE (init);
if (DIRECT_LIST_INIT_P (elt)
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-list1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-list1.C
new file mode 100644
index 0000000..f831a11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-list1.C
@@ -0,0 +1,15 @@
+// PR c++/72457
+// { dg-do compile { target c++11 } }
+
+struct A {
+ int i;
+ constexpr A(): i(0) {}
+};
+
+struct B: A { };
+
+struct C
+{
+ B b;
+ constexpr C() : b{} {}
+};