summaryrefslogtreecommitdiff
path: root/gcc/c-decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c-decl.c')
-rw-r--r--gcc/c-decl.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index c03c1262f3b..82e42f04e66 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -3061,7 +3061,24 @@ finish_decl (tree decl, tree init, tree asmspec_tree)
}
if (TREE_CODE (decl) != FUNCTION_DECL)
- add_stmt (build_stmt (DECL_EXPR, decl));
+ {
+ /* If we're building a variable sized type, and we might be
+ reachable other than via the top of the current binding
+ level, then create a new BIND_EXPR so that we deallocate
+ the object at the right time. */
+ /* Note that DECL_SIZE can be null due to errors. */
+ if (DECL_SIZE (decl)
+ && !TREE_CONSTANT (DECL_SIZE (decl))
+ && STATEMENT_LIST_HAS_LABEL (cur_stmt_list))
+ {
+ tree bind;
+ bind = build (BIND_EXPR, void_type_node, NULL, NULL, NULL);
+ TREE_SIDE_EFFECTS (bind) = 1;
+ add_stmt (bind);
+ BIND_EXPR_BODY (bind) = push_stmt_list ();
+ }
+ add_stmt (build_stmt (DECL_EXPR, decl));
+ }
}