]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c++/72457 - ICE with list-value-initialized base.
authorJason Merrill <jason@redhat.com>
Mon, 18 Sep 2017 18:33:58 +0000 (14:33 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 18 Sep 2017 18:33:58 +0000 (14:33 -0400)
* 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

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

index f8c3a89fc980b12ed60eac260ac8bbf405dd4ef9..f78bce6be987f8d545148888a7ef66c31490f316 100644 (file)
@@ -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 {}.
index b996e98027fb531bb638f98bc576af49159883ca..3f37cd50fcf293cf74491cc249b722f78776de58 100644 (file)
@@ -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;
 }
 
index 98caa9556ca890f190d6ca6fdf563f899ea3bcb4..841afbd8f518256c4bc3972ea691f8038753eafc 100644 (file)
@@ -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 (file)
index 0000000..f831a11
--- /dev/null
@@ -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{} {}
+};