Patchwork C++ PATCH for c++/49996 (stray gimple_with_cleanup_expr with new and init-list)

login
register
mail settings
Submitter Jason Merrill
Date Oct. 25, 2011, 7 p.m.
Message ID <4EA70751.7090601@redhat.com>
Download mbox | patch
Permalink /patch/121781/
State New
Headers show

Comments

Jason Merrill - Oct. 25, 2011, 7 p.m.
In a new-expression, we try to pre-evaluate all of the arguments to a 
constructor before allocating the memory in order to improve EH region 
nesting.  In the case of a list-initialized object, we want to 
pre-evaluate the arguments to any constructors for each of the 
subobjects.  If the subobject is scalar, we also want to pre-evaluate 
its value; this patch adds that.

Tested x86_64-pc-linux-gnu, applying to trunk.

Patch

commit f1a7cdfc760884b87fc888e70c34f3268d77aeac
Author: Jason Merrill <jason@redhat.com>
Date:   Tue Oct 25 10:37:47 2011 -0400

    	PR c++/49996
    	* tree.c (stabilize_init): Stabilize scalar elements of a
    	CONSTRUCTOR, too.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d023eb8..707f2c8 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3345,11 +3345,20 @@  stabilize_init (tree init, tree *initp)
       /* Aggregate initialization: stabilize each of the field
 	 initializers.  */
       unsigned i;
-      tree value;
+      constructor_elt *ce;
       bool good = true;
-      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, value)
-	if (!stabilize_init (value, initp))
-	  good = false;
+      VEC(constructor_elt,gc) *v = CONSTRUCTOR_ELTS (t);
+      for (i = 0; VEC_iterate (constructor_elt, v, i, ce); ++i)
+	{
+	  tree type = TREE_TYPE (ce->value);
+	  tree subinit;
+	  if (TREE_CODE (type) == REFERENCE_TYPE
+	      || SCALAR_TYPE_P (type))
+	    ce->value = stabilize_expr (ce->value, &subinit);
+	  else if (!stabilize_init (ce->value, &subinit))
+	    good = false;
+	  *initp = add_stmt_to_compound (*initp, subinit);
+	}
       return good;
     }
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist59.C b/gcc/testsuite/g++.dg/cpp0x/initlist59.C
new file mode 100644
index 0000000..2cc015d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist59.C
@@ -0,0 +1,18 @@ 
+// PR c++/49996
+// { dg-options -std=c++0x }
+
+struct A
+{
+  ~A()
+  { }
+};
+
+struct B
+{
+  const A& ref;
+};
+
+int main()
+{
+  B* p = new B{A()};
+}