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.
commit f1a7cdfc760884b87fc888e70c34f3268d77aeac
Author: Jason Merrill <ja...@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()};
+}