aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/semantics.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cp/semantics.c')
-rw-r--r--gcc/cp/semantics.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index e53222f..92efe44 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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_stmt)
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 switch_stmt)
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 has_no_scope)
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_subtrees, void* data)
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. */