c-common.h (STATEMENT_LIST_HAS_LABEL): New.
authorRichard Henderson <rth@redhat.com>
Thu, 12 Aug 2004 04:09:57 +0000 (21:09 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 12 Aug 2004 04:09:57 +0000 (21:09 -0700)
        * 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
gcc/c-common.h
gcc/c-decl.c
gcc/c-semantics.c
gcc/testsuite/gcc.c-torture/execute/20040811-1.c [new file with mode: 0644]

index e3cd92d..b0e986b 100644 (file)
@@ -1,5 +1,12 @@
 2004-08-12  Richard Henderson  <rth@redhat.com>
 
+       * 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  <rth@redhat.com>
+
        * stor-layout.c (round_up, round_down): Move ...
        * fold-const.c (round_up, round_down): ... here.  Use 
        multiple_of_p to avoid any arithmetic at all.
index e8d245c..1c9286e 100644 (file)
@@ -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)
index c03c126..82e42f0 100644 (file)
@@ -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));
+           }
        }
   
 
index f40f5a2..f011cb9 100644 (file)
@@ -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 (file)
index 0000000..62f377a
--- /dev/null
@@ -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;
+}