From 696b765437b4a9213e3883ff416034daaebc891c Mon Sep 17 00:00:00 2001 From: herman ten brugge Date: Tue, 18 Aug 2020 20:05:53 +0200 Subject: [PATCH] Fix switch/case Fix switch for signed/unsigned switch Also add new testcase 118 --- tccgen.c | 4 +- tests/tests2/118_switch_test.c | 75 +++++++++++++++++++++++++++++ tests/tests2/118_switch_test.expect | 40 +++++++++++++++ 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 tests/tests2/118_switch_test.c create mode 100644 tests/tests2/118_switch_test.expect diff --git a/tccgen.c b/tccgen.c index a369e0dd..d02e4b12 100644 --- a/tccgen.c +++ b/tccgen.c @@ -7131,7 +7131,9 @@ again: qsort(sw->p, sw->n, sizeof(void*), case_cmpi); for (b = 1; b < sw->n; b++) - if (sw->p[b - 1]->v2 >= sw->p[b]->v1) + if (sw->sv.type.t & VT_UNSIGNED + ? (uint64_t)sw->p[b - 1]->v2 >= (uint64_t)sw->p[b]->v1 + : sw->p[b - 1]->v2 >= sw->p[b]->v1) tcc_error("duplicate case value"); vpushv(&sw->sv); diff --git a/tests/tests2/118_switch_test.c b/tests/tests2/118_switch_test.c new file mode 100644 index 00000000..789dd06c --- /dev/null +++ b/tests/tests2/118_switch_test.c @@ -0,0 +1,75 @@ +#include +#include +#include + +int ibdg(long long n) +{ + switch (n) { + case 1LL ... 9LL: return 1; + case 10LL ... 99LL: return 2; + case 100LL ... 999LL: return 3; + case 1000LL ... 9999LL: return 4; + case 10000LL ... 99999LL: return 5; + case 100000LL ... 999999LL: return 6; + case 1000000LL ... 9999999LL: return 7; + case 10000000LL ... 99999999LL: return 8; + case 100000000LL ... 999999999LL: return 9; + case 1000000000LL ... 9999999999LL: return 10; + case 10000000000LL ... 99999999999LL: return 11; + case 100000000000LL ... 999999999999LL: return 12; + case 1000000000000LL ... 9999999999999LL: return 13; + case 10000000000000LL ... 99999999999999LL: return 14; + case 100000000000000LL ... 999999999999999LL: return 15; + case 1000000000000000LL ... 9999999999999999LL: return 16; + case 10000000000000000LL ... 99999999999999999LL: return 17; + case 100000000000000000LL ... 999999999999999999LL: return 18; + case 1000000000000000000LL ... 9223372036854775807LL: return 19; + case -9223372036854775807LL-1LL ... -1LL: return 20; + } + return 0; +} + +int ubdg(unsigned long long n) +{ + switch (n) { + case 1ULL ... 9ULL: return 1; + case 10ULL ... 99ULL: return 2; + case 100ULL ... 999ULL: return 3; + case 1000ULL ... 9999ULL: return 4; + case 10000ULL ... 99999ULL: return 5; + case 100000ULL ... 999999ULL: return 6; + case 1000000ULL ... 9999999ULL: return 7; + case 10000000ULL ... 99999999ULL: return 8; + case 100000000ULL ... 999999999ULL: return 9; + case 1000000000ULL ... 9999999999ULL: return 10; + case 10000000000ULL ... 99999999999ULL: return 11; + case 100000000000ULL ... 999999999999ULL: return 12; + case 1000000000000ULL ... 9999999999999ULL: return 13; + case 10000000000000ULL ... 99999999999999ULL: return 14; + case 100000000000000ULL ... 999999999999999ULL: return 15; + case 1000000000000000ULL ... 9999999999999999ULL: return 16; + case 10000000000000000ULL ... 99999999999999999ULL: return 17; + case 100000000000000000ULL ... 999999999999999999ULL: return 18; + case 1000000000000000000ULL ... 9999999999999999999ULL: return 19; + case 10000000000000000000ULL ... 18446744073709551615ULL: return 20; + } + return 0; +} + +int main(int argc, char **argv) +{ + unsigned int i; + unsigned long long v = 1; + + v = 1; + for (i = 1; i <= 20; i++) { + printf("%lld : %d\n", (long long) v, ibdg((long long)v)); + v *= 10; + } + v = 1; + for (i = 1; i <= 20; i++) { + printf("%llu : %d\n", v, ubdg(v)); + v *= 10; + } + return 0; +} diff --git a/tests/tests2/118_switch_test.expect b/tests/tests2/118_switch_test.expect new file mode 100644 index 00000000..4155eb48 --- /dev/null +++ b/tests/tests2/118_switch_test.expect @@ -0,0 +1,40 @@ +1 : 1 +10 : 2 +100 : 3 +1000 : 4 +10000 : 5 +100000 : 6 +1000000 : 7 +10000000 : 8 +100000000 : 9 +1000000000 : 10 +10000000000 : 11 +100000000000 : 12 +1000000000000 : 13 +10000000000000 : 14 +100000000000000 : 15 +1000000000000000 : 16 +10000000000000000 : 17 +100000000000000000 : 18 +1000000000000000000 : 19 +-8446744073709551616 : 20 +1 : 1 +10 : 2 +100 : 3 +1000 : 4 +10000 : 5 +100000 : 6 +1000000 : 7 +10000000 : 8 +100000000 : 9 +1000000000 : 10 +10000000000 : 11 +100000000000 : 12 +1000000000000 : 13 +10000000000000 : 14 +100000000000000 : 15 +1000000000000000 : 16 +10000000000000000 : 17 +100000000000000000 : 18 +1000000000000000000 : 19 +10000000000000000000 : 20