diff options
author | Richard Guenther <rguenther@suse.de> | 2010-01-15 11:53:26 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-01-15 11:53:26 +0000 |
commit | 1197e78957aea05816665f843e4a0b936c847e07 (patch) | |
tree | 67ed89e55330179795b12967f60c0b05168d6454 | |
parent | 58be9ce9c30e0b16d4d4cb6ccccc4b910b8ae834 (diff) | |
download | gcc-1197e78957aea05816665f843e4a0b936c847e07.zip gcc-1197e78957aea05816665f843e4a0b936c847e07.tar.gz gcc-1197e78957aea05816665f843e4a0b936c847e07.tar.bz2 |
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
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/torture/pr42739.C | 16 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 9 | ||||
-rw-r--r-- | gcc/tree-cfgcleanup.c | 53 |
5 files changed, 74 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e72f321..a13093e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,13 @@ 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. 2010-01-14 Michael Meissner <meissner@linux.vnet.ibm.com> diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ba2aa6c..990ea36 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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> * g++.dg/template/error45.C: Revert as part of reverting changes diff --git a/gcc/testsuite/g++.dg/torture/pr42739.C b/gcc/testsuite/g++.dg/torture/pr42739.C new file mode 100644 index 0000000..ccc05f8 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr42739.C @@ -0,0 +1,16 @@ +/* { dg-do compile } */ + +struct s { ~s() { s(); } }; + +int f() +{ + M: + s o = s(); + f(); + f(); + + L: + goto *(f() ? &&L : &&M); + + return 0; +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 4ba9dd7..0a3d544 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -4268,6 +4268,15 @@ gimple_verify_flow_info (void) 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) { error ("label "); diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 9fb489a..5904407 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -338,7 +338,6 @@ remove_forwarder_block (basic_block bb) gimple label; edge_iterator ei; gimple_stmt_iterator gsi, gsi_to; - bool seen_abnormal_edge = false; /* We check for infinite loops already in tree_forwarder_block_p. However it may happen that the infinite loop is created @@ -365,14 +364,10 @@ remove_forwarder_block (basic_block bb) 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. */ - if (has_abnormal_incoming_edge_p (bb)) - { - seen_abnormal_edge = true; - - if (has_abnormal_incoming_edge_p (dest) - || !gimple_seq_empty_p (phi_nodes (dest))) - return false; - } + if (has_abnormal_incoming_edge_p (bb) + && (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 predecessors of BB are also predecessors of DEST, check that the @@ -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 - the abnormal edges works. */ - gsi_to = gsi_start_bb (dest); - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) + gsi_to = gsi_after_labels (dest); + for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); ) { - label = gsi_stmt (gsi); - gcc_assert (gimple_code (label) == GIMPLE_LABEL - || is_gimple_debug (label)); + if (!is_gimple_debug (gsi_stmt (gsi))) + break; gsi_remove (&gsi, false); gsi_insert_before (&gsi_to, label, GSI_SAME_STMT); } |