Commit fad41cd7 by Richard Henderson Committed by Richard Henderson

re PR middle-end/26084 (ICE (segfault) on C++ OpenMP code)

        PR middle-end/26084
        * except.c (duplicate_eh_regions_0): New.
        (duplicate_eh_region_1): Duplicate the children of the node as
        well as the node itself.  Link them up properly.
        (duplicate_eh_region_2): Merge into ...
        (duplicate_eh_regions): ... here.  Take copy_region argument, and
        copy only a sub-tree if asked.  Simplify copying and fixup.
        (eh_region_outer_p): New.
        * except.h (duplicate_eh_regions): Update decl.
        (eh_region_outer_p): Declare.
        * omp-low.c (lower_omp_single): Fix eh region placement wrt OMP_RETURN.
        (lower_omp_master): Likewise.
        (lower_omp_ordered): Likewise.
        * tree-cfg.c (struct move_stmt_d): Add new_label_map.
        (move_stmt_r): Use it to remap labels.  Handle recursion vs
        remap_decls_p properly.
        (move_block_to_fn): Pass in new_label_map.  Remap RESX_EXPR.
        (find_outermost_region_in_block): New.
        (new_label_mapper): New.
        (move_sese_region_to_fn): Copy eh information to the new function
        properly.
        * tree-inline.c (copy_cfg_body): Update for new duplicate_eh_regions
        argument.
        * tree-pretty-print.c (dump_generic_node): Dump RESX_EXPR region
        number.

From-SVN: r112283
parent ee51e035
2006-03-22 Richard Henderson <rth@redhat.com>
PR middle-end/26084
* except.c (duplicate_eh_regions_0): New.
(duplicate_eh_region_1): Duplicate the children of the node as
well as the node itself. Link them up properly.
(duplicate_eh_region_2): Merge into ...
(duplicate_eh_regions): ... here. Take copy_region argument, and
copy only a sub-tree if asked. Simplify copying and fixup.
(eh_region_outer_p): New.
* except.h (duplicate_eh_regions): Update decl.
(eh_region_outer_p): Declare.
* omp-low.c (lower_omp_single): Fix eh region placement wrt OMP_RETURN.
(lower_omp_master): Likewise.
(lower_omp_ordered): Likewise.
* tree-cfg.c (struct move_stmt_d): Add new_label_map.
(move_stmt_r): Use it to remap labels. Handle recursion vs
remap_decls_p properly.
(move_block_to_fn): Pass in new_label_map. Remap RESX_EXPR.
(find_outermost_region_in_block): New.
(new_label_mapper): New.
(move_sese_region_to_fn): Copy eh information to the new function
properly.
* tree-inline.c (copy_cfg_body): Update for new duplicate_eh_regions
argument.
* tree-pretty-print.c (dump_generic_node): Dump RESX_EXPR region
number.
2006-03-22 Richard Sandiford <richard@codesourcery.com>
* doc/md.texi (-mshared): Mention that -mshared code can be linked
......
......@@ -857,84 +857,145 @@ current_function_has_exception_handlers (void)
return false;
}
static struct eh_region *
duplicate_eh_region_1 (struct eh_region *o)
{
struct eh_region *n = ggc_alloc_cleared (sizeof (struct eh_region));
*n = *o;
/* A subroutine of duplicate_eh_regions. Search the region tree under O
for the miniumum and maximum region numbers. Update *MIN and *MAX. */
n->region_number = o->region_number + cfun->eh->last_region_number;
VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n);
gcc_assert (!o->aka);
static void
duplicate_eh_regions_0 (eh_region o, int *min, int *max)
{
if (o->region_number < *min)
*min = o->region_number;
if (o->region_number > *max)
*max = o->region_number;
return n;
if (o->inner)
{
o = o->inner;
duplicate_eh_regions_0 (o, min, max);
while (o->next_peer)
{
o = o->next_peer;
duplicate_eh_regions_0 (o, min, max);
}
}
}
static void
duplicate_eh_region_2 (struct eh_region *o, struct eh_region **n_array,
struct eh_region *prev_try)
/* A subroutine of duplicate_eh_regions. Copy the region tree under OLD.
Root it at OUTER, and apply EH_OFFSET to the region number. Don't worry
about the other internal pointers just yet, just the tree-like pointers. */
static eh_region
duplicate_eh_regions_1 (eh_region old, eh_region outer, int eh_offset)
{
struct eh_region *n = n_array[o->region_number];
eh_region ret, n;
switch (n->type)
{
case ERT_TRY:
if (o->u.try.catch)
n->u.try.catch = n_array[o->u.try.catch->region_number];
if (o->u.try.last_catch)
n->u.try.last_catch = n_array[o->u.try.last_catch->region_number];
break;
ret = n = ggc_alloc (sizeof (struct eh_region));
case ERT_CATCH:
if (o->u.catch.next_catch)
n->u.catch.next_catch = n_array[o->u.catch.next_catch->region_number];
if (o->u.catch.prev_catch)
n->u.catch.prev_catch = n_array[o->u.catch.prev_catch->region_number];
break;
*n = *old;
n->outer = outer;
gcc_assert (!old->aka);
case ERT_CLEANUP:
if (o->u.cleanup.prev_try)
n->u.cleanup.prev_try = n_array[o->u.cleanup.prev_try->region_number];
else
n->u.cleanup.prev_try = prev_try;
break;
n->region_number += eh_offset;
VEC_replace (eh_region, cfun->eh->region_array, n->region_number, n);
default:
break;
if (old->inner)
{
old = old->inner;
n = n->inner = duplicate_eh_regions_1 (old, ret, eh_offset);
while (old->next_peer)
{
old = old->next_peer;
n = n->next_peer = duplicate_eh_regions_1 (old, ret, eh_offset);
}
}
if (o->outer)
n->outer = n_array[o->outer->region_number];
if (o->inner)
n->inner = n_array[o->inner->region_number];
if (o->next_peer)
n->next_peer = n_array[o->next_peer->region_number];
return ret;
}
/* Duplicate the EH regions of IFUN into current function, root the tree in
OUTER_REGION and remap labels using MAP callback. */
/* Duplicate the EH regions of IFUN, rootted at COPY_REGION, into current
function and root the tree below OUTER_REGION. Remap labels using MAP
callback. The special case of COPY_REGION of 0 means all regions. */
int
duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
void *data, int outer_region)
void *data, int copy_region, int outer_region)
{
int ifun_last_region_number = ifun->eh->last_region_number;
struct eh_region **n_array, *root, *cur, *prev_try;
int i;
eh_region cur, prev_try, outer, *splice;
int i, min_region, max_region, eh_offset, cfun_last_region_number;
int num_regions;
if (ifun_last_region_number == 0 || !ifun->eh->region_tree)
if (!ifun->eh->region_tree)
return 0;
n_array = xcalloc (ifun_last_region_number + 1, sizeof (*n_array));
/* Find the range of region numbers to be copied. The interface we
provide here mandates a single offset to find new number from old,
which means we must look at the numbers present, instead of the
count or something else. */
if (copy_region > 0)
{
min_region = INT_MAX;
max_region = 0;
cur = VEC_index (eh_region, ifun->eh->region_array, copy_region);
duplicate_eh_regions_0 (cur, &min_region, &max_region);
}
else
min_region = 1, max_region = ifun->eh->last_region_number;
num_regions = max_region - min_region + 1;
cfun_last_region_number = cfun->eh->last_region_number;
eh_offset = cfun_last_region_number + 1 - min_region;
/* If we've not yet created a region array, do so now. */
VEC_safe_grow (eh_region, gc, cfun->eh->region_array,
cfun->eh->last_region_number + 1 + ifun_last_region_number);
cfun_last_region_number + 1 + num_regions);
cfun->eh->last_region_number = max_region + eh_offset;
/* We might've created new cfun->eh->region_array so zero out nonexisting region 0. */
/* We may have just allocated the array for the first time.
Make sure that element zero is null. */
VEC_replace (eh_region, cfun->eh->region_array, 0, 0);
for (i = cfun->eh->last_region_number + 1;
i < cfun->eh->last_region_number + 1 + ifun_last_region_number; i++)
VEC_replace (eh_region, cfun->eh->region_array, i, 0);
/* Zero all entries in the range allocated. */
memset (VEC_address (eh_region, cfun->eh->region_array)
+ cfun_last_region_number + 1, 0, num_regions);
/* Locate the spot at which to insert the new tree. */
if (outer_region > 0)
{
outer = VEC_index (eh_region, cfun->eh->region_array, outer_region);
splice = &outer->inner;
}
else
{
outer = NULL;
splice = &cfun->eh->region_tree;
}
while (*splice)
splice = &(*splice)->next_peer;
/* Copy all the regions in the subtree. */
if (copy_region > 0)
{
cur = VEC_index (eh_region, ifun->eh->region_array, copy_region);
*splice = duplicate_eh_regions_1 (cur, outer, eh_offset);
}
else
{
eh_region n;
cur = ifun->eh->region_tree;
*splice = n = duplicate_eh_regions_1 (cur, outer, eh_offset);
while (cur->next_peer)
{
cur = cur->next_peer;
n = n->next_peer = duplicate_eh_regions_1 (cur, outer, eh_offset);
}
}
/* Remap all the labels in the new regions. */
for (i = cfun_last_region_number + 1;
VEC_iterate (eh_region, cfun->eh->region_array, i, cur); ++i)
if (cur && cur->tree_label)
cur->tree_label = map (cur->tree_label, data);
/* Search for the containing ERT_TRY region to fix up
the prev_try short-cuts for ERT_CLEANUP regions. */
......@@ -945,67 +1006,77 @@ duplicate_eh_regions (struct function *ifun, duplicate_eh_regions_map map,
prev_try = prev_try->outer)
;
for (i = 1; i <= ifun_last_region_number; ++i)
{
cur = VEC_index (eh_region, ifun->eh->region_array, i);
if (!cur || cur->region_number != i)
continue;
n_array[i] = duplicate_eh_region_1 (cur);
if (cur->tree_label)
{
tree newlabel = map (cur->tree_label, data);
n_array[i]->tree_label = newlabel;
}
else
n_array[i]->tree_label = NULL;
}
for (i = 1; i <= ifun_last_region_number; ++i)
/* Remap all of the internal catch and cleanup linkages. Since we
duplicate entire subtrees, all of the referenced regions will have
been copied too. And since we renumbered them as a block, a simple
bit of arithmetic finds us the index for the replacement region. */
for (i = cfun_last_region_number + 1;
VEC_iterate (eh_region, cfun->eh->region_array, i, cur); ++i)
{
cur = VEC_index (eh_region, ifun->eh->region_array, i);
if (!cur || cur->region_number != i)
if (cur == NULL)
continue;
duplicate_eh_region_2 (cur, n_array, prev_try);
}
root = n_array[ifun->eh->region_tree->region_number];
gcc_assert (root->outer == NULL);
if (outer_region > 0)
{
struct eh_region *cur
= VEC_index (eh_region, cfun->eh->region_array, outer_region);
struct eh_region *p = cur->inner;
#define REMAP(REG) \
(REG) = VEC_index (eh_region, cfun->eh->region_array, \
(REG)->region_number + eh_offset)
if (p)
switch (cur->type)
{
while (p->next_peer)
p = p->next_peer;
p->next_peer = root;
}
else
cur->inner = root;
for (i = 1; i <= ifun_last_region_number; ++i)
if (n_array[i] && n_array[i]->outer == NULL)
n_array[i]->outer = cur;
}
else
{
struct eh_region *p = cfun->eh->region_tree;
if (p)
{
while (p->next_peer)
p = p->next_peer;
p->next_peer = root;
case ERT_TRY:
if (cur->u.try.catch)
REMAP (cur->u.try.catch);
if (cur->u.try.last_catch)
REMAP (cur->u.try.last_catch);
break;
case ERT_CATCH:
if (cur->u.catch.next_catch)
REMAP (cur->u.catch.next_catch);
if (cur->u.catch.prev_catch)
REMAP (cur->u.catch.prev_catch);
break;
case ERT_CLEANUP:
if (cur->u.cleanup.prev_try)
REMAP (cur->u.cleanup.prev_try);
else
cur->u.cleanup.prev_try = prev_try;
break;
default:
break;
}
else
cfun->eh->region_tree = root;
#undef REMAP
}
free (n_array);
return eh_offset;
}
i = cfun->eh->last_region_number;
cfun->eh->last_region_number = i + ifun_last_region_number;
/* Return true if REGION_A is outer to REGION_B in IFUN. */
return i;
bool
eh_region_outer_p (struct function *ifun, int region_a, int region_b)
{
struct eh_region *rp_a, *rp_b;
gcc_assert (ifun->eh->last_region_number > 0);
gcc_assert (ifun->eh->region_tree);
rp_a = VEC_index (eh_region, ifun->eh->region_array, region_a);
rp_b = VEC_index (eh_region, ifun->eh->region_array, region_b);
gcc_assert (rp_a != NULL);
gcc_assert (rp_b != NULL);
do
{
if (rp_a == rp_b)
return true;
rp_b = rp_b->outer;
}
while (rp_b);
return false;
}
static int
......
......@@ -82,7 +82,8 @@ extern rtx expand_builtin_extend_pointer (tree);
extern rtx get_exception_pointer (struct function *);
extern rtx get_exception_filter (struct function *);
typedef tree (*duplicate_eh_regions_map) (tree, void *);
extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map, void *, int);
extern int duplicate_eh_regions (struct function *, duplicate_eh_regions_map,
void *, int, int);
extern void sjlj_emit_function_exit_after (rtx);
extern void default_init_unwind_resume_libfunc (void);
......@@ -106,6 +107,7 @@ extern void collect_eh_region_array (void);
extern void expand_resx_expr (tree);
extern void verify_eh_tree (struct function *);
extern void dump_eh_tree (FILE *, struct function *);
extern bool eh_region_outer_p (struct function *, int, int);
/* tree-eh.c */
extern void add_stmt_to_eh_region_fn (struct function *, tree, int);
......
......@@ -3464,6 +3464,9 @@ lower_omp_sections (tree *stmt_p, omp_context *ctx)
new_body = alloc_stmt_list ();
append_to_statement_list (ilist, &new_body);
append_to_statement_list (stmt, &new_body);
/* ??? The OMP_RETURN doesn't logically belong here, but in
expand_omp_sections we expect this marker to be where the
individual sections join after completing the loop. */
append_to_statement_list (region_exit, &new_body);
append_to_statement_list (olist, &new_body);
append_to_statement_list (dlist, &new_body);
......@@ -3610,9 +3613,9 @@ lower_omp_single (tree *stmt_p, omp_context *ctx)
lower_omp_single_simple (single_stmt, &BIND_EXPR_BODY (bind));
append_to_statement_list (dlist, &BIND_EXPR_BODY (bind));
maybe_catch_exception (&BIND_EXPR_BODY (bind));
t = make_node (OMP_RETURN_EXPR);
append_to_statement_list (t, &BIND_EXPR_BODY (bind));
maybe_catch_exception (&BIND_EXPR_BODY (bind));
pop_gimplify_context (bind);
BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
......@@ -3647,9 +3650,9 @@ lower_omp_master (tree *stmt_p, omp_context *ctx)
x = build1 (LABEL_EXPR, void_type_node, lab);
gimplify_and_add (x, &BIND_EXPR_BODY (bind));
maybe_catch_exception (&BIND_EXPR_BODY (bind));
x = make_node (OMP_RETURN_EXPR);
append_to_statement_list (x, &BIND_EXPR_BODY (bind));
maybe_catch_exception (&BIND_EXPR_BODY (bind));
pop_gimplify_context (bind);
BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
......@@ -3683,9 +3686,9 @@ lower_omp_ordered (tree *stmt_p, omp_context *ctx)
x = built_in_decls[BUILT_IN_GOMP_ORDERED_END];
x = build_function_call_expr (x, NULL);
gimplify_and_add (x, &BIND_EXPR_BODY (bind));
maybe_catch_exception (&BIND_EXPR_BODY (bind));
x = make_node (OMP_RETURN_EXPR);
append_to_statement_list (x, &BIND_EXPR_BODY (bind));
maybe_catch_exception (&BIND_EXPR_BODY (bind));
pop_gimplify_context (bind);
BIND_EXPR_VARS (bind) = chainon (BIND_EXPR_VARS (bind), ctx->block_vars);
......
......@@ -4591,6 +4591,7 @@ struct move_stmt_d
tree from_context;
tree to_context;
bitmap vars_to_remove;
htab_t new_label_map;
bool remap_decls_p;
};
......@@ -4599,39 +4600,62 @@ struct move_stmt_d
variable referenced in *TP. */
static tree
move_stmt_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
move_stmt_r (tree *tp, int *walk_subtrees, void *data)
{
struct move_stmt_d *p = (struct move_stmt_d *) data;
tree t = *tp;
if (p->block && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (*tp))))
TREE_BLOCK (*tp) = p->block;
if (p->block && IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t))))
TREE_BLOCK (t) = p->block;
if (OMP_DIRECTIVE_P (*tp))
if (OMP_DIRECTIVE_P (t) && TREE_CODE (t) != OMP_RETURN_EXPR)
{
/* Do not remap variables inside OMP directives. Variables
referenced in clauses and directive header belong to the
parent function and should not be moved into the child
function. */
bool save_remap_decls_p = p->remap_decls_p;
p->remap_decls_p = false;
}
*walk_subtrees = 0;
walk_tree (&OMP_BODY (t), move_stmt_r, p, NULL);
if (p->remap_decls_p
&& DECL_P (*tp)
&& DECL_CONTEXT (*tp) == p->from_context)
p->remap_decls_p = save_remap_decls_p;
}
else if (DECL_P (t) && DECL_CONTEXT (t) == p->from_context)
{
DECL_CONTEXT (*tp) = p->to_context;
if (TREE_CODE (t) == LABEL_DECL)
{
if (p->new_label_map)
{
struct tree_map in, *out;
in.from = t;
out = htab_find_with_hash (p->new_label_map, &in, DECL_UID (t));
if (out)
*tp = t = out->to;
}
if (TREE_CODE (*tp) == VAR_DECL)
DECL_CONTEXT (t) = p->to_context;
}
else if (p->remap_decls_p)
{
struct function *f = DECL_STRUCT_FUNCTION (p->to_context);
f->unexpanded_var_list = tree_cons (0, *tp, f->unexpanded_var_list);
DECL_CONTEXT (t) = p->to_context;
/* Mark *TP to be removed from the original function,
otherwise it will be given a DECL_RTL when the original
function is expanded. */
bitmap_set_bit (p->vars_to_remove, DECL_UID (*tp));
if (TREE_CODE (t) == VAR_DECL)
{
struct function *f = DECL_STRUCT_FUNCTION (p->to_context);
f->unexpanded_var_list
= tree_cons (0, t, f->unexpanded_var_list);
/* Mark T to be removed from the original function,
otherwise it will be given a DECL_RTL when the
original function is expanded. */
bitmap_set_bit (p->vars_to_remove, DECL_UID (t));
}
}
}
else if (TYPE_P (t))
*walk_subtrees = 0;
return NULL_TREE;
}
......@@ -4650,7 +4674,7 @@ move_stmt_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, void *data)
static void
move_block_to_fn (struct function *dest_cfun, basic_block bb,
basic_block after, bool update_edge_count_p,
bitmap vars_to_remove)
bitmap vars_to_remove, htab_t new_label_map, int eh_offset)
{
struct control_flow_graph *cfg;
edge_iterator ei;
......@@ -4701,10 +4725,12 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{
tree stmt = bsi_stmt (si);
int region;
d.from_context = cfun->decl;
d.to_context = dest_cfun->decl;
d.remap_decls_p = true;
d.new_label_map = new_label_map;
if (TREE_BLOCK (stmt))
d.block = DECL_INITIAL (dest_cfun->decl);
......@@ -4736,11 +4762,66 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
if (uid >= dest_cfun->last_label_uid)
dest_cfun->last_label_uid = uid + 1;
}
else if (TREE_CODE (stmt) == RESX_EXPR && eh_offset != 0)
TREE_OPERAND (stmt, 0) =
build_int_cst (NULL_TREE,
TREE_INT_CST_LOW (TREE_OPERAND (stmt, 0))
+ eh_offset);
region = lookup_stmt_eh_region (stmt);
if (region >= 0)
{
add_stmt_to_eh_region_fn (dest_cfun, stmt, region + eh_offset);
remove_stmt_from_eh_region (stmt);
}
}
}
/* Examine the statements in BB (which is in SRC_CFUN); find and return
the outermost EH region. Use REGION as the incoming base EH region. */
static int
find_outermost_region_in_block (struct function *src_cfun,
basic_block bb, int region)
{
block_stmt_iterator si;
for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
{
tree stmt = bsi_stmt (si);
int stmt_region;
remove_stmt_from_eh_region (stmt);
stmt_region = lookup_stmt_eh_region_fn (src_cfun, stmt);
if (stmt_region > 0
&& (region < 0 || eh_region_outer_p (src_cfun, stmt_region, region)))
region = stmt_region;
}
return region;
}
static tree
new_label_mapper (tree decl, void *data)
{
htab_t hash = (htab_t) data;
struct tree_map *m;
void **slot;
gcc_assert (TREE_CODE (decl) == LABEL_DECL);
m = xmalloc (sizeof (struct tree_map));
m->hash = DECL_UID (decl);
m->from = decl;
m->to = create_artificial_label ();
LABEL_DECL_UID (m->to) = LABEL_DECL_UID (decl);
slot = htab_find_slot_with_hash (hash, m, m->hash, INSERT);
gcc_assert (*slot == NULL);
*slot = m;
return m->to;
}
/* Move a single-entry, single-exit region delimited by ENTRY_BB and
EXIT_BB to function DEST_CFUN. The whole region is replaced by a
......@@ -4763,11 +4844,12 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
VEC(basic_block,heap) *bbs;
basic_block after, bb, *entry_pred, *exit_succ;
struct function *saved_cfun;
int *entry_flag, *exit_flag;
int *entry_flag, *exit_flag, eh_offset;
unsigned i, num_entry_edges, num_exit_edges;
edge e;
edge_iterator ei;
bitmap vars_to_remove;
htab_t new_label_map;
saved_cfun = cfun;
......@@ -4813,7 +4895,28 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
/* Switch context to the child function to initialize DEST_FN's CFG. */
gcc_assert (dest_cfun->cfg == NULL);
cfun = dest_cfun;
init_empty_tree_cfg ();
/* Initialize EH information for the new function. */
eh_offset = 0;
new_label_map = NULL;
if (saved_cfun->eh)
{
int region = -1;
for (i = 0; VEC_iterate (basic_block, bbs, i, bb); i++)
region = find_outermost_region_in_block (saved_cfun, bb, region);
init_eh_for_function ();
if (region != -1)
{
new_label_map = htab_create (17, tree_map_hash, tree_map_eq, free);
eh_offset = duplicate_eh_regions (saved_cfun, new_label_mapper,
new_label_map, region, 0);
}
}
cfun = saved_cfun;
/* Move blocks from BBS into DEST_CFUN. */
......@@ -4825,10 +4928,14 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
/* No need to update edge counts on the last block. It has
already been updated earlier when we detached the region from
the original CFG. */
move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, vars_to_remove);
move_block_to_fn (dest_cfun, bb, after, bb != exit_bb, vars_to_remove,
new_label_map, eh_offset);
after = bb;
}
if (new_label_map)
htab_delete (new_label_map);
/* Remove the variables marked in VARS_TO_REMOVE from
CFUN->UNEXPANDED_VAR_LIST. Otherwise, they will be given a
DECL_RTL in the context of CFUN. */
......
......@@ -924,7 +924,8 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency,
if (id->transform_new_cfg)
init_eh_for_function ();
id->eh_region_offset
= duplicate_eh_regions (cfun_to_copy, remap_decl_1, id, id->eh_region);
= duplicate_eh_regions (cfun_to_copy, remap_decl_1, id,
0, id->eh_region);
}
/* Use aux pointers to map the original blocks to copy. */
FOR_EACH_BB_FN (bb, cfun_to_copy)
......
......@@ -1557,8 +1557,8 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break;
case RESX_EXPR:
pp_string (buffer, "resx");
/* ??? Any sensible way to present the eh region? */
pp_string (buffer, "resx ");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
break;
case ASM_EXPR:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment