Patchwork [committed] Fix up C++ ICEs in build_constructor (PR c++/56241)

login
register
mail settings
Submitter Jakub Jelinek
Date Feb. 7, 2013, 9:30 p.m.
Message ID <20130207213027.GJ4385@tucnak.redhat.com>
Download mbox | patch
Permalink /patch/218994/
State New
Headers show

Comments

Jakub Jelinek - Feb. 7, 2013, 9:30 p.m.
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  <jakub@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.


	Jakub

Patch

--- 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 "" }