From 174283a3c26828ee2bf0acd05f6350f439beefcc Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Wed, 11 Aug 2004 21:09:57 -0700 Subject: [PATCH] c-common.h (STATEMENT_LIST_HAS_LABEL): New. * c-common.h (STATEMENT_LIST_HAS_LABEL): New. * c-semantics.c (add_stmt): Set it. * c-decl.c (finish_decl): Use it to create a new BIND_EXPR before instantiating a variable sized type. From-SVN: r85849 --- gcc/ChangeLog | 7 +++++++ gcc/c-common.h | 6 +++++- gcc/c-decl.c | 19 ++++++++++++++++++- gcc/c-semantics.c | 3 +++ .../gcc.c-torture/execute/20040811-1.c | 19 +++++++++++++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20040811-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e3cd92d3725..b0e986be8fc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2004-08-12 Richard Henderson + + * c-common.h (STATEMENT_LIST_HAS_LABEL): New. + * c-semantics.c (add_stmt): Set it. + * c-decl.c (finish_decl): Use it to create a new BIND_EXPR + before instantiating a variable sized type. + 2004-08-12 Richard Henderson * stor-layout.c (round_up, round_down): Move ... diff --git a/gcc/c-common.h b/gcc/c-common.h index e8d245c88b1..1c9286ef7b7 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -35,7 +35,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA STMT_IS_FULL_EXPR_P (in _STMT) STATEMENT_LIST_STMT_EXPR (in STATEMENT_LIST) 2: unused - 3: unused + 3: STATEMENT_LIST_HAS_LABEL (in STATEMENT_LIST) 4: unused */ @@ -708,6 +708,10 @@ extern void finish_file (void); #define STATEMENT_LIST_STMT_EXPR(NODE) \ TREE_LANG_FLAG_1 (STATEMENT_LIST_CHECK (NODE)) +/* Nonzero if a label has been added to the statement list. */ +#define STATEMENT_LIST_HAS_LABEL(NODE) \ + TREE_LANG_FLAG_3 (STATEMENT_LIST_CHECK (NODE)) + /* WHILE_STMT accessors. These give access to the condition of the while statement and the body of the while statement, respectively. */ #define WHILE_COND(NODE) TREE_OPERAND (WHILE_STMT_CHECK (NODE), 0) 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)); + } } diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c index f40f5a2e495..f011cb90a1e 100644 --- a/gcc/c-semantics.c +++ b/gcc/c-semantics.c @@ -140,6 +140,9 @@ add_stmt (tree t) STMT_IS_FULL_EXPR_P (t) = stmts_are_full_exprs_p (); } + if (code == LABEL_EXPR || code == CASE_LABEL_EXPR) + STATEMENT_LIST_HAS_LABEL (cur_stmt_list) = 1; + /* Add T to the statement-tree. Non-side-effect statements need to be recorded during statement expressions. */ append_to_statement_list_force (t, &cur_stmt_list); diff --git a/gcc/testsuite/gcc.c-torture/execute/20040811-1.c b/gcc/testsuite/gcc.c-torture/execute/20040811-1.c new file mode 100644 index 00000000000..62f377a2f24 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20040811-1.c @@ -0,0 +1,19 @@ +/* Ensure that we deallocate X when branching back before its + declaration. */ + +void *volatile p; + +int +main (void) +{ + int n = 0; + lab:; + int x[n % 1000 + 1]; + x[0] = 1; + x[n % 1000] = 2; + p = x; + n++; + if (n < 1000000) + goto lab; + return 0; +} -- 2.30.2