From 56410ddc589f8d5adc45c8ee4cc27ec1aa0dfe85 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 4 May 2012 22:35:20 +0900 Subject: [PATCH] Prevent merged if/goto losing its way. When mering if/goto (ie, if skipping a goto), the rest of the dead code remover is used to delete the goto. That part of the code unuses the goto's label. The if was getting the goto's label without the lable's used count being incremented (the usaged temporarily increases by one). I have no idea why the problem showed up randomly, but this seems to fix it (it fixes /a/ bug, anyway). --- tools/qfcc/source/statements.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 9cb78a672..41f112415 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -1065,6 +1065,7 @@ remove_label_from_dest (ex_label_t *label) debug (0, "dropping deceased label %s", label->name); sblock = label->dest; + label->dest = 0; for (l = &sblock->labels; *l; l = &(*l)->next) { if (*l == label) { *l = label->next; @@ -1232,9 +1233,10 @@ remove_dead_blocks (sblock_t *blocks) s = (statement_t *) sblock->tail; if (is_conditional (s) && is_goto (sb->statements) && s->opb->o.label->dest == sb->next) { - debug (0, "meging if/goto %p %p", sblock, sb); + debug (0, "merging if/goto %p %p", sblock, sb); unuse_label (s->opb->o.label); s->opb->o.label = sb->statements->opa->o.label; + s->opb->o.label->used++; invert_conditional (s); sb->reachable = 0; for (sb = sb->next; sb; sb = sb->next)