All branches must of course be done to existing BBs. Validate that it is the case for BR, CBR & SWITCH (COMPUTEDGOTO is left aside for the moment). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- ir.c | 37 ++++++++++++++++++++++++++++++++++--- linearize.h | 6 ++++++ 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/ir.c b/ir.c index 1890eb13c..533e8e238 100644 --- a/ir.c +++ b/ir.c @@ -82,7 +82,29 @@ static int check_user(struct instruction *insn, pseudo_t pseudo) return 0; } -static int validate_insn(struct instruction *insn) +static int check_branch(struct entrypoint *ep, struct instruction *insn, struct basic_block *bb) +{ + if (bb->ep && lookup_bb(ep->bbs, bb)) + return 0; + sparse_error(insn->pos, "branch to dead BB: %s", show_instruction(insn)); + return 1; +} + +static int check_switch(struct entrypoint *ep, struct instruction *insn) +{ + struct multijmp *jmp; + int err = 0; + + FOR_EACH_PTR(insn->multijmp_list, jmp) { + err = check_branch(ep, insn, jmp->target); + if (err) + return err; + } END_FOR_EACH_PTR(jmp); + + return err; +} + +static int validate_insn(struct entrypoint *ep, struct instruction *insn) { int err = 0; @@ -104,6 +126,9 @@ static int validate_insn(struct instruction *insn) break; case OP_CBR: + err += check_branch(ep, insn, insn->bb_true); + err += check_branch(ep, insn, insn->bb_false); + /* fall through */ case OP_COMPUTEDGOTO: err += check_user(insn, insn->cond); break; @@ -124,8 +149,14 @@ static int validate_insn(struct instruction *insn) err += check_user(insn, insn->src); break; - case OP_ENTRY: case OP_BR: + err += check_branch(ep, insn, insn->bb_true); + break; + case OP_SWITCH: + err += check_switch(ep, insn); + break; + + case OP_ENTRY: case OP_SETVAL: default: break; @@ -147,7 +178,7 @@ int ir_validate(struct entrypoint *ep) FOR_EACH_PTR(bb->insns, insn) { if (!insn->bb) continue; - err += validate_insn(insn); + err += validate_insn(ep, insn); } END_FOR_EACH_PTR(insn); } END_FOR_EACH_PTR(bb); diff --git a/linearize.h b/linearize.h index 413bf0132..25fc4ce98 100644 --- a/linearize.h +++ b/linearize.h @@ -335,6 +335,12 @@ static inline int bb_reachable(struct basic_block *bb) return bb != NULL; } +static inline int lookup_bb(struct basic_block_list *list, struct basic_block *bb) +{ + return lookup_ptr_list_entry((struct ptr_list *)list, bb); +} + + static inline void add_pseudo_user_ptr(struct pseudo_user *user, struct pseudo_user_list **list) { add_ptr_list(list, user); -- 2.18.0