On 01/09/18 01:26, Luc Van Oostenryck wrote: > All branches must of course be done to existing BBs. All branches must target an existing BB. ? ATB, Ramsay Jones > > 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); >