summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-09-06 13:26:39 +0200
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-09-08 16:53:25 +0200
commit78ce37356fd090e5353bc61031de1c8e717d24f6 (patch)
treef72f589145fb645209a7b710567f1c22f3a846d6
parentf43d375657f22cf69668a417f555fcc7a0a780d5 (diff)
downloadsparse-78ce37356fd090e5353bc61031de1c8e717d24f6.tar.gz
fix linearization of non-constant switch-cases
The linearization of switches & cases makes the assumption that the expressions for the cases are constants (EXPR_VALUE). So, the corresponding values are dereferenced without checks. However, if the code uses a non-constant case, this dereference produces a random value, probably one corresponding to some pointers belonging to the real type of the expression. Fix this by checking during linearization the constness of the expression and ignore the non-constant ones. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r--linearize.c7
-rw-r--r--validation/linear/non-const-case.c1
2 files changed, 5 insertions, 3 deletions
diff --git a/linearize.c b/linearize.c
index 670e3830..ac913131 100644
--- a/linearize.c
+++ b/linearize.c
@@ -2230,12 +2230,15 @@ static pseudo_t linearize_switch(struct entrypoint *ep, struct statement *stmt)
if (!case_stmt->case_expression) {
default_case = bb_case;
continue;
+ } else if (case_stmt->case_expression->type != EXPR_VALUE) {
+ continue;
} else {
+ struct expression *case_to = case_stmt->case_to;
long long begin, end;
begin = end = case_stmt->case_expression->value;
- if (case_stmt->case_to)
- end = case_stmt->case_to->value;
+ if (case_to && case_to->type == EXPR_VALUE)
+ end = case_to->value;
if (begin > end)
jmp = alloc_multijmp(bb_case, end, begin);
else
diff --git a/validation/linear/non-const-case.c b/validation/linear/non-const-case.c
index 5cf55717..7291589c 100644
--- a/validation/linear/non-const-case.c
+++ b/validation/linear/non-const-case.c
@@ -30,7 +30,6 @@ label:
/*
* check-name: non-const-case
* check-command: test-linearize -Wno-decl $file
- * check-known-to-fail
*
* check-error-ignore
* check-output-ignore