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