diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2004-11-28 12:11:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-07 21:05:09 -0700 |
commit | c1b6cc7405d2d1e956df63b31ddc9bea3c2136b5 (patch) | |
tree | f0d40d9add49d3848447a89d38a8e9b65b3e8b9c /flow.c | |
parent | Remember to pack the pointer list after deleting entries from it. (diff) | |
download | sparse-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.c | 16 |
1 files changed, 9 insertions, 7 deletions
@@ -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, |