static void unsave_expr_1 (tree);
static tree unsave_r (tree *, int *, void *);
static void declare_inline_vars (tree bind_expr, tree vars);
+static void remap_save_expr (tree *, void *, int *);
/* Insert a tree->tree mapping for ID. Despite the name suggests
that the trees should be variables, it is used for more than that. */
remap_save_expr (tp, id->decl_map, walk_subtrees);
else if (TREE_CODE (*tp) == BIND_EXPR)
copy_bind_expr (tp, walk_subtrees, id);
- else if (TREE_CODE (*tp) == LABELED_BLOCK_EXPR)
- {
- /* We need a new copy of this labeled block; the EXIT_BLOCK_EXPR
- will refer to it, so save a copy ready for remapping. We
- save it in the decl_map, although it isn't a decl. */
- tree new_block = copy_node (*tp);
- insert_decl_map (id, *tp, new_block);
- *tp = new_block;
- }
- else if (TREE_CODE (*tp) == EXIT_BLOCK_EXPR)
- {
- splay_tree_node n
- = splay_tree_lookup (id->decl_map,
- (splay_tree_key) TREE_OPERAND (*tp, 0));
- /* We _must_ have seen the enclosing LABELED_BLOCK_EXPR. */
- gcc_assert (n);
- *tp = copy_node (*tp);
- TREE_OPERAND (*tp, 0) = (tree) n->value;
- }
/* Types may need remapping as well. */
else if (TYPE_P (*tp))
*tp = remap_type (*tp, id);
+ /* If this is a constant, we have to copy the node iff the type will be
+ remapped. copy_tree_r will not copy a constant. */
+ else if (TREE_CODE_CLASS (TREE_CODE (*tp)) == tcc_constant)
+ {
+ tree new_type = remap_type (TREE_TYPE (*tp), id);
+
+ if (new_type == TREE_TYPE (*tp))
+ *walk_subtrees = 0;
+
+ else if (TREE_CODE (*tp) == INTEGER_CST)
+ *tp = build_int_cst_wide (new_type, TREE_INT_CST_LOW (*tp),
+ TREE_INT_CST_HIGH (*tp));
+ else
+ {
+ *tp = copy_node (*tp);
+ TREE_TYPE (*tp) = new_type;
+ }
+ }
+
/* Otherwise, just copy the node. Note that copy_tree_r already
knows not to copy VAR_DECLs, etc., so this is safe. */
else
STRIP_TYPE_NOPS (value);
if (TREE_CONSTANT (value) || TREE_READONLY_DECL_P (value))
{
- *tp = value;
+ *tp = build_empty_stmt ();
return copy_body_r (tp, walk_subtrees, data);
}
}
UNION_TYPE nodes, then it goes into infinite recursion on a
structure containing a pointer to its own type. If it doesn't,
then the type node for S doesn't get adjusted properly when
- F is inlined, and we abort in find_function_data. */
+ F is inlined, and we abort in find_function_data.
+
+ ??? This is likely no longer true, but it's too late in the 4.0
+ cycle to try to find out. This should be checked for 4.1. */
for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
if (variably_modified_type_p (TREE_TYPE (t), NULL))
{
case FILTER_EXPR: /* ??? */
case COMPOUND_EXPR:
case BIND_EXPR:
- case LABELED_BLOCK_EXPR:
case WITH_CLEANUP_EXPR:
case NOP_EXPR:
case VIEW_CONVERT_EXPR:
case SAVE_EXPR:
case ADDR_EXPR:
case COMPLEX_EXPR:
- case EXIT_BLOCK_EXPR:
case CASE_LABEL_EXPR:
case SSA_NAME:
case CATCH_EXPR:
}
}
- else if (code != EXIT_BLOCK_EXPR
- && code != SAVE_EXPR
+ else if (code != SAVE_EXPR
&& code != BIND_EXPR
&& IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
{
case CONSTRUCTOR:
WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
- case EXIT_BLOCK_EXPR:
- WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1));
-
case SAVE_EXPR:
WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 0));
information indicating to what new SAVE_EXPR this one should be mapped,
use that one. Otherwise, create a new node and enter it in ST. */
-void
+static void
remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
{
splay_tree st = (splay_tree) st_;