aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-08-31 23:37:07 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-09-01 08:43:12 +0200
commit378ecc473f60f9d40a917dab21a4e8b51e7422c7 (patch)
treeeb2e9613e3cc55f823d7fbfd0dae6f58b46f055d
parentd82ff76577aafcb3f01422c2592aebd503816d80 (diff)
downloadsparse-dev-378ecc473f60f9d40a917dab21a4e8b51e7422c7.tar.gz
ir-validate: validate return value
A valid non-void function should not return VOID. VOID can only be returned if no return statements have been issued. Note: even if the expression is erroneous, and thus VOID, this returned value would be via a phi-node. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--ir.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/ir.c b/ir.c
index 836d4eb2..2e284c25 100644
--- a/ir.c
+++ b/ir.c
@@ -107,6 +107,17 @@ static int check_switch(struct entrypoint *ep, struct instruction *insn)
return err;
}
+static int check_return(struct instruction *insn)
+{
+ struct symbol *ctype = insn->type;
+
+ if (ctype && ctype->bit_size > 0 && insn->src == VOID) {
+ sparse_error(insn->pos, "return without value");
+ return 1;
+ }
+ return 0;
+}
+
static int validate_insn(struct entrypoint *ep, struct instruction *insn)
{
int err = 0;
@@ -152,6 +163,10 @@ static int validate_insn(struct entrypoint *ep, struct instruction *insn)
err += check_user(insn, insn->src);
break;
+ case OP_RET:
+ err += check_return(insn);
+ break;
+
case OP_BR:
err += check_branch(ep, insn, insn->bb_true);
break;