Commit 1197e789 by Richard Guenther Committed by Richard Biener

re PR middle-end/42739 (ICE with computed goto, destructors, and optimization)

2010-01-15  Richard Guenther  <rguenther@suse.de>

	PR middle-end/42739
	* tree-cfgcleanup.c (remove_forwarder_block): Move destination
	labels of computed or non-local gotos to the destination.
	* tree-cfg.c (gimple_verify_flow_info): Verify that a EH
	landing pad label is the first label.

	* g++.dg/torture/pr42739.C: New testcase.

From-SVN: r155937
parent 58be9ce9
2010-01-15 Richard Guenther <rguenther@suse.de> 2010-01-15 Richard Guenther <rguenther@suse.de>
PR middle-end/42739
* tree-cfgcleanup.c (remove_forwarder_block): Move destination
labels of computed or non-local gotos to the destination.
* tree-cfg.c (gimple_verify_flow_info): Verify that a EH
landing pad label is the first label.
2010-01-15 Richard Guenther <rguenther@suse.de>
* tree-ssa-loop-im.c (gen_lsm_tmp_name): Fix bogus fallthru. * tree-ssa-loop-im.c (gen_lsm_tmp_name): Fix bogus fallthru.
2010-01-14 Michael Meissner <meissner@linux.vnet.ibm.com> 2010-01-14 Michael Meissner <meissner@linux.vnet.ibm.com>
......
2010-01-15 Richard Guenther <rguenther@suse.de>
PR middle-end/42739
* g++.dg/torture/pr42739.C: New testcase.
2010-01-15 Dodji Seketeli <dodji@redhat.com> 2010-01-15 Dodji Seketeli <dodji@redhat.com>
* g++.dg/template/error45.C: Revert as part of reverting changes * g++.dg/template/error45.C: Revert as part of reverting changes
......
/* { dg-do compile } */
struct s { ~s() { s(); } };
int f()
{
M:
s o = s();
f();
f();
L:
goto *(f() ? &&L : &&M);
return 0;
}
...@@ -4268,6 +4268,15 @@ gimple_verify_flow_info (void) ...@@ -4268,6 +4268,15 @@ gimple_verify_flow_info (void)
err = 1; err = 1;
} }
if (prev_stmt && EH_LANDING_PAD_NR (label) != 0)
{
error ("EH landing pad label ");
print_generic_expr (stderr, label, 0);
fprintf (stderr, " is not first in a sequence of labels in bb %d",
bb->index);
err = 1;
}
if (label_to_block (label) != bb) if (label_to_block (label) != bb)
{ {
error ("label "); error ("label ");
......
...@@ -338,7 +338,6 @@ remove_forwarder_block (basic_block bb) ...@@ -338,7 +338,6 @@ remove_forwarder_block (basic_block bb)
gimple label; gimple label;
edge_iterator ei; edge_iterator ei;
gimple_stmt_iterator gsi, gsi_to; gimple_stmt_iterator gsi, gsi_to;
bool seen_abnormal_edge = false;
/* We check for infinite loops already in tree_forwarder_block_p. /* We check for infinite loops already in tree_forwarder_block_p.
However it may happen that the infinite loop is created However it may happen that the infinite loop is created
...@@ -365,14 +364,10 @@ remove_forwarder_block (basic_block bb) ...@@ -365,14 +364,10 @@ remove_forwarder_block (basic_block bb)
So if there is an abnormal edge to BB, proceed only if there is So if there is an abnormal edge to BB, proceed only if there is
no abnormal edge to DEST and there are no phi nodes in DEST. */ no abnormal edge to DEST and there are no phi nodes in DEST. */
if (has_abnormal_incoming_edge_p (bb)) if (has_abnormal_incoming_edge_p (bb)
{ && (has_abnormal_incoming_edge_p (dest)
seen_abnormal_edge = true; || !gimple_seq_empty_p (phi_nodes (dest))))
return false;
if (has_abnormal_incoming_edge_p (dest)
|| !gimple_seq_empty_p (phi_nodes (dest)))
return false;
}
/* If there are phi nodes in DEST, and some of the blocks that are /* If there are phi nodes in DEST, and some of the blocks that are
predecessors of BB are also predecessors of DEST, check that the predecessors of BB are also predecessors of DEST, check that the
...@@ -419,16 +414,40 @@ remove_forwarder_block (basic_block bb) ...@@ -419,16 +414,40 @@ remove_forwarder_block (basic_block bb)
} }
} }
if (seen_abnormal_edge) /* Move nonlocal labels and computed goto targets as well as user
defined labels and labels with an EH landing pad number to the
new block, so that the redirection of the abnormal edges works,
jump targets end up in a sane place and debug information for
labels is retained. */
gsi_to = gsi_start_bb (dest);
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{
tree decl;
label = gsi_stmt (gsi);
if (is_gimple_debug (label))
break;
decl = gimple_label_label (label);
if (EH_LANDING_PAD_NR (decl) != 0
|| DECL_NONLOCAL (decl)
|| FORCED_LABEL (decl)
|| !DECL_ARTIFICIAL (decl))
{
gsi_remove (&gsi, false);
gsi_insert_before (&gsi_to, label, GSI_SAME_STMT);
}
else
gsi_next (&gsi);
}
/* Move debug statements if the destination has just a single
predecessor. */
if (single_pred_p (dest))
{ {
/* Move the labels to the new block, so that the redirection of gsi_to = gsi_after_labels (dest);
the abnormal edges works. */ for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); )
gsi_to = gsi_start_bb (dest);
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
{ {
label = gsi_stmt (gsi); if (!is_gimple_debug (gsi_stmt (gsi)))
gcc_assert (gimple_code (label) == GIMPLE_LABEL break;
|| is_gimple_debug (label));
gsi_remove (&gsi, false); gsi_remove (&gsi, false);
gsi_insert_before (&gsi_to, label, GSI_SAME_STMT); gsi_insert_before (&gsi_to, label, GSI_SAME_STMT);
} }
......
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