diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 4d65dd1b7f1760163c7fd77aac23665b73057cfa..8ef95aa0b17a4c5c240810eae5e0a62ff7343a81 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -487,18 +487,13 @@ struct GTY(()) stmt_tree_s {
   VEC(tree,gc) *x_cur_stmt_list;
 
   /* In C++, Nonzero if we should treat statements as full
-     expressions.  In particular, this variable is no-zero if at the
+     expressions.  In particular, this variable is non-zero if at the
      end of a statement we should destroy any temporaries created
      during that statement.  Similarly, if, at the end of a block, we
      should destroy any local variables in this block.  Normally, this
      variable is nonzero, since those are the normal semantics of
      C++.
 
-     However, in order to represent aggregate initialization code as
-     tree structure, we use statement-expressions.  The statements
-     within the statement expression should not result in cleanups
-     being run until the entire enclosing statement is complete.
-
      This flag has no effect in C.  */
   int stmts_are_full_exprs_p;
 };
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 42573eff39d3158d95690063a92c6a8a5105e6b9..55addacfe464d945523c99809f15b7064942a3dd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2011-11-30  Jason Merrill  <jason@redhat.com>
+
+	PR c++/51009
+	* name-lookup.c (push_to_top_level): Set stmts_are_full_exprs_p.
+	* decl.c (build_aggr_init_full_exprs): Just assert that it's true.
+	(check_initializer): Here too.
+
 2011-11-30  Paolo Carlini  <paolo.carlini@oracle.com>
 
 	PR c++/51299
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 84064326f4dd00172dd9c480eb77cac7eb9e2ab4..055c1b2020f014c51c6e88e57ffc2fc99de176ca 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -5367,17 +5367,8 @@ static tree
 build_aggr_init_full_exprs (tree decl, tree init, int flags)
      
 {
-  int saved_stmts_are_full_exprs_p = 0;
-  if (building_stmt_list_p ())
-    {
-      saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
-      current_stmt_tree ()->stmts_are_full_exprs_p = 1;
-    }
-  init = build_aggr_init (decl, init, flags, tf_warning_or_error);
-  if (building_stmt_list_p ())
-    current_stmt_tree ()->stmts_are_full_exprs_p =
-      saved_stmts_are_full_exprs_p;
-  return init;
+  gcc_assert (stmts_are_full_exprs_p ());
+  return build_aggr_init (decl, init, flags, tf_warning_or_error);
 }
 
 /* Verify INIT (the initializer for DECL), and record the
@@ -5550,7 +5541,13 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups)
 
       if (init && TREE_CODE (init) != TREE_VEC)
 	{
+	  /* In aggregate initialization of a variable, each element
+	     initialization is a full-expression because there is no
+	     enclosing expression.  */
+	  gcc_assert (stmts_are_full_exprs_p ());
+
 	  init_code = store_init_value (decl, init, cleanups, flags);
+
 	  if (pedantic && TREE_CODE (type) == ARRAY_TYPE
 	      && DECL_INITIAL (decl)
 	      && TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 7f6b8cdcf296beb6e5e97f7ffbf5a86d3cfcc946..ceecdef3e8ddcf21ffbb517e1f0d54d82185f427 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5916,6 +5916,7 @@ push_to_top_level (void)
   s->function_decl = current_function_decl;
   s->unevaluated_operand = cp_unevaluated_operand;
   s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
+  s->x_stmt_tree.stmts_are_full_exprs_p = true;
 
   scope_chain = s;
   current_function_decl = NULL_TREE;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9e8ec39ceee390e4c64b99121c68fa40b68c1640..8e29dab0ade33c36e4f3b084409273d4932e1f5f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-11-30  Jason Merrill  <jason@redhat.com>
+
+	PR c++/51009
+	* g++.dg/init/aggr8.C: New.
+
 2011-11-30  Jakub Jelinek  <jakub@redhat.com>
 
 	PR target/50725
diff --git a/gcc/testsuite/g++.dg/init/aggr8.C b/gcc/testsuite/g++.dg/init/aggr8.C
new file mode 100644
index 0000000000000000000000000000000000000000..7e6edc9ad6c81b910fadc9670968283eb0745ef5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/aggr8.C
@@ -0,0 +1,19 @@
+// PR c++/51009
+
+struct A
+{
+  ~A();
+};
+
+struct B
+{
+  A a;
+  B(const A& = A());
+};
+
+struct C
+{
+  B b1, b2;
+};
+
+C c = {};