[Bug middle-end/42859] [4.5 regression] ICE in verify_flow_info
abel at gcc dot gnu dot org
gcc-bugzilla@gcc.gnu.org
Tue Feb 16 15:43:00 GMT 2010
------- Comment #6 from abel at gcc dot gnu dot org 2010-02-16 15:43 -------
How about the below patch? It fixes all testcases for me. I'm not sure
whether it makes sense to filter duplicate labels this late, but I don't know
how to do this earlier, as catches seem to be lowering independently of each
other.
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 2cb334f..c18b807 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -28,6 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "function.h"
#include "except.h"
+#include "pointer-set.h"
#include "tree-flow.h"
#include "tree-dump.h"
#include "tree-inline.h"
@@ -3063,6 +3064,7 @@ lower_eh_dispatch (basic_block src, gimple stmt)
eh_catch c;
edge_iterator ei;
edge e;
+ struct pointer_set_t *seen_values = pointer_set_create ();
/* Collect the labels for a switch. Zero the post_landing_pad
field becase we'll no longer have anything keeping these labels
@@ -3071,6 +3073,7 @@ lower_eh_dispatch (basic_block src, gimple stmt)
for (c = r->u.eh_try.first_catch; c ; c = c->next_catch)
{
tree tp_node, flt_node, lab = c->label;
+ bool have_label = false;
c->label = NULL;
tp_node = c->type_list;
@@ -3083,14 +3086,26 @@ lower_eh_dispatch (basic_block src, gimple stmt)
}
do
{
- tree t = build3 (CASE_LABEL_EXPR, void_type_node,
- TREE_VALUE (flt_node), NULL, lab);
- VEC_safe_push (tree, heap, labels, t);
+ /* Filter out duplicate labels that arise when this handler
+ is shadowed by an earlier one. When no labels are
+ attached to the handler anymore, we remove
+ the corresponding edge and then we delete unreachable
+ blocks at the end of this pass. */
+ if (! pointer_set_contains (seen_values, TREE_VALUE
(flt_node)))
+ {
+ tree t = build3 (CASE_LABEL_EXPR, void_type_node,
+ TREE_VALUE (flt_node), NULL, lab);
+ VEC_safe_push (tree, heap, labels, t);
+ pointer_set_insert (seen_values, TREE_VALUE (flt_node));
+ have_label = true;
+ }
tp_node = TREE_CHAIN (tp_node);
flt_node = TREE_CHAIN (flt_node);
}
while (tp_node);
+ if (! have_label)
+ remove_edge (find_edge (src, label_to_block (lab)));
}
/* Clean up the edge flags. */
@@ -3132,6 +3147,7 @@ lower_eh_dispatch (basic_block src, gimple stmt)
VEC_free (tree, heap, labels);
}
+ pointer_set_destroy (seen_values);
}
break;
@@ -3185,6 +3201,8 @@ execute_lower_eh_dispatch (void)
}
}
+ if (any_rewritten)
+ delete_unreachable_blocks ();
return any_rewritten ? TODO_update_ssa_only_virtuals : 0;
}
--
abel at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |abel at gcc dot gnu dot org
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42859
More information about the Gcc-bugs
mailing list