[PATCH 1/3] ir-validate: add validation branch to dead BB

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Newbies FAQ]     [LKML]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Trinity Fuzzer Tool]

  Powered by Linux