aboutsummaryrefslogtreecommitdiff
path: root/flow.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-11-28 12:11:01 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:05:09 -0700
commitc1b6cc7405d2d1e956df63b31ddc9bea3c2136b5 (patch)
treef0d40d9add49d3848447a89d38a8e9b65b3e8b9c /flow.c
parentRemember to pack the pointer list after deleting entries from it. (diff)
downloadsparse-c1b6cc7405d2d1e956df63b31ddc9bea3c2136b5.tar.gz
sparse-c1b6cc7405d2d1e956df63b31ddc9bea3c2136b5.tar.bz2
sparse-c1b6cc7405d2d1e956df63b31ddc9bea3c2136b5.zip
Be more careful when rewriting parent branches.
The act of rewriting a parent branch may change the list of parents, so... There are still more bb rewriting bugs hiding, but I'll get them all and their little dogs too!
Diffstat (limited to 'flow.c')
-rw-r--r--flow.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/flow.c b/flow.c
index ac6ea27..9a91a27 100644
--- a/flow.c
+++ b/flow.c
@@ -688,7 +688,6 @@ static int rewrite_parent_branch(struct basic_block *bb, struct basic_block *old
static struct basic_block * rewrite_branch_bb(struct basic_block *bb, struct instruction *br)
{
- struct basic_block *success;
struct basic_block *parent;
struct basic_block *target = br->bb_true;
struct basic_block *false = br->bb_false;
@@ -700,13 +699,16 @@ static struct basic_block * rewrite_branch_bb(struct basic_block *bb, struct ins
target = cond->value ? target : false;
}
- target = target ? : false;
- success = target;
- FOR_EACH_PTR(bb->parents, parent) {
+ /*
+ * We can't do FOR_EACH_PTR() here, because the parent list
+ * may change when we rewrite the parent.
+ */
+ while ((parent = first_basic_block(bb->parents)) != NULL) {
if (!rewrite_parent_branch(parent, bb, target))
- success = NULL;
- } END_FOR_EACH_PTR(parent);
- return success;
+ return NULL;
+ remove_bb_from_list(&bb->parents, parent, 0);
+ }
+ return target;
}
static void simplify_one_switch(struct basic_block *bb,