diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-12-10 01:03:25 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-12-10 01:03:25 +0100 |
commit | 0c43faa22682ab65525638be813632b44c7a45fd (patch) | |
tree | 425b2d0852860af6bfbaad6606c55c6d20774cad | |
parent | d6d857f2d160fc2740137dea4eec605dbd93b1ef (diff) | |
parent | 78ce37356fd090e5353bc61031de1c8e717d24f6 (diff) | |
download | sparse-0c43faa22682ab65525638be813632b44c7a45fd.tar.gz |
Merge branch 'fix-non-const-case' into tip
* fix linearization of non-constant switch-cases
-rw-r--r-- | linearize.c | 7 | ||||
-rw-r--r-- | validation/linear/non-const-case.c | 37 |
2 files changed, 42 insertions, 2 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 new file mode 100644 index 00000000..7291589c --- /dev/null +++ b/validation/linear/non-const-case.c @@ -0,0 +1,37 @@ +static int foo(int a) +{ + switch (a) { + case 0: + return a; + case a: + return 0; + case (a - a): + return 1; + default: + return a; + } +} + +static int bar(int a) +{ + switch (a) { + case 0: + break; + case a: + a++; +label: + return a; + } + + goto label; +} + + +/* + * check-name: non-const-case + * check-command: test-linearize -Wno-decl $file + * + * check-error-ignore + * check-output-ignore + * check-output-excludes:switch \\. + */ |