This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Generate CLEANUP_POINT_EXPRs early
- From: Richard Henderson <rth at twiddle dot net>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 20 Jun 2004 03:18:53 -0700
- Subject: Generate CLEANUP_POINT_EXPRs early
Step 1 toward removing the essentially content-free EXPR_STMT.
Instead of looking at a saved copy of stmts_are_full_exprs_p
during gimplification, examine the original copy during code
generation and build the CLEANUP_POINT_EXPR on the spot.
EXPR_STMTs are still tied up with STMT_EXPRs; it'll take a bit
more to tease that knot apart so that this node can vanish.
r~
* c-common.h (add_decl_stmt): Move to cp-tree.h.
* c-decl.c (finish_decl): Don't use add_decl_stmt.
* c-parse.in: Likewise.
* c-gimplify.c (gimplify_expr_stmt): Don't build CLEANUP_POINT_EXPR.
(gimplify_c_loop, gimplify_return_stmt, gimplify_decl_stmt): Likewise.
* c-semantics.c (add_decl_stmt): Move to cp/semantics.c.
cp/
* cp-tree.h (add_decl_stmt): Declare.
* pt.c (tsubst_copy): Abort for CLEANUP_POINT_EXPR.
* semantics.c (maybe_cleanup_point_expr): New.
(add_decl_stmt, finish_expr_stmt, finish_return_stmt,
finish_for_expr, finish_switch_cond): Use it.
(finalize_nrv_r): Don't build an EXPR_STMT. Don't frob TREE_CHAIN.
Index: gcc/c-common.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.h,v
retrieving revision 1.240
diff -u -p -u -r1.240 c-common.h
--- gcc/c-common.h 20 Jun 2004 09:18:04 -0000 1.240
+++ gcc/c-common.h 20 Jun 2004 10:04:20 -0000
@@ -294,7 +294,6 @@ extern tree push_stmt_list (void);
extern tree re_push_stmt_list (tree);
extern tree pop_stmt_list (tree);
extern tree add_stmt (tree);
-extern void add_decl_stmt (tree);
extern void push_cleanup (tree, tree, bool);
extern tree walk_stmt_tree (tree *, walk_tree_fn, void *);
Index: gcc/c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.511
diff -u -p -u -r1.511 c-decl.c
--- gcc/c-decl.c 20 Jun 2004 08:34:43 -0000 1.511
+++ gcc/c-decl.c 20 Jun 2004 10:04:21 -0000
@@ -2940,7 +2940,7 @@ finish_decl (tree decl, tree init, tree
}
if (TREE_CODE (decl) != FUNCTION_DECL)
- add_decl_stmt (decl);
+ add_stmt (build_stmt (DECL_STMT, decl));
}
if (!DECL_FILE_SCOPE_P (decl))
@@ -2967,7 +2967,7 @@ finish_decl (tree decl, tree init, tree
{
if (!DECL_FILE_SCOPE_P (decl)
&& variably_modified_type_p (TREE_TYPE (decl)))
- add_decl_stmt (decl);
+ add_stmt (build_stmt (DECL_STMT, decl));
rest_of_decl_compilation (decl, NULL, DECL_FILE_SCOPE_P (decl), 0);
}
Index: gcc/c-gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-gimplify.c,v
retrieving revision 2.12
diff -u -p -u -r2.12 c-gimplify.c
--- gcc/c-gimplify.c 20 Jun 2004 09:18:04 -0000 2.12
+++ gcc/c-gimplify.c 20 Jun 2004 10:04:21 -0000
@@ -249,8 +249,6 @@ gimplify_expr_stmt (tree *stmt_p)
if (stmt == NULL_TREE)
stmt = build_empty_stmt ();
- else if (stmts_are_full_exprs_p ())
- stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
*stmt_p = stmt;
@@ -383,8 +381,6 @@ gimplify_c_loop (tree cond, tree body, t
cont_block = begin_bc_block (bc_continue);
gimplify_stmt (&body);
- if (incr && stmts_are_full_exprs_p ())
- incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
gimplify_stmt (&incr);
body = finish_bc_block (cont_block, body);
@@ -483,8 +479,6 @@ gimplify_return_stmt (tree *stmt_p)
{
tree expr = RETURN_STMT_EXPR (*stmt_p);
expr = build1 (RETURN_EXPR, void_type_node, expr);
- if (stmts_are_full_exprs_p ())
- expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
*stmt_p = expr;
return GS_OK;
}
@@ -553,8 +547,6 @@ gimplify_decl_stmt (tree *stmt_p)
DECL_INITIAL (decl) = NULL_TREE;
init = build (MODIFY_EXPR, void_type_node, decl, init);
- if (stmts_are_full_exprs_p ())
- init = build1 (CLEANUP_POINT_EXPR, void_type_node, init);
append_to_compound_expr (init, &pre);
}
else
Index: gcc/c-parse.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-parse.in,v
retrieving revision 1.215
diff -u -p -u -r1.215 c-parse.in
--- gcc/c-parse.in 18 Jun 2004 01:20:51 -0000 1.215
+++ gcc/c-parse.in 20 Jun 2004 10:04:21 -0000
@@ -1540,7 +1540,7 @@ nested_function:
add_stmt ($6);
finish_function ();
pop_function_context ();
- add_decl_stmt (decl); }
+ add_stmt (build_stmt (DECL_STMT, decl)); }
;
notype_nested_function:
@@ -1570,7 +1570,7 @@ notype_nested_function:
add_stmt ($6);
finish_function ();
pop_function_context ();
- add_decl_stmt (decl); }
+ add_stmt (build_stmt (DECL_STMT, decl)); }
;
/* Any kind of declarator (thus, all declarators allowed
@@ -2019,7 +2019,7 @@ label_decl:
{
tree label = declare_label (TREE_VALUE (link));
C_DECLARED_LABEL_FLAG (label) = 1;
- add_decl_stmt (label);
+ add_stmt (build_stmt (DECL_STMT, label));
}
}
;
Index: gcc/c-semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-semantics.c,v
retrieving revision 1.86
diff -u -p -u -r1.86 c-semantics.c
--- gcc/c-semantics.c 20 Jun 2004 09:18:04 -0000 1.86
+++ gcc/c-semantics.c 20 Jun 2004 10:04:21 -0000
@@ -145,19 +145,6 @@ add_stmt (tree t)
return t;
}
-/* Create a declaration statement for the declaration given by the
- DECL. */
-
-void
-add_decl_stmt (tree decl)
-{
- tree decl_stmt;
-
- /* We need the type to last until instantiation time. */
- decl_stmt = build_stmt (DECL_STMT, decl);
- add_stmt (decl_stmt);
-}
-
/* Build a generic statement based on the given type of node and
arguments. Similar to `build_nt', except that we set
EXPR_LOCUS to be the current source location. */
Index: gcc/cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.982
diff -u -p -u -r1.982 cp-tree.h
--- gcc/cp/cp-tree.h 20 Jun 2004 09:18:09 -0000 1.982
+++ gcc/cp/cp-tree.h 20 Jun 2004 10:04:22 -0000
@@ -4028,6 +4028,7 @@ extern void pop_to_parent_deferring_acce
extern void perform_deferred_access_checks (void);
extern void perform_or_defer_access_check (tree, tree);
extern void init_cp_semantics (void);
+extern void add_decl_stmt (tree);
extern tree finish_expr_stmt (tree);
extern tree begin_if_stmt (void);
extern void finish_if_stmt_cond (tree, tree);
Index: gcc/cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.869
diff -u -p -u -r1.869 pt.c
--- gcc/cp/pt.c 19 Jun 2004 19:34:22 -0000 1.869
+++ gcc/cp/pt.c 20 Jun 2004 10:04:23 -0000
@@ -7726,6 +7726,12 @@ tsubst_copy (tree t, tree args, tsubst_f
in_decl),
tsubst (TREE_TYPE (t), args, complain, in_decl));
+ case CLEANUP_POINT_EXPR:
+ /* We shouldn't have built any of these during initial template
+ generation. Instead, they should be built during instantiation
+ in response to the saved STMT_IS_FULL_EXPR_P setting. */
+ abort ();
+
default:
return t;
}
Index: gcc/cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.404
diff -u -p -u -r1.404 semantics.c
--- gcc/cp/semantics.c 20 Jun 2004 09:18:13 -0000 1.404
+++ gcc/cp/semantics.c 20 Jun 2004 10:04:24 -0000
@@ -304,6 +304,27 @@ current_stmt_tree (void)
: &scope_chain->x_stmt_tree);
}
+/* If statements are full expressions, wrap STMT in a CLEANUP_POINT_EXPR. */
+
+static tree
+maybe_cleanup_point_expr (tree expr)
+{
+ if (!processing_template_decl && stmts_are_full_exprs_p ())
+ expr = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (expr), expr));
+ return expr;
+}
+
+/* Create a declaration statement for the declaration given by the DECL. */
+
+void
+add_decl_stmt (tree decl)
+{
+ tree r = build_stmt (DECL_STMT, decl);
+ if (DECL_INITIAL (decl))
+ r = maybe_cleanup_point_expr (r);
+ add_stmt (r);
+}
+
/* Nonzero if TYPE is an anonymous union or struct type. We have to use a
flag for this because "A union for which objects or pointers are
declared is not an anonymous union" [class.union]. */
@@ -478,8 +499,13 @@ finish_expr_stmt (tree expr)
/* Simplification of inner statement expressions, compound exprs,
etc can result in the us already having an EXPR_STMT. */
- if (TREE_CODE (expr) != EXPR_STMT)
- expr = build_stmt (EXPR_STMT, expr);
+ if (TREE_CODE (expr) != CLEANUP_POINT_EXPR)
+ {
+ if (TREE_CODE (expr) != EXPR_STMT)
+ expr = build_stmt (EXPR_STMT, expr);
+ expr = maybe_cleanup_point_expr (expr);
+ }
+
r = add_stmt (expr);
}
@@ -636,7 +662,10 @@ finish_return_stmt (tree expr)
return finish_goto_stmt (dtor_label);
}
}
- r = add_stmt (build_stmt (RETURN_STMT, expr));
+
+ r = build_stmt (RETURN_STMT, expr);
+ r = maybe_cleanup_point_expr (r);
+ r = add_stmt (r);
finish_stmt ();
return r;
@@ -690,13 +719,16 @@ finish_for_cond (tree cond, tree for_stm
void
finish_for_expr (tree expr, tree for_stmt)
{
+ if (!expr)
+ return;
/* If EXPR is an overloaded function, issue an error; there is no
context available to use to perform overload resolution. */
- if (expr && type_unknown_p (expr))
+ if (type_unknown_p (expr))
{
cxx_incomplete_type_error (expr, TREE_TYPE (expr));
expr = error_mark_node;
}
+ expr = maybe_cleanup_point_expr (expr);
FOR_EXPR (for_stmt) = expr;
}
@@ -777,7 +809,7 @@ finish_switch_cond (tree cond, tree swit
Integral promotions are performed. */
cond = perform_integral_promotions (cond);
- cond = fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (cond), cond));
+ cond = maybe_cleanup_point_expr (cond);
}
if (cond != error_mark_node)
@@ -1499,8 +1531,7 @@ finish_stmt_expr (tree stmt_expr, bool h
init = TREE_OPERAND (target_expr, 1);
type = TREE_TYPE (init);
- if (stmts_are_full_exprs_p ())
- init = fold (build1 (CLEANUP_POINT_EXPR, type, init));
+ init = maybe_cleanup_point_expr (init);
*result_stmt_p = init;
if (VOID_TYPE_P (type))
@@ -2995,10 +3026,8 @@ finalize_nrv_r (tree* tp, int* walk_subt
DECL_INITIAL (dp->var) = error_mark_node;
}
else
- init = NULL_TREE;
- init = build_stmt (EXPR_STMT, init);
+ init = build_empty_stmt ();
SET_EXPR_LOCUS (init, EXPR_LOCUS (*tp));
- TREE_CHAIN (init) = TREE_CHAIN (*tp);
*tp = init;
}
/* And replace all uses of the NRV with the RESULT_DECL. */