From 22f5fccc2c06b8f7584b41d981742d2afe153a71 Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Sun, 6 Nov 2016 05:02:11 +0100 Subject: Fix 64bit enums and switch cases See testcases. We now support 64bit case constants. At the same time also 64bit enum constants on L64 platforms (otherwise the Sym struct isn't large enough for now). The testcase also checks for various cases where sign/zero extension was confused. --- tests/tcctest.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) (limited to 'tests') diff --git a/tests/tcctest.c b/tests/tcctest.c index 7b1ac1a..2249cb4 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -606,6 +606,24 @@ enum test { struct S_enum { enum {E6 = 42, E7, E8} e:8; }; + +enum ELong { + /* This is either 0 on L32 machines, or a large number + on L64 machines. We should be able to store this. */ + EL_large = (unsigned long)0xf000 << 32, +}; + +enum { BIASU = -1U<<31 }; +enum { BIASS = -1 << 31 }; + +static int getint(int i) +{ + if (i) + return 0; + else + return (int)(-1U << 31); +} + void enum_test() { enum test b1; @@ -617,6 +635,16 @@ void enum_test() E0, E1, E2, E3, E4, E5); b1 = 1; printf("b1=%d\n", b1); + printf("enum large: %ld\n", EL_large); + + if (getint(0) == BIASU) + printf("enum unsigned: ok\n"); + else + printf("enum unsigned: wrong\n"); + if (getint(0) == BIASS) + printf("enum unsigned: ok\n"); + else + printf("enum unsigned: wrong\n"); } typedef int *my_ptr; @@ -1727,10 +1755,45 @@ void init_test(void) printf("linit18= %d %d\n", linit18[0], linit18[1]); } +void switch_uc(unsigned char uc) +{ + switch (uc) { + case 0xfb ... 0xfe: + printf("ucsw:1\n"); + break; + case 0xff: + printf("ucsw:2\n"); + break; + case 0 ... 5: + printf("ucsw:3\n"); + break; + default: + printf("ucsw: broken!\n"); + } +} + +void switch_sc(signed char sc) +{ + switch (sc) { + case -5 ... -2: + printf("scsw:1\n"); + break; + case -1: + printf("scsw:2\n"); + break; + case 0 ... 5: + printf("scsw:3\n"); + break; + default: + printf("scsw: broken!\n"); + } +} void switch_test() { int i; + unsigned long long ull; + long long ll; for(i=0;i<15;i++) { switch(i) { @@ -1753,6 +1816,60 @@ void switch_test() } } printf("\n"); + + for (i = 1; i <= 5; i++) { + ull = (unsigned long long)i << 61; + switch (ull) { + case 1ULL << 61: + printf("ullsw:1\n"); + break; + case 2ULL << 61: + printf("ullsw:2\n"); + break; + case 3ULL << 61: + printf("ullsw:3\n"); + break; + case 4ULL << 61: + printf("ullsw:4\n"); + break; + case 5ULL << 61: + printf("ullsw:5\n"); + break; + default: + printf("ullsw: broken!\n"); + } + } + + for (i = 1; i <= 5; i++) { + ll = (long long)i << 61; + switch (ll) { + case 1LL << 61: + printf("llsw:1\n"); + break; + case 2LL << 61: + printf("llsw:2\n"); + break; + case 3LL << 61: + printf("llsw:3\n"); + break; + case 4LL << 61: + printf("llsw:4\n"); + break; + case 5LL << 61: + printf("llsw:5\n"); + break; + default: + printf("llsw: broken!\n"); + } + } + + for (i = -5; i <= 5; i++) { + switch_uc((unsigned char)i); + } + + for (i = -5; i <= 5; i++) { + switch_sc ((signed char)i); + } } /* ISOC99 _Bool type */ -- cgit v1.3.1