commit ed588cf8d90c740ea189727eecb7dac3b7c24320
Author: Jason Merrill <jason@redhat.com>
Date: Wed Nov 30 16:32:22 2011 -0500
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.
@@ -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;
};
@@ -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
@@ -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;
new file mode 100644
@@ -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 = {};