diff options
author | Jason Merrill <jason@redhat.com> | 2017-09-18 14:33:58 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2017-09-18 14:33:58 -0400 |
commit | 6df911fd1d0f8d697b3a133a8c48a2ecb46f1dd0 (patch) | |
tree | 1370b34e7078c924719ba198c6fe52a77ea8a686 | |
parent | 3632267ff2d567e12f4a77d28488733d480340f8 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/constexpr.c | 7 | ||||
-rw-r--r-- | gcc/cp/init.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-list1.C | 15 |
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{} {} +}; |