Hi!

build_constructor assumes the elts it is called with have all non-NULL
value, otherwise one shouldn't add those elts at all.

The following patch makes sure that we don't push elts with NULL value
into the ctor element vectors.

Bootstrapped/regtested on x86_64-linux and i686-linux, approved by Jason in
the PR, committed to trunk.

2013-02-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/56241
        * init.c (build_vec_init): Don't append NULL values into new_vec.
        (build_zero_init_1): Don't push anything into v if recursive call
        returned NULL_TREE.
        (build_value_init_noctor): Don't push anything into v if
        build_value_init call returned NULL_TREE.

        * g++.dg/parse/crash61.C: New test.

--- gcc/cp/init.c.jj    2013-02-07 17:40:59.432029399 +0100
+++ gcc/cp/init.c       2013-02-07 19:05:02.044062934 +0100
@@ -253,8 +253,6 @@ build_zero_init_1 (tree type, tree nelts
        {
          constructor_elt ce;
 
-         vec_alloc (v, 1);
-
          /* If this is a one element array, we just use a regular init.  */
          if (tree_int_cst_equal (size_zero_node, max_index))
            ce.index = size_zero_node;
@@ -265,7 +263,11 @@ build_zero_init_1 (tree type, tree nelts
          ce.value = build_zero_init_1 (TREE_TYPE (type),
                                         /*nelts=*/NULL_TREE,
                                         static_storage_p, NULL_TREE);
-         v->quick_push (ce);
+         if (ce.value)
+           {
+             vec_alloc (v, 1);
+             v->quick_push (ce);
+           }
        }
 
       /* Build a constructor to contain the initializations.  */
@@ -447,8 +449,6 @@ build_value_init_noctor (tree type, tsub
        {
          constructor_elt ce;
 
-         vec_alloc (v, 1);
-
          /* If this is a one element array, we just use a regular init.  */
          if (tree_int_cst_equal (size_zero_node, max_index))
            ce.index = size_zero_node;
@@ -456,16 +456,20 @@ build_value_init_noctor (tree type, tsub
            ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node, max_index);
 
          ce.value = build_value_init (TREE_TYPE (type), complain);
-         v->quick_push (ce);
+         if (ce.value)
+           {
+             if (ce.value == error_mark_node)
+               return error_mark_node;
 
-         if (ce.value == error_mark_node)
-           return error_mark_node;
+             vec_alloc (v, 1);
+             v->quick_push (ce);
 
-         /* We shouldn't have gotten here for anything that would need
-            non-trivial initialization, and gimplify_init_ctor_preeval
-            would need to be fixed to allow it.  */
-         gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR
-                     && TREE_CODE (ce.value) != AGGR_INIT_EXPR);
+             /* We shouldn't have gotten here for anything that would need
+                non-trivial initialization, and gimplify_init_ctor_preeval
+                would need to be fixed to allow it.  */
+             gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR
+                         && TREE_CODE (ce.value) != AGGR_INIT_EXPR);
+           }
        }
 
       /* Build a constructor to contain the initializations.  */
@@ -3469,9 +3473,12 @@ build_vec_init (tree base, tree maxindex
              else
                {
                  if (do_static_init)
-                   CONSTRUCTOR_APPEND_ELT (new_vec, field,
-                                           build_zero_init (TREE_TYPE (e),
-                                                            NULL_TREE, true));
+                   {
+                     tree value = build_zero_init (TREE_TYPE (e), NULL_TREE,
+                                                   true);
+                     if (value)
+                       CONSTRUCTOR_APPEND_ELT (new_vec, field, value);
+                   }
                  saw_non_const = true;
                }
            }
--- gcc/testsuite/g++.dg/parse/crash61.C.jj     2013-02-07 19:03:49.713481742 
+0100
+++ gcc/testsuite/g++.dg/parse/crash61.C        2013-02-07 19:03:49.713481742 
+0100
@@ -0,0 +1,6 @@
+// PR c++/56241
+// { dg-do compile }
+
+struct pair { constexpr pair (const) : }; // { dg-error "" }
+template <0> make_pair () {}             // { dg-error "" }
+pair prefix[] = { 0, make_pair }         // { dg-error "" }

        Jakub

Reply via email to