diff options
Diffstat (limited to 'tinycc/tests/tests2')
246 files changed, 10731 insertions, 0 deletions
diff --git a/tinycc/tests/tests2/00_assignment.c b/tinycc/tests/tests2/00_assignment.c new file mode 100644 index 0000000..c96109f --- /dev/null +++ b/tinycc/tests/tests2/00_assignment.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + int a; + a = 42; + printf("%d\n", a); + + int b = 64; + printf("%d\n", b); + + int c = 12, d = 34; + printf("%d, %d\n", c, d); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/00_assignment.expect b/tinycc/tests/tests2/00_assignment.expect new file mode 100644 index 0000000..d4407f3 --- /dev/null +++ b/tinycc/tests/tests2/00_assignment.expect @@ -0,0 +1,3 @@ +42 +64 +12, 34 diff --git a/tinycc/tests/tests2/01_comment.c b/tinycc/tests/tests2/01_comment.c new file mode 100644 index 0000000..a2e6bc6 --- /dev/null +++ b/tinycc/tests/tests2/01_comment.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main() +{ + printf("Hello\n"); + printf("Hello\n"); /* this is a comment */ printf("Hello\n"); + printf("Hello\n"); + // this is also a comment sayhello(); + printf("Hello\n"); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/01_comment.expect b/tinycc/tests/tests2/01_comment.expect new file mode 100644 index 0000000..b1387ad --- /dev/null +++ b/tinycc/tests/tests2/01_comment.expect @@ -0,0 +1,5 @@ +Hello +Hello +Hello +Hello +Hello diff --git a/tinycc/tests/tests2/02_printf.c b/tinycc/tests/tests2/02_printf.c new file mode 100644 index 0000000..4c34dd8 --- /dev/null +++ b/tinycc/tests/tests2/02_printf.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + printf("Hello world\n"); + + int Count; + for (Count = -5; Count <= 5; Count++) + printf("Count = %d\n", Count); + + printf("String 'hello', 'there' is '%s', '%s'\n", "hello", "there"); + printf("Character 'A' is '%c'\n", 65); + printf("Character 'a' is '%c'\n", 'a'); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/02_printf.expect b/tinycc/tests/tests2/02_printf.expect new file mode 100644 index 0000000..f67a0f6 --- /dev/null +++ b/tinycc/tests/tests2/02_printf.expect @@ -0,0 +1,15 @@ +Hello world +Count = -5 +Count = -4 +Count = -3 +Count = -2 +Count = -1 +Count = 0 +Count = 1 +Count = 2 +Count = 3 +Count = 4 +Count = 5 +String 'hello', 'there' is 'hello', 'there' +Character 'A' is 'A' +Character 'a' is 'a' diff --git a/tinycc/tests/tests2/03_struct.c b/tinycc/tests/tests2/03_struct.c new file mode 100644 index 0000000..fd73133 --- /dev/null +++ b/tinycc/tests/tests2/03_struct.c @@ -0,0 +1,38 @@ +extern int printf(const char*, ...); + +struct fred; + +void fred$(struct fred* this) +{ + printf("~fred()\n"); +} + +struct __attribute__((__cleanup__(fred$))) fred +{ + int boris; + int natasha; +}; + +int main() +{ + struct fred __attribute__((__cleanup__(fred$))) bloggs; + + bloggs.boris = 12; + bloggs.natasha = 34; + + printf("%d\n", bloggs.boris); + printf("%d\n", bloggs.natasha); + + struct fred jones[2]; + jones[0].boris = 12; + jones[0].natasha = 34; + jones[1].boris = 56; + jones[1].natasha = 78; + + printf("%d\n", jones[0].boris); + printf("%d\n", jones[0].natasha); + printf("%d\n", jones[1].boris); + printf("%d\n", jones[1].natasha); + + return 0; +} diff --git a/tinycc/tests/tests2/03_struct.expect b/tinycc/tests/tests2/03_struct.expect new file mode 100644 index 0000000..be8df37 --- /dev/null +++ b/tinycc/tests/tests2/03_struct.expect @@ -0,0 +1,8 @@ +03_struct.c:14: warning: attribute '__cleanup__' ignored on type +12 +34 +12 +34 +56 +78 +~fred() diff --git a/tinycc/tests/tests2/04_for.c b/tinycc/tests/tests2/04_for.c new file mode 100644 index 0000000..312fed8 --- /dev/null +++ b/tinycc/tests/tests2/04_for.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 1; Count <= 10; Count++) + { + printf("%d\n", Count); + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/04_for.expect b/tinycc/tests/tests2/04_for.expect new file mode 100644 index 0000000..f00c965 --- /dev/null +++ b/tinycc/tests/tests2/04_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/tinycc/tests/tests2/05_array.c b/tinycc/tests/tests2/05_array.c new file mode 100644 index 0000000..c218f31 --- /dev/null +++ b/tinycc/tests/tests2/05_array.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int Count; + int Array[10]; + + for (Count = 1; Count <= 10; Count++) + { + Array[Count-1] = Count * Count; + } + + for (Count = 0; Count < 10; Count++) + { + printf("%d\n", Array[Count]); + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/05_array.expect b/tinycc/tests/tests2/05_array.expect new file mode 100644 index 0000000..bc7257c --- /dev/null +++ b/tinycc/tests/tests2/05_array.expect @@ -0,0 +1,10 @@ +1 +4 +9 +16 +25 +36 +49 +64 +81 +100 diff --git a/tinycc/tests/tests2/06_case.c b/tinycc/tests/tests2/06_case.c new file mode 100644 index 0000000..c0191e2 --- /dev/null +++ b/tinycc/tests/tests2/06_case.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +int main() +{ + int Count; + + for (Count = 0; Count < 4; Count++) + { + printf("%d\n", Count); + switch (Count) + { + case 1: + printf("%d\n", 1); + break; + + case 2: + printf("%d\n", 2); + break; + + default: + printf("%d\n", 0); + break; + } + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/06_case.expect b/tinycc/tests/tests2/06_case.expect new file mode 100644 index 0000000..fab2c20 --- /dev/null +++ b/tinycc/tests/tests2/06_case.expect @@ -0,0 +1,8 @@ +0 +0 +1 +1 +2 +2 +3 +0 diff --git a/tinycc/tests/tests2/07_function.c b/tinycc/tests/tests2/07_function.c new file mode 100644 index 0000000..006e0a7 --- /dev/null +++ b/tinycc/tests/tests2/07_function.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +int myfunc(int x) +{ + return x * x; +} + +void vfunc(int a) +{ + printf("a=%d\n", a); +} + +void qfunc() +{ + printf("qfunc()\n"); +} + +void zfunc() +{ + ((void (*)(void))0) (); +} + +int main() +{ + printf("%d\n", myfunc(3)); + printf("%d\n", myfunc(4)); + + vfunc(1234); + + qfunc(); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/07_function.expect b/tinycc/tests/tests2/07_function.expect new file mode 100644 index 0000000..8ffb0a7 --- /dev/null +++ b/tinycc/tests/tests2/07_function.expect @@ -0,0 +1,4 @@ +9 +16 +a=1234 +qfunc() diff --git a/tinycc/tests/tests2/08_while.c b/tinycc/tests/tests2/08_while.c new file mode 100644 index 0000000..602ffc7 --- /dev/null +++ b/tinycc/tests/tests2/08_while.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int p; + int t; + + a = 1; + p = 0; + t = 0; + + while (a < 100) + { + printf("%d\n", a); + t = a; + a = t + p; + p = t; + } + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/08_while.expect b/tinycc/tests/tests2/08_while.expect new file mode 100644 index 0000000..702d4c0 --- /dev/null +++ b/tinycc/tests/tests2/08_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/tinycc/tests/tests2/09_do_while.c b/tinycc/tests/tests2/09_do_while.c new file mode 100644 index 0000000..1d3315d --- /dev/null +++ b/tinycc/tests/tests2/09_do_while.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int p; + int t; + + a = 1; + p = 0; + t = 0; + + do + { + printf("%d\n", a); + t = a; + a = t + p; + p = t; + } while (a < 100); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/09_do_while.expect b/tinycc/tests/tests2/09_do_while.expect new file mode 100644 index 0000000..702d4c0 --- /dev/null +++ b/tinycc/tests/tests2/09_do_while.expect @@ -0,0 +1,11 @@ +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 diff --git a/tinycc/tests/tests2/100_c99array-decls.c b/tinycc/tests/tests2/100_c99array-decls.c new file mode 100644 index 0000000..46950aa --- /dev/null +++ b/tinycc/tests/tests2/100_c99array-decls.c @@ -0,0 +1,34 @@ +void foo(int [5]); +void fooc(int x[const 5]); +void foos(int x[static 5]); +void foov(int x[volatile 5]); +void foor(int x[restrict 5]); +void fooc(int [const 5]); +void foos(int [static 5]); +void foov(int [volatile 5]); +void foor(int [restrict 5]); +void fooc(int (* const x)); +void foos(int *x); +void foov(int * volatile x); +void foor(int * restrict x); +void fooc(int x[volatile 5]) +{ + x[3] = 42; +#ifdef INVALID + x = 0; +#endif +} +void foovm(int x[const *]); +void foovm(int * const x); +#ifdef INVALID +void wrongc(int x[3][const 4]); +void wrongvm(int x[static *]); +void foovm(int x[const *]) +{ + x[2] = 1; +} +#endif +int main() +{ + return 0; +} diff --git a/tinycc/tests/tests2/100_c99array-decls.expect b/tinycc/tests/tests2/100_c99array-decls.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/100_c99array-decls.expect diff --git a/tinycc/tests/tests2/101_cleanup.c b/tinycc/tests/tests2/101_cleanup.c new file mode 100644 index 0000000..de5dca2 --- /dev/null +++ b/tinycc/tests/tests2/101_cleanup.c @@ -0,0 +1,227 @@ +extern int printf(const char*, ...); +static int glob_i = 0; + +void incr_glob_i(int *i) +{ + glob_i += *i; +} + +#define INCR_GI { \ + int i __attribute__ ((__cleanup__(incr_glob_i))) = 1; \ + } + +#define INCR_GI0 INCR_GI INCR_GI INCR_GI INCR_GI +#define INCR_GI1 INCR_GI0 INCR_GI0 INCR_GI0 INCR_GI0 +#define INCR_GI2 INCR_GI1 INCR_GI1 INCR_GI1 INCR_GI1 +#define INCR_GI3 INCR_GI2 INCR_GI2 INCR_GI2 INCR_GI2 +#define INCR_GI4 INCR_GI3 INCR_GI3 INCR_GI3 INCR_GI3 +#define INCR_GI5 INCR_GI4 INCR_GI4 INCR_GI4 INCR_GI4 +#define INCR_GI6 INCR_GI5 INCR_GI5 INCR_GI5 INCR_GI5 +#define INCR_GI7 INCR_GI6 INCR_GI6 INCR_GI6 INCR_GI6 + + +void check2(char **hum); + +void check(int *j) +{ + char * __attribute__ ((cleanup(check2))) stop_that = "wololo"; + int chk = 0; + + { + char * __attribute__ ((cleanup(check2))) stop_that = "plop"; + + { + non_plopage: + printf("---- %d\n", chk); + } + if (!chk) { + chk = 1; + goto non_plopage; + } + } + + { + char * __attribute__ ((cleanup(check2))) stop_that = "tata !"; + + goto out; + stop_that = "titi"; + } + again: + chk = 2; + { + char * __attribute__ ((cleanup(check2))) cascade1 = "1"; + { + char * __attribute__ ((cleanup(check2))) cascade2 = "2"; + { + char * __attribute__ ((cleanup(check2))) cascade3 = "3"; + + goto out; + cascade3 = "nope"; + } + } + } + out: + if (chk != 2) + goto again; + { + { + char * __attribute__ ((cleanup(check2))) out = "last goto out"; + ++chk; + if (chk != 3) + goto out; + } + } + return; +} + +void check_oh_i(char *oh_i) +{ + printf("c: %c\n", *oh_i); +} + +void goto_hell(double *f) +{ + printf("oo: %f\n", *f); +} + +char *test() +{ + char *__attribute__ ((cleanup(check2))) str = "I don't think this should be print(but gcc got it wrong too)"; + + return str; +} + +void test_ret_subcall(char *that) +{ + printf("should be print before\n"); +} + +void test_ret() +{ + char *__attribute__ ((cleanup(check2))) that = "that"; + return test_ret_subcall(that); +} + +void test_ret2() +{ + char *__attribute__ ((cleanup(check2))) that = "-that"; + { + char *__attribute__ ((cleanup(check2))) that = "this should appear only once"; + } + { + char *__attribute__ ((cleanup(check2))) that = "-that2"; + return; + } +} + +void test2(void) { + int chk = 0; +again: + if (!chk) { + char * __attribute__ ((cleanup(check2))) stop_that = "test2"; + chk++; + goto again; + } +} + +int test3(void) { + char * __attribute__ ((cleanup(check2))) stop_that = "three"; + int chk = 0; + + if (chk) { + { + outside: + { + char * __attribute__ ((cleanup(check2))) stop_that = "two"; + printf("---- %d\n", chk); + } + } + } + if (!chk) + { + char * __attribute__ ((cleanup(check2))) stop_that = "one"; + + if (!chk) { + chk = 1; + goto outside; + } + } + return 0; +} + +void cl(int *ip) +{ + printf("%d\n", *ip); +} + +void loop_cleanups(void) +{ + __attribute__((cleanup(cl))) int l = 1000; + + printf("-- loop 0 --\n"); + for ( __attribute__((cleanup(cl))) int i = 0; i < 10; ++i) { + __attribute__((cleanup(cl))) int j = 100; + } + + printf("-- loop 1 --\n"); + for (__attribute__((cleanup(cl))) int i = 0; i < 10; ++i) { + __attribute__((cleanup(cl))) int j = 200; + continue; + } + + printf("-- loop 2 --\n"); + for (__attribute__((cleanup(cl))) int i = 0; i < 10; ++i) { + __attribute__((cleanup(cl))) int j = 300; + break; + } + + printf("-- loop 3 --\n"); + for (int i = 0; i < 2; ++i) { + __attribute__((cleanup(cl))) int j = 400; + switch (i) { + case 0: + continue; + default: + { + __attribute__((cleanup(cl))) int jj = 500; + break; + } + } + } + printf("after break\n"); +} + +int main() +{ + int i __attribute__ ((__cleanup__(check))) = 0, not_i; + int chk = 0; + (void)not_i; + + { + __attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'o', o = 'a'; + } + + INCR_GI7; + printf("glob_i: %d\n", glob_i); + naaaaaaaa: + if (!chk) { + __attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'f'; + double __attribute__ ((__cleanup__(goto_hell))) f = 2.6; + + chk = 1; + goto naaaaaaaa; + } + i = 105; + printf("because what if free was call inside cleanup function %s\n", test()); + test_ret(); + test_ret2(); + test2(); + test3(); + loop_cleanups(); + return i; +} + +void check2(char **hum) +{ + printf("str: %s\n", *hum); +} diff --git a/tinycc/tests/tests2/101_cleanup.expect b/tinycc/tests/tests2/101_cleanup.expect new file mode 100644 index 0000000..84960cd --- /dev/null +++ b/tinycc/tests/tests2/101_cleanup.expect @@ -0,0 +1,59 @@ +c: a +c: o +glob_i: 65536 +oo: 2.600000 +c: f +str: I don't think this should be print(but gcc got it wrong too) +because what if free was call inside cleanup function I don't think this should be print(but gcc got it wrong too) +should be print before +str: that +str: this should appear only once +str: -that2 +str: -that +str: test2 +str: one +---- 1 +str: two +str: three +-- loop 0 -- +100 +100 +100 +100 +100 +100 +100 +100 +100 +100 +10 +-- loop 1 -- +200 +200 +200 +200 +200 +200 +200 +200 +200 +200 +10 +-- loop 2 -- +300 +0 +-- loop 3 -- +400 +500 +400 +after break +1000 +---- 0 +---- 1 +str: plop +str: tata ! +str: 3 +str: 2 +str: 1 +str: last goto out +str: wololo diff --git a/tinycc/tests/tests2/102_alignas.c b/tinycc/tests/tests2/102_alignas.c new file mode 100644 index 0000000..62d3ed2 --- /dev/null +++ b/tinycc/tests/tests2/102_alignas.c @@ -0,0 +1,29 @@ +_Alignas(16) int i1; +int _Alignas(16) i2; +void _Alignas(16) *p2; +_Alignas(16) i3; +int _Alignas(double) i4; +int _Alignas(int) i5; +#if 0 +/* The following are currently wrongly accepted by TCC but really shouldn't. */ +int _Alignas(int _Alignas(16)) i6; //wrong, 'int _Alignas(16)' is no type-name +typedef int _Alignas(16) int16aligned_t; //wrong, _Alignas invalid on typedef +int16aligned_t i7; +#endif +/* i8 should get an alignment of 16, because unlike _Alignas the + corresponding attribute _does_ apply to type-name, though not in + some clang versions. */ +int _Alignas(int __attribute__((aligned(16)))) i8; +extern int printf(const char*, ...); +#ifdef _MSC_VER +#define alignof(x) (int)__alignof(x) +#else +#define alignof(x) (int)__alignof__(x) +#endif +int main() +{ + printf("%d %d %d %d\n", + alignof(i1) == 16, alignof(i4) == alignof(double), + alignof(i5) == alignof(int) , alignof(i8) == 16); + return 0; +} diff --git a/tinycc/tests/tests2/102_alignas.expect b/tinycc/tests/tests2/102_alignas.expect new file mode 100644 index 0000000..b458e07 --- /dev/null +++ b/tinycc/tests/tests2/102_alignas.expect @@ -0,0 +1,2 @@ +102_alignas.c:4: warning: type defaults to int +1 1 1 1 diff --git a/tinycc/tests/tests2/103_implicit_memmove.c b/tinycc/tests/tests2/103_implicit_memmove.c new file mode 100644 index 0000000..1592fb2 --- /dev/null +++ b/tinycc/tests/tests2/103_implicit_memmove.c @@ -0,0 +1,20 @@ +/* Test that the memmove TCC is emitting for the struct copy + and hence implicitely declares can be declared properly also + later. */ +struct S { int a,b,c,d, e[1024];}; +int foo (struct S *a, struct S *b) +{ + *a = *b; + return 0; +} + +void *memmove(void*,const void*,__SIZE_TYPE__); +void foo2 (struct S *a, struct S *b) +{ + memmove(a, b, sizeof *a); +} + +int main() +{ + return 0; +} diff --git a/tinycc/tests/tests2/103_implicit_memmove.expect b/tinycc/tests/tests2/103_implicit_memmove.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/103_implicit_memmove.expect diff --git a/tinycc/tests/tests2/104+_inline.c b/tinycc/tests/tests2/104+_inline.c new file mode 100644 index 0000000..3c48eb8 --- /dev/null +++ b/tinycc/tests/tests2/104+_inline.c @@ -0,0 +1,54 @@ + +#define GOT(f) \ + __attribute__((weak)) void f(void); \ + printf("%d %s\n", !!((__SIZE_TYPE__)f & ~0u), #f); + +int printf(const char*, ...); + +void check_exports() +{ + // 0 + GOT(inline_inline_2decl_only) + GOT(inline_inline_undeclared) + GOT(inline_inline_predeclared) + GOT(inline_inline_postdeclared) + GOT(inline_inline_prepostdeclared) + GOT(inline_inline_undeclared2) + GOT(inline_inline_predeclared2) + GOT(inline_inline_postdeclared2) + GOT(inline_inline_prepostdeclared2) + + // 1 + GOT(extern_extern_postdeclared) + GOT(extern_extern_postdeclared2) + GOT(extern_extern_predeclared) + GOT(extern_extern_predeclared2) + GOT(extern_extern_prepostdeclared) + GOT(extern_extern_prepostdeclared2) + GOT(extern_extern_undeclared) + GOT(extern_extern_undeclared2) + GOT(extern_postdeclared) + GOT(extern_postdeclared2) + GOT(extern_predeclared) + GOT(extern_predeclared2) + GOT(extern_prepostdeclared) + GOT(extern_undeclared) + GOT(extern_undeclared2) + GOT(inst2_extern_inline_postdeclared) + GOT(inst2_extern_inline_predeclared) + GOT(inst3_extern_inline_predeclared) + GOT(inst_extern_inline_postdeclared) + GOT(inst_extern_inline_predeclared) + GOT(main) + GOT(noinst_extern_inline_func) + GOT(noinst_extern_inline_postdeclared) + GOT(noinst_extern_inline_postdeclared2) + GOT(noinst_extern_inline_undeclared) + + // 0 + GOT(noinst_static_inline_postdeclared) + GOT(noinst2_static_inline_postdeclared) + GOT(noinst_static_inline_predeclared) + GOT(noinst2_static_inline_predeclared) + GOT(static_func) +} diff --git a/tinycc/tests/tests2/104_inline.c b/tinycc/tests/tests2/104_inline.c new file mode 100644 index 0000000..766f94a --- /dev/null +++ b/tinycc/tests/tests2/104_inline.c @@ -0,0 +1,132 @@ +inline void inline_inline_2decl_only(void); +inline void inline_inline_2decl_only(void); + +inline void inline_inline_undeclared(void){} + +inline void inline_inline_predeclared(void); +inline void inline_inline_predeclared(void){} + +inline void inline_inline_postdeclared(void){} +inline void inline_inline_postdeclared(void); + +inline void inline_inline_prepostdeclared(void); +inline void inline_inline_prepostdeclared(void){} +inline void inline_inline_prepostdeclared(void); + +inline void inline_inline_undeclared2(void){} + +inline void inline_inline_predeclared2(void); +inline void inline_inline_predeclared2(void); +inline void inline_inline_predeclared2(void){} + +inline void inline_inline_postdeclared2(void){} +inline void inline_inline_postdeclared2(void); +inline void inline_inline_postdeclared2(void); + +inline void inline_inline_prepostdeclared2(void); +inline void inline_inline_prepostdeclared2(void); +inline void inline_inline_prepostdeclared2(void){} +inline void inline_inline_prepostdeclared2(void); +inline void inline_inline_prepostdeclared2(void); + +extern void extern_extern_undeclared(void){} + +extern void extern_extern_predeclared(void); +extern void extern_extern_predeclared(void){} + +extern void extern_extern_postdeclared(void){} +extern void extern_extern_postdeclared(void); + +extern void extern_extern_prepostdeclared(void); +extern void extern_extern_prepostdeclared(void){} +extern void extern_extern_prepostdeclared(void); + +extern void extern_extern_undeclared2(void){} + +extern void extern_extern_predeclared2(void); +extern void extern_extern_predeclared2(void); +extern void extern_extern_predeclared2(void){} + +extern void extern_extern_postdeclared2(void){} +extern void extern_extern_postdeclared2(void); +extern void extern_extern_postdeclared2(void); + +extern void extern_extern_prepostdeclared2(void); +extern void extern_extern_prepostdeclared2(void); +extern void extern_extern_prepostdeclared2(void){} +extern void extern_extern_prepostdeclared2(void); +extern void extern_extern_prepostdeclared2(void); + +void extern_undeclared(void){} + +void extern_predeclared(void); +void extern_predeclared(void){} + +void extern_postdeclared(void){} +void extern_postdeclared(void); + +void extern_prepostdeclared(void); +void extern_prepostdeclared(void){} +void extern_prepostdeclared(void); + +void extern_undeclared2(void){} + +void extern_predeclared2(void); +void extern_predeclared2(void); +void extern_predeclared2(void){} + +void extern_postdeclared2(void){} +void extern_postdeclared2(void); +void extern_postdeclared2(void); + + +extern inline void noinst_extern_inline_undeclared(void){} + +extern inline void noinst_extern_inline_postdeclared(void){} +inline void noinst_extern_inline_postdeclared(void); + +extern inline void noinst_extern_inline_postdeclared2(void){} +inline void noinst_extern_inline_postdeclared2(void); +inline void noinst_extern_inline_postdeclared2(void); + +extern inline void inst_extern_inline_postdeclared(void){} +extern inline void inst_extern_inline_postdeclared(void); +inline void inst2_extern_inline_postdeclared(void){} +void inst2_extern_inline_postdeclared(void); + +void inst_extern_inline_predeclared(void); +extern inline void inst_extern_inline_predeclared(void){} +void inst2_extern_inline_predeclared(void); +inline void inst2_extern_inline_predeclared(void){} +extern inline void inst3_extern_inline_predeclared(void); +inline void inst3_extern_inline_predeclared(void){} + +static inline void noinst_static_inline_postdeclared(void){} +static inline void noinst_static_inline_postdeclared(void); +static inline void noinst2_static_inline_postdeclared(void){} +static void noinst2_static_inline_postdeclared(void); + +static void noinst_static_inline_predeclared(void); +static inline void noinst_static_inline_predeclared(void){} +static void noinst2_static_inline_predeclared(void); +static inline void noinst2_static_inline_predeclared(void){} + +static void static_func(void); +void static_func(void) { } + +inline void noinst_extern_inline_func(void); +void noinst_extern_inline_func(void) { } + +int main() +{ + inline_inline_undeclared(); inline_inline_predeclared(); inline_inline_postdeclared(); + inline_inline_undeclared2(); inline_inline_predeclared2(); inline_inline_postdeclared2(); + noinst_static_inline_predeclared(); + noinst2_static_inline_predeclared(); + noinst_static_inline_predeclared(); + noinst2_static_inline_predeclared(); + + void check_exports(); + check_exports(); + return 0; +} diff --git a/tinycc/tests/tests2/104_inline.expect b/tinycc/tests/tests2/104_inline.expect new file mode 100644 index 0000000..bdb0994 --- /dev/null +++ b/tinycc/tests/tests2/104_inline.expect @@ -0,0 +1,39 @@ +0 inline_inline_2decl_only +0 inline_inline_undeclared +0 inline_inline_predeclared +0 inline_inline_postdeclared +0 inline_inline_prepostdeclared +0 inline_inline_undeclared2 +0 inline_inline_predeclared2 +0 inline_inline_postdeclared2 +0 inline_inline_prepostdeclared2 +1 extern_extern_postdeclared +1 extern_extern_postdeclared2 +1 extern_extern_predeclared +1 extern_extern_predeclared2 +1 extern_extern_prepostdeclared +1 extern_extern_prepostdeclared2 +1 extern_extern_undeclared +1 extern_extern_undeclared2 +1 extern_postdeclared +1 extern_postdeclared2 +1 extern_predeclared +1 extern_predeclared2 +1 extern_prepostdeclared +1 extern_undeclared +1 extern_undeclared2 +1 inst2_extern_inline_postdeclared +1 inst2_extern_inline_predeclared +1 inst3_extern_inline_predeclared +1 inst_extern_inline_postdeclared +1 inst_extern_inline_predeclared +1 main +1 noinst_extern_inline_func +1 noinst_extern_inline_postdeclared +1 noinst_extern_inline_postdeclared2 +1 noinst_extern_inline_undeclared +0 noinst_static_inline_postdeclared +0 noinst2_static_inline_postdeclared +0 noinst_static_inline_predeclared +0 noinst2_static_inline_predeclared +0 static_func diff --git a/tinycc/tests/tests2/105_local_extern.c b/tinycc/tests/tests2/105_local_extern.c new file mode 100644 index 0000000..a248bb4 --- /dev/null +++ b/tinycc/tests/tests2/105_local_extern.c @@ -0,0 +1,12 @@ +extern int printf(const char *, ...); +void f(void); +void bar(void) { void f(void); f(); } +void foo(void) { extern void f(void); f(); } +void f(void) { printf("f\n"); } + +int main() +{ + bar(); + foo(); + return 0; +} diff --git a/tinycc/tests/tests2/105_local_extern.expect b/tinycc/tests/tests2/105_local_extern.expect new file mode 100644 index 0000000..445ae74 --- /dev/null +++ b/tinycc/tests/tests2/105_local_extern.expect @@ -0,0 +1,2 @@ +f +f diff --git a/tinycc/tests/tests2/106_versym.c b/tinycc/tests/tests2/106_versym.c new file mode 100644 index 0000000..dcce508 --- /dev/null +++ b/tinycc/tests/tests2/106_versym.c @@ -0,0 +1,18 @@ +#include <stdio.h> +#include <pthread.h> +#include <errno.h> + +int +main(void) +{ + int ret; + pthread_condattr_t attr; + pthread_cond_t condition; + + /* This test fails if symbol versioning does not work */ + pthread_condattr_init (&attr); + pthread_condattr_setpshared (&attr, PTHREAD_PROCESS_SHARED); + printf ("%s\n", pthread_cond_init (&condition, &attr) ? "fail":"ok"); + pthread_condattr_destroy (&attr); + return 0; +} diff --git a/tinycc/tests/tests2/106_versym.expect b/tinycc/tests/tests2/106_versym.expect new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/tinycc/tests/tests2/106_versym.expect @@ -0,0 +1 @@ +ok diff --git a/tinycc/tests/tests2/107_stack_safe.c b/tinycc/tests/tests2/107_stack_safe.c new file mode 100644 index 0000000..479c84d --- /dev/null +++ b/tinycc/tests/tests2/107_stack_safe.c @@ -0,0 +1,13 @@ +extern int printf(const char *, ...); + +static void func_ull_ull(unsigned long long l1,unsigned long long l2){ +} + +int main() +{ + int a,b,c,d; + a=1;b=2;c=3;d=4; + func_ull_ull((unsigned long long)a/1.0,(unsigned long long)b/1.0); + printf("%d %d %d %d",a,b,c,d); + return 0; +} diff --git a/tinycc/tests/tests2/107_stack_safe.expect b/tinycc/tests/tests2/107_stack_safe.expect new file mode 100644 index 0000000..e9e9cd7 --- /dev/null +++ b/tinycc/tests/tests2/107_stack_safe.expect @@ -0,0 +1 @@ +1 2 3 4
\ No newline at end of file diff --git a/tinycc/tests/tests2/108_constructor.c b/tinycc/tests/tests2/108_constructor.c new file mode 100644 index 0000000..145d0da --- /dev/null +++ b/tinycc/tests/tests2/108_constructor.c @@ -0,0 +1,20 @@ +extern int write (int fd, void *buf, int len); + +static void __attribute__ ((constructor)) +testc (void) +{ + write (1, "constructor\n", 12); +} + +static void __attribute__ ((destructor)) +testd (void) +{ + write (1, "destructor\n", 11); +} + +int +main (void) +{ + write (1, "main\n", 5); + return 0; +} diff --git a/tinycc/tests/tests2/108_constructor.expect b/tinycc/tests/tests2/108_constructor.expect new file mode 100644 index 0000000..167ca51 --- /dev/null +++ b/tinycc/tests/tests2/108_constructor.expect @@ -0,0 +1,3 @@ +constructor +main +destructor diff --git a/tinycc/tests/tests2/109_float_struct_calling.c b/tinycc/tests/tests2/109_float_struct_calling.c new file mode 100644 index 0000000..90fc045 --- /dev/null +++ b/tinycc/tests/tests2/109_float_struct_calling.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +/* This test used to fail on x86_64 on linux with sse registers */ + +struct Point { + float x; + float y; +}; + +struct Rect { + struct Point top_left; + struct Point size; +}; + +float foo(struct Point p, struct Rect r) { + return r.size.x; +} + +int main(int argc, char **argv) { + struct Point p = {1, 2}; + struct Rect r = {{3, 4}, {5, 6}}; + printf("%f\n", foo(p, r)); + return 0; +} diff --git a/tinycc/tests/tests2/109_float_struct_calling.expect b/tinycc/tests/tests2/109_float_struct_calling.expect new file mode 100644 index 0000000..eaa6787 --- /dev/null +++ b/tinycc/tests/tests2/109_float_struct_calling.expect @@ -0,0 +1 @@ +5.000000 diff --git a/tinycc/tests/tests2/10_pointer.c b/tinycc/tests/tests2/10_pointer.c new file mode 100644 index 0000000..0177f4d --- /dev/null +++ b/tinycc/tests/tests2/10_pointer.c @@ -0,0 +1,40 @@ +#include <stdio.h> + +struct ziggy +{ + int a; + int b; + int c; +} bolshevic; + +int main() +{ + int a; + int *b; + int c; + + a = 42; + b = &a; + printf("a = %d\n", *b); + + bolshevic.a = 12; + bolshevic.b = 34; + bolshevic.c = 56; + + printf("bolshevic.a = %d\n", bolshevic.a); + printf("bolshevic.b = %d\n", bolshevic.b); + printf("bolshevic.c = %d\n", bolshevic.c); + + struct ziggy *tsar = &bolshevic; + + printf("tsar->a = %d\n", tsar->a); + printf("tsar->b = %d\n", tsar->b); + printf("tsar->c = %d\n", tsar->c); + + b = &(bolshevic.b); + printf("bolshevic.b = %d\n", *b); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/10_pointer.expect b/tinycc/tests/tests2/10_pointer.expect new file mode 100644 index 0000000..1e3c473 --- /dev/null +++ b/tinycc/tests/tests2/10_pointer.expect @@ -0,0 +1,8 @@ +a = 42 +bolshevic.a = 12 +bolshevic.b = 34 +bolshevic.c = 56 +tsar->a = 12 +tsar->b = 34 +tsar->c = 56 +bolshevic.b = 34 diff --git a/tinycc/tests/tests2/110_average.c b/tinycc/tests/tests2/110_average.c new file mode 100644 index 0000000..273b511 --- /dev/null +++ b/tinycc/tests/tests2/110_average.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +typedef struct +{ + double average; + int count; +} +stats_type; + +static void +testc (stats_type *s, long long data) +{ + s->average = (s->average * s->count + data) / (s->count + 1); + s->count++; +} + +int main (void) +{ + stats_type s; + + s.average = 0; + s.count = 0; + testc (&s, 10); + testc (&s, 20); + printf ("%g %d\n", s.average, s.count); + return 0; +} diff --git a/tinycc/tests/tests2/110_average.expect b/tinycc/tests/tests2/110_average.expect new file mode 100644 index 0000000..4955335 --- /dev/null +++ b/tinycc/tests/tests2/110_average.expect @@ -0,0 +1 @@ +15 2 diff --git a/tinycc/tests/tests2/111_conversion.c b/tinycc/tests/tests2/111_conversion.c new file mode 100644 index 0000000..c0815e1 --- /dev/null +++ b/tinycc/tests/tests2/111_conversion.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +union u { + unsigned long ul; + long double ld; +}; + +void +conv (union u *p) +{ + p->ul = (unsigned int) p->ld; +} + +int main (void) +{ + union u v; + + v.ld = 42; + conv (&v); + printf ("%lu\n", v.ul); + return 0; +} diff --git a/tinycc/tests/tests2/111_conversion.expect b/tinycc/tests/tests2/111_conversion.expect new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/tinycc/tests/tests2/111_conversion.expect @@ -0,0 +1 @@ +42 diff --git a/tinycc/tests/tests2/112_backtrace.c b/tinycc/tests/tests2/112_backtrace.c new file mode 100644 index 0000000..0b596d0 --- /dev/null +++ b/tinycc/tests/tests2/112_backtrace.c @@ -0,0 +1,175 @@ +#include <stdio.h> + +/* ------------------------------------------------------- */ +#if defined test_backtrace_1 + +void f3() +{ + printf("* f3()\n"), fflush(stdout); + *(void**)0 = 0; +} +void f2() +{ + printf("* f2()\n"), fflush(stdout); + f3(); +} +void f1() +{ + printf("* f1()\n"), fflush(stdout); + f2(); +} +int main(int argc, char **argv) +{ + printf("* main\n"), fflush(stdout); + f1(); + printf("* exit main\n"), fflush(stdout); + return 0; +} + +/* ------------------------------------------------------- */ +#elif defined test_bcheck_1 + +struct s { int a,b,c,d,e; }; +struct s s[3]; +struct s *ps = s; +void f1() +{ + printf("* f1()\n"), fflush(stdout); + ps[3] = ps[2]; +} +int main(int argc, char **argv) +{ + printf("* main\n"), fflush(stdout); + f1(); + printf("* exit main\n"), fflush(stdout); + return 0; +} + +/* ------------------------------------------------------- */ +#elif defined test_tcc_backtrace_2 + +/* test custom backtrace and 'exit()' redirection */ +int tcc_backtrace(const char *fmt, ...); +void exit(int); + +void f2() +{ + printf("* f2()\n"); + printf("* exit f2\n"), fflush(stdout); + exit(34); +} +void f1() +{ + printf("* f1()\n"), fflush(stdout); + tcc_backtrace("Hello from %s!", "f1"); + f2(); +} +int main(int argc, char **argv) +{ + printf("* main\n"), fflush(stdout); + f1(); + printf("* exit main\n"), fflush(stdout); + return 0; +} + +/* ------------------------------------------------------- */ +#elif defined test_tcc_backtrace_3 + +/* this test should be run despite of the exit(34) above */ +int main(int argc, char **argv) +{ + printf("* main\n"), fflush(stdout); + return 1; +} + +/* ------------------------------------------------------- */ +#else +#include <stdlib.h> +#include <string.h> +char *strdup(); +int main() +{ + char pad1[10]; + char a[10]; + char pad2[10]; + char b[10]; + char pad3[10]; + memset (pad1, 0, sizeof(pad1)); + memset (pad2, 0, sizeof(pad2)); + memset (pad3, 0, sizeof(pad3)); + + memset (a, 'a', 10); + a[3] = 0; + a[9] = 0; + memset (b, 'b', 10); + +#if defined test_bcheck_100 + memcpy(&a[1],&b[0],10); +#elif defined test_bcheck_101 + memcpy(&a[0],&b[1],10); +#elif defined test_bcheck_102 + memcpy(&a[0],&a[3],4); +#elif defined test_bcheck_103 + memcpy(&a[3],&a[0],4); +#elif defined test_bcheck_104 + memcmp(&b[1],&b[0],10); +#elif defined test_bcheck_105 + memcmp(&b[0],&b[1],10); +#elif defined test_bcheck_106 + memmove(&b[1],&b[0],10); +#elif defined test_bcheck_107 + memmove(&b[0],&b[1],10); +#elif defined test_bcheck_108 + memset(&b[1],'b',10); +#elif defined test_bcheck_109 + strlen(&b[0]); +#elif defined test_bcheck_110 + strcpy(&a[7], &a[0]); +#elif defined test_bcheck_111 + strcpy(&a[0], &b[7]); +#elif defined test_bcheck_112 + strcpy(&a[0], &a[1]); +#elif defined test_bcheck_113 + strcpy(&a[2], &a[0]); +#elif defined test_bcheck_114 + strncpy(&a[7], &a[0], 10); +#elif defined test_bcheck_115 + strncpy(&a[0], &b[7], 10); +#elif defined test_bcheck_116 + strncpy(&a[0], &a[1], 10); +#elif defined test_bcheck_117 + strncpy(&a[2], &a[0], 10); +#elif defined test_bcheck_118 + strcmp(&b[2], &b[0]); +#elif defined test_bcheck_119 + strcmp(&b[0], &b[2]); +#elif defined test_bcheck_120 + strncmp(&b[5], &b[0], 10); +#elif defined test_bcheck_121 + strncmp(&b[0], &b[5], 10); +#elif defined test_bcheck_122 + strcat(&a[7], &a[0]); +#elif defined test_bcheck_123 + strcat(&a[0], &b[3]); +#elif defined test_bcheck_124 + strcat(&a[0], &a[4]); +#elif defined test_bcheck_125 + strcat(&a[3], &a[0]); +#elif defined test_bcheck_126 + strncat(&a[7], &a[0], 3); +#elif defined test_bcheck_127 + strncat(&a[0], &b[3], 8); +#elif defined test_bcheck_128 + strncat(&a[0], &a[4], 3); +#elif defined test_bcheck_129 + strncat(&a[3], &a[0], 10); +#elif defined test_bcheck_130 + strchr(&b[0], 'a'); +#elif defined test_bcheck_131 + strrchr(&b[0], 'a'); +#elif defined test_bcheck_132 + free(strdup(&b[0])); +#endif +} +/* ------------------------------------------------------- */ +#endif diff --git a/tinycc/tests/tests2/112_backtrace.expect b/tinycc/tests/tests2/112_backtrace.expect new file mode 100644 index 0000000..ec2c6b8 --- /dev/null +++ b/tinycc/tests/tests2/112_backtrace.expect @@ -0,0 +1,162 @@ +[test_backtrace_1] +* main +* f1() +* f2() +* f3() +112_backtrace.c:9: at f3: RUNTIME ERROR: invalid memory access +112_backtrace.c:14: by f2 +112_backtrace.c:19: by f1 +112_backtrace.c:24: by main +[returns 255] + +[test_bcheck_1] +* main +* f1() +112_backtrace.c:38: at f1: BCHECK: invalid pointer ........, size 0x? in memmove dest +112_backtrace.c:43: by main +[returns 255] + +[test_tcc_backtrace_2] +* main +* f1() +112_backtrace.c:64: at f1: Hello from f1! +112_backtrace.c:70: by main +* f2() +* exit f2 +[returns 34] + +[test_tcc_backtrace_3] +* main +[returns 1] + +[test_bcheck_100] +112_backtrace.c:107: at main: BCHECK: invalid pointer ........, size 0x? in memcpy dest +[returns 255] + +[test_bcheck_101] +112_backtrace.c:109: at main: BCHECK: invalid pointer ........, size 0x? in memcpy src +[returns 255] + +[test_bcheck_102] +112_backtrace.c:111: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in memcpy +[returns 255] + +[test_bcheck_103] +112_backtrace.c:113: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in memcpy +[returns 255] + +[test_bcheck_104] +112_backtrace.c:115: at main: BCHECK: invalid pointer ........, size 0x? in memcmp s1 +[returns 255] + +[test_bcheck_105] +112_backtrace.c:117: at main: BCHECK: invalid pointer ........, size 0x? in memcmp s2 +[returns 255] + +[test_bcheck_106] +112_backtrace.c:119: at main: BCHECK: invalid pointer ........, size 0x? in memmove dest +[returns 255] + +[test_bcheck_107] +112_backtrace.c:121: at main: BCHECK: invalid pointer ........, size 0x? in memmove src +[returns 255] + +[test_bcheck_108] +112_backtrace.c:123: at main: BCHECK: invalid pointer ........, size 0x? in memset +[returns 255] + +[test_bcheck_109] +112_backtrace.c:125: at main: BCHECK: invalid pointer ........, size 0x? in strlen +[returns 255] + +[test_bcheck_110] +112_backtrace.c:127: at main: BCHECK: invalid pointer ........, size 0x? in strcpy dest +[returns 255] + +[test_bcheck_111] +112_backtrace.c:129: at main: BCHECK: invalid pointer ........, size 0x? in strcpy src +[returns 255] + +[test_bcheck_112] +112_backtrace.c:131: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strcpy +[returns 255] + +[test_bcheck_113] +112_backtrace.c:133: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strcpy +[returns 255] + +[test_bcheck_114] +112_backtrace.c:135: at main: BCHECK: invalid pointer ........, size 0x? in strncpy dest +[returns 255] + +[test_bcheck_115] +112_backtrace.c:137: at main: BCHECK: invalid pointer ........, size 0x? in strncpy src +[returns 255] + +[test_bcheck_116] +112_backtrace.c:139: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncpy +[returns 255] + +[test_bcheck_117] +112_backtrace.c:141: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncpy +[returns 255] + +[test_bcheck_118] +112_backtrace.c:143: at main: BCHECK: invalid pointer ........, size 0x? in strcmp s1 +[returns 255] + +[test_bcheck_119] +112_backtrace.c:145: at main: BCHECK: invalid pointer ........, size 0x? in strcmp s2 +[returns 255] + +[test_bcheck_120] +112_backtrace.c:147: at main: BCHECK: invalid pointer ........, size 0x? in strncmp s1 +[returns 255] + +[test_bcheck_121] +112_backtrace.c:149: at main: BCHECK: invalid pointer ........, size 0x? in strncmp s2 +[returns 255] + +[test_bcheck_122] +112_backtrace.c:151: at main: BCHECK: invalid pointer ........, size 0x? in strcat dest +[returns 255] + +[test_bcheck_123] +112_backtrace.c:153: at main: BCHECK: invalid pointer ........, size 0x? in strcat dest +[returns 255] + +[test_bcheck_124] +112_backtrace.c:155: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strcat +[returns 255] + +[test_bcheck_125] +112_backtrace.c:157: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strcat +[returns 255] + +[test_bcheck_126] +112_backtrace.c:159: at main: BCHECK: invalid pointer ........, size 0x? in strncat dest +[returns 255] + +[test_bcheck_127] +112_backtrace.c:161: at main: BCHECK: invalid pointer ........, size 0x? in strncat dest +[returns 255] + +[test_bcheck_128] +112_backtrace.c:163: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncat +[returns 255] + +[test_bcheck_129] +112_backtrace.c:165: at main: BCHECK: overlapping regions ........(0x?), ........(0x?) in strncat +[returns 255] + +[test_bcheck_130] +112_backtrace.c:167: at main: BCHECK: invalid pointer ........, size 0x? in strchr +[returns 255] + +[test_bcheck_131] +112_backtrace.c:169: at main: BCHECK: invalid pointer ........, size 0x? in strrchr +[returns 255] + +[test_bcheck_132] +112_backtrace.c:171: at main: BCHECK: invalid pointer ........, size 0x? in strdup +[returns 255] diff --git a/tinycc/tests/tests2/113_btdll.c b/tinycc/tests/tests2/113_btdll.c new file mode 100644 index 0000000..8ae8981 --- /dev/null +++ b/tinycc/tests/tests2/113_btdll.c @@ -0,0 +1,43 @@ +int tcc_backtrace(const char*, ...); +#define hello() \ + tcc_backtrace("hello from %s() / %s:%d",__FUNCTION__,__FILE__,__LINE__) + +#ifndef _WIN32 +# define __declspec(n) +#endif + +#if DLL==1 +__declspec(dllexport) int f_1() +{ + hello(); + return 0; +} + + +#elif DLL==2 +__declspec(dllexport) int f_2() +{ + hello(); + return 0; +} + + +#else + +int f_1(); +int f_2(); +int f_main() +{ + hello(); + return 0; +} + +int main () +{ + f_1(); + f_2(); + f_main(); + return 0; +} + +#endif diff --git a/tinycc/tests/tests2/113_btdll.expect b/tinycc/tests/tests2/113_btdll.expect new file mode 100644 index 0000000..34de481 --- /dev/null +++ b/tinycc/tests/tests2/113_btdll.expect @@ -0,0 +1,6 @@ +113_btdll.c:12: at f_1: hello from f_1() / 113_btdll.c:12 +113_btdll.c:37: by main +113_btdll.c:20: at f_2: hello from f_2() / 113_btdll.c:20 +113_btdll.c:38: by main +113_btdll.c:31: at f_main: hello from f_main() / 113_btdll.c:31 +113_btdll.c:39: by main diff --git a/tinycc/tests/tests2/114_bound_signal.c b/tinycc/tests/tests2/114_bound_signal.c new file mode 100644 index 0000000..d11b146 --- /dev/null +++ b/tinycc/tests/tests2/114_bound_signal.c @@ -0,0 +1,143 @@ +#include <stdio.h> +#include <pthread.h> +#include <semaphore.h> +#include <signal.h> +#include <string.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <setjmp.h> + +static volatile int run = 1; +static sem_t sem; +static sem_t sem_child; + +static void +add (int n) +{ + int i; + int arr[n]; + + for (i = 0; i < n; i++) { + arr[i]++; + } + memset (&arr[0], 0, n * sizeof(int)); +} + +static void * +high_load (void *unused) +{ + while (run) { + add(10); + add(20); + } + return NULL; +} + +static void * +do_signal (void *unused) +{ + while (run) { + kill (getpid(), SIGUSR1); + while (sem_wait(&sem) < 0 && errno == EINTR); + } + return NULL; +} + +static void * +do_fork (void *unused) +{ + pid_t pid; + + while (run) { + switch ((pid = fork())) { + case 0: + add(1000); + add(2000); + exit(0); + break; + case -1: + return NULL; + default: + while (sem_wait(&sem_child) < 0 && errno == EINTR); + wait(NULL); + break; + } + } + return NULL; +} + +static void signal_handler(int sig) +{ + add(10); + add(20); + sem_post (&sem); +} + +static void child_handler(int sig) +{ + add(10); + add(20); + sem_post (&sem_child); +} + +int +main (void) +{ + int i; + pthread_t id1, id2, id3; + struct sigaction act; + sigjmp_buf sj; + sigset_t m; + time_t end; + + memset (&act, 0, sizeof (act)); + act.sa_handler = signal_handler; + act.sa_flags = 0; + sigemptyset (&act.sa_mask); + sigaction (SIGUSR1, &act, NULL); + act.sa_handler = child_handler; + sigaction (SIGCHLD, &act, NULL); + + printf ("start\n"); fflush(stdout); + + sem_init (&sem, 0, 0); + sem_init (&sem_child, 0, 0); + pthread_create(&id1, NULL, high_load, NULL); + pthread_create(&id2, NULL, do_signal, NULL); +#if !defined(__APPLE__) + pthread_create(&id3, NULL, do_fork, NULL); +#endif + + /* sleep does not work !!! */ + end = time(NULL) + 2; + while (time(NULL) < end) ; + run = 0; + + pthread_join(id1, NULL); + pthread_join(id2, NULL); +#if !defined(__APPLE__) + pthread_join(id3, NULL); +#endif + sem_destroy (&sem); + sem_destroy (&sem_child); + + printf ("end\n"); fflush(stdout); + + sigemptyset (&m); + sigprocmask (SIG_SETMASK, &m, NULL); + if (sigsetjmp (sj, 0) == 0) + { + sigaddset (&m, SIGUSR1); + sigprocmask (SIG_SETMASK, &m, NULL); + siglongjmp (sj, 1); + printf ("failed"); + return 1; + } + sigprocmask (SIG_SETMASK, NULL, &m); + if (!sigismember (&m, SIGUSR1)) + printf ("failed"); + return 0; +} diff --git a/tinycc/tests/tests2/114_bound_signal.expect b/tinycc/tests/tests2/114_bound_signal.expect new file mode 100644 index 0000000..5d0fb3b --- /dev/null +++ b/tinycc/tests/tests2/114_bound_signal.expect @@ -0,0 +1,2 @@ +start +end diff --git a/tinycc/tests/tests2/115_bound_setjmp.c b/tinycc/tests/tests2/115_bound_setjmp.c new file mode 100644 index 0000000..793db58 --- /dev/null +++ b/tinycc/tests/tests2/115_bound_setjmp.c @@ -0,0 +1,172 @@ +#include <stdio.h> +#include <string.h> +#include <setjmp.h> + +#define TST int i, a[2], b[2]; \ + for (i = 0; i < 2; i++) a[i] = 0; \ + for (i = 0; i < 2; i++) b[i] = 0 + +static jmp_buf jmp; + +static void tst1 (void) +{ + TST; + longjmp(jmp, 1); +} + +static void tst2(void) +{ + jmp_buf jmp; + + setjmp (jmp); + TST; + tst1(); +} + +static void tst3 (jmp_buf loc) +{ + TST; + longjmp(loc, 1); +} + +static void tst4(jmp_buf loc) +{ + jmp_buf jmp; + + setjmp (jmp); + TST; + tst3(loc); +} + +static void tst (void) +{ + jmp_buf loc; + static int cnt; + + cnt = 0; + if (setjmp (jmp) == 0) { + TST; + tst2(); + } + else { + cnt++; + } + if (setjmp (loc) == 0) { + TST; + tst4(loc); + } + else { + cnt++; + } + if (cnt != 2) + printf ("incorrect cnt %d\n", cnt); +} + +static jmp_buf buf1; +static jmp_buf buf2; +static int *p; +static int n_x = 6; +static int g_counter; + +static void stack (void) +{ + static int counter; + static int way_point1; + static int way_point2; + + counter = 0; + way_point1 = 3; + way_point2 = 2; + g_counter = 0; + if (setjmp (buf1) != 101) { + int a[n_x]; + g_counter++; + p = &a[0]; + if (g_counter < 5) + longjmp (buf1, 2); + else if (g_counter == 5) + longjmp (buf1, 101); + else { + setjmp (buf2); + longjmp (buf1, 101); + } + } + + way_point1--; + + if (counter == 0) { + counter++; + { + int a[n_x]; + g_counter++; + p = &a[0]; + if (g_counter < 5) + longjmp (buf1, 2); + else if (g_counter == 5) + longjmp (buf1, 101); + else { + setjmp (buf2); + longjmp (buf1, 101); + } + } + } + + way_point2--; + + if (counter == 1) { + counter++; + longjmp (buf2, 2); + } + + if (!(way_point1 == 0 && way_point2 == 0 && + g_counter == 6 && counter == 2)) + printf ("Failed %d %d %d %d\n", + way_point1, way_point2, g_counter, counter); +} + +static jmp_buf env; +static int last_value; + +static void jump (int val) +{ + longjmp (env, val); +} + +static void check (void) +{ + int value; + + last_value = -1; + value = setjmp (env); + if (value != last_value + 1) { + printf ("incorrect value %d %d\n", + value, last_value + 1); + return; + } + last_value = value; + switch (value) { +#if !(defined(__FreeBSD__) || defined(__NetBSD__)) + /* longjmp(jmp_buf, 0) not supported */ + case 0: + jump (0); +#endif + default: + if (value < 10) + jump (value + 1); + } +} + +int +main (void) +{ + int i; + + for (i = 0; i < 10; i++) { + tst(); + stack(); + check(); + } + return 0; +} + + diff --git a/tinycc/tests/tests2/115_bound_setjmp.expect b/tinycc/tests/tests2/115_bound_setjmp.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/115_bound_setjmp.expect diff --git a/tinycc/tests/tests2/116_bound_setjmp2.c b/tinycc/tests/tests2/116_bound_setjmp2.c new file mode 100644 index 0000000..151114d --- /dev/null +++ b/tinycc/tests/tests2/116_bound_setjmp2.c @@ -0,0 +1,84 @@ +#include <stdio.h> +#include <string.h> +#include <setjmp.h> +#if !defined(_WIN32) +#include <pthread.h> +#else +#include <windows.h> +#endif + +#define SIZE 10 +#define COUNT 10 + +#define TST int i, a[2], b[2]; \ + for (i = 0; i < 2; i++) a[i] = 0; \ + for (i = 0; i < 2; i++) b[i] = 0 + +static int count[SIZE]; + +static void tst1 (jmp_buf loc) +{ + TST; + longjmp(loc, 1); +} + +static void tst2(jmp_buf loc) +{ + jmp_buf jmp; + + setjmp (jmp); + TST; + tst1(loc); +} + +static void *tst (void * index) +{ + jmp_buf loc; + int i = *(int *) index; + static int v[SIZE]; + + for (v[i] = 0; v[i] < COUNT; v[i]++) { + if (setjmp (loc) == 0) { + TST; + tst2(loc); + } + else { + count[i]++; + } + i = *(int *) index; + } + return NULL; +} + +int +main (void) +{ + int i; +#if !defined(_WIN32) + pthread_t id[SIZE]; +#else + HANDLE id[SIZE]; +#endif + int index[SIZE]; + + for (i = 0; i < SIZE; i++) { + index[i] = i; +#if !defined(_WIN32) + pthread_create (&id[i], NULL, tst, (void *) &index[i]); +#else + id[i] = CreateThread(NULL, 8192, (LPTHREAD_START_ROUTINE) tst, (void *) &index[i], 0, NULL); +#endif + } + for (i = 0; i < SIZE; i++) { +#if !defined(_WIN32) + pthread_join (id[i], NULL); +#else + WaitForSingleObject(id[i], INFINITE); +#endif + } + for (i = 0; i < SIZE; i++) { + if (count[i] != COUNT) + printf ("error: %d %d\n", i, count[i]); + } + return 0; +} diff --git a/tinycc/tests/tests2/116_bound_setjmp2.expect b/tinycc/tests/tests2/116_bound_setjmp2.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/116_bound_setjmp2.expect diff --git a/tinycc/tests/tests2/117_builtins.c b/tinycc/tests/tests2/117_builtins.c new file mode 100644 index 0000000..b57a73e --- /dev/null +++ b/tinycc/tests/tests2/117_builtins.c @@ -0,0 +1,94 @@ +#include <stdio.h> + +struct big_struct { char a[262144]; }; + +static const char str[] = "abcdefghijklmnopqrstuvwxyz"; + +int +main (void) +{ + char *p; + char tmp[100]; + int r = 0; + +#if defined __TCC_BCHECK__ + printf("BOUNDS ON:\n"); +#else + printf("BOUNDS OFF:\n"); +#endif + + if (r != 0) + __builtin_abort(); + + r = (__builtin_offsetof(struct big_struct, a) != 0); + printf(" 1:%d", !r); + + p = __builtin_memcpy (tmp, str, sizeof(str)); + r = (p != tmp); + printf(" 2:%d", !r); + + r = __builtin_memcmp (p, str, sizeof(str)); + printf(" 3:%d", !r); + + p = __builtin_memmove(tmp, str, sizeof(str)); + r = (__builtin_memcmp (p, str, sizeof(str))); + printf(" 4:%d", !r); + + p = __builtin_memset(tmp, 0, sizeof (tmp)); + r = (p != tmp || tmp[0] != 0 || tmp[99] != 0); + printf(" 5:%d", !r); + + r = (__builtin_strlen(str) != sizeof(str) - 1); + printf(" 6:%d", !r); + + p = __builtin_strcpy(tmp, str); + r = (__builtin_memcmp (p, str, sizeof(str))); + printf(" 7:%d", !r); + + p = __builtin_strncpy(tmp, str, sizeof(str)); + r = (__builtin_memcmp (p, str, sizeof(str))); + printf(" 8:%d", !r); + + r = (__builtin_strcmp (p, str)); + printf(" 9:%d", !r); + + r = (__builtin_strncmp (p, str, sizeof(str))); + printf(" 10:%d", !r); + + tmp[0] = '\0'; + p = __builtin_strcat(tmp, str); + r = (__builtin_memcmp (p, str, sizeof(str))); + printf(" 11:%d", !r); + + tmp[0] = '\0'; + p = __builtin_strncat(tmp, str, __builtin_strlen(str)); + r = (__builtin_memcmp (p, str, sizeof(str))); + printf(" 12:%d", !r); + + r = (__builtin_strchr(p, 'z') != &p[25]); + printf(" 13:%d", !r); + + r = (__builtin_strrchr(p, 'z') != &p[25]); + printf(" 14:%d", !r); + + p = __builtin_strdup (str); + r = (__builtin_memcmp (p, str, sizeof(str))); + printf(" 15:%d", !r); + __builtin_free(p); + + p = __builtin_malloc (100); + __builtin_memset(p, 0, 100); + p = __builtin_realloc (p, 1000); + __builtin_memset(p, 0, 1000); + __builtin_free(p); + + p = __builtin_calloc(10, 10); + __builtin_memset(p, 0, 100); + __builtin_free(p); + +#if defined(__i386__) || defined(__x86_64__) + p = __builtin_alloca(100); + __builtin_memset(p, 0, 100); +#endif + printf("\n"); +} diff --git a/tinycc/tests/tests2/117_builtins.expect b/tinycc/tests/tests2/117_builtins.expect new file mode 100644 index 0000000..f2c78ba --- /dev/null +++ b/tinycc/tests/tests2/117_builtins.expect @@ -0,0 +1,4 @@ +BOUNDS OFF: + 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 14:1 15:1 +BOUNDS ON: + 1:1 2:1 3:1 4:1 5:1 6:1 7:1 8:1 9:1 10:1 11:1 12:1 13:1 14:1 15:1 diff --git a/tinycc/tests/tests2/118_switch.c b/tinycc/tests/tests2/118_switch.c new file mode 100644 index 0000000..789dd06 --- /dev/null +++ b/tinycc/tests/tests2/118_switch.c @@ -0,0 +1,75 @@ +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> + +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/tinycc/tests/tests2/118_switch.expect b/tinycc/tests/tests2/118_switch.expect new file mode 100644 index 0000000..4155eb4 --- /dev/null +++ b/tinycc/tests/tests2/118_switch.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 diff --git a/tinycc/tests/tests2/119_random_stuff.c b/tinycc/tests/tests2/119_random_stuff.c new file mode 100644 index 0000000..0b7a4e5 --- /dev/null +++ b/tinycc/tests/tests2/119_random_stuff.c @@ -0,0 +1,120 @@ +#include <stdio.h> + +struct big_struct { char a[262144]; }; + +static const char str[] = "abcdefghijklmnopqrstuvwxyz"; + +void tst_branch(void) +{ + printf("tst_branch --"); + goto *&&a; + printf (" dummy"); +a: ; + printf(" --\n"); +} + +void tst_void_ptr(void *pv, int i) +{ + i ? *pv : *pv; // dr106 +} + +void tst_shift(void) +{ + int i = 1; + long long l = 1; + i = i << 32; // illegal. just test + l = l << 64; // illegal. just test +} + +#if !defined(_WIN32) +#include <sys/mman.h> + +void tst_const_addr(void) +{ + void *addr = mmap ((void *)0x20000000, 4096, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANONYMOUS, -1, 0); + if (addr != (void *) -1) { + *(int *)0x20000000 += 42; + munmap (addr, 4096); + } +} +#endif + +struct zero_struct {}; + +struct zero_struct tst_zero_struct(void) +{ + struct zero_struct ret; + return ret; +} + +struct big_struct tst_big(struct big_struct tst) +{ + return tst; +} + +void tst_adr (int (*fp)(char *, const char *, ...)) +{ + char buf[10]; + (*fp)(buf, "%.0f", 5.0); + printf("tst_adr %s\n", buf); +} + +int tst(void) +{ + long long value = 3; + return -value; +} + +void tst_compare(void) +{ + /* This failed on risc64 */ + printf ("tst_compare: %s\n", tst() > 0 ? "error" : "ok"); +} + +#pragma pack(1) +struct S { int d:24; int f:14; } i, j; +#pragma pack() + +void tst_pack (void) +{ + i.f = 5; j.f = 5; + printf("tst_pack: j.f = %d, i.f = %d\n", j.f, i.f); +} + +void tst_cast(void) +{ + signed char c = (signed char) 0xaaaaaaaa; + int r = (unsigned short) c ^ (signed char) 0x99999999; + printf ("schar to ushort cast: %x\n", r); +} + +struct { + int (*print)(const char *format, ...); +} tst_indir = { + printf +}; + +void tst_indir_func(void) +{ + tst_indir.print("tst_indir_func %d\n", 10); +} + +int +main (void) +{ + struct big_struct big; + + tst_branch(); + tst_shift(); + tst_void_ptr(&big.a[0], 0); +#if !defined(_WIN32) + tst_const_addr(); +#endif + tst_zero_struct(); + tst_big(big); + tst_adr(&sprintf); + tst_compare(); + tst_pack(); + tst_cast(); + tst_indir_func(); +} diff --git a/tinycc/tests/tests2/119_random_stuff.expect b/tinycc/tests/tests2/119_random_stuff.expect new file mode 100644 index 0000000..3bd4a87 --- /dev/null +++ b/tinycc/tests/tests2/119_random_stuff.expect @@ -0,0 +1,6 @@ +tst_branch -- -- +tst_adr 5 +tst_compare: ok +tst_pack: j.f = 5, i.f = 5 +schar to ushort cast: ffff0033 +tst_indir_func 10 diff --git a/tinycc/tests/tests2/11_precedence.c b/tinycc/tests/tests2/11_precedence.c new file mode 100644 index 0000000..845b6bf --- /dev/null +++ b/tinycc/tests/tests2/11_precedence.c @@ -0,0 +1,41 @@ +//#include <stdio.h> +extern int printf(const char *, ...); + +int main() +{ + int a; + int b; + int c; + int d; + int e; + int f; + int x; + int y; + + a = 12; + b = 34; + c = 56; + d = 78; + e = 0; + f = 1; + + printf("%d\n", c + d); + printf("%d\n", (y = c + d)); + printf("%d\n", e || e && f); + printf("%d\n", e || f && f); + printf("%d\n", e && e || f); + printf("%d\n", e && f || f); + printf("%d\n", a && f | f); + printf("%d\n", a | b ^ c & d); + printf("%d, %d\n", a == a, a == b); + printf("%d, %d\n", a != a, a != b); + printf("%d\n", a != b && c != d); + printf("%d\n", a + b * c / f); + printf("%d\n", a + b * c / f); + printf("%d\n", (4 << 4)); + printf("%d\n", (64 >> 4)); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/11_precedence.expect b/tinycc/tests/tests2/11_precedence.expect new file mode 100644 index 0000000..b692396 --- /dev/null +++ b/tinycc/tests/tests2/11_precedence.expect @@ -0,0 +1,15 @@ +134 +134 +0 +1 +1 +1 +1 +46 +1, 0 +0, 1 +1 +1916 +1916 +64 +4 diff --git a/tinycc/tests/tests2/120+_alias.c b/tinycc/tests/tests2/120+_alias.c new file mode 100644 index 0000000..8f29d8d --- /dev/null +++ b/tinycc/tests/tests2/120+_alias.c @@ -0,0 +1,15 @@ +extern int printf (const char *, ...); +extern void target(void); +extern void alias_for_target(void); +extern void asm_for_target(void); + +void inunit2(void); + +void inunit2(void) +{ + target(); + alias_for_target(); + /* This symbol is not supposed to be available in this unit: + asm_for_target(); + */ +} diff --git a/tinycc/tests/tests2/120_alias.c b/tinycc/tests/tests2/120_alias.c new file mode 100644 index 0000000..5bead0f --- /dev/null +++ b/tinycc/tests/tests2/120_alias.c @@ -0,0 +1,29 @@ +/* Check semantics of various constructs to generate renamed symbols. */ +extern int printf (const char *, ...); +void target(void); +void target(void) { + printf("in target function\n"); +} + +void alias_for_target(void) __attribute__((alias("target"))); +#ifdef __leading_underscore +void asm_for_target(void) __asm__("_target"); +#else +void asm_for_target(void) __asm__("target"); +#endif + +/* This is not supposed to compile, alias targets must be defined in the + same unit. In TCC they even must be defined before the reference +void alias_for_undef(void) __attribute__((alias("undefined"))); +*/ + +extern void inunit2(void); + +int main(void) +{ + target(); + alias_for_target(); + asm_for_target(); + inunit2(); + return 0; +} diff --git a/tinycc/tests/tests2/120_alias.expect b/tinycc/tests/tests2/120_alias.expect new file mode 100644 index 0000000..021e3f0 --- /dev/null +++ b/tinycc/tests/tests2/120_alias.expect @@ -0,0 +1,5 @@ +in target function +in target function +in target function +in target function +in target function diff --git a/tinycc/tests/tests2/121_struct_return.c b/tinycc/tests/tests2/121_struct_return.c new file mode 100644 index 0000000..147761b --- /dev/null +++ b/tinycc/tests/tests2/121_struct_return.c @@ -0,0 +1,35 @@ +#include <stdio.h> + +typedef struct { + int data[4]; + double d1; + double d2; +} Node; + +Node init(Node self) { + self.data[0] = 0; + self.data[1] = 1; + self.data[2] = 2; + self.data[3] = 3; + self.d1 = 1234; + self.d2 = 2345; + return self; +} + +void dummy(Node self) { +} + +void print_data(Node data) { + printf ("%d %d %d %d %g %g\n", + data.data[0], data.data[1], data.data[2], data.data[3], + data.d1, data.d2); +} + +int main(void) { + /* This code resulted in a bounds checking error */ + Node data; + dummy (data); + char val; + data = init (data); + print_data(data); +} diff --git a/tinycc/tests/tests2/121_struct_return.expect b/tinycc/tests/tests2/121_struct_return.expect new file mode 100644 index 0000000..fa68b11 --- /dev/null +++ b/tinycc/tests/tests2/121_struct_return.expect @@ -0,0 +1 @@ +0 1 2 3 1234 2345 diff --git a/tinycc/tests/tests2/122_vla_reuse.c b/tinycc/tests/tests2/122_vla_reuse.c new file mode 100644 index 0000000..feb47de --- /dev/null +++ b/tinycc/tests/tests2/122_vla_reuse.c @@ -0,0 +1,31 @@ +#include <stdio.h> + +int +main (void) +{ + int n = 0; + int first=1; + int *p[101]; + if (0) { + lab:; + } + int x[n % 100 + 1]; + if (first == 0) { + if (&x[0] != p[n % 100 + 1]) { + printf ("ERROR: %p %p\n", &x[0], p[n % 100 + 1]); + return(1); + } + } + else { + p[n % 100 + 1] = &x[0]; + first = n < 100; + } + x[0] = 1; + x[n % 100] = 2; + n++; + if (n < 100000) + goto lab; + printf ("OK\n"); + return 0; +} + diff --git a/tinycc/tests/tests2/122_vla_reuse.expect b/tinycc/tests/tests2/122_vla_reuse.expect new file mode 100644 index 0000000..d86bac9 --- /dev/null +++ b/tinycc/tests/tests2/122_vla_reuse.expect @@ -0,0 +1 @@ +OK diff --git a/tinycc/tests/tests2/123_vla_bug.c b/tinycc/tests/tests2/123_vla_bug.c new file mode 100644 index 0000000..6d92c27 --- /dev/null +++ b/tinycc/tests/tests2/123_vla_bug.c @@ -0,0 +1,40 @@ +typedef __SIZE_TYPE__ size_t; +extern int printf(const char*, ...); +extern size_t strlen(const char*); +char str[] = "blabla"; +int g; +int main() +{ + //char helpme[strlen(str) + 1]; + int i = 0; +#if 0 + if (g) { + char buf[strlen(str) + 10]; + buf[0] = 0; + } +alabel: + printf("default: i = %d\n", i); +#else + for (i = 0; i < 5; i++) { + switch (i) { + case 10: + if (g) { + char buf[strlen(str) + 10]; + buf[0] = 0; + goto do_cmd; + } + break; + case 1: + printf("reached 3\n"); + do_cmd: + printf("after do_cmd"); + break; + default: + g++; + printf("default: i = %d\n", i); + break; + } + } +#endif + return 0; +} diff --git a/tinycc/tests/tests2/123_vla_bug.expect b/tinycc/tests/tests2/123_vla_bug.expect new file mode 100644 index 0000000..2468f80 --- /dev/null +++ b/tinycc/tests/tests2/123_vla_bug.expect @@ -0,0 +1,5 @@ +default: i = 0 +reached 3 +after do_cmddefault: i = 2 +default: i = 3 +default: i = 4 diff --git a/tinycc/tests/tests2/124_atomic_counter.c b/tinycc/tests/tests2/124_atomic_counter.c new file mode 100644 index 0000000..67a500a --- /dev/null +++ b/tinycc/tests/tests2/124_atomic_counter.c @@ -0,0 +1,152 @@ +#include <stddef.h> +#include <stdint.h> +#include <stdlib.h> +#include <stdio.h> +#include <pthread.h> +#include <stdatomic.h> + +#define NR_THREADS 16 +#define NR_STEPS ((uint32_t)UINT16_MAX) + +#define BUG_ON(COND) \ + do { \ + if (!!(COND)) \ + abort(); \ + } while (0) + +#if defined __x86_64__ || defined __aarch64__ || defined __riscv +#define HAS_64BITS +#endif + +typedef struct { + atomic_flag flag; + atomic_uchar uc; + atomic_ushort us; + atomic_uint ui; +#ifdef HAS_64BITS + atomic_size_t ul; +#endif +} counter_type; + +static +void *adder_simple(void *arg) +{ + size_t step; + counter_type *counter = arg; + + for (step = 0; step < NR_STEPS; ++step) { + atomic_fetch_add_explicit(&counter->uc, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&counter->us, 1, memory_order_relaxed); + atomic_fetch_add_explicit(&counter->ui, 1, memory_order_relaxed); +#ifdef HAS_64BITS + atomic_fetch_add_explicit(&counter->ul, 1, memory_order_relaxed); +#endif + } + + return NULL; +} + +static +void *adder_cmpxchg(void *arg) +{ + size_t step; + counter_type *counter = arg; + + for (step = 0; step < NR_STEPS; ++step) { + unsigned char xchgc; + unsigned short xchgs; + unsigned int xchgi; +#ifdef HAS_64BITS + size_t xchgl; +#endif + unsigned char cmpc = atomic_load_explicit(&counter->uc, memory_order_relaxed); + unsigned short cmps = atomic_load_explicit(&counter->us, memory_order_relaxed); + unsigned int cmpi = atomic_load_explicit(&counter->ui, memory_order_relaxed); +#ifdef HAS_64BITS + size_t cmpl = atomic_load_explicit(&counter->ul, memory_order_relaxed); +#endif + + do { + xchgc = (cmpc + 1); + } while (!atomic_compare_exchange_strong_explicit(&counter->uc, + &cmpc, xchgc, memory_order_relaxed, memory_order_relaxed)); + do { + xchgs = (cmps + 1); + } while (!atomic_compare_exchange_strong_explicit(&counter->us, + &cmps, xchgs, memory_order_relaxed, memory_order_relaxed)); + do { + xchgi = (cmpi + 1); + } while (!atomic_compare_exchange_strong_explicit(&counter->ui, + &cmpi, xchgi, memory_order_relaxed, memory_order_relaxed)); +#ifdef HAS_64BITS + do { + xchgl = (cmpl + 1); + } while (!atomic_compare_exchange_strong_explicit(&counter->ul, + &cmpl, xchgl, memory_order_relaxed, memory_order_relaxed)); +#endif + } + + return NULL; +} + +static +void *adder_test_and_set(void *arg) +{ + size_t step; + counter_type *counter = arg; + + for (step = 0; step < NR_STEPS; ++step) { + while (atomic_flag_test_and_set(&counter->flag)); + ++counter->uc; + ++counter->us; + ++counter->ui; +#ifdef HAS_64BITS + ++counter->ul; +#endif + atomic_flag_clear(&counter->flag); + } + + return NULL; +} + +static +void atomic_counter_test(void *(*adder)(void *arg)) +{ + size_t index; + counter_type counter; + pthread_t thread[NR_THREADS]; + + atomic_flag_clear(&counter.flag); + atomic_init(&counter.uc, 0); + atomic_init(&counter.us, 0); + atomic_init(&counter.ui, 0); +#ifdef HAS_64BITS + atomic_init(&counter.ul, 0); +#endif + + for (index = 0; index < NR_THREADS; ++index) + BUG_ON(pthread_create(&thread[index], NULL, adder, (void *)&counter)); + + for (index = 0; index < NR_THREADS; ++index) + BUG_ON(pthread_join(thread[index], NULL)); + + if (atomic_load(&counter.uc) == ((NR_THREADS * NR_STEPS) & 0xffu) + && atomic_load(&counter.us) == ((NR_THREADS * NR_STEPS) & 0xffffu) + && atomic_load(&counter.ui) == (NR_THREADS * NR_STEPS) +#ifdef HAS_64BITS + && atomic_load(&counter.ul) == (NR_THREADS * NR_STEPS) +#endif + ) + printf("SUCCESS\n"); + else + printf("FAILURE\n"); +} + +int main(void) +{ + atomic_counter_test(adder_simple); + atomic_counter_test(adder_cmpxchg); + atomic_counter_test(adder_test_and_set); + + return 0; +} diff --git a/tinycc/tests/tests2/124_atomic_counter.expect b/tinycc/tests/tests2/124_atomic_counter.expect new file mode 100644 index 0000000..21667a7 --- /dev/null +++ b/tinycc/tests/tests2/124_atomic_counter.expect @@ -0,0 +1,3 @@ +SUCCESS +SUCCESS +SUCCESS diff --git a/tinycc/tests/tests2/125_atomic_misc.c b/tinycc/tests/tests2/125_atomic_misc.c new file mode 100644 index 0000000..2d10631 --- /dev/null +++ b/tinycc/tests/tests2/125_atomic_misc.c @@ -0,0 +1,227 @@ +#include <stdatomic.h> +int printf(const char*,...); + +#if defined test_atomic_compare_exchange +int main() +{ + _Atomic int a = 12; + int b = 77; + int r; + + atomic_store(&a, b + 0); + r = atomic_compare_exchange_strong(&a, &b, 99); + printf("%d %d %d\n", r, a, b); + + atomic_store(&a, b + 3); + r = atomic_compare_exchange_strong(&a, &b, 99); + printf("%d %d %d\n", r, a, b); + + atomic_store(&a, b + 5); + r = atomic_exchange(&a, 33); + printf("%d %d %d\n", r, a, b); + + atomic_store(&a, b + 10); + r = atomic_exchange(&a, 66); + printf("%d %d %d\n", r, a, b); + + return 0; +} + +#elif defined test_atomic_store +int main() +{ + int _Atomic i; + int r; + atomic_store(&i, 12); + r = atomic_fetch_add(&i, i); + printf("r = %d, i = %d\n", r, i); +} + +#elif defined test_atomic_store_pointer +typedef struct { char c[4]; } c4; +int main() +{ + int i = 1; + int _Atomic *p = &i; + int k = 2; + atomic_store(&p, &k); + printf("*p = %d\n", *p); +} + +#elif defined test_atomic_store_struct +typedef struct { char c[4]; } c4; +int main() +{ + c4 _Atomic p; + c4 v = { 1,2,3,4 }; + atomic_store(&p, v); + printf("%d %d %d %d\n", p.c[0], p.c[1], p.c[2], p.c[3]); +} + +#elif defined test_atomic_op + +#define OP1(func, v, e1, e2) atomic_##func(&c, v) == e1 && c == e2 +#define OP2(func, v, e1, e2) atomic_##func(&s, v) == e1 && s == e2 +#define OP4(func, v, e1, e2) atomic_##func(&i, v) == e1 && i == e2 +#if defined __x86_64__ || defined __aarch64__ || defined __riscv +#define OP8(func, v, e1, e2) atomic_##func(&l, v) == e1 && l == e2 +#define HAS_64BITS +#else +#define OP8(func, v, e1, e2) 1 +#endif + +#define OP(func, v, e1, e2) printf ("%s: %s\n", #func, \ + OP1(func,v,e1,e2) && OP2(func,v,e1,e2) && \ + OP4(func,v,e1,e2) && OP8(func,v,e1,e2) \ + ? "SUCCESS" : "FAIL"); + +int main() +{ + atomic_char c; + atomic_short s; + atomic_int i; +#ifdef HAS_64BITS + atomic_size_t l; +#endif + + atomic_init(&c, 0); + atomic_init(&s, 0); + atomic_init(&i, 0); +#ifdef HAS_64BITS + atomic_init(&l, 0); +#endif + + OP(fetch_add, 10, 0, 10); + OP(fetch_sub, 5, 10, 5); + OP(fetch_or, 0x10, 5, 21); + OP(fetch_xor, 0x20, 21, 53); + OP(fetch_and, 0x0f, 53, 5); +} + +#elif defined test_atomic_op2 + +typedef __SIZE_TYPE__ size64_t; + +#define OP1(func, v, e1, e2) \ + __atomic_##func(&c, v, __ATOMIC_SEQ_CST) == e1 && c == e2 +#define OP2(func, v, e1, e2)\ + __atomic_##func(&s, v, __ATOMIC_SEQ_CST) == e1 && s == e2 +#define OP4(func, v, e1, e2)\ + __atomic_##func(&i, v, __ATOMIC_SEQ_CST) == e1 && i == e2 +#if defined __x86_64__ || defined __aarch64__ || defined __riscv +#define OP8(func, v, e1, e2)\ + __atomic_##func(&l, v, __ATOMIC_SEQ_CST) == e1 && l == e2 +#define HAS_64BITS +#else +#define OP8(func, v, e1, e2) 1 +#endif + +#define OP(func, v, e1, e2) printf ("%s: %s\n", #func, \ + OP1(func,v,e1,e2) && OP2(func,v,e1,e2) && \ + OP4(func,v,e1,e2) && OP8(func,v,e1,e2) \ + ? "SUCCESS" : "FAIL"); + +int main() +{ + signed char c; + short s; + int i; +#ifdef HAS_64BITS + size64_t l; +#endif + + atomic_init(&c, 0); + atomic_init(&s, 0); + atomic_init(&i, 0); +#ifdef HAS_64BITS + atomic_init(&l, 0); +#endif + + OP(fetch_add, 10, 0, 10); + OP(fetch_sub, 5, 10, 5); + OP(fetch_or, 0x10, 5, 21); + OP(fetch_xor, 0x20, 21, 53); + OP(fetch_and, 0x0f, 53, 5); + OP(fetch_nand, 0x01, 5, -2); + + atomic_init(&c, 0); + atomic_init(&s, 0); + atomic_init(&i, 0); +#ifdef HAS_64BITS + atomic_init(&l, 0); +#endif + + OP(add_fetch, 10, 10, 10); + OP(sub_fetch, 5, 5, 5); + OP(or_fetch, 0x10, 21, 21); + OP(xor_fetch, 0x20, 53, 53); + OP(and_fetch, 0x0f, 5, 5); + OP(nand_fetch, 0x01, -2, -2); +} + +#elif defined test_atomic_thread_signal +int main() +{ + int c; + + atomic_thread_fence(__ATOMIC_SEQ_CST); + atomic_signal_fence(__ATOMIC_SEQ_CST); + printf ("%d\n", atomic_is_lock_free(&c)); +} + +#elif defined test_atomic_error_1 +int main() +{ + int _Atomic i; + atomic_load(i); +} + +#elif defined test_atomic_error_2 +int main() +{ + struct { char c[3]; } _Atomic c3; + atomic_load(&c3); +} + +#elif defined test_atomic_error_3 +int main() +{ + _Atomic int *p = 0; + atomic_fetch_add(&p, 1); +} + +#elif defined test_atomic_error_4 +int main() +{ + int _Atomic i = 1; + char c = 2; + atomic_compare_exchange_strong(&i, &c, 0); +} + +#elif defined test_atomic_warn_1 +int main() +{ + size_t _Atomic i = 1; + /* assignment to integer from pointer */ + atomic_store(&i, &i); +} + +#elif defined test_atomic_warn_2 +int main() +{ + int i = 1; + char c = 2; + int _Atomic *p = &i; + /* assignment from incompatible pointer */ + atomic_store(&p, &c); +} + +#elif defined test_atomic_warn_3 +int main() +{ + int const i = 1; + /* assignment to read-only -location */ + atomic_fetch_add(&i, 2); +} + +#endif diff --git a/tinycc/tests/tests2/125_atomic_misc.expect b/tinycc/tests/tests2/125_atomic_misc.expect new file mode 100644 index 0000000..61bd29f --- /dev/null +++ b/tinycc/tests/tests2/125_atomic_misc.expect @@ -0,0 +1,59 @@ +[test_atomic_compare_exchange] +1 99 77 +0 80 80 +85 33 80 +90 66 80 + +[test_atomic_store] +r = 12, i = 24 + +[test_atomic_store_pointer] +*p = 2 + +[test_atomic_store_struct] +1 2 3 4 + +[test_atomic_op] +fetch_add: SUCCESS +fetch_sub: SUCCESS +fetch_or: SUCCESS +fetch_xor: SUCCESS +fetch_and: SUCCESS + +[test_atomic_op2] +fetch_add: SUCCESS +fetch_sub: SUCCESS +fetch_or: SUCCESS +fetch_xor: SUCCESS +fetch_and: SUCCESS +fetch_nand: SUCCESS +add_fetch: SUCCESS +sub_fetch: SUCCESS +or_fetch: SUCCESS +xor_fetch: SUCCESS +and_fetch: SUCCESS +nand_fetch: SUCCESS + +[test_atomic_thread_signal] +1 + +[test_atomic_error_1] +125_atomic_misc.c:176: error: pointer expected + +[test_atomic_error_2] +125_atomic_misc.c:183: error: integral or integer-sized pointer target type expected + +[test_atomic_error_3] +125_atomic_misc.c:190: error: integral or integer-sized pointer target type expected + +[test_atomic_error_4] +125_atomic_misc.c:198: error: pointer target type mismatch in argument 2 + +[test_atomic_warn_1] +125_atomic_misc.c:206: warning: assignment makes integer from pointer without a cast + +[test_atomic_warn_2] +125_atomic_misc.c:216: warning: assignment from incompatible pointer type + +[test_atomic_warn_3] +125_atomic_misc.c:224: warning: assignment of read-only location diff --git a/tinycc/tests/tests2/126_bound_global.c b/tinycc/tests/tests2/126_bound_global.c new file mode 100644 index 0000000..d3a5c3b --- /dev/null +++ b/tinycc/tests/tests2/126_bound_global.c @@ -0,0 +1,13 @@ +/* test bound checking code without -run */ + +int arr[10]; + +int +main(int argc, char **argv) +{ + int i; + + for (i = 0; i <= sizeof(arr)/sizeof(arr[0]); i++) + arr[i] = 0; + return 0; +} diff --git a/tinycc/tests/tests2/126_bound_global.expect b/tinycc/tests/tests2/126_bound_global.expect new file mode 100644 index 0000000..fcdea90 --- /dev/null +++ b/tinycc/tests/tests2/126_bound_global.expect @@ -0,0 +1,2 @@ +126_bound_global.c:11: at main: BCHECK: ........ is outside of the region +126_bound_global.c:11: at main: RUNTIME ERROR: invalid memory access diff --git a/tinycc/tests/tests2/127_asm_goto.c b/tinycc/tests/tests2/127_asm_goto.c new file mode 100644 index 0000000..de631aa --- /dev/null +++ b/tinycc/tests/tests2/127_asm_goto.c @@ -0,0 +1,62 @@ +static int simple_jump(void) +{ + asm goto ("jmp %l[label]" : : : : label); + return 0; +label: + return 1; +} + +static int three_way_jump(int val, int *addr) +{ + *addr = 42; + asm goto ("cmp $0, %1\n\t" + "jg %l[larger]\n\t" + "jl %l[smaller]\n\t" + "incl %0\n\t" + : "=m" (*addr) + : "r" (val) + : + : smaller, larger); + return 1; +smaller: + return 2; +larger: + return 3; +} + +static int another_jump(void) +{ + asm goto ("jmp %l[label]" : : : : label); + return 70; + /* Use the same label name as in simple_jump to check that + that doesn't confuse our C/ASM symbol tables */ +label: + return 71; +} + +extern int printf (const char *, ...); +int main(void) +{ + int i; + if (simple_jump () == 1) + printf ("simple_jump: okay\n"); + else + printf ("simple_jump: wrong\n"); + if (another_jump () == 71) + printf ("another_jump: okay\n"); + else + printf ("another_jump: wrong\n"); + if (three_way_jump(0, &i) == 1 && i == 43) + printf ("three_way_jump(0): okay\n"); + else + printf ("three_way_jump(0): wrong (i=%d)\n", i); + if (three_way_jump(1, &i) == 3 && i == 42) + printf ("three_way_jump(1): okay\n"); + else + printf ("three_way_jump(1): wrong (i=%d)\n", i); + if (three_way_jump(-1, &i) == 2 && i == 42) + printf ("three_way_jump(-1): okay\n"); + else + printf ("three_way_jump(-1): wrong (i=%d)\n", i); + return 0; +} diff --git a/tinycc/tests/tests2/127_asm_goto.expect b/tinycc/tests/tests2/127_asm_goto.expect new file mode 100644 index 0000000..e1b7169 --- /dev/null +++ b/tinycc/tests/tests2/127_asm_goto.expect @@ -0,0 +1,5 @@ +simple_jump: okay +another_jump: okay +three_way_jump(0): okay +three_way_jump(1): okay +three_way_jump(-1): okay diff --git a/tinycc/tests/tests2/128_run_atexit.c b/tinycc/tests/tests2/128_run_atexit.c new file mode 100644 index 0000000..0748c86 --- /dev/null +++ b/tinycc/tests/tests2/128_run_atexit.c @@ -0,0 +1,54 @@ +#include <stdio.h> + +int atexit(void (*function)(void)); +int on_exit(void (*function)(int, void *), void *arg); +void exit(int status); + +void cleanup1(void) +{ + printf ("cleanup1\n"); + fflush(stdout); +} + +void cleanup2(void) +{ + printf ("cleanup2\n"); +} + +void cleanup3(int ret, void *arg) +{ + printf ("%d %s\n", ret, (char *) arg); +} + +void cleanup4(int ret, void *arg) +{ + printf ("%d %s\n", ret, (char *) arg); +} + +void __attribute((destructor)) cleanup5(void) +{ + printf ("cleanup5\n"); +} + +void test(void) +{ + atexit(cleanup1); + atexit(cleanup2); + on_exit(cleanup3, "cleanup3"); + on_exit(cleanup4, "cleanup4"); +} + +#if defined test_128_return +int main(int argc, char **argv) +{ + test(); + return 1; +} + +#elif defined test_128_exit +int main(int argc, char **argv) +{ + test(); + exit(2); +} +#endif diff --git a/tinycc/tests/tests2/128_run_atexit.expect b/tinycc/tests/tests2/128_run_atexit.expect new file mode 100644 index 0000000..3305785 --- /dev/null +++ b/tinycc/tests/tests2/128_run_atexit.expect @@ -0,0 +1,15 @@ +[test_128_return] +cleanup5 +1 cleanup4 +1 cleanup3 +cleanup2 +cleanup1 +[returns 1] + +[test_128_exit] +cleanup5 +2 cleanup4 +2 cleanup3 +cleanup2 +cleanup1 +[returns 2] diff --git a/tinycc/tests/tests2/129_scopes.c b/tinycc/tests/tests2/129_scopes.c new file mode 100644 index 0000000..b63b682 --- /dev/null +++ b/tinycc/tests/tests2/129_scopes.c @@ -0,0 +1,43 @@ +#include <stdio.h> +enum{ in = 0}; +#define myassert(X) do{ if(!X) printf("%d: assertion failed\n", __LINE__); }while(0) +int main(){ + { + myassert(!in); + if(sizeof(enum{in=1})) myassert(in); + myassert(!in); //OOPS + } + { + myassert(!in); + switch(sizeof(enum{in=1})) { default: myassert(in); } + myassert(!in); //OOPS + } + { + myassert(!in); + while(sizeof(enum{in=1})) { myassert(in); break; } + myassert(!in); //OOPS + } + { + myassert(!in); + do{ myassert(!in);}while(0*sizeof(enum{in=1})); + myassert(!in); //OOPS + } + + { + myassert(!in); + for(sizeof(enum{in=1});;){ myassert(in); break; } + myassert(!in); //OK + } + { + myassert(!in); + for(;;sizeof(enum{in=1})){ myassert(in); break; } + myassert(!in); //OK + } + { + myassert(!in); + for(;sizeof(enum{in=1});){ myassert(in); break; } + myassert(!in); //OK + } + +} + diff --git a/tinycc/tests/tests2/129_scopes.expect b/tinycc/tests/tests2/129_scopes.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/129_scopes.expect diff --git a/tinycc/tests/tests2/12_hashdefine.c b/tinycc/tests/tests2/12_hashdefine.c new file mode 100644 index 0000000..5c521e0 --- /dev/null +++ b/tinycc/tests/tests2/12_hashdefine.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +#define FRED 12 +#define BLOGGS(x) (12*(x)) + +int main() +{ + printf("%d\n", FRED); + printf("%d, %d, %d\n", BLOGGS(1), BLOGGS(2), BLOGGS(3)); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/12_hashdefine.expect b/tinycc/tests/tests2/12_hashdefine.expect new file mode 100644 index 0000000..99f2ed5 --- /dev/null +++ b/tinycc/tests/tests2/12_hashdefine.expect @@ -0,0 +1,2 @@ +12 +12, 24, 36 diff --git a/tinycc/tests/tests2/130_large_argument.c b/tinycc/tests/tests2/130_large_argument.c new file mode 100644 index 0000000..8415c85 --- /dev/null +++ b/tinycc/tests/tests2/130_large_argument.c @@ -0,0 +1,41 @@ +#include<stdio.h> + +struct large1 { + int a[768]; +}; + +struct large2 { + int a[1920]; +}; + +void pass_large_struct1(struct large1 in) +{ + printf("%d %d\n", in.a[200], in.a[767]); + return; +} + +void pass_large_struct2(struct large2 in) +{ + printf("%d %d %d\n", in.a[200], in.a[1023], in.a[1919]); + return; +} + +void pass_many_args(int a, int b, int c, int d, int e, int f, int g, int h, int i, + int j, int k, int l, int m) +{ + printf("%d %d %d %d %d %d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h, i, + j, k, l, m); + return; +} + +struct large1 l1 = { .a = { [200] = 1, [767] = 2 } }; +struct large2 l2 = { .a = { [200] = 3, [1023] = 4, [1919] = 5} }; + +int main(void) +{ + pass_large_struct1(l1); + pass_large_struct2(l2); + pass_many_args(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1); + + return 0; +} diff --git a/tinycc/tests/tests2/130_large_argument.expect b/tinycc/tests/tests2/130_large_argument.expect new file mode 100644 index 0000000..8c5d9cd --- /dev/null +++ b/tinycc/tests/tests2/130_large_argument.expect @@ -0,0 +1,3 @@ +1 2 +3 4 5 +13 12 11 10 9 8 7 6 5 4 3 2 1 diff --git a/tinycc/tests/tests2/13_integer_literals.c b/tinycc/tests/tests2/13_integer_literals.c new file mode 100644 index 0000000..7cee98b --- /dev/null +++ b/tinycc/tests/tests2/13_integer_literals.c @@ -0,0 +1,20 @@ +#include <stdio.h> + +int main() +{ + int a = 24680; + int b = 01234567; + int c = 0x2468ac; + int d = 0x2468AC; + int e = 0b010101010101; + + printf("%d\n", a); + printf("%d\n", b); + printf("%d\n", c); + printf("%d\n", d); + printf("%d\n", e); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/13_integer_literals.expect b/tinycc/tests/tests2/13_integer_literals.expect new file mode 100644 index 0000000..f5aca06 --- /dev/null +++ b/tinycc/tests/tests2/13_integer_literals.expect @@ -0,0 +1,5 @@ +24680 +342391 +2386092 +2386092 +1365 diff --git a/tinycc/tests/tests2/14_if.c b/tinycc/tests/tests2/14_if.c new file mode 100644 index 0000000..2bd2550 --- /dev/null +++ b/tinycc/tests/tests2/14_if.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int a = 1; + + if (a) + printf("a is true\n"); + else + printf("a is false\n"); + + int b = 0; + if (b) + printf("b is true\n"); + else + printf("b is false\n"); + + return 0; +} + +// vim: set expandtab ts=4 sw=3 sts=3 tw=80 : diff --git a/tinycc/tests/tests2/14_if.expect b/tinycc/tests/tests2/14_if.expect new file mode 100644 index 0000000..c32c415 --- /dev/null +++ b/tinycc/tests/tests2/14_if.expect @@ -0,0 +1,2 @@ +a is true +b is false diff --git a/tinycc/tests/tests2/15_recursion.c b/tinycc/tests/tests2/15_recursion.c new file mode 100644 index 0000000..f79a00d --- /dev/null +++ b/tinycc/tests/tests2/15_recursion.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int factorial(int i) +{ + if (i < 2) + return i; + else + return i * factorial(i - 1); +} + +int main() +{ + int Count; + + for (Count = 1; Count <= 10; Count++) + printf("%d\n", factorial(Count)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/15_recursion.expect b/tinycc/tests/tests2/15_recursion.expect new file mode 100644 index 0000000..db47b28 --- /dev/null +++ b/tinycc/tests/tests2/15_recursion.expect @@ -0,0 +1,10 @@ +1 +2 +6 +24 +120 +720 +5040 +40320 +362880 +3628800 diff --git a/tinycc/tests/tests2/16_nesting.c b/tinycc/tests/tests2/16_nesting.c new file mode 100644 index 0000000..2b72cc0 --- /dev/null +++ b/tinycc/tests/tests2/16_nesting.c @@ -0,0 +1,21 @@ +#include <stdio.h> + +int main() +{ + int x, y, z; + + for (x = 0; x < 2; x++) + { + for (y = 0; y < 3; y++) + { + for (z = 0; z < 3; z++) + { + printf("%d %d %d\n", x, y, z); + } + } + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/16_nesting.expect b/tinycc/tests/tests2/16_nesting.expect new file mode 100644 index 0000000..5a3431e --- /dev/null +++ b/tinycc/tests/tests2/16_nesting.expect @@ -0,0 +1,18 @@ +0 0 0 +0 0 1 +0 0 2 +0 1 0 +0 1 1 +0 1 2 +0 2 0 +0 2 1 +0 2 2 +1 0 0 +1 0 1 +1 0 2 +1 1 0 +1 1 1 +1 1 2 +1 2 0 +1 2 1 +1 2 2 diff --git a/tinycc/tests/tests2/17_enum.c b/tinycc/tests/tests2/17_enum.c new file mode 100644 index 0000000..e2bc736 --- /dev/null +++ b/tinycc/tests/tests2/17_enum.c @@ -0,0 +1,72 @@ +#include <stdio.h> + +enum fred +{ + a, + b, + c, + d, + e = 54, + f = 73, + g, + h +}; + +/* All following uses of enum efoo should compile + without warning. While forward enums aren't ISO C, + it's accepted by GCC also in strict mode, and only warned + about with -pedantic. This happens in the real world. */ +/* Strict ISO C doesn't allow this kind of forward declaration of + enums, but GCC accepts it (and gives only pedantic warning), and + it occurs in the wild. */ +enum efoo; +struct Sforward_use { + int (*fmember) (enum efoo x); +}; + +extern enum efoo it_real_fn(void); +enum efoo { + ONE, + TWO, +}; +struct S2 { + enum efoo (*f2) (void); +}; +void should_compile(struct S2 *s) +{ + s->f2 = it_real_fn; +} + +enum efoo it_real_fn(void) +{ + return TWO; +} + +static unsigned int deref_uintptr(unsigned int *p) +{ + return *p; +} + +enum Epositive { + epos_one, epos_two +}; + +int main() +{ + enum fred frod; + enum Epositive epos = epos_two; + + printf("%d %d %d %d %d %d %d %d\n", a, b, c, d, e, f, g, h); + /* printf("%d\n", frod); */ + frod = 12; + printf("%d\n", frod); + frod = e; + printf("%d\n", frod); + + /* Following should compile without warning. */ + printf ("enum to int: %u\n", deref_uintptr(&epos)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/17_enum.expect b/tinycc/tests/tests2/17_enum.expect new file mode 100644 index 0000000..d453a61 --- /dev/null +++ b/tinycc/tests/tests2/17_enum.expect @@ -0,0 +1,4 @@ +0 1 2 3 54 73 74 75 +12 +54 +enum to int: 1 diff --git a/tinycc/tests/tests2/18_include.c b/tinycc/tests/tests2/18_include.c new file mode 100644 index 0000000..9ff60c9 --- /dev/null +++ b/tinycc/tests/tests2/18_include.c @@ -0,0 +1,47 @@ +#include <stdio.h> + +int main() +{ + printf("including\n"); +#include "18_include.h" +#define test_missing_nl + printf("done\n"); + +#define INC "18_include.h" + +#ifdef __has_include +#if defined __has_include +#if __has_include("18_include.h") + printf("has_include\n"); +#endif +#if __has_include(INC) + printf("has_include\n"); +#endif +#if __has_include("not_found_18_include.h") + printf("has_include not found\n"); +#endif +#endif +#endif + +#ifdef __has_include_next +#if defined __has_include_next +#if __has_include_next("18_include.h") + printf("has_include_next\n"); +#endif +#if __has_include_next(INC) + printf("has_include_next\n"); +#endif +#if __has_include_next("not_found_18_include.h") + printf("has_include_next not found\n"); +#endif +#endif +#endif + +#include "18_include2.h" +#include "./18_include2.h" +#include "../tests2/18_include2.h" + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/18_include.expect b/tinycc/tests/tests2/18_include.expect new file mode 100644 index 0000000..fbc6d13 --- /dev/null +++ b/tinycc/tests/tests2/18_include.expect @@ -0,0 +1,8 @@ +including +included +done +has_include +has_include +has_include_next +has_include_next +counter 0 diff --git a/tinycc/tests/tests2/18_include.h b/tinycc/tests/tests2/18_include.h new file mode 100644 index 0000000..cad2433 --- /dev/null +++ b/tinycc/tests/tests2/18_include.h @@ -0,0 +1,5 @@ +printf("included\n"); +/* test file with missing newline */ +#ifndef INCLUDE +#define INCLUDE +#endif /* INCLUDE */
\ No newline at end of file diff --git a/tinycc/tests/tests2/18_include2.h b/tinycc/tests/tests2/18_include2.h new file mode 100644 index 0000000..2a89c3d --- /dev/null +++ b/tinycc/tests/tests2/18_include2.h @@ -0,0 +1,2 @@ +#pragma once +printf ("counter %d\n", __COUNTER__); diff --git a/tinycc/tests/tests2/19_pointer_arithmetic.c b/tinycc/tests/tests2/19_pointer_arithmetic.c new file mode 100644 index 0000000..aff65e5 --- /dev/null +++ b/tinycc/tests/tests2/19_pointer_arithmetic.c @@ -0,0 +1,28 @@ +#include <stdio.h> + +int main() +{ + int a; + int *b; + int *c; + + a = 42; + b = &a; + c = NULL; + + printf("%d\n", *b); + + if (b == NULL) + printf("b is NULL\n"); + else + printf("b is not NULL\n"); + + if (c == NULL) + printf("c is NULL\n"); + else + printf("c is not NULL\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/19_pointer_arithmetic.expect b/tinycc/tests/tests2/19_pointer_arithmetic.expect new file mode 100644 index 0000000..0cf781b --- /dev/null +++ b/tinycc/tests/tests2/19_pointer_arithmetic.expect @@ -0,0 +1,3 @@ +42 +b is not NULL +c is NULL diff --git a/tinycc/tests/tests2/20_pointer_comparison.c b/tinycc/tests/tests2/20_pointer_comparison.c new file mode 100644 index 0000000..825f778 --- /dev/null +++ b/tinycc/tests/tests2/20_pointer_comparison.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +int main() +{ + int a; + int b; + int *d; + int *e; + d = &a; + e = &b; + a = 12; + b = 34; + printf("%d\n", *d); + printf("%d\n", *e); + printf("%d\n", d == e); + printf("%d\n", d != e); + d = e; + printf("%d\n", d == e); + printf("%d\n", d != e); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/20_pointer_comparison.expect b/tinycc/tests/tests2/20_pointer_comparison.expect new file mode 100644 index 0000000..5d1e5f5 --- /dev/null +++ b/tinycc/tests/tests2/20_pointer_comparison.expect @@ -0,0 +1,6 @@ +12 +34 +0 +1 +1 +0 diff --git a/tinycc/tests/tests2/21_char_array.c b/tinycc/tests/tests2/21_char_array.c new file mode 100644 index 0000000..f22f527 --- /dev/null +++ b/tinycc/tests/tests2/21_char_array.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +int main() +{ + int x = 'a'; + char y = x; + + char *a = "hello"; + + printf("%s\n", a); + + int c; + c = *a; + + char *b; + for (b = a; *b != 0; b++) + printf("%c: %d\n", *b, *b); + + char destarray[10]; + char *dest = &destarray[0]; + char *src = a; + + while (*src != 0) + *dest++ = *src++; + + *dest = 0; + + printf("copied string is %s\n", destarray); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/21_char_array.expect b/tinycc/tests/tests2/21_char_array.expect new file mode 100644 index 0000000..dbc6068 --- /dev/null +++ b/tinycc/tests/tests2/21_char_array.expect @@ -0,0 +1,7 @@ +hello +h: 104 +e: 101 +l: 108 +l: 108 +o: 111 +copied string is hello diff --git a/tinycc/tests/tests2/22_floating_point.c b/tinycc/tests/tests2/22_floating_point.c new file mode 100644 index 0000000..5dc7b74 --- /dev/null +++ b/tinycc/tests/tests2/22_floating_point.c @@ -0,0 +1,70 @@ +#include <stdio.h> +#include <math.h> + +float fd; + +int +test() +{ + // was an internal tcc compiler error with arm64 backend until 2019-11-08 + if (fd < 5.5) { + return 1; + } else { + return 0; + } +} + +int main() +{ + static int e1 = -1.0 == 0.0; + static int e2 = -1.0 != 0.0; + static int e3 = -1.0 < 0.0; + static int e4 = -1.0 >= 0.0; + static int e5 = -1.0 <= 0.0; + static int e6 = -1.0 > 0.0; + // variables + float a = 12.34 + 56.78; + printf("%f\n", a); + + // infix operators + printf("%f\n", 12.34 + 56.78); + printf("%f\n", 12.34 - 56.78); + printf("%f\n", 12.34 * 56.78); + printf("%f\n", 12.34 / 56.78); + + // comparison operators + printf("%d %d %d %d %d %d\n", 12.34 < 56.78, 12.34 <= 56.78, 12.34 == 56.78, 12.34 >= 56.78, 12.34 > 56.78, 12.34 != 56.78); + printf("%d %d %d %d %d %d\n", 12.34 < 12.34, 12.34 <= 12.34, 12.34 == 12.34, 12.34 >= 12.34, 12.34 > 12.34, 12.34 != 12.34); + printf("%d %d %d %d %d %d\n", 56.78 < 12.34, 56.78 <= 12.34, 56.78 == 12.34, 56.78 >= 12.34, 56.78 > 12.34, 56.78 != 12.34); + printf("%d %d %d %d %d %d\n", e1, e2, e3, e4, e5, e6); + + // assignment operators + a = 12.34; + a += 56.78; + printf("%f\n", a); + + a = 12.34; + a -= 56.78; + printf("%f\n", a); + + a = 12.34; + a *= 56.78; + printf("%f\n", a); + + a = 12.34; + a /= 56.78; + printf("%f\n", a); + + // prefix operators + printf("%f\n", +12.34); + printf("%f\n", -12.34); + + // type coercion + a = 2; + printf("%f\n", a); + printf("%f\n", sin(2)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/22_floating_point.expect b/tinycc/tests/tests2/22_floating_point.expect new file mode 100644 index 0000000..a989eca --- /dev/null +++ b/tinycc/tests/tests2/22_floating_point.expect @@ -0,0 +1,17 @@ +69.120003 +69.120000 +-44.440000 +700.665200 +0.217330 +1 1 0 0 0 1 +0 1 1 1 0 0 +0 0 0 1 1 1 +0 1 1 0 1 0 +69.120003 +-44.439999 +700.665222 +0.217330 +12.340000 +-12.340000 +2.000000 +0.909297 diff --git a/tinycc/tests/tests2/23_type_coercion.c b/tinycc/tests/tests2/23_type_coercion.c new file mode 100644 index 0000000..1fcc335 --- /dev/null +++ b/tinycc/tests/tests2/23_type_coercion.c @@ -0,0 +1,54 @@ +#include <stdio.h> + +void charfunc(char a) +{ + printf("char: %c\n", a); +} + +void intfunc(int a) +{ + printf("int: %d\n", a); +} + +void floatfunc(float a) +{ + printf("float: %f\n", a); +} + +int main() +{ + charfunc('a'); + charfunc(98); + charfunc(99.0); + + intfunc('a'); + intfunc(98); + intfunc(99.0); + + floatfunc('a'); + floatfunc(98); + floatfunc(99.0); + + /* printf("%c %d %f\n", 'a', 'b', 'c'); */ + /* printf("%c %d %f\n", 97, 98, 99); */ + /* printf("%c %d %f\n", 97.0, 98.0, 99.0); */ + + char b = 97; + char c = 97.0; + + printf("%d %d\n", b, c); + + int d = 'a'; + int e = 97.0; + + printf("%d %d\n", d, e); + + float f = 'a'; + float g = 97; + + printf("%f %f\n", f, g); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/23_type_coercion.expect b/tinycc/tests/tests2/23_type_coercion.expect new file mode 100644 index 0000000..d9076f0 --- /dev/null +++ b/tinycc/tests/tests2/23_type_coercion.expect @@ -0,0 +1,12 @@ +char: a +char: b +char: c +int: 97 +int: 98 +int: 99 +float: 97.000000 +float: 98.000000 +float: 99.000000 +97 97 +97 97 +97.000000 97.000000 diff --git a/tinycc/tests/tests2/24_math_library.c b/tinycc/tests/tests2/24_math_library.c new file mode 100644 index 0000000..514a25f --- /dev/null +++ b/tinycc/tests/tests2/24_math_library.c @@ -0,0 +1,30 @@ +#define _ISOC99_SOURCE 1 + +#include <stdio.h> +#include <math.h> + +int main() +{ + printf("%f\n", sin(0.12)); + printf("%f\n", cos(0.12)); + printf("%f\n", tan(0.12)); + printf("%f\n", asin(0.12)); + printf("%f\n", acos(0.12)); + printf("%f\n", atan(0.12)); + printf("%f\n", sinh(0.12)); + printf("%f\n", cosh(0.12)); + printf("%f\n", tanh(0.12)); + printf("%f\n", exp(0.12)); + printf("%f\n", fabs(-0.12)); + printf("%f\n", log(0.12)); + printf("%f\n", log10(0.12)); + printf("%f\n", pow(0.12, 0.12)); + printf("%f\n", sqrt(0.12)); + printf("%f\n", round(12.34)); + printf("%f\n", ceil(12.34)); + printf("%f\n", floor(12.34)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/24_math_library.expect b/tinycc/tests/tests2/24_math_library.expect new file mode 100644 index 0000000..99f7299 --- /dev/null +++ b/tinycc/tests/tests2/24_math_library.expect @@ -0,0 +1,18 @@ +0.119712 +0.992809 +0.120579 +0.120290 +1.450506 +0.119429 +0.120288 +1.007209 +0.119427 +1.127497 +0.120000 +-2.120264 +-0.920819 +0.775357 +0.346410 +12.000000 +13.000000 +12.000000 diff --git a/tinycc/tests/tests2/25_quicksort.c b/tinycc/tests/tests2/25_quicksort.c new file mode 100644 index 0000000..5cc08bd --- /dev/null +++ b/tinycc/tests/tests2/25_quicksort.c @@ -0,0 +1,83 @@ +#include <stdio.h> + +int array[16]; + +//Swap integer values by array indexes +void swap(int a, int b) +{ + int tmp = array[a]; + array[a] = array[b]; + array[b] = tmp; +} + +//Partition the array into two halves and return the +//index about which the array is partitioned +int partition(int left, int right) +{ + int pivotIndex = left; + int pivotValue = array[pivotIndex]; + int index = left; + int i; + + swap(pivotIndex, right); + for(i = left; i < right; i++) + { + if(array[i] < pivotValue) + { + swap(i, index); + index += 1; + } + } + swap(right, index); + + return index; +} + +//Quicksort the array +void quicksort(int left, int right) +{ + if(left >= right) + return; + + int index = partition(left, right); + quicksort(left, index - 1); + quicksort(index + 1, right); +} + +int main() +{ + int i; + + array[0] = 62; + array[1] = 83; + array[2] = 4; + array[3] = 89; + array[4] = 36; + array[5] = 21; + array[6] = 74; + array[7] = 37; + array[8] = 65; + array[9] = 33; + array[10] = 96; + array[11] = 38; + array[12] = 53; + array[13] = 16; + array[14] = 74; + array[15] = 55; + + for (i = 0; i < 16; i++) + printf("%d ", array[i]); + + printf("\n"); + + quicksort(0, 15); + + for (i = 0; i < 16; i++) + printf("%d ", array[i]); + + printf("\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/25_quicksort.expect b/tinycc/tests/tests2/25_quicksort.expect new file mode 100644 index 0000000..2d39cd3 --- /dev/null +++ b/tinycc/tests/tests2/25_quicksort.expect @@ -0,0 +1,2 @@ +62 83 4 89 36 21 74 37 65 33 96 38 53 16 74 55 +4 16 21 33 36 37 38 53 55 62 65 74 74 83 89 96 diff --git a/tinycc/tests/tests2/26_character_constants.c b/tinycc/tests/tests2/26_character_constants.c new file mode 100644 index 0000000..95c4423 --- /dev/null +++ b/tinycc/tests/tests2/26_character_constants.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + printf("%d\n", '\1'); + printf("%d\n", '\10'); + printf("%d\n", '\100'); + printf("%d\n", '\x01'); + printf("%d\n", '\x0e'); + printf("%d\n", '\x10'); + printf("%d\n", '\x40'); + printf("test \x40\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/26_character_constants.expect b/tinycc/tests/tests2/26_character_constants.expect new file mode 100644 index 0000000..8f8bfa4 --- /dev/null +++ b/tinycc/tests/tests2/26_character_constants.expect @@ -0,0 +1,8 @@ +1 +8 +64 +1 +14 +16 +64 +test @ diff --git a/tinycc/tests/tests2/27_sizeof.c b/tinycc/tests/tests2/27_sizeof.c new file mode 100644 index 0000000..5ae0ede --- /dev/null +++ b/tinycc/tests/tests2/27_sizeof.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + char a; + int b; + double c; + + printf("%d\n", sizeof(a)); + printf("%d\n", sizeof(b)); + printf("%d\n", sizeof(c)); + + printf("%d\n", sizeof(!a)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/27_sizeof.expect b/tinycc/tests/tests2/27_sizeof.expect new file mode 100644 index 0000000..a47ea3a --- /dev/null +++ b/tinycc/tests/tests2/27_sizeof.expect @@ -0,0 +1,4 @@ +1 +4 +8 +4 diff --git a/tinycc/tests/tests2/28_strings.c b/tinycc/tests/tests2/28_strings.c new file mode 100644 index 0000000..2db2298 --- /dev/null +++ b/tinycc/tests/tests2/28_strings.c @@ -0,0 +1,45 @@ +#include <stdio.h> +#include <string.h> + +int main() +{ + char a[10]; + + strcpy(a, "hello"); + printf("%s\n", a); + + strncpy(a, "gosh", 2); + printf("%s\n", a); + + printf("%d\n", strcmp(a, "apple") > 0); + printf("%d\n", strcmp(a, "goere") > 0); + printf("%d\n", strcmp(a, "zebra") < 0); + + printf("%d\n", strlen(a)); + + strcat(a, "!"); + printf("%s\n", a); + + printf("%d\n", strncmp(a, "apple", 2) > 0); + printf("%d\n", strncmp(a, "goere", 2) == 0); + printf("%d\n", strncmp(a, "goerg", 2) == 0); + printf("%d\n", strncmp(a, "zebra", 2) < 0); + + printf("%s\n", strchr(a, 'o')); + printf("%s\n", strrchr(a, 'l')); + printf("%d\n", strrchr(a, 'x') == NULL); + + memset(&a[1], 'r', 4); + printf("%s\n", a); + + memcpy(&a[2], a, 2); + printf("%s\n", a); + + printf("%d\n", memcmp(a, "apple", 4) > 0); + printf("%d\n", memcmp(a, "grgr", 4) == 0); + printf("%d\n", memcmp(a, "zebra", 4) < 0); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/28_strings.expect b/tinycc/tests/tests2/28_strings.expect new file mode 100644 index 0000000..fd9217a --- /dev/null +++ b/tinycc/tests/tests2/28_strings.expect @@ -0,0 +1,19 @@ +hello +gollo +1 +1 +1 +5 +gollo! +1 +1 +1 +1 +ollo! +lo! +1 +grrrr! +grgrr! +1 +1 +1 diff --git a/tinycc/tests/tests2/29_array_address.c b/tinycc/tests/tests2/29_array_address.c new file mode 100644 index 0000000..bda5ddd --- /dev/null +++ b/tinycc/tests/tests2/29_array_address.c @@ -0,0 +1,13 @@ +#include <stdio.h> +#include <string.h> + +int main() +{ + char a[10]; + strcpy(a, "abcdef"); + printf("%s\n", &a[1]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/29_array_address.expect b/tinycc/tests/tests2/29_array_address.expect new file mode 100644 index 0000000..9bc8683 --- /dev/null +++ b/tinycc/tests/tests2/29_array_address.expect @@ -0,0 +1 @@ +bcdef diff --git a/tinycc/tests/tests2/30_hanoi.c b/tinycc/tests/tests2/30_hanoi.c new file mode 100644 index 0000000..7c0893b --- /dev/null +++ b/tinycc/tests/tests2/30_hanoi.c @@ -0,0 +1,122 @@ +/* example from http://barnyard.syr.edu/quickies/hanoi.c */ + +/* hanoi.c: solves the tower of hanoi problem. (Programming exercise.) */ +/* By Terry R. McConnell (12/2/97) */ +/* Compile: cc -o hanoi hanoi.c */ + +/* This program does no error checking. But then, if it's right, + it's right ... right ? */ + + +/* The original towers of hanoi problem seems to have been originally posed + by one M. Claus in 1883. There is a popular legend that goes along with + it that has been often repeated and paraphrased. It goes something like this: + In the great temple at Benares there are 3 golden spikes. On one of them, + God placed 64 disks increasing in size from bottom to top, at the beginning + of time. Since then, and to this day, the priest on duty constantly transfers + disks, one at a time, in such a way that no larger disk is ever put on top + of a smaller one. When the disks have been transferred entirely to another + spike the Universe will come to an end in a large thunderclap. + + This paraphrases the original legend due to DeParville, La Nature, Paris 1884, + Part I, 285-286. For this and further information see: Mathematical + Recreations & Essays, W.W. Rouse Ball, MacMillan, NewYork, 11th Ed. 1967, + 303-305. + * + * + */ + +#include <stdio.h> +#include <stdlib.h> + +#define TRUE 1 +#define FALSE 0 + +/* This is the number of "disks" on tower A initially. Taken to be 64 in the + * legend. The number of moves required, in general, is 2^N - 1. For N = 64, + * this is 18,446,744,073,709,551,615 */ +#define N 4 + +/* These are the three towers. For example if the state of A is 0,1,3,4, that + * means that there are three discs on A of sizes 1, 3, and 4. (Think of right + * as being the "down" direction.) */ +int A[N], B[N], C[N]; + +void Hanoi(int,int*,int*,int*); + +/* Print the current configuration of A, B, and C to the screen */ +void PrintAll() +{ + int i; + + printf("A: "); + for(i=0;i<N;i++)printf(" %d ",A[i]); + printf("\n"); + + printf("B: "); + for(i=0;i<N;i++)printf(" %d ",B[i]); + printf("\n"); + + printf("C: "); + for(i=0;i<N;i++)printf(" %d ",C[i]); + printf("\n"); + printf("------------------------------------------\n"); + return; +} + +/* Move the leftmost nonzero element of source to dest, leave behind 0. */ +/* Returns the value moved (not used.) */ +int Move(int *source, int *dest) +{ + int i = 0, j = 0; + + while (i<N && (source[i])==0) i++; + while (j<N && (dest[j])==0) j++; + + dest[j-1] = source[i]; + source[i] = 0; + PrintAll(); /* Print configuration after each move. */ + return dest[j-1]; +} + + +/* Moves first n nonzero numbers from source to dest using the rules of Hanoi. + Calls itself recursively. + */ +void Hanoi(int n,int *source, int *dest, int *spare) +{ + int i; + if(n==1){ + Move(source,dest); + return; + } + + Hanoi(n-1,source,spare,dest); + Move(source,dest); + Hanoi(n-1,spare,dest,source); + return; +} + +int main() +{ + int i; + + /* initialize the towers */ + for(i=0;i<N;i++)A[i]=i+1; + for(i=0;i<N;i++)B[i]=0; + for(i=0;i<N;i++)C[i]=0; + + printf("Solution of Tower of Hanoi Problem with %d Disks\n\n",N); + + /* Print the starting state */ + printf("Starting state:\n"); + PrintAll(); + printf("\n\nSubsequent states:\n\n"); + + /* Do it! Use A = Source, B = Destination, C = Spare */ + Hanoi(N,A,B,C); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/30_hanoi.expect b/tinycc/tests/tests2/30_hanoi.expect new file mode 100644 index 0000000..7798ee0 --- /dev/null +++ b/tinycc/tests/tests2/30_hanoi.expect @@ -0,0 +1,71 @@ +Solution of Tower of Hanoi Problem with 4 Disks + +Starting state: +A: 1 2 3 4 +B: 0 0 0 0 +C: 0 0 0 0 +------------------------------------------ + + +Subsequent states: + +A: 0 2 3 4 +B: 0 0 0 0 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 3 4 +B: 0 0 0 2 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 3 4 +B: 0 0 1 2 +C: 0 0 0 0 +------------------------------------------ +A: 0 0 0 4 +B: 0 0 1 2 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 4 +B: 0 0 0 2 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 4 +B: 0 0 0 0 +C: 0 0 2 3 +------------------------------------------ +A: 0 0 0 4 +B: 0 0 0 0 +C: 0 1 2 3 +------------------------------------------ +A: 0 0 0 0 +B: 0 0 0 4 +C: 0 1 2 3 +------------------------------------------ +A: 0 0 0 0 +B: 0 0 1 4 +C: 0 0 2 3 +------------------------------------------ +A: 0 0 0 2 +B: 0 0 1 4 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 2 +B: 0 0 0 4 +C: 0 0 0 3 +------------------------------------------ +A: 0 0 1 2 +B: 0 0 3 4 +C: 0 0 0 0 +------------------------------------------ +A: 0 0 0 2 +B: 0 0 3 4 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 0 0 +B: 0 2 3 4 +C: 0 0 0 1 +------------------------------------------ +A: 0 0 0 0 +B: 1 2 3 4 +C: 0 0 0 0 +------------------------------------------ diff --git a/tinycc/tests/tests2/31_args.c b/tinycc/tests/tests2/31_args.c new file mode 100644 index 0000000..dcafed5 --- /dev/null +++ b/tinycc/tests/tests2/31_args.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main(int argc, char **argv) +{ + int Count; + + printf("hello world %d\n", argc); + for (Count = 1; Count < argc; Count++) + printf("arg %d: %s\n", Count, argv[Count]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/31_args.expect b/tinycc/tests/tests2/31_args.expect new file mode 100644 index 0000000..8c60bfc --- /dev/null +++ b/tinycc/tests/tests2/31_args.expect @@ -0,0 +1,6 @@ +hello world 6 +arg 1: arg1 +arg 2: arg2 +arg 3: arg3 +arg 4: arg4 +arg 5: arg5 diff --git a/tinycc/tests/tests2/32_led.c b/tinycc/tests/tests2/32_led.c new file mode 100644 index 0000000..5596cbf --- /dev/null +++ b/tinycc/tests/tests2/32_led.c @@ -0,0 +1,266 @@ +/* example from http://barnyard.syr.edu/quickies/led.c */ + +/* led.c: print out number as if on 7 line led display. I.e., write integer + given on command line like this: + _ _ _ + | _| _| |_| |_ + | |_ _| | _| etc. + + We assume the terminal behaves like a classical teletype. So the top + lines of all digits have to be printed first, then the middle lines of + all digits, etc. + + By Terry R. McConnell + +compile: cc -o led led.c + +If you just want to link in the subroutine print_led that does all the +work, compile with -DNO_MAIN, and declare the following in any source file +that uses the call: + +extern void print_led(unsigned long x, char *buf); + +Bug: you cannot call repeatedly to print more than one number to a line. +That would require curses or some other terminal API that allows moving the +cursor to a previous line. + +*/ + + + +#include <stdlib.h> +#include <stdio.h> + +#define MAX_DIGITS 32 +#define NO_MAIN + + +/* Print the top line of the digit d into buffer. + Does not null terminate buffer. */ + +void topline(int d, char *p){ + + *p++ = ' '; + switch(d){ + + /* all these have _ on top line */ + + case 0: + case 2: + case 3: + case 5: + case 7: + case 8: + case 9: + *p++ = '_'; + break; + default: + *p++=' '; + + } + *p++=' '; +} + +/* Print the middle line of the digit d into the buffer. + Does not null terminate. */ + +void midline(int d, char *p){ + + switch(d){ + + /* those that have leading | on middle line */ + + case 0: + case 4: + case 5: + case 6: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + } + switch(d){ + + /* those that have _ on middle line */ + + case 2: + case 3: + case 4: + case 5: + case 6: + case 8: + case 9: + *p++='_'; + break; + default: + *p++=' '; + + } + switch(d){ + + /* those that have closing | on middle line */ + + case 0: + case 1: + case 2: + case 3: + case 4: + case 7: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + + } +} + +/* Print the bottom line of the digit d. Does not null terminate. */ + +void botline(int d, char *p){ + + + switch(d){ + + /* those that have leading | on bottom line */ + + case 0: + case 2: + case 6: + case 8: + *p++='|'; + break; + default: + *p++=' '; + } + switch(d){ + + /* those that have _ on bottom line */ + + case 0: + case 2: + case 3: + case 5: + case 6: + case 8: + *p++='_'; + break; + default: + *p++=' '; + + } + switch(d){ + + /* those that have closing | on bottom line */ + + case 0: + case 1: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + *p++='|'; + break; + default: + *p++=' '; + + } +} + +/* Write the led representation of integer to string buffer. */ + +void print_led(unsigned long x, char *buf) +{ + + int i=0,n; + static int d[MAX_DIGITS]; + + + /* extract digits from x */ + + n = ( x == 0L ? 1 : 0 ); /* 0 is a digit, hence a special case */ + + while(x){ + d[n++] = (int)(x%10L); + if(n >= MAX_DIGITS)break; + x = x/10L; + } + + /* print top lines of all digits */ + + for(i=n-1;i>=0;i--){ + topline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; /* move teletype to next line */ + + /* print middle lines of all digits */ + + for(i=n-1;i>=0;i--){ + midline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; + + /* print bottom lines of all digits */ + + for(i=n-1;i>=0;i--){ + botline(d[i],buf); + buf += 3; + *buf++=' '; + } + *buf++='\n'; + *buf='\0'; +} + +int main() +{ + char buf[5*MAX_DIGITS]; + print_led(1234567, buf); + printf("%s\n",buf); + + return 0; +} + +#ifndef NO_MAIN +int main(int argc, char **argv) +{ + + int i=0,n; + long x; + static int d[MAX_DIGITS]; + char buf[5*MAX_DIGITS]; + + if(argc != 2){ + fprintf(stderr,"led: usage: led integer\n"); + return 1; + } + + /* fetch argument from command line */ + + x = atol(argv[1]); + + /* sanity check */ + + if(x<0){ + fprintf(stderr,"led: %d must be non-negative\n",x); + return 1; + } + + print_led(x,buf); + printf("%s\n",buf); + + return 0; + +} +#endif + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/32_led.expect b/tinycc/tests/tests2/32_led.expect new file mode 100644 index 0000000..c53b58a --- /dev/null +++ b/tinycc/tests/tests2/32_led.expect @@ -0,0 +1,4 @@ + _ _ _ _ + | _| _| |_| |_ |_ | + | |_ _| | _| |_| | + diff --git a/tinycc/tests/tests2/33_ternary_op.c b/tinycc/tests/tests2/33_ternary_op.c new file mode 100644 index 0000000..8305438 --- /dev/null +++ b/tinycc/tests/tests2/33_ternary_op.c @@ -0,0 +1,119 @@ +#include <assert.h> +extern int printf(const char*, ...); + +char arr[1]; +static void f (void){} +void (*fp)(void) = f; +void call_fp() +{ + (fp?f:f)(); + (fp?fp:fp)(); + (fp?fp:&f)(); + (fp?&f:fp)(); + (fp?&f:&f)(); + _Generic(0?arr:arr, char*: (void)0); + _Generic(0?&arr[0]:arr, char*: (void)0); + _Generic(0?arr:&arr[0], char*: (void)0); + _Generic(1?arr:arr, char*: (void)0); + _Generic(1?&arr[0]:arr, char*: (void)0); + _Generic(1?arr:&arr[0], char*: (void)0); + _Generic((__typeof(1?f:f)*){0}, void (**)(void): (void)0); + (fp?&f:f)(); + (fp?f:&f)(); + _Generic((__typeof(fp?0L:(void)0)*){0}, void*: (void)0); + + /* The following line causes a warning */ + void *xx = fp?f:1; +} + +struct condstruct { + int i; +}; + +static int getme(struct condstruct* s, int i) +{ + int i1 = (i != 0 ? 0 : s)->i; + int i2 = (i == 0 ? s : 0)->i; + int i3 = (i != 0 ? (void*)0 : s)->i; + int i4 = (i == 0 ? s : (void*)0)->i; + return i1 + i2 + i3 + i4; +} + +int someglobal; + +void constantcond(void) +{ + /* This was broken by 8227db3a2, it saved/restored the CODE_OFF state + during the expression and that bled out to the outer one disabling + codegen for if-body. */ + if (( (someglobal ? 0 : 0) ? 8 : 9)) + printf("okay\n"); +} + +unsigned short tf_4_var_2 = 29886; +const unsigned short tf_4_var_34 = 54077; +const unsigned short tf_4_var_86 = 1129; +long int tf_4_var_98 = -4448775496354969734L; + +unsigned short tf_4_array_8 [9] = + {52593, 34626, 28127, 8124, 11473, 14634, 8370, 31153, 31060}; +unsigned short tf_4_array_2 [6] = + {7493, 64504, 22566, 54931, 44752, 18026}; +unsigned short tf_4_array_3 [9] = + {22671, 46595, 24007, 22460, 12020, 19732, 46148, 3906, 26139}; +unsigned short tf_4_array_7 [9] = + {24530, 26236, 61122, 9019, 26099, 31028, 1078, 27042, 36756}; +unsigned short tf_4_array_4 [9] = + {32711, 2853, 55531, 52731, 6621, 38797, 23543, 64627, 55640}; + +long int tf_4_var_132 = -6396431410421938408L; + +static void tst_yarpgen(void) +{ + /* generated by yarpgen */ + tf_4_var_132 = (long int) (((unsigned long long int) (((((((int) (tf_4_var_86)) && ((int) (tf_4_array_8 [0]))) ? (((int) (tf_4_var_2)) || ((int) (8))) : (((int) (tf_4_array_2 [0])) || (-4096)))) || ((((int) (tf_4_array_3 [6])) || ((int) (tf_4_var_34))) && (((int) (tf_4_array_3 [7])) || ((int) (tf_4_var_98))))) % ((+((int) ((unsigned short) (-6)))) && ((((int) (tf_4_array_7 [5])) & ((int) (tf_4_array_7 [1]))) | (((int) (tf_4_array_4 [0])) & ((int) (tf_4_array_4 [0]))))))) <= (((unsigned long long int) ((int) ((unsigned short) (((7192886880476152731ULL) * (7192886880476152731ULL)) * ((unsigned long long int) (((-9223372036854775807L - 1L)) * ((long int) ((int) (0))))))))) * (((unsigned long long int) (((-6) * ((int) (3))) * (-((int) (4))))) * (((8ULL) * (4ULL)) * ((unsigned long long int) (((long int) (-6)) * (-3L))))))); + printf("%ld\n", tf_4_var_132); +} + +int main() +{ + int Count; + + for (Count = 0; Count < 10; Count++) + { + printf("%d\n", (Count < 5) ? (Count*Count) : (Count * 3)); + } + + { + int c = 0; + #define ASSERT(X) assert(X) + static struct stru { int x; } a={'A'},b={'B'}; + static const struct stru2 { int x; } d = { 'D' }; + ASSERT('A'==(*(1?&a:&b)).x); + ASSERT('A'==(1?a:b).x); + ASSERT('A'==(c?b:a).x); + ASSERT('A'==(0?b:a).x); + c=1; + ASSERT('A'==(c?a:b).x); + ASSERT(sizeof(int) == sizeof(0 ? 'a' : c)); + ASSERT(sizeof(double) == sizeof(0 ? 'a' : 1.0)); + ASSERT(sizeof(double) == sizeof(0 ? 0.0 : 'a')); + ASSERT(sizeof(float) == sizeof(0 ? 'a' : 1.0f)); + ASSERT(sizeof(double) == sizeof(0 ? 0.0 : 1.0f)); + struct condstruct cs = { 38 }; + printf("%d\n", getme(&cs, 0)); + + // the following lines contain type mismatch errors in every ternary expression + //printf("comparing double with pointer : size = %d\n", sizeof(0 ? &c : 0.0)); + //printf("'%c' <> '%c'\n", (0 ? a : d).x, (1 ? a : d).x); + //0 ? a : 0.0; + } + + constantcond(); + + tst_yarpgen(); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/33_ternary_op.expect b/tinycc/tests/tests2/33_ternary_op.expect new file mode 100644 index 0000000..c21f5fb --- /dev/null +++ b/tinycc/tests/tests2/33_ternary_op.expect @@ -0,0 +1,14 @@ +33_ternary_op.c:26: warning: pointer/integer mismatch in conditional expression +0 +1 +4 +9 +16 +15 +18 +21 +24 +27 +152 +okay +1 diff --git a/tinycc/tests/tests2/34_array_assignment.c b/tinycc/tests/tests2/34_array_assignment.c new file mode 100644 index 0000000..5885c97 --- /dev/null +++ b/tinycc/tests/tests2/34_array_assignment.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +int main() +{ + int a[4]; + + a[0] = 12; + a[1] = 23; + a[2] = 34; + a[3] = 45; + + printf("%d %d %d %d\n", a[0], a[1], a[2], a[3]); + + int b[4]; + + b = a; + + printf("%d %d %d %d\n", b[0], b[1], b[2], b[3]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/34_array_assignment.expect b/tinycc/tests/tests2/34_array_assignment.expect new file mode 100644 index 0000000..9736bf5 --- /dev/null +++ b/tinycc/tests/tests2/34_array_assignment.expect @@ -0,0 +1,2 @@ +12 23 34 45 +12 23 34 45 diff --git a/tinycc/tests/tests2/35_sizeof.c b/tinycc/tests/tests2/35_sizeof.c new file mode 100644 index 0000000..672e87e --- /dev/null +++ b/tinycc/tests/tests2/35_sizeof.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +int main() +{ + char a; + short b; + + printf("%d %d\n", sizeof(char), sizeof(a)); + printf("%d %d\n", sizeof(short), sizeof(b)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/35_sizeof.expect b/tinycc/tests/tests2/35_sizeof.expect new file mode 100644 index 0000000..534fb83 --- /dev/null +++ b/tinycc/tests/tests2/35_sizeof.expect @@ -0,0 +1,2 @@ +1 1 +2 2 diff --git a/tinycc/tests/tests2/36_array_initialisers.c b/tinycc/tests/tests2/36_array_initialisers.c new file mode 100644 index 0000000..ac56f5a --- /dev/null +++ b/tinycc/tests/tests2/36_array_initialisers.c @@ -0,0 +1,25 @@ +#include <stdio.h> + +extern int Array3[10]; +int Array3[] = { 12, 34, }; +int main() +{ + int Count; + + int Array[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753 }; + + for (Count = 0; Count < 10; Count++) + printf("%d: %d\n", Count, Array[Count]); + + int Array2[10] = { 12, 34, 56, 78, 90, 123, 456, 789, 8642, 9753, }; + + for (Count = 0; Count < 10; Count++) + printf("%d: %d\n", Count, Array2[Count]); + + for (Count = 0; Count < 10; Count++) + printf("%d: %d\n", Count, Array3[Count]); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/36_array_initialisers.expect b/tinycc/tests/tests2/36_array_initialisers.expect new file mode 100644 index 0000000..4bb5ab7 --- /dev/null +++ b/tinycc/tests/tests2/36_array_initialisers.expect @@ -0,0 +1,30 @@ +0: 12 +1: 34 +2: 56 +3: 78 +4: 90 +5: 123 +6: 456 +7: 789 +8: 8642 +9: 9753 +0: 12 +1: 34 +2: 56 +3: 78 +4: 90 +5: 123 +6: 456 +7: 789 +8: 8642 +9: 9753 +0: 12 +1: 34 +2: 0 +3: 0 +4: 0 +5: 0 +6: 0 +7: 0 +8: 0 +9: 0 diff --git a/tinycc/tests/tests2/37_sprintf.c b/tinycc/tests/tests2/37_sprintf.c new file mode 100644 index 0000000..1dd1dce --- /dev/null +++ b/tinycc/tests/tests2/37_sprintf.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + char Buf[100]; + int Count; + + for (Count = 1; Count <= 20; Count++) + { + sprintf(Buf, "->%02d<-\n", Count); + printf("%s", Buf); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/37_sprintf.expect b/tinycc/tests/tests2/37_sprintf.expect new file mode 100644 index 0000000..a643da8 --- /dev/null +++ b/tinycc/tests/tests2/37_sprintf.expect @@ -0,0 +1,20 @@ +->01<- +->02<- +->03<- +->04<- +->05<- +->06<- +->07<- +->08<- +->09<- +->10<- +->11<- +->12<- +->13<- +->14<- +->15<- +->16<- +->17<- +->18<- +->19<- +->20<- diff --git a/tinycc/tests/tests2/38_multiple_array_index.c b/tinycc/tests/tests2/38_multiple_array_index.c new file mode 100644 index 0000000..4e1868e --- /dev/null +++ b/tinycc/tests/tests2/38_multiple_array_index.c @@ -0,0 +1,32 @@ +#include <stdio.h> + +int main() +{ + int a[4][4]; + int b = 0; + int x; + int y; + + for (x = 0; x < 4; x++) + { + for (y = 0; y < 4; y++) + { + b++; + a[x][y] = b; + } + } + + for (x = 0; x < 4; x++) + { + printf("x=%d: ", x); + for (y = 0; y < 4; y++) + { + printf("%d ", a[x][y]); + } + printf("\n"); + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/38_multiple_array_index.expect b/tinycc/tests/tests2/38_multiple_array_index.expect new file mode 100644 index 0000000..747ad75 --- /dev/null +++ b/tinycc/tests/tests2/38_multiple_array_index.expect @@ -0,0 +1,4 @@ +x=0: 1 2 3 4 +x=1: 5 6 7 8 +x=2: 9 10 11 12 +x=3: 13 14 15 16 diff --git a/tinycc/tests/tests2/39_typedef.c b/tinycc/tests/tests2/39_typedef.c new file mode 100644 index 0000000..da73f71 --- /dev/null +++ b/tinycc/tests/tests2/39_typedef.c @@ -0,0 +1,65 @@ +#include <stdio.h> + +typedef int MyInt; + +struct FunStruct +{ + int i; + int j; +}; + +typedef struct FunStruct MyFunStruct; + +typedef MyFunStruct *MoreFunThanEver; + +int main() +{ + MyInt a = 1; + printf("%d\n", a); + + MyFunStruct b; + b.i = 12; + b.j = 34; + printf("%d,%d\n", b.i, b.j); + + MoreFunThanEver c = &b; + printf("%d,%d\n", c->i, c->j); + + return 0; +} + +/* "If the specification of an array type includes any type qualifiers, + the element type is so-qualified, not the array type." */ + +typedef int A[3]; +extern A const ca; +extern const A ca; +extern const int ca[3]; + +typedef A B[1][2]; +extern B const cb; +extern const B cb; +extern const int cb[1][2][3]; + +extern B b; +extern int b[1][2][3]; + +/* Funny but valid function declaration. */ +typedef int functype (int); +extern functype func; +int func(int i) +{ + return i + 1; +} + +/* Even funnier function decl and definition using typeof. */ +int set_anon_super(void); +int set_anon_super(void) +{ + return 42; +} +typedef int sas_type (void); +extern typeof(set_anon_super) set_anon_super; +extern sas_type set_anon_super; + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/39_typedef.expect b/tinycc/tests/tests2/39_typedef.expect new file mode 100644 index 0000000..b9050a9 --- /dev/null +++ b/tinycc/tests/tests2/39_typedef.expect @@ -0,0 +1,3 @@ +1 +12,34 +12,34 diff --git a/tinycc/tests/tests2/40_stdio.c b/tinycc/tests/tests2/40_stdio.c new file mode 100644 index 0000000..b986093 --- /dev/null +++ b/tinycc/tests/tests2/40_stdio.c @@ -0,0 +1,52 @@ +#include <stdio.h> + +int main() +{ + FILE *f = fopen("fred.txt", "w"); + fwrite("hello\nhello\n", 1, 12, f); + fclose(f); + + char freddy[7]; + f = fopen("fred.txt", "r"); + if (fread(freddy, 1, 6, f) != 6) + printf("couldn't read fred.txt\n"); + + freddy[6] = '\0'; + fclose(f); + + printf("%s", freddy); + + int InChar; + char ShowChar; + f = fopen("fred.txt", "r"); + while ( (InChar = fgetc(f)) != EOF) + { + ShowChar = InChar; + if (ShowChar < ' ') + ShowChar = '.'; + + printf("ch: %d '%c'\n", InChar, ShowChar); + } + fclose(f); + + f = fopen("fred.txt", "r"); + while ( (InChar = getc(f)) != EOF) + { + ShowChar = InChar; + if (ShowChar < ' ') + ShowChar = '.'; + + printf("ch: %d '%c'\n", InChar, ShowChar); + } + fclose(f); + + f = fopen("fred.txt", "r"); + while (fgets(freddy, sizeof(freddy), f) != NULL) + printf("x: %s", freddy); + + fclose(f); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/40_stdio.expect b/tinycc/tests/tests2/40_stdio.expect new file mode 100644 index 0000000..e08167a --- /dev/null +++ b/tinycc/tests/tests2/40_stdio.expect @@ -0,0 +1,27 @@ +hello +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +ch: 104 'h' +ch: 101 'e' +ch: 108 'l' +ch: 108 'l' +ch: 111 'o' +ch: 10 '.' +x: hello +x: hello diff --git a/tinycc/tests/tests2/41_hashif.c b/tinycc/tests/tests2/41_hashif.c new file mode 100644 index 0000000..cb37b9e --- /dev/null +++ b/tinycc/tests/tests2/41_hashif.c @@ -0,0 +1,85 @@ +#include <stdio.h> + +int main() +{ + printf("#include test\n"); + +#if 1 +#if 0 + printf("a\n"); +#else + printf("b\n"); +#endif +#else +#if 0 + printf("c\n"); +#else + printf("d\n"); +#endif +#endif + +#if 0 +#if 1 + printf("e\n"); +#else + printf("f\n"); +#endif +#else +#if 1 + printf("g\n"); +#else + printf("h\n"); +#endif +#endif + +#define DEF + +#ifdef DEF +#ifdef DEF + printf("i\n"); +#else + printf("j\n"); +#endif +#else +#ifdef DEF + printf("k\n"); +#else + printf("l\n"); +#endif +#endif + +#ifndef DEF +#ifndef DEF + printf("m\n"); +#else + printf("n\n"); +#endif +#else +#ifndef DEF + printf("o\n"); +#else + printf("p\n"); +#endif +#endif + +#define ONE 1 +#define ZERO 0 + +#if ONE +#if ZERO + printf("q\n"); +#else + printf("r\n"); +#endif +#else +#if ZERO + printf("s\n"); +#else + printf("t\n"); +#endif +#endif + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/41_hashif.expect b/tinycc/tests/tests2/41_hashif.expect new file mode 100644 index 0000000..5fd414b --- /dev/null +++ b/tinycc/tests/tests2/41_hashif.expect @@ -0,0 +1,6 @@ +#include test +b +g +i +p +r diff --git a/tinycc/tests/tests2/42_function_pointer.c b/tinycc/tests/tests2/42_function_pointer.c new file mode 100644 index 0000000..697bd79 --- /dev/null +++ b/tinycc/tests/tests2/42_function_pointer.c @@ -0,0 +1,22 @@ +#include <stdio.h> + +int fred(int p) +{ + printf("yo %d\n", p); + return 42; +} + +int (*f)(int) = &fred; + +/* To test what this is supposed to test the destination function + (fprint here) must not be called directly anywhere in the test. */ +int (*fprintfptr)(FILE *, const char *, ...) = &fprintf; + +int main() +{ + fprintfptr(stdout, "%d\n", (*f)(24)); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/42_function_pointer.expect b/tinycc/tests/tests2/42_function_pointer.expect new file mode 100644 index 0000000..6c8b6ce --- /dev/null +++ b/tinycc/tests/tests2/42_function_pointer.expect @@ -0,0 +1,2 @@ +yo 24 +42 diff --git a/tinycc/tests/tests2/43_void_param.c b/tinycc/tests/tests2/43_void_param.c new file mode 100644 index 0000000..de17098 --- /dev/null +++ b/tinycc/tests/tests2/43_void_param.c @@ -0,0 +1,15 @@ +#include <stdio.h> + +void fred(void) +{ + printf("yo\n"); +} + +int main() +{ + fred(); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/43_void_param.expect b/tinycc/tests/tests2/43_void_param.expect new file mode 100644 index 0000000..092bfb9 --- /dev/null +++ b/tinycc/tests/tests2/43_void_param.expect @@ -0,0 +1 @@ +yo diff --git a/tinycc/tests/tests2/44_scoped_declarations.c b/tinycc/tests/tests2/44_scoped_declarations.c new file mode 100644 index 0000000..f38664f --- /dev/null +++ b/tinycc/tests/tests2/44_scoped_declarations.c @@ -0,0 +1,17 @@ +#include <stdio.h> + +int main() +{ + int a; + + for (a = 0; a < 2; a++) + { + int b = a; + } + + printf("it's all good\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/44_scoped_declarations.expect b/tinycc/tests/tests2/44_scoped_declarations.expect new file mode 100644 index 0000000..231ccc0 --- /dev/null +++ b/tinycc/tests/tests2/44_scoped_declarations.expect @@ -0,0 +1 @@ +it's all good diff --git a/tinycc/tests/tests2/45_empty_for.c b/tinycc/tests/tests2/45_empty_for.c new file mode 100644 index 0000000..7cef513 --- /dev/null +++ b/tinycc/tests/tests2/45_empty_for.c @@ -0,0 +1,18 @@ +#include <stdio.h> + +int main() +{ + int Count = 0; + + for (;;) + { + Count++; + printf("%d\n", Count); + if (Count >= 10) + break; + } + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/45_empty_for.expect b/tinycc/tests/tests2/45_empty_for.expect new file mode 100644 index 0000000..f00c965 --- /dev/null +++ b/tinycc/tests/tests2/45_empty_for.expect @@ -0,0 +1,10 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/tinycc/tests/tests2/46_grep.c b/tinycc/tests/tests2/46_grep.c new file mode 100644 index 0000000..acda793 --- /dev/null +++ b/tinycc/tests/tests2/46_grep.c @@ -0,0 +1,570 @@ +/* + * The information in this document is subject to change + * without notice and should not be construed as a commitment + * by Digital Equipment Corporation or by DECUS. + * + * Neither Digital Equipment Corporation, DECUS, nor the authors + * assume any responsibility for the use or reliability of this + * document or the described software. + * + * Copyright (C) 1980, DECUS + * + * General permission to copy or modify, but not for profit, is + * hereby granted, provided that the above copyright notice is + * included and reference made to the fact that reproduction + * privileges were granted by DECUS. + */ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> // tolower() + +/* + * grep + * + * Runs on the Decus compiler or on vms, On vms, define as: + * grep :== "$disk:[account]grep" (native) + * grep :== "$disk:[account]grep grep" (Decus) + * See below for more information. + */ + +char *documentation[] = { + "grep searches a file for a given pattern. Execute by", + " grep [flags] regular_expression file_list\n", + "Flags are single characters preceded by '-':", + " -c Only a count of matching lines is printed", + " -f Print file name for matching lines switch, see below", + " -n Each line is preceded by its line number", + " -v Only print non-matching lines\n", + "The file_list is a list of files (wildcards are acceptable on RSX modes).", + "\nThe file name is normally printed if there is a file given.", + "The -f flag reverses this action (print name no file, not if more).\n", + 0 }; + +char *patdoc[] = { + "The regular_expression defines the pattern to search for. Upper- and", + "lower-case are always ignored. Blank lines never match. The expression", + "should be quoted to prevent file-name translation.", + "x An ordinary character (not mentioned below) matches that character.", + "'\\' The backslash quotes any character. \"\\$\" matches a dollar-sign.", + "'^' A circumflex at the beginning of an expression matches the", + " beginning of a line.", + "'$' A dollar-sign at the end of an expression matches the end of a line.", + "'.' A period matches any character except \"new-line\".", + "':a' A colon matches a class of characters described by the following", + "':d' character. \":a\" matches any alphabetic, \":d\" matches digits,", + "':n' \":n\" matches alphanumerics, \": \" matches spaces, tabs, and", + "': ' other control characters, such as new-line.", + "'*' An expression followed by an asterisk matches zero or more", + " occurrences of that expression: \"fo*\" matches \"f\", \"fo\"", + " \"foo\", etc.", + "'+' An expression followed by a plus sign matches one or more", + " occurrences of that expression: \"fo+\" matches \"fo\", etc.", + "'-' An expression followed by a minus sign optionally matches", + " the expression.", + "'[]' A string enclosed in square brackets matches any character in", + " that string, but no others. If the first character in the", + " string is a circumflex, the expression matches any character", + " except \"new-line\" and the characters in the string. For", + " example, \"[xyz]\" matches \"xx\" and \"zyx\", while \"[^xyz]\"", + " matches \"abc\" but not \"axb\". A range of characters may be", + " specified by two characters separated by \"-\". Note that,", + " [a-z] matches alphabetics, while [z-a] never matches.", + "The concatenation of regular expressions is a regular expression.", + 0}; + +#define LMAX 512 +#define PMAX 256 + +#define CHAR 1 +#define BOL 2 +#define EOL 3 +#define ANY 4 +#define CLASS 5 +#define NCLASS 6 +#define STAR 7 +#define PLUS 8 +#define MINUS 9 +#define ALPHA 10 +#define DIGIT 11 +#define NALPHA 12 +#define PUNCT 13 +#define RANGE 14 +#define ENDPAT 15 + +int cflag=0, fflag=0, nflag=0, vflag=0, nfile=0, debug=0; + +char *pp, lbuf[LMAX], pbuf[PMAX]; + +char *cclass(); +char *pmatch(); +void store(int); +void error(char *); +void badpat(char *, char *, char *); +int match(void); + + +/*** Display a file name *******************************/ +void file(char *s) +{ + printf("File %s:\n", s); +} + +/*** Report unopenable file ****************************/ +void cant(char *s) +{ + fprintf(stderr, "%s: cannot open\n", s); +} + +/*** Give good help ************************************/ +void help(char **hp) +{ + char **dp; + + for (dp = hp; *dp; ++dp) + printf("%s\n", *dp); +} + +/*** Display usage summary *****************************/ +void usage(char *s) +{ + fprintf(stderr, "?GREP-E-%s\n", s); + fprintf(stderr, + "Usage: grep [-cfnv] pattern [file ...]. grep ? for help\n"); + exit(1); +} + +/*** Compile the pattern into global pbuf[] ************/ +void compile(char *source) +{ + char *s; /* Source string pointer */ + char *lp; /* Last pattern pointer */ + int c; /* Current character */ + int o; /* Temp */ + char *spp; /* Save beginning of pattern */ + + s = source; + if (debug) + printf("Pattern = \"%s\"\n", s); + pp = pbuf; + while (c = *s++) { + /* + * STAR, PLUS and MINUS are special. + */ + if (c == '*' || c == '+' || c == '-') { + if (pp == pbuf || + (o=pp[-1]) == BOL || + o == EOL || + o == STAR || + o == PLUS || + o == MINUS) + badpat("Illegal occurrence op.", source, s); + store(ENDPAT); + store(ENDPAT); + spp = pp; /* Save pattern end */ + while (--pp > lp) /* Move pattern down */ + *pp = pp[-1]; /* one byte */ + *pp = (c == '*') ? STAR : + (c == '-') ? MINUS : PLUS; + pp = spp; /* Restore pattern end */ + continue; + } + /* + * All the rest. + */ + lp = pp; /* Remember start */ + switch(c) { + + case '^': + store(BOL); + break; + + case '$': + store(EOL); + break; + + case '.': + store(ANY); + break; + + case '[': + s = cclass(source, s); + break; + + case ':': + if (*s) { + switch(tolower(c = *s++)) { + + case 'a': + case 'A': + store(ALPHA); + break; + + case 'd': + case 'D': + store(DIGIT); + break; + + case 'n': + case 'N': + store(NALPHA); + break; + + case ' ': + store(PUNCT); + break; + + default: + badpat("Unknown : type", source, s); + + } + break; + } + else badpat("No : type", source, s); + + case '\\': + if (*s) + c = *s++; + + default: + store(CHAR); + store(tolower(c)); + } + } + store(ENDPAT); + store(0); /* Terminate string */ + if (debug) { + for (lp = pbuf; lp < pp;) { + if ((c = (*lp++ & 0377)) < ' ') + printf("\\%o ", c); + else printf("%c ", c); + } + printf("\n"); + } +} + +/*** Compile a class (within []) ***********************/ +char *cclass(char *source, char *src) + /* char *source; // Pattern start -- for error msg. */ + /* char *src; // Class start */ +{ + char *s; /* Source pointer */ + char *cp; /* Pattern start */ + int c; /* Current character */ + int o; /* Temp */ + + s = src; + o = CLASS; + if (*s == '^') { + ++s; + o = NCLASS; + } + store(o); + cp = pp; + store(0); /* Byte count */ + while ((c = *s++) && c!=']') { + if (c == '\\') { /* Store quoted char */ + if ((c = *s++) == '\0') /* Gotta get something */ + badpat("Class terminates badly", source, s); + else store(tolower(c)); + } + else if (c == '-' && + (pp - cp) > 1 && *s != ']' && *s != '\0') { + c = pp[-1]; /* Range start */ + pp[-1] = RANGE; /* Range signal */ + store(c); /* Re-store start */ + c = *s++; /* Get end char and*/ + store(tolower(c)); /* Store it */ + } + else { + store(tolower(c)); /* Store normal char */ + } + } + if (c != ']') + badpat("Unterminated class", source, s); + if ((c = (pp - cp)) >= 256) + badpat("Class too large", source, s); + if (c == 0) + badpat("Empty class", source, s); + *cp = c; + return(s); +} + +/*** Store an entry in the pattern buffer **************/ +void store(int op) +{ + if (pp >= &pbuf[PMAX]) + error("Pattern too complex\n"); + *pp++ = op; +} + +/*** Report a bad pattern specification ****************/ +void badpat(char *message, char *source, char *stop) + /* char *message; // Error message */ + /* char *source; // Pattern start */ + /* char *stop; // Pattern end */ +{ + fprintf(stderr, "-GREP-E-%s, pattern is\"%s\"\n", message, source); + fprintf(stderr, "-GREP-E-Stopped at byte %ld, '%c'\n", + stop-source, stop[-1]); + error("?GREP-E-Bad pattern\n"); +} + +/*** Scan the file for the pattern in pbuf[] ***********/ +void grep(FILE *fp, char *fn) + /* FILE *fp; // File to process */ + /* char *fn; // File name (for -f option) */ +{ + int lno, count, m; + + lno = 0; + count = 0; + while (fgets(lbuf, LMAX, fp)) { + ++lno; + m = match(); + if ((m && !vflag) || (!m && vflag)) { + ++count; + if (!cflag) { + if (fflag && fn) { + file(fn); + fn = 0; + } + if (nflag) + printf("%d\t", lno); + printf("%s\n", lbuf); + } + } + } + if (cflag) { + if (fflag && fn) + file(fn); + printf("%d\n", count); + } +} + +/*** Match line (lbuf) with pattern (pbuf) return 1 if match ***/ +int match() +{ + char *l; /* Line pointer */ + + for (l = lbuf; *l; ++l) { + if (pmatch(l, pbuf)) + return(1); + } + return(0); +} + +/*** Match partial line with pattern *******************/ +char *pmatch(char *line, char *pattern) + /* char *line; // (partial) line to match */ + /* char *pattern; // (partial) pattern to match */ +{ + char *l; /* Current line pointer */ + char *p; /* Current pattern pointer */ + char c; /* Current character */ + char *e; /* End for STAR and PLUS match */ + int op; /* Pattern operation */ + int n; /* Class counter */ + char *are; /* Start of STAR match */ + + l = line; + if (debug > 1) + printf("pmatch(\"%s\")\n", line); + p = pattern; + while ((op = *p++) != ENDPAT) { + if (debug > 1) + printf("byte[%ld] = 0%o, '%c', op = 0%o\n", + l-line, *l, *l, op); + switch(op) { + + case CHAR: + if (tolower(*l++) != *p++) + return(0); + break; + + case BOL: + if (l != lbuf) + return(0); + break; + + case EOL: + if (*l != '\0') + return(0); + break; + + case ANY: + if (*l++ == '\0') + return(0); + break; + + case DIGIT: + if ((c = *l++) < '0' || (c > '9')) + return(0); + break; + + case ALPHA: + c = tolower(*l++); + if (c < 'a' || c > 'z') + return(0); + break; + + case NALPHA: + c = tolower(*l++); + if (c >= 'a' && c <= 'z') + break; + else if (c < '0' || c > '9') + return(0); + break; + + case PUNCT: + c = *l++; + if (c == 0 || c > ' ') + return(0); + break; + + case CLASS: + case NCLASS: + c = tolower(*l++); + n = *p++ & 0377; + do { + if (*p == RANGE) { + p += 3; + n -= 2; + if (c >= p[-2] && c <= p[-1]) + break; + } + else if (c == *p++) + break; + } while (--n > 1); + if ((op == CLASS) == (n <= 1)) + return(0); + if (op == CLASS) + p += n - 2; + break; + + case MINUS: + e = pmatch(l, p); /* Look for a match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + if (e) /* Got a match? */ + l = e; /* Yes, update string */ + break; /* Always succeeds */ + + case PLUS: /* One or more ... */ + if ((l = pmatch(l, p)) == 0) + return(0); /* Gotta have a match */ + case STAR: /* Zero or more ... */ + are = l; /* Remember line start */ + while (*l && (e = pmatch(l, p))) + l = e; /* Get longest match */ + while (*p++ != ENDPAT); /* Skip over pattern */ + while (l > are) { /* Try to match rest */ + if (e = pmatch(l, p)) + return(e); + --l; /* Nope, try earlier */ + } + if (e = pmatch(l, p)) + return(e); + return(0); /* Nothing else worked */ + + default: + printf("Bad op code %d\n", op); + error("Cannot happen -- match\n"); + } + } + return(l); +} + +/*** Report an error ***********************************/ +void error(char *s) +{ + fprintf(stderr, "%s", s); + exit(1); +} + +/*** Main program - parse arguments & grep *************/ +int main(int argc, char **argv) +{ + char *p; + int c, i; + int gotpattern; + + FILE *f; + + if (argc <= 1) + usage("No arguments"); + if (argc == 2 && argv[1][0] == '?' && argv[1][1] == 0) { + help(documentation); + help(patdoc); + return 0; + } + nfile = argc-1; + gotpattern = 0; + for (i=1; i < argc; ++i) { + p = argv[i]; + if (*p == '-') { + ++p; + while (c = *p++) { + switch(tolower(c)) { + + case '?': + help(documentation); + break; + + case 'C': + case 'c': + ++cflag; + break; + + case 'D': + case 'd': + ++debug; + break; + + case 'F': + case 'f': + ++fflag; + break; + + case 'n': + case 'N': + ++nflag; + break; + + case 'v': + case 'V': + ++vflag; + break; + + default: + usage("Unknown flag"); + } + } + argv[i] = 0; + --nfile; + } else if (!gotpattern) { + compile(p); + argv[i] = 0; + ++gotpattern; + --nfile; + } + } + if (!gotpattern) + usage("No pattern"); + if (nfile == 0) + grep(stdin, 0); + else { + fflag = fflag ^ (nfile > 0); + for (i=1; i < argc; ++i) { + if (p = argv[i]) { + if ((f=fopen(p, "r")) == NULL) + cant(p); + else { + grep(f, p); + fclose(f); + } + } + } + } + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/46_grep.expect b/tinycc/tests/tests2/46_grep.expect new file mode 100644 index 0000000..e8a6791 --- /dev/null +++ b/tinycc/tests/tests2/46_grep.expect @@ -0,0 +1,3 @@ +File 46_grep.c: +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ + diff --git a/tinycc/tests/tests2/47_switch_return.c b/tinycc/tests/tests2/47_switch_return.c new file mode 100644 index 0000000..1ec7924 --- /dev/null +++ b/tinycc/tests/tests2/47_switch_return.c @@ -0,0 +1,24 @@ +#include <stdio.h> + +void fred(int x) +{ + switch (x) + { + case 1: printf("1\n"); return; + case 2: printf("2\n"); break; + case 3: printf("3\n"); return; + } + + printf("out\n"); +} + +int main() +{ + fred(1); + fred(2); + fred(3); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/47_switch_return.expect b/tinycc/tests/tests2/47_switch_return.expect new file mode 100644 index 0000000..b6deb7e --- /dev/null +++ b/tinycc/tests/tests2/47_switch_return.expect @@ -0,0 +1,4 @@ +1 +2 +out +3 diff --git a/tinycc/tests/tests2/48_nested_break.c b/tinycc/tests/tests2/48_nested_break.c new file mode 100644 index 0000000..5bc5ba4 --- /dev/null +++ b/tinycc/tests/tests2/48_nested_break.c @@ -0,0 +1,26 @@ +#include <stdio.h> + +int main() +{ + int a; + char b; + + a = 0; + while (a < 2) + { + printf("%d", a++); + break; + + b = 'A'; + while (b < 'C') + { + printf("%c", b++); + } + printf("e"); + } + printf("\n"); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/48_nested_break.expect b/tinycc/tests/tests2/48_nested_break.expect new file mode 100644 index 0000000..573541a --- /dev/null +++ b/tinycc/tests/tests2/48_nested_break.expect @@ -0,0 +1 @@ +0 diff --git a/tinycc/tests/tests2/49_bracket_evaluation.c b/tinycc/tests/tests2/49_bracket_evaluation.c new file mode 100644 index 0000000..0cbe57d --- /dev/null +++ b/tinycc/tests/tests2/49_bracket_evaluation.c @@ -0,0 +1,23 @@ +#include <stdio.h> + +struct point +{ + double x; + double y; +}; + +struct point point_array[100]; + +int main() +{ + int my_point = 10; + + point_array[my_point].x = 12.34; + point_array[my_point].y = 56.78; + + printf("%f, %f\n", point_array[my_point].x, point_array[my_point].y); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/49_bracket_evaluation.expect b/tinycc/tests/tests2/49_bracket_evaluation.expect new file mode 100644 index 0000000..1da66db --- /dev/null +++ b/tinycc/tests/tests2/49_bracket_evaluation.expect @@ -0,0 +1 @@ +12.340000, 56.780000 diff --git a/tinycc/tests/tests2/50_logical_second_arg.c b/tinycc/tests/tests2/50_logical_second_arg.c new file mode 100644 index 0000000..ddec08c --- /dev/null +++ b/tinycc/tests/tests2/50_logical_second_arg.c @@ -0,0 +1,29 @@ +#include <stdio.h> + +int fred() +{ + printf("fred\n"); + return 0; +} + +int joe() +{ + printf("joe\n"); + return 1; +} + +int main() +{ + printf("%d\n", fred() && joe()); + printf("%d\n", fred() || joe()); + printf("%d\n", joe() && fred()); + printf("%d\n", joe() || fred()); + printf("%d\n", fred() && (1 + joe())); + printf("%d\n", fred() || (0 + joe())); + printf("%d\n", joe() && (0 + fred())); + printf("%d\n", joe() || (1 + fred())); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/50_logical_second_arg.expect b/tinycc/tests/tests2/50_logical_second_arg.expect new file mode 100644 index 0000000..d6174ae --- /dev/null +++ b/tinycc/tests/tests2/50_logical_second_arg.expect @@ -0,0 +1,20 @@ +fred +0 +fred +joe +1 +joe +fred +0 +joe +1 +fred +0 +fred +joe +1 +joe +fred +0 +joe +1 diff --git a/tinycc/tests/tests2/51_static.c b/tinycc/tests/tests2/51_static.c new file mode 100644 index 0000000..d6c0917 --- /dev/null +++ b/tinycc/tests/tests2/51_static.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +static int fred = 1234; +static int joe; + +void henry() +{ + static int fred = 4567; + + printf("%d\n", fred); + fred++; +} + +int main() +{ + printf("%d\n", fred); + henry(); + henry(); + henry(); + henry(); + printf("%d\n", fred); + fred = 8901; + joe = 2345; + printf("%d\n", fred); + printf("%d\n", joe); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/51_static.expect b/tinycc/tests/tests2/51_static.expect new file mode 100644 index 0000000..18224fa --- /dev/null +++ b/tinycc/tests/tests2/51_static.expect @@ -0,0 +1,8 @@ +1234 +4567 +4568 +4569 +4570 +1234 +8901 +2345 diff --git a/tinycc/tests/tests2/52_unnamed_enum.c b/tinycc/tests/tests2/52_unnamed_enum.c new file mode 100644 index 0000000..d0395b2 --- /dev/null +++ b/tinycc/tests/tests2/52_unnamed_enum.c @@ -0,0 +1,27 @@ +#include <stdio.h> + +enum fred { a, b, c }; + +int main() +{ + printf("a=%d\n", a); + printf("b=%d\n", b); + printf("c=%d\n", c); + + enum fred d; + + typedef enum { e, f, g } h; + typedef enum { i, j, k } m; + + printf("e=%d\n", e); + printf("f=%d\n", f); + printf("g=%d\n", g); + + printf("i=%d\n", i); + printf("j=%d\n", j); + printf("k=%d\n", k); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/52_unnamed_enum.expect b/tinycc/tests/tests2/52_unnamed_enum.expect new file mode 100644 index 0000000..84f2ac8 --- /dev/null +++ b/tinycc/tests/tests2/52_unnamed_enum.expect @@ -0,0 +1,9 @@ +a=0 +b=1 +c=2 +e=0 +f=1 +g=2 +i=0 +j=1 +k=2 diff --git a/tinycc/tests/tests2/54_goto.c b/tinycc/tests/tests2/54_goto.c new file mode 100644 index 0000000..2e151bb --- /dev/null +++ b/tinycc/tests/tests2/54_goto.c @@ -0,0 +1,56 @@ +#include <stdio.h> + +void fred() +{ + printf("In fred()\n"); + goto done; + printf("In middle\n"); +done: + printf("At end\n"); +} + +void joe() +{ + int b = 5678; + + printf("In joe()\n"); + + { + int c = 1234; + printf("c = %d\n", c); + goto outer; + printf("uh-oh\n"); + } + +outer: + + printf("done\n"); +} + +void henry() +{ + int a; + + printf("In henry()\n"); + goto inner; + + { + int b; +inner: + b = 1234; + printf("b = %d\n", b); + } + + printf("done\n"); +} + +int main() +{ + fred(); + joe(); + henry(); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/54_goto.expect b/tinycc/tests/tests2/54_goto.expect new file mode 100644 index 0000000..8e553fa --- /dev/null +++ b/tinycc/tests/tests2/54_goto.expect @@ -0,0 +1,8 @@ +In fred() +At end +In joe() +c = 1234 +done +In henry() +b = 1234 +done diff --git a/tinycc/tests/tests2/55_lshift_type.c b/tinycc/tests/tests2/55_lshift_type.c new file mode 100644 index 0000000..aa3e51a --- /dev/null +++ b/tinycc/tests/tests2/55_lshift_type.c @@ -0,0 +1,52 @@ +/* $Id: lshift-type.c 53089 2012-07-06 11:18:26Z vinc17/ypig $ + +Tests on left-shift type, written by Vincent Lefevre <vincent@vinc17.net>. + +ISO C99 TC3 says: [6.5.7#3] "The integer promotions are performed on +each of the operands. The type of the result is that of the promoted +left operand." +*/ + +#include <stdio.h> + +#define PTYPE(M) ((M) < 0 || -(M) < 0 ? -1 : 1) * (int) sizeof((M)+0) +#define CHECK(X,T) check(#X, PTYPE(X), PTYPE((X) << (T) 1)) +#define TEST1(X,T) do { CHECK(X,T); CHECK(X,unsigned T); } while (0) +#define TEST2(X) \ + do \ + { \ + TEST1((X),short); \ + TEST1((X),int); \ + TEST1((X),long); \ + TEST1((X),long long); \ + } \ + while (0) +#define TEST3(X,T) do { TEST2((T)(X)); TEST2((unsigned T)(X)); } while (0) +#define TEST4(X) \ + do \ + { \ + TEST3((X),short); \ + TEST3((X),int); \ + TEST3((X),long); \ + TEST3((X),long long); \ + } \ + while (0) + +static int debug, nfailed = 0; + +static void check (const char *s, int arg1, int shift) +{ + int failed = arg1 != shift; + if (debug || failed) + printf ("%s %d %d\n", s, arg1, shift); + nfailed += failed; +} + +int main (int argc, char **argv) +{ + debug = argc > 1; + TEST4(1); + TEST4(-1); + printf ("%d test(s) failed\n", nfailed); + return nfailed != 0; +} diff --git a/tinycc/tests/tests2/55_lshift_type.expect b/tinycc/tests/tests2/55_lshift_type.expect new file mode 100644 index 0000000..8523767 --- /dev/null +++ b/tinycc/tests/tests2/55_lshift_type.expect @@ -0,0 +1 @@ +0 test(s) failed diff --git a/tinycc/tests/tests2/60_errors_and_warnings.c b/tinycc/tests/tests2/60_errors_and_warnings.c new file mode 100644 index 0000000..960c64f --- /dev/null +++ b/tinycc/tests/tests2/60_errors_and_warnings.c @@ -0,0 +1,466 @@ +#if defined test_56_btype_excess_1 +struct A {} int i; + +#elif defined test_57_btype_excess_2 +char int i; + +#elif defined test_58_function_redefinition +int f(void) { return 0; } +int f(void) { return 1; } + +#elif defined test_global_redefinition +int xxx = 1; +int xxx; +int xxx = 2; + +#elif defined test_59_function_array +int (*fct)[42](int x); + +#elif defined test_60_enum_redefinition +enum color { RED, GREEN, BLUE }; +enum color { R, G, B }; +enum color c; + +#elif defined test_62_enumerator_redefinition +enum color { RED, GREEN, BLUE }; +enum rgb { RED, G, B}; +enum color c = RED; + +#elif defined test_63_local_enumerator_redefinition +enum { + FOO, + BAR +}; + +int main(void) +{ + enum { + FOO = 2, + BAR + }; + + return BAR - FOO; +} + +#elif defined test_61_undefined_enum +enum rgb3 c = 42; + +#elif defined test_74_non_const_init +int i = i++; + +#elif defined test_pointer_assignment + +void (*f1)(void); +void f2(void) {} + +struct s1 *ps1; +struct s2 *ps2; + +void *v1, **v2, ***v3; + +enum e1 { a = 4 } e10, *e11, *e12; +enum e2 { b = -4 } e20, *e21; +enum e3 { c = 5000000000LL } e30; + +int *ip; +unsigned int *up; +long *lp; +long long *llp; + +char **c1; +char const **c2; +unsigned char **u1; + +int no_main () +{ + // function + f1 = f2; + // struct + ps1 = ps2; + // void* + v1 = v3; + v2 = v3; + + // enum + e11 = e12; + e11 = e21; + e11 = &e10; + ip = &e10; + ip = &e20; + up = &e10; + up = &e20; + up = &e30; + + lp = ip; + lp = llp; + + // constness + c1 = c2; + *c1 = *c2; + **c1 = **c2; + + // unsigned = signed + u1 = c2; + *u1 = *c2; + **u1 = **c2; + + c2 = c1; + *c2 = *c1; + **c2 = **c1; + + return 0; +} + + +#elif defined test_enum_compat +enum e4; +enum e5; +void f3(enum e4 e); +void f3(enum e5 e); + +#elif defined test_enum_compat_2 +enum e6 { E1 = -1, E0 }; +void f3(enum e6); +void f3(int); // should work as int and e6 are compatible +void f4(enum e6 e); +void f4(unsigned e); // should error as unsigned and e6 are incompatible + +#elif defined test_ptr_to_str +void f() { _Generic((int const *[]){0}, int:0); } +#elif defined test_fnptr_to_str +void f() { _Generic((int (*(*)(float,char))(double,int)){0}, int:0); } +#elif defined test_array_to_str +void f() { _Generic((int(*)[3]){0}, int:0); } +#elif defined test_duplicate_def_1 +static enum myenum { L = -1 } L; +#elif defined test_duplicate_def_2 +void foo(void) { +static enum myenum { L = -1 } L; +} +#elif defined test_abstract_decls +int bar(const char *()); // abstract declarator here is okay +int bar (const char *(*g)()) // should match this 'g' argument +{ + g(); + return 42; +} +int foo(int ()) // abstract decl is wrong in definitions +{ + return 0; +#elif defined test_invalid_1 +void f(char*); +void g(void) { + f((char[]){1, ,}); +} +#elif defined test_invalid_2 +int ga = 0.42 { 2 }; +#elif defined test_invalid_3 +struct S { int a, b; }; +struct T { struct S x; }; +struct T gt = { 42 a: 1, 43 }; +#elif defined test_invalid_4 +enum E { + x = 1 / 0 +}; +#elif defined test_conflicting_types +int i; +void foo(void) { + int i; + { + extern double i; + i = 42.2; + } +} +#elif defined test_nested_types +union u { + union u { + int i; + } m; +}; +#elif defined test_vla_1 +int X=1; + +int main(void) { + int t[][][X]; +} +#elif defined test_invalid_alignas +/* _Alignas is no type qualifier */ +void * _Alignas(16) p1; + +#elif defined test_static_assert + +#define ONE 0 + _Static_assert(ONE == 0, "don't show me this"); + struct x{ _Static_assert(ONE == 1, "ONE is not 1"); }; + +#elif defined test_static_assert_2 + _Static_assert(1, "1"" is 1"); +struct y { _Static_assert(0, "0"" is 0"); }; + +#elif defined test_static_assert_c2x + _Static_assert(1); +struct z { _Static_assert(0); } + +#elif defined test_static_assert_empty_string + _Static_assert(0,""); + +#elif defined test_void_array + void t[3]; + +#elif defined test_incomplete_enum_array + enum e t[3]; + +#elif defined test_incomplete_struct_array + struct s t[3]; + +#elif defined test_const_fun_array + typedef void f(void); + const f t[3]; + +#elif defined test_incomplete_array_array + int t[][3]; // gr: not an error, see below + +/******************************************************************/ +#elif defined test_extern_array +int iii[] = { 1,2,3 }; +extern int iii[]; +int x[]; +int x[2]; +int x[]; +int x[2]; +int x[]; +extern int x[2]; +extern int x[]; +int x[3]; + +/******************************************************************/ +#elif defined test_func_1 \ + || defined test_func_2 \ + || defined test_func_3 \ + || defined test_func_4 \ + || defined test_func_5 \ + || defined test_func_6 +#if defined test_func_1 +int hello(int); +#elif defined test_func_4 +static int hello(int); +#endif +int main () { +#if defined test_func_6 + static +#endif + int hello(int); + hello(123); + return 0; +} +int printf(const char*, ...); +#if defined test_func_3 +static int hello(int a) +#elif defined test_func_5 +int hello(int a, int b) +#else +int hello(int a) +#endif +{ printf("%s: a = %d\n", __FUNCTION__, a); return 0; } + +/******************************************************************/ +#elif defined test_var_1 \ + || defined test_var_2 \ + || defined test_var_3 +#define P(n,v) printf("%-5s: %d ; %d\n", __FUNCTION__, n, v) +#if defined test_var_1 +int xxx[]; +#endif +int bar(); +int printf(const char*, ...); +int main () +{ +#if !defined test_var_3 + int xxx = 2; +#endif + { + extern int xxx[ +#if defined test_var_3 + 2 +#endif + ]; + P(1, xxx[0]); + xxx[0] += 2; + } +#if !defined test_var_3 + P(2, xxx); +#endif + bar(123); + return 0; +} +int xxx[1] = {1}; +int bar() { P(3, xxx[0]); return 0; } + +#elif defined test_var_4 +struct yyy { int y; }; +struct zzz; +void f1() { + extern char *x; + extern char **xx; + extern struct yyy y; + extern struct yyy *yy; + extern struct zzz z; + extern struct zzz *zz; +} +void f2() { + extern char *x; + extern char **xx; + extern struct yyy y; + extern struct yyy *yy; + extern struct zzz z; + extern struct zzz *zz; +} +struct yyy y, *yy; +struct zzz { int z; } z, *zz; + +/******************************************************************/ +#elif defined test_long_double_type_for_win32 + +int main() +{ + double *a = 0; + long double *b = a; + int n = _Generic(*a, double:0, long double:1); +} + +#elif defined test_stray_backslash +#define x \a +x + +#elif defined test_stray_backslash2 +int printf(const char*, ...); +int main() +{ +#define _S(x) #x +#define S(x) _S(x) + printf("%sn\n", S(\\)); +} + +/******************************************************************/ +#elif defined test_var_array + +static struct var_len { int i; const char str[]; } var_array[] = +{ { 1, "abcdefghijklmnopqrstuvwxyz" }, + { 2, "longlonglonglonglong" }, + { 3, "tst3" } }; + +#elif defined test_var_array2 + +struct c1 { int a; int b[]; }; +struct c1 c1 = { 1, { 2, 3, 4 } }; + +struct c2 { int c; struct c1 c1; }; +struct c2 c2 = { 1, { 2, { 3, 4, 5 }}}; + +#elif defined test_var_array3 +/* similar to test_var_array2 but with string initializers */ +struct A { int a; char b[]; }; +struct A a = { 1, "1" }; +struct B { struct A a; }; +struct B b = { { 1, "1" } }; +/******************************************************************/ +#elif defined test_default_int_type +n; // warn +f(); // don't warn + +#elif defined test_invalid_global_stmtexpr +n[sizeof({3;})]; // crashed in block() due to missing local scope + +#elif defined test_invalid_tokckill +f(){"12"3;} // second const token killed the value of the first + +/******************************************************************/ +#elif defined test_duplicate_member +struct S { + int a, a; +}; +#elif defined test_duplicate_member_anon +struct S1 { + int b; + struct { + int b; + } c; +}; +struct S2 { + int d; + struct { + int d; + }; +}; + +/******************************************************************/ +#elif defined test_conflicting_array_definition +extern int array[2]; +int array[] = { 1, 2, 3 }; + +#elif defined test_incompatible_local_redef +void foo (void) +{ + typedef int localfunctype (int); + extern localfunctype func2; + typedef void localfunctype (int, int); +} + +#elif defined test_cast_from_void +void v() {} +int f() { return v(); } + +#elif defined test_switch_W1 || defined test_switch_W2 \ + || defined test_switch_W3 || defined test_switch_W4 +#if defined test_switch_W1 +#pragma comment(option, "-Wall") +#elif defined test_switch_W2 +#pragma comment(option, "-Wunsupported -Wno-implicit-function-declaration -Wstuff") +#elif defined test_switch_W3 +#pragma comment(option, "-Wwrite-strings -Werror=discarded-qualifiers") +#elif defined test_switch_W4 +#pragma comment(option, "-Wunsupported -Wno-error=implicit-function-declaration -Werror") +#endif +void func() +{ + char *ccp = "123"; + fink(); +} +__attribute__((stuff)) int fink() {return 0;} + +#elif defined test_invalid_funcparam_1 +void func(int a, int b, int a); + +#elif defined test_invalid_funcparam_2 +void func(int a, int if); + +#elif defined test_array_funcparam +int amain(int argc, char *argv[static argc + 1]) +{ + int i; + int printf(const char*, ...); + for (i = 0; i < argc; ++i) + printf("arg[%d] = \"%s\"\n", i, argv[i]); + return 0; +} +int main() +{ + return amain(2, (char *[]){ "X", "Y", 0 }); +} + +#elif defined test_return_from_statement_expr +int f() { ({ return 78; }); } +int main() { return f(); } + +/******************************************************************/ + +#elif defined test_illegal_unicode +int main() { + char *str = "\Uffffffff"; +} + +#elif defined test_error_string +#error \123\\ +456 + +#endif diff --git a/tinycc/tests/tests2/60_errors_and_warnings.expect b/tinycc/tests/tests2/60_errors_and_warnings.expect new file mode 100644 index 0000000..9a95e93 --- /dev/null +++ b/tinycc/tests/tests2/60_errors_and_warnings.expect @@ -0,0 +1,230 @@ +[test_56_btype_excess_1] +60_errors_and_warnings.c:2: error: too many basic types + +[test_57_btype_excess_2] +60_errors_and_warnings.c:5: error: too many basic types + +[test_58_function_redefinition] +60_errors_and_warnings.c:9: error: redefinition of 'f' + +[test_global_redefinition] +60_errors_and_warnings.c:14: error: redefinition of 'xxx' + +[test_59_function_array] +60_errors_and_warnings.c:17: error: declaration of an array of functions + +[test_60_enum_redefinition] +60_errors_and_warnings.c:21: error: struct/union/enum already defined + +[test_62_enumerator_redefinition] +60_errors_and_warnings.c:26: error: redefinition of enumerator 'RED' + +[test_63_local_enumerator_redefinition] +[returns 1] + +[test_61_undefined_enum] +60_errors_and_warnings.c:46: error: unknown type size + +[test_74_non_const_init] +60_errors_and_warnings.c:49: error: initializer element is not constant + +[test_pointer_assignment] +60_errors_and_warnings.c:79: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:82: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:86: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:88: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:91: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:92: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:94: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:95: warning: assignment from incompatible pointer type +60_errors_and_warnings.c:98: warning: assignment discards qualifiers from pointer target type +60_errors_and_warnings.c:99: warning: assignment discards qualifiers from pointer target type +60_errors_and_warnings.c:103: warning: assignment discards qualifiers from pointer target type +60_errors_and_warnings.c:104: warning: assignment discards qualifiers from pointer target type +60_errors_and_warnings.c:109: warning: assignment of read-only location + +[test_enum_compat] +60_errors_and_warnings.c:119: error: incompatible types for redefinition of 'f3' + +[test_enum_compat_2] +60_errors_and_warnings.c:126: error: incompatible types for redefinition of 'f4' + +[test_ptr_to_str] +60_errors_and_warnings.c:129: error: type 'const int **' does not match any association + +[test_fnptr_to_str] +60_errors_and_warnings.c:131: error: type 'int (*(*)(float, char))(double, int)' does not match any association + +[test_array_to_str] +60_errors_and_warnings.c:133: error: type 'int (*)[3]' does not match any association + +[test_duplicate_def_1] +60_errors_and_warnings.c:135: error: redefinition of 'L' + +[test_duplicate_def_2] +60_errors_and_warnings.c:138: error: redeclaration of 'L' + +[test_abstract_decls] +60_errors_and_warnings.c:148: error: identifier expected + +[test_invalid_1] +60_errors_and_warnings.c:153: error: identifier expected + +[test_invalid_2] +60_errors_and_warnings.c:156: error: ';' expected (got "{") + +[test_invalid_3] +60_errors_and_warnings.c:160: error: ',' expected (got "a") + +[test_invalid_4] +60_errors_and_warnings.c:164: error: division by zero in constant + +[test_conflicting_types] +60_errors_and_warnings.c:170: error: incompatible types for redefinition of 'i' + +[test_nested_types] +60_errors_and_warnings.c:177: error: struct/union/enum already defined + +[test_vla_1] +60_errors_and_warnings.c:184: error: need explicit inner array size in VLAs + +[test_invalid_alignas] +60_errors_and_warnings.c:188: error: identifier expected + +[test_static_assert] +60_errors_and_warnings.c:194: error: ONE is not 1 + +[test_static_assert_2] +60_errors_and_warnings.c:198: error: 0 is 0 + +[test_static_assert_c2x] +60_errors_and_warnings.c:202: error: _Static_assert fail + +[test_static_assert_empty_string] +60_errors_and_warnings.c:205: error: + +[test_void_array] +60_errors_and_warnings.c:208: error: declaration of an array of incomplete type elements + +[test_incomplete_enum_array] +60_errors_and_warnings.c:211: error: declaration of an array of incomplete type elements + +[test_incomplete_struct_array] +60_errors_and_warnings.c:214: error: declaration of an array of incomplete type elements + +[test_const_fun_array] +60_errors_and_warnings.c:218: error: declaration of an array of functions + +[test_incomplete_array_array] + +[test_extern_array] +60_errors_and_warnings.c:234: error: incompatible types for redefinition of 'x' + +[test_func_1] +hello: a = 123 + +[test_func_2] +hello: a = 123 + +[test_func_3] +60_errors_and_warnings.c:264: warning: static storage ignored for redefinition of 'hello' +hello: a = 123 + +[test_func_4] +hello: a = 123 + +[test_func_5] +60_errors_and_warnings.c:264: error: incompatible types for redefinition of 'hello' + +[test_func_6] +60_errors_and_warnings.c:252: error: function without file scope cannot be static + +[test_var_1] +main : 1 ; 1 +main : 2 ; 2 +bar : 3 ; 3 + +[test_var_2] +main : 1 ; 1 +main : 2 ; 2 +bar : 3 ; 3 + +[test_var_3] +60_errors_and_warnings.c:296: error: incompatible types for redefinition of 'xxx' + +[test_var_4] + +[test_long_double_type_for_win32] +60_errors_and_warnings.c:327: warning: assignment from incompatible pointer type + +[test_stray_backslash] +60_errors_and_warnings.c:333: error: stray '\' in program + +[test_stray_backslash2] +\n + +[test_var_array] +60_errors_and_warnings.c:348: error: flexible array has zero size in this context + +[test_var_array2] +60_errors_and_warnings.c:358: error: flexible array has zero size in this context + +[test_var_array3] +60_errors_and_warnings.c:365: error: flexible array has zero size in this context + +[test_default_int_type] +60_errors_and_warnings.c:368: warning: type defaults to int + +[test_invalid_global_stmtexpr] +60_errors_and_warnings.c:372: error: statement expression outside of function + +[test_invalid_tokckill] +60_errors_and_warnings.c:375: error: ';' expected (got "3") + +[test_duplicate_member] +60_errors_and_warnings.c:381: error: duplicate member 'a' + +[test_duplicate_member_anon] +60_errors_and_warnings.c:394: error: duplicate member 'd' + +[test_conflicting_array_definition] +60_errors_and_warnings.c:399: error: incompatible types for redefinition of 'array' + +[test_incompatible_local_redef] +60_errors_and_warnings.c:406: error: incompatible redefinition of 'localfunctype' + +[test_cast_from_void] +60_errors_and_warnings.c:411: error: cannot convert 'void' to 'int' + +[test_switch_W1] +60_errors_and_warnings.c:427: warning: implicit declaration of function 'fink' + +[test_switch_W2] +60_errors_and_warnings.c:418: warning: unsupported option '-Wstuff' +60_errors_and_warnings.c:429: warning: 'stuff' attribute ignored + +[test_switch_W3] +60_errors_and_warnings.c:426: error: assignment discards qualifiers from pointer target type + +[test_switch_W4] +60_errors_and_warnings.c:427: warning: implicit declaration of function 'fink' +60_errors_and_warnings.c:429: error: 'stuff' attribute ignored + +[test_invalid_funcparam_1] +60_errors_and_warnings.c:432: error: redeclaration of 'a' + +[test_invalid_funcparam_2] +60_errors_and_warnings.c:435: error: identifier expected + +[test_array_funcparam] +arg[0] = "X" +arg[1] = "Y" + +[test_return_from_statement_expr] +[returns 78] + +[test_illegal_unicode] +60_errors_and_warnings.c:459: error: 0xffffffff is not a valid universal character + +[test_error_string] +60_errors_and_warnings.c:464: error: #error \123\456 diff --git a/tinycc/tests/tests2/61_integers.c b/tinycc/tests/tests2/61_integers.c new file mode 100644 index 0000000..de29b3c --- /dev/null +++ b/tinycc/tests/tests2/61_integers.c @@ -0,0 +1,70 @@ +#include <stdio.h> + +/* This was first introduced to test the ARM port */ + +#define UINT_MAX ((unsigned) -1) + +int main() +{ + printf("18/21=%u\n", 18/21); + printf("18%%21=%u\n", 18%21); + printf("41/21=%u\n", 41/21); + printf("41%%21=%u\n", 41%21); + printf("42/21=%u\n", 42/21); + printf("42%%21=%u\n", 42%21); + printf("43/21=%u\n", 43/21); + printf("43%%21=%u\n", 43%21); + printf("126/21=%u\n", 126/21); + printf("126%%21=%u\n", 126%21); + printf("131/21=%u\n", 131/21); + printf("131%%21=%u\n", 131%21); + printf("(UINT_MAX/2+3)/2=%u\n", (UINT_MAX/2+3)/2); + printf("(UINT_MAX/2+3)%%2=%u\n", (UINT_MAX/2+3)%2); + + printf("18/-21=%u\n", 18/-21); + printf("18%%-21=%u\n", 18%-21); + printf("41/-21=%u\n", 41/-21); + printf("41%%-21=%u\n", 41%-21); + printf("42/-21=%u\n", 42/-21); + printf("42%%-21=%u\n", 42%-21); + printf("43/-21=%u\n", 43/-21); + printf("43%%-21=%u\n", 43%-21); + printf("126/-21=%u\n", 126/-21); + printf("126%%-21=%u\n", 126%-21); + printf("131/-21=%u\n", 131/-21); + printf("131%%-21=%u\n", 131%-21); + printf("(UINT_MAX/2+3)/-2=%u\n", (UINT_MAX/2+3)/-2); + printf("(UINT_MAX/2+3)%%-2=%u\n", (UINT_MAX/2+3)%-2); + + printf("-18/21=%u\n", -18/21); + printf("-18%%21=%u\n", -18%21); + printf("-41/21=%u\n", -41/21); + printf("-41%%21=%u\n", -41%21); + printf("-42/21=%u\n", -42/21); + printf("-42%%21=%u\n", -42%21); + printf("-43/21=%u\n", -43/21); + printf("-43%%21=%u\n", -43%21); + printf("-126/21=%u\n", -126/21); + printf("-126%%21=%u\n", -126%21); + printf("-131/21=%u\n", -131/21); + printf("-131%%21=%u\n", -131%21); + printf("-(UINT_MAX/2+3)/2=%u\n", (0-(UINT_MAX/2+3))/2); + printf("-(UINT_MAX/2+3)%%2=%u\n", (0-(UINT_MAX/2+3))%2); + + printf("-18/-21=%u\n", -18/-21); + printf("-18%%-21=%u\n", -18%-21); + printf("-41/-21=%u\n", -41/-21); + printf("-41%%-21=%u\n", -41%-21); + printf("-42/-21=%u\n", -42/-21); + printf("-42%%-21=%u\n", -42%-21); + printf("-43/-21=%u\n", -43/-21); + printf("-43%%-21=%u\n", -43%-21); + printf("-126/-21=%u\n", -126/-21); + printf("-126%%-21=%u\n", -126%-21); + printf("-131/-21=%u\n", -131/-21); + printf("-131%%-21=%u\n", -131%-21); + printf("-(UINT_MAX/2+3)/-2=%u\n", (0-(UINT_MAX/2+3))/-2); + printf("-(UINT_MAX/2+3)%%-2=%u\n", (0-(UINT_MAX/2+3))%-2); + + return 0; +} diff --git a/tinycc/tests/tests2/61_integers.expect b/tinycc/tests/tests2/61_integers.expect new file mode 100644 index 0000000..22c8d1b --- /dev/null +++ b/tinycc/tests/tests2/61_integers.expect @@ -0,0 +1,56 @@ +18/21=0 +18%21=18 +41/21=1 +41%21=20 +42/21=2 +42%21=0 +43/21=2 +43%21=1 +126/21=6 +126%21=0 +131/21=6 +131%21=5 +(UINT_MAX/2+3)/2=1073741825 +(UINT_MAX/2+3)%2=0 +18/-21=0 +18%-21=18 +41/-21=4294967295 +41%-21=20 +42/-21=4294967294 +42%-21=0 +43/-21=4294967294 +43%-21=1 +126/-21=4294967290 +126%-21=0 +131/-21=4294967290 +131%-21=5 +(UINT_MAX/2+3)/-2=0 +(UINT_MAX/2+3)%-2=2147483650 +-18/21=0 +-18%21=4294967278 +-41/21=4294967295 +-41%21=4294967276 +-42/21=4294967294 +-42%21=0 +-43/21=4294967294 +-43%21=4294967295 +-126/21=4294967290 +-126%21=0 +-131/21=4294967290 +-131%21=4294967291 +-(UINT_MAX/2+3)/2=1073741823 +-(UINT_MAX/2+3)%2=0 +-18/-21=0 +-18%-21=4294967278 +-41/-21=1 +-41%-21=4294967276 +-42/-21=2 +-42%-21=0 +-43/-21=2 +-43%-21=4294967295 +-126/-21=6 +-126%-21=0 +-131/-21=6 +-131%-21=4294967291 +-(UINT_MAX/2+3)/-2=0 +-(UINT_MAX/2+3)%-2=2147483646 diff --git a/tinycc/tests/tests2/64_macro_nesting.c b/tinycc/tests/tests2/64_macro_nesting.c new file mode 100644 index 0000000..676e5d3 --- /dev/null +++ b/tinycc/tests/tests2/64_macro_nesting.c @@ -0,0 +1,12 @@ +#include <stdio.h> // printf() + +#define CAT2(a,b) a##b +#define CAT(a,b) CAT2(a,b) +#define AB(x) CAT(x,y) + +int main(void) +{ + int xy = 42; + printf("%d\n", CAT(A,B)(x)); + return 0; +} diff --git a/tinycc/tests/tests2/64_macro_nesting.expect b/tinycc/tests/tests2/64_macro_nesting.expect new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/tinycc/tests/tests2/64_macro_nesting.expect @@ -0,0 +1 @@ +42 diff --git a/tinycc/tests/tests2/67_macro_concat.c b/tinycc/tests/tests2/67_macro_concat.c new file mode 100644 index 0000000..c580d3a --- /dev/null +++ b/tinycc/tests/tests2/67_macro_concat.c @@ -0,0 +1,14 @@ +#include <stdio.h> + +#define P(A,B) A ## B ; bob +#define Q(A,B) A ## B+ + +int main(void) +{ + int bob, jim = 21; + bob = P(jim,) *= 2; + printf("jim: %d, bob: %d\n", jim, bob); + jim = 60 Q(+,)3; + printf("jim: %d\n", jim); + return 0; +} diff --git a/tinycc/tests/tests2/67_macro_concat.expect b/tinycc/tests/tests2/67_macro_concat.expect new file mode 100644 index 0000000..8386c2d --- /dev/null +++ b/tinycc/tests/tests2/67_macro_concat.expect @@ -0,0 +1,2 @@ +jim: 21, bob: 42 +jim: 63 diff --git a/tinycc/tests/tests2/70_floating_point_literals.c b/tinycc/tests/tests2/70_floating_point_literals.c new file mode 100644 index 0000000..012fb4f --- /dev/null +++ b/tinycc/tests/tests2/70_floating_point_literals.c @@ -0,0 +1,77 @@ +#include <stdio.h> + +int main() +{ + /* decimal floating constant */ + float fa0 = .123f; + float fa1 = .123E12F; + float fa2 = .123e-12f; + float fa3 = .123e+12f; + printf("%f\n%f\n%f\n%f\n\n", fa0, fa1, fa2, fa3); + + float fb0 = 123.123f; + float fb1 = 123.123E12F; + float fb2 = 123.123e-12f; + float fb3 = 123.123e+12f; + printf("%f\n%f\n%f\n%f\n\n", fb0, fb1, fb2, fb3); + + float fc0 = 123.f; + float fc1 = 123.E12F; + float fc2 = 123.e-12f; + float fc3 = 123.e+12f; + printf("%f\n%f\n%f\n%f\n\n", fc0, fc1, fc2, fc3); + + float fd0 = 123E12F; + float fd1 = 123e-12f; + float fd2 = 123e+12f; + printf("%f\n%f\n%f\n\n", fd0, fd1, fd2); + printf("\n"); + + /* hexadecimal floating constant */ + double da0 = 0X.1ACP12; + double da1 = 0x.1acp-12; + double da2 = 0x.1acp+12; + printf("%f\n%f\n%f\n\n", da0, da1, da2); + + double db0 = 0X1AC.BDP12; + double db1 = 0x1ac.bdp-12; + double db2 = 0x1ac.dbp+12; + printf("%f\n%f\n%f\n\n", db0, db1, db2); + + double dc0 = 0X1AC.P12; + double dc1 = 0x1ac.p-12; + double dc2 = 0x1ac.p+12; + printf("%f\n%f\n%f\n\n", dc0, dc1, dc2); + + double dd0 = 0X1ACP12; + double dd1 = 0x1acp-12; + double dd2 = 0x1acp+12; + printf("%f\n%f\n%f\n\n", dd0, dd1, dd2); + printf("\n"); + +#ifdef __TINYC__ + /* TCC extension + binary floating constant */ + long double la0 = 0B.110101100P12L; + long double la1 = 0b.110101100p-12l; + long double la2 = 0b.110101100p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", la0, la1, la2); + + long double lb0 = 0B110101100.10111101P12L; + long double lb1 = 0b110101100.10111101p-12l; + long double lb2 = 0b110101100.10111101p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", lb0, lb1, lb2); + + long double lc0 = 0B110101100.P12L; + long double lc1 = 0b110101100.p-12l; + long double lc2 = 0b110101100.p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", lc0, lc1, lc2); + + long double ld0 = 0B110101100P12L; + long double ld1 = 0b110101100p-12l; + long double ld2 = 0b110101100p+12l; + printf("%Lf\n%Lf\n%Lf\n\n", ld0, ld1, ld2); +#endif + + return 0; +} diff --git a/tinycc/tests/tests2/70_floating_point_literals.expect b/tinycc/tests/tests2/70_floating_point_literals.expect new file mode 100644 index 0000000..7eb1efb --- /dev/null +++ b/tinycc/tests/tests2/70_floating_point_literals.expect @@ -0,0 +1,53 @@ +0.123000 +122999996416.000000 +0.000000 +122999996416.000000 + +123.123001 +123122997002240.000000 +0.000000 +123122997002240.000000 + +123.000000 +123000003231744.000000 +0.000000 +123000003231744.000000 + +123000003231744.000000 +0.000000 +123000003231744.000000 + + +428.000000 +0.000026 +428.000000 + +1756112.000000 +0.104672 +1756592.000000 + +1753088.000000 +0.104492 +1753088.000000 + +1753088.000000 +0.104492 +1753088.000000 + + +3424.000000 +0.000204 +3424.000000 + +1756112.000000 +0.104672 +1756112.000000 + +1753088.000000 +0.104492 +1753088.000000 + +1753088.000000 +0.104492 +1753088.000000 + diff --git a/tinycc/tests/tests2/71_macro_empty_arg.c b/tinycc/tests/tests2/71_macro_empty_arg.c new file mode 100644 index 0000000..f0d3511 --- /dev/null +++ b/tinycc/tests/tests2/71_macro_empty_arg.c @@ -0,0 +1,9 @@ +#include <stdio.h> + +#define T(a,b,c) a b c + +int main(void) +{ + printf("%d", T(1,+,2) T(+,,) T(,2,*) T(,7,) T(,,)); + return 0; +} diff --git a/tinycc/tests/tests2/71_macro_empty_arg.expect b/tinycc/tests/tests2/71_macro_empty_arg.expect new file mode 100644 index 0000000..98d9bcb --- /dev/null +++ b/tinycc/tests/tests2/71_macro_empty_arg.expect @@ -0,0 +1 @@ +17 diff --git a/tinycc/tests/tests2/72_long_long_constant.c b/tinycc/tests/tests2/72_long_long_constant.c new file mode 100644 index 0000000..6608213 --- /dev/null +++ b/tinycc/tests/tests2/72_long_long_constant.c @@ -0,0 +1,19 @@ +#include <stdio.h> + +int main() +{ + long long int res = 0; + + if (res < -2147483648LL) { + printf("Error: 0 < -2147483648\n"); + return 1; + } + else + if (2147483647LL < res) { + printf("Error: 2147483647 < 0\n"); + return 2; + } + else + printf("long long constant test ok.\n"); + return 0; +} diff --git a/tinycc/tests/tests2/72_long_long_constant.expect b/tinycc/tests/tests2/72_long_long_constant.expect new file mode 100644 index 0000000..dda9e66 --- /dev/null +++ b/tinycc/tests/tests2/72_long_long_constant.expect @@ -0,0 +1 @@ +long long constant test ok. diff --git a/tinycc/tests/tests2/73_arm64.c b/tinycc/tests/tests2/73_arm64.c new file mode 100644 index 0000000..855c476 --- /dev/null +++ b/tinycc/tests/tests2/73_arm64.c @@ -0,0 +1,538 @@ +// This program is designed to test some arm64-specific things, such as the +// calling convention, but should give the same results on any architecture. + +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> + +struct s1 { char x[1]; } s1 = { "0" }; +struct s2 { char x[2]; } s2 = { "12" }; +struct s3 { char x[3]; } s3 = { "345" }; +struct s4 { char x[4]; } s4 = { "6789" }; +struct s5 { char x[5]; } s5 = { "abcde" }; +struct s6 { char x[6]; } s6 = { "fghijk" }; +struct s7 { char x[7]; } s7 = { "lmnopqr" }; +struct s8 { char x[8]; } s8 = { "stuvwxyz" }; +struct s9 { char x[9]; } s9 = { "ABCDEFGHI" }; +struct s10 { char x[10]; } s10 = { "JKLMNOPQRS" }; +struct s11 { char x[11]; } s11 = { "TUVWXYZ0123" }; +struct s12 { char x[12]; } s12 = { "456789abcdef" }; +struct s13 { char x[13]; } s13 = { "ghijklmnopqrs" }; +struct s14 { char x[14]; } s14 = { "tuvwxyzABCDEFG" }; +struct s15 { char x[15]; } s15 = { "HIJKLMNOPQRSTUV" }; +struct s16 { char x[16]; } s16 = { "WXYZ0123456789ab" }; +struct s17 { char x[17]; } s17 = { "cdefghijklmnopqrs" }; + +struct hfa11 { float a; } hfa11 = { 11.1 }; +struct hfa12 { float a, b; } hfa12 = { 12.1, 12.2 }; +struct hfa13 { float a, b, c; } hfa13 = { 13.1, 13.2, 13.3 }; +struct hfa14 { float a, b, c, d; } hfa14 = { 14.1, 14.2, 14.3, 14.4 }; + +struct hfa21 { double a; } hfa21 = { 21.1 }; +struct hfa22 { double a, b; } hfa22 = { 22.1, 22.2 }; +struct hfa23 { double a, b, c; } hfa23 = { 23.1, 23.2, 23.3 }; +struct hfa24 { double a, b, c, d; } hfa24 = { 24.1, 24.2, 24.3, 24.4 }; + +struct hfa31 { long double a; } hfa31 = { 31.1 }; +struct hfa32 { long double a, b; } hfa32 = { 32.1, 32.2 }; +struct hfa33 { long double a, b, c; } hfa33 = { 33.1, 33.2, 33.3 }; +struct hfa34 { long double a, b, c, d; } hfa34 = { 34.1, 34.2, 34.3, 34.4 }; + +void fa_s1(struct s1 a) { printf("%.1s\n", a.x); } +void fa_s2(struct s2 a) { printf("%.2s\n", a.x); } +void fa_s3(struct s3 a) { printf("%.3s\n", a.x); } +void fa_s4(struct s4 a) { printf("%.4s\n", a.x); } +void fa_s5(struct s5 a) { printf("%.5s\n", a.x); } +void fa_s6(struct s6 a) { printf("%.6s\n", a.x); } +void fa_s7(struct s7 a) { printf("%.7s\n", a.x); } +void fa_s8(struct s8 a) { printf("%.8s\n", a.x); } +void fa_s9(struct s9 a) { printf("%.9s\n", a.x); } +void fa_s10(struct s10 a) { printf("%.10s\n", a.x); } +void fa_s11(struct s11 a) { printf("%.11s\n", a.x); } +void fa_s12(struct s12 a) { printf("%.12s\n", a.x); } +void fa_s13(struct s13 a) { printf("%.13s\n", a.x); } +void fa_s14(struct s14 a) { printf("%.14s\n", a.x); } +void fa_s15(struct s15 a) { printf("%.15s\n", a.x); } +void fa_s16(struct s16 a) { printf("%.16s\n", a.x); } +void fa_s17(struct s17 a) { printf("%.17s\n", a.x); } + +void fa_hfa11(struct hfa11 a) +{ printf("%.1f\n", a.a); } +void fa_hfa12(struct hfa12 a) +{ printf("%.1f %.1f\n", a.a, a.a); } +void fa_hfa13(struct hfa13 a) +{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); } +void fa_hfa14(struct hfa14 a) +{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); } + +void fa_hfa21(struct hfa21 a) +{ printf("%.1f\n", a.a); } +void fa_hfa22(struct hfa22 a) +{ printf("%.1f %.1f\n", a.a, a.a); } +void fa_hfa23(struct hfa23 a) +{ printf("%.1f %.1f %.1f\n", a.a, a.b, a.c); } +void fa_hfa24(struct hfa24 a) +{ printf("%.1f %.1f %.1f %.1f\n", a.a, a.b, a.c, a.d); } + +void fa_hfa31(struct hfa31 a) +{ printf("%.1Lf\n", a.a); } +void fa_hfa32(struct hfa32 a) +{ printf("%.1Lf %.1Lf\n", a.a, a.a); } +void fa_hfa33(struct hfa33 a) +{ printf("%.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c); } +void fa_hfa34(struct hfa34 a) +{ printf("%.1Lf %.1Lf %.1Lf %.1Lf\n", a.a, a.b, a.c, a.d); } + +void fa1(struct s8 a, struct s9 b, struct s10 c, struct s11 d, + struct s12 e, struct s13 f) +{ + printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x); +} + +void fa2(struct s9 a, struct s10 b, struct s11 c, struct s12 d, + struct s13 e, struct s14 f) +{ + printf("%.3s %.3s %.3s %.3s %.3s %.3s\n", a.x, b.x, c.x, d.x, e.x, f.x); +} + +void fa3(struct hfa14 a, struct hfa23 b, struct hfa32 c) +{ + printf("%.1f %.1f %.1f %.1f %.1Lf %.1Lf\n", + a.a, a.d, b.a, b.c, c.a, c.b); +} + +void fa4(struct s1 a, struct hfa14 b, struct s2 c, struct hfa24 d, + struct s3 e, struct hfa34 f) +{ + printf("%.1s %.1f %.1f %.2s %.1f %.1f %.3s %.1Lf %.1Lf\n", + a.x, b.a, b.d, c.x, d.a, d.d, e.x, f.a, f.d); +} + +void arg(void) +{ + printf("Arguments:\n"); + fa_s1(s1); + fa_s2(s2); + fa_s3(s3); + fa_s4(s4); + fa_s5(s5); + fa_s6(s6); + fa_s7(s7); + fa_s8(s8); + fa_s9(s9); + fa_s10(s10); + fa_s11(s11); + fa_s12(s12); + fa_s13(s13); + fa_s14(s14); + fa_s15(s15); + fa_s16(s16); + fa_s17(s17); + fa_hfa11(hfa11); + fa_hfa12(hfa12); + fa_hfa13(hfa13); + fa_hfa14(hfa14); + fa_hfa21(hfa21); + fa_hfa22(hfa22); + fa_hfa23(hfa23); + fa_hfa24(hfa24); + fa_hfa31(hfa31); + fa_hfa32(hfa32); + fa_hfa33(hfa33); + fa_hfa34(hfa34); + fa1(s8, s9, s10, s11, s12, s13); + fa2(s9, s10, s11, s12, s13, s14); + fa3(hfa14, hfa23, hfa32); + fa4(s1, hfa14, s2, hfa24, s3, hfa34); +} + +struct s1 fr_s1(void) { return s1; } +struct s2 fr_s2(void) { return s2; } +struct s3 fr_s3(void) { return s3; } +struct s4 fr_s4(void) { return s4; } +struct s5 fr_s5(void) { return s5; } +struct s6 fr_s6(void) { return s6; } +struct s7 fr_s7(void) { return s7; } +struct s8 fr_s8(void) { return s8; } +struct s9 fr_s9(void) { return s9; } +struct s10 fr_s10(void) { return s10; } +struct s11 fr_s11(void) { return s11; } +struct s12 fr_s12(void) { return s12; } +struct s13 fr_s13(void) { return s13; } +struct s14 fr_s14(void) { return s14; } +struct s15 fr_s15(void) { return s15; } +struct s16 fr_s16(void) { return s16; } +struct s17 fr_s17(void) { return s17; } + +struct hfa11 fr_hfa11(void) { return hfa11; } +struct hfa12 fr_hfa12(void) { return hfa12; } +struct hfa13 fr_hfa13(void) { return hfa13; } +struct hfa14 fr_hfa14(void) { return hfa14; } + +struct hfa21 fr_hfa21(void) { return hfa21; } +struct hfa22 fr_hfa22(void) { return hfa22; } +struct hfa23 fr_hfa23(void) { return hfa23; } +struct hfa24 fr_hfa24(void) { return hfa24; } + +struct hfa31 fr_hfa31(void) { return hfa31; } +struct hfa32 fr_hfa32(void) { return hfa32; } +struct hfa33 fr_hfa33(void) { return hfa33; } +struct hfa34 fr_hfa34(void) { return hfa34; } + +void ret(void) +{ + struct s1 t1 = fr_s1(); + struct s2 t2 = fr_s2(); + struct s3 t3 = fr_s3(); + struct s4 t4 = fr_s4(); + struct s5 t5 = fr_s5(); + struct s6 t6 = fr_s6(); + struct s7 t7 = fr_s7(); + struct s8 t8 = fr_s8(); + struct s9 t9 = fr_s9(); + struct s10 t10 = fr_s10(); + struct s11 t11 = fr_s11(); + struct s12 t12 = fr_s12(); + struct s13 t13 = fr_s13(); + struct s14 t14 = fr_s14(); + struct s15 t15 = fr_s15(); + struct s16 t16 = fr_s16(); + struct s17 t17 = fr_s17(); + printf("Return values:\n"); + printf("%.1s\n", t1.x); + printf("%.2s\n", t2.x); + printf("%.3s\n", t3.x); + printf("%.4s\n", t4.x); + printf("%.5s\n", t5.x); + printf("%.6s\n", t6.x); + printf("%.7s\n", t7.x); + printf("%.8s\n", t8.x); + printf("%.9s\n", t9.x); + printf("%.10s\n", t10.x); + printf("%.11s\n", t11.x); + printf("%.12s\n", t12.x); + printf("%.13s\n", t13.x); + printf("%.14s\n", t14.x); + printf("%.15s\n", t15.x); + printf("%.16s\n", t16.x); + printf("%.17s\n", t17.x); + printf("%.1f\n", fr_hfa11().a); + printf("%.1f %.1f\n", fr_hfa12().a, fr_hfa12().b); + printf("%.1f %.1f\n", fr_hfa13().a, fr_hfa13().c); + printf("%.1f %.1f\n", fr_hfa14().a, fr_hfa14().d); + printf("%.1f\n", fr_hfa21().a); + printf("%.1f %.1f\n", fr_hfa22().a, fr_hfa22().b); + printf("%.1f %.1f\n", fr_hfa23().a, fr_hfa23().c); + printf("%.1f %.1f\n", fr_hfa24().a, fr_hfa24().d); + printf("%.1Lf\n", fr_hfa31().a); + printf("%.1Lf %.1Lf\n", fr_hfa32().a, fr_hfa32().b); + printf("%.1Lf %.1Lf\n", fr_hfa33().a, fr_hfa33().c); + printf("%.1Lf %.1Lf\n", fr_hfa34().a, fr_hfa34().d); +} + +void* +va_arg_with_struct_ptr(va_list ap) { + /* + * This was a BUG identified with FFTW-3.3.8 on arm64. + * The test case only checks it compiles. + */ + struct X { int _x; }; + struct X *x = va_arg(ap, struct X *); + return x; +} + +int match(const char **s, const char *f) +{ + const char *p = *s; + for (p = *s; *f && *f == *p; f++, p++) + ; + if (!*f) { + *s = p - 1; + return 1; + } + return 0; +} + +void myprintf(const char *format, ...) +{ + const char *s; + va_list ap; + va_start(ap, format); + for (s = format; *s; s++) { + if (match(&s, "%7s")) { + struct s7 t7 = va_arg(ap, struct s7); + printf("%.7s", t7.x); + } + else if (match(&s, "%9s")) { + struct s9 t9 = va_arg(ap, struct s9); + printf("%.9s", t9.x); + } + else if (match(&s, "%hfa11")) { + struct hfa11 x = va_arg(ap, struct hfa11); + printf("%.1f,%.1f", x.a, x.a); + } + else if (match(&s, "%hfa12")) { + struct hfa12 x = va_arg(ap, struct hfa12); + printf("%.1f,%.1f", x.a, x.b); + } + else if (match(&s, "%hfa13")) { + struct hfa13 x = va_arg(ap, struct hfa13); + printf("%.1f,%.1f", x.a, x.c); + } + else if (match(&s, "%hfa14")) { + struct hfa14 x = va_arg(ap, struct hfa14); + printf("%.1f,%.1f", x.a, x.d); + } + else if (match(&s, "%hfa21")) { + struct hfa21 x = va_arg(ap, struct hfa21); + printf("%.1f,%.1f", x.a, x.a); + } + else if (match(&s, "%hfa22")) { + struct hfa22 x = va_arg(ap, struct hfa22); + printf("%.1f,%.1f", x.a, x.b); + } + else if (match(&s, "%hfa23")) { + struct hfa23 x = va_arg(ap, struct hfa23); + printf("%.1f,%.1f", x.a, x.c); + } + else if (match(&s, "%hfa24")) { + struct hfa24 x = va_arg(ap, struct hfa24); + printf("%.1f,%.1f", x.a, x.d); + } + else if (match(&s, "%hfa31")) { + struct hfa31 x = va_arg(ap, struct hfa31); + printf("%.1Lf,%.1Lf", x.a, x.a); + } + else if (match(&s, "%hfa32")) { + struct hfa32 x = va_arg(ap, struct hfa32); + printf("%.1Lf,%.1Lf", x.a, x.b); + } + else if (match(&s, "%hfa33")) { + struct hfa33 x = va_arg(ap, struct hfa33); + printf("%.1Lf,%.1Lf", x.a, x.c); + } + else if (match(&s, "%hfa34")) { + struct hfa34 x = va_arg(ap, struct hfa34); + printf("%.1Lf,%.1Lf", x.a, x.d); + } + else + putchar(*s); + } + putchar('\n'); +} + +void stdarg(void) +{ + printf("stdarg:\n"); + myprintf("%9s %9s %9s %9s %9s %9s", s9, s9, s9, s9, s9, s9); + myprintf("%7s %9s %9s %9s %9s %9s", s7, s9, s9, s9, s9, s9); + + myprintf("HFA long double:"); + myprintf("%hfa34 %hfa34 %hfa34 %hfa34", hfa34, hfa34, hfa34, hfa34); + myprintf("%hfa33 %hfa34 %hfa34 %hfa34", hfa33, hfa34, hfa34, hfa34); + myprintf("%hfa32 %hfa34 %hfa34 %hfa34", hfa32, hfa34, hfa34, hfa34); + myprintf("%hfa31 %hfa34 %hfa34 %hfa34", hfa31, hfa34, hfa34, hfa34); + + myprintf("%hfa32 %hfa33 %hfa33 %hfa33 %hfa33", + hfa32, hfa33, hfa33, hfa33, hfa33); + myprintf("%hfa31 %hfa33 %hfa33 %hfa33 %hfa33", + hfa31, hfa33, hfa33, hfa33, hfa33); + myprintf("%hfa33 %hfa33 %hfa33 %hfa33", + hfa33, hfa33, hfa33, hfa33); + + myprintf("%hfa34 %hfa32 %hfa32 %hfa32 %hfa32", + hfa34, hfa32, hfa32, hfa32, hfa32); + myprintf("%hfa33 %hfa32 %hfa32 %hfa32 %hfa32", + hfa33, hfa32, hfa32, hfa32, hfa32); + + myprintf("%hfa34 %hfa32 %hfa31 %hfa31 %hfa31 %hfa31", + hfa34, hfa32, hfa31, hfa31, hfa31, hfa31); + + myprintf("HFA double:"); + myprintf("%hfa24 %hfa24 %hfa24 %hfa24", hfa24, hfa24, hfa24, hfa24); + myprintf("%hfa23 %hfa24 %hfa24 %hfa24", hfa23, hfa24, hfa24, hfa24); + myprintf("%hfa22 %hfa24 %hfa24 %hfa24", hfa22, hfa24, hfa24, hfa24); + myprintf("%hfa21 %hfa24 %hfa24 %hfa24", hfa21, hfa24, hfa24, hfa24); + + myprintf("%hfa22 %hfa23 %hfa23 %hfa23 %hfa23", + hfa22, hfa23, hfa23, hfa23, hfa23); + myprintf("%hfa21 %hfa23 %hfa23 %hfa23 %hfa23", + hfa21, hfa23, hfa23, hfa23, hfa23); + myprintf("%hfa23 %hfa23 %hfa23 %hfa23", + hfa23, hfa23, hfa23, hfa23); + + myprintf("%hfa24 %hfa22 %hfa22 %hfa22 %hfa22", + hfa24, hfa22, hfa22, hfa22, hfa22); + myprintf("%hfa23 %hfa22 %hfa22 %hfa22 %hfa22", + hfa23, hfa22, hfa22, hfa22, hfa22); + + myprintf("%hfa24 %hfa22 %hfa21 %hfa21 %hfa21 %hfa21", + hfa24, hfa22, hfa21, hfa21, hfa21, hfa21); + + myprintf("HFA float:"); + myprintf("%hfa14 %hfa14 %hfa14 %hfa14", hfa14, hfa14, hfa14, hfa14); + myprintf("%hfa13 %hfa14 %hfa14 %hfa14", hfa13, hfa14, hfa14, hfa14); + myprintf("%hfa12 %hfa14 %hfa14 %hfa14", hfa12, hfa14, hfa14, hfa14); + myprintf("%hfa11 %hfa14 %hfa14 %hfa14", hfa11, hfa14, hfa14, hfa14); + + myprintf("%hfa12 %hfa13 %hfa13 %hfa13 %hfa13", + hfa12, hfa13, hfa13, hfa13, hfa13); + myprintf("%hfa11 %hfa13 %hfa13 %hfa13 %hfa13", + hfa11, hfa13, hfa13, hfa13, hfa13); + myprintf("%hfa13 %hfa13 %hfa13 %hfa13", + hfa13, hfa13, hfa13, hfa13); + + myprintf("%hfa14 %hfa12 %hfa12 %hfa12 %hfa12", + hfa14, hfa12, hfa12, hfa12, hfa12); + myprintf("%hfa13 %hfa12 %hfa12 %hfa12 %hfa12", + hfa13, hfa12, hfa12, hfa12, hfa12); + + myprintf("%hfa14 %hfa12 %hfa11 %hfa11 %hfa11 %hfa11", + hfa14, hfa12, hfa11, hfa11, hfa11, hfa11); +} + +void pll(unsigned long long x) +{ + printf("%llx\n", x); +} + +void movi(void) +{ + printf("MOVI:\n"); + pll(0); + pll(0xabcd); + pll(0xabcd0000); + pll(0xabcd00000000); + pll(0xabcd000000000000); + pll(0xffffabcd); + pll(0xabcdffff); + pll(0xffffffffffffabcd); + pll(0xffffffffabcdffff); + pll(0xffffabcdffffffff); + pll(0xabcdffffffffffff); + pll(0xaaaaaaaa); + pll(0x5555555555555555); + pll(0x77777777); + pll(0x3333333333333333); + pll(0xf8f8f8f8); + pll(0x1e1e1e1e1e1e1e1e); + pll(0x3f803f80); + pll(0x01ff01ff01ff01ff); + pll(0x007fffc0); + pll(0x03fff80003fff800); + pll(0x0007fffffffffe00); + + pll(0xabcd1234); + pll(0xabcd00001234); + pll(0xabcd000000001234); + pll(0xabcd12340000); + pll(0xabcd000012340000); + pll(0xabcd123400000000); + pll(0xffffffffabcd1234); + pll(0xffffabcdffff1234); + pll(0xabcdffffffff1234); + pll(0xffffabcd1234ffff); + pll(0xabcdffff1234ffff); + pll(0xabcd1234ffffffff); + + pll(0xffffef0123456789); + pll(0xabcdef012345ffff); + + pll(0xabcdef0123456789); +} + +static uint32_t addip0(uint32_t x) { return x + 0; } +static uint64_t sublp0(uint64_t x) { return x - 0; } +static uint32_t addip123(uint32_t x) { return x + 123; } +static uint64_t addlm123(uint64_t x) { return x + -123; } +static uint64_t sublp4095(uint64_t x) { return x - 4095; } +static uint32_t subim503808(uint32_t x) { return x - -503808; } +static uint64_t addp12345(uint64_t x) { return x + 12345; } +static uint32_t subp12345(uint32_t x) { return x - 12345; } + +static uint32_t mvni(uint32_t x) { return 0xffffffff - x; } +static uint64_t negl(uint64_t x) { return 0 - x; } +static uint32_t rsbi123(uint32_t x) { return 123 - x; } +static uint64_t rsbl123(uint64_t x) { return 123 - x; } + +static uint32_t andi0(uint32_t x) { return x & 0; } +static uint64_t andlm1(uint64_t x) { return x & -1; } +static uint64_t orrl0(uint64_t x) { return x | 0; } +static uint32_t orrim1(uint32_t x) { return x | -1; } +static uint32_t eori0(uint32_t x) { return x ^ 0; } +static uint64_t eorlm1(uint64_t x) { return x ^ -1; } +static uint32_t and0xf0(uint32_t x) { return x & 0xf0; } +static uint64_t orr0xf0(uint64_t x) { return x | 0xf0; } +static uint64_t eor0xf0(uint64_t x) { return x ^ 0xf0; } + +static uint32_t lsli0(uint32_t x) { return x << 0; } +static uint32_t lsri0(uint32_t x) { return x >> 0; } +static int64_t asrl0(int64_t x) { return x >> 0; } +static uint32_t lsli1(uint32_t x) { return x << 1; } +static uint32_t lsli31(uint32_t x) { return x << 31; } +static uint64_t lsll1(uint64_t x) { return x << 1; } +static uint64_t lsll63(uint64_t x) { return x << 63; } +static uint32_t lsri1(uint32_t x) { return x >> 1; } +static uint32_t lsri31(uint32_t x) { return x >> 31; } +static uint64_t lsrl1(uint64_t x) { return x >> 1; } +static uint64_t lsrl63(uint64_t x) { return x >> 63; } +static int32_t asri1(int32_t x) { return x >> 1; } +static int32_t asri31(int32_t x) { return x >> 31; } +static int64_t asrl1(int64_t x) { return x >> 1; } +static int64_t asrl63(int64_t x) { return x >> 63; } + +void opi(void) +{ + int x = 1000; + pll(addip0(x)); + pll(sublp0(x)); + pll(addip123(x)); + pll(addlm123(x)); + pll(sublp4095(x)); + pll(subim503808(x)); + pll(addp12345(x)); + pll(subp12345(x)); + pll(mvni(x)); + pll(negl(x)); + pll(rsbi123(x)); + pll(rsbl123(x)); + pll(andi0(x)); + pll(andlm1(x)); + pll(orrl0(x)); + pll(orrim1(x)); + pll(eori0(x)); + pll(eorlm1(x)); + pll(and0xf0(x)); + pll(orr0xf0(x)); + pll(eor0xf0(x)); + pll(lsli0(x)); + pll(lsri0(x)); + pll(asrl0(x)); + pll(lsli1(x)); + pll(lsli31(x)); + pll(lsll1(x)); + pll(lsll63(x)); + pll(lsri1(x)); + pll(lsri31(x)); + pll(lsrl1(x)); + pll(lsrl63(x)); + pll(asri1(x)); + pll(asri31(x)); + pll(asrl1(x)); + pll(asrl63(x)); +} + +void pcs(void) +{ + arg(); + ret(); + stdarg(); + movi(); + opi(); +} + +int main() +{ + pcs(); + return 0; +} diff --git a/tinycc/tests/tests2/73_arm64.expect b/tinycc/tests/tests2/73_arm64.expect new file mode 100644 index 0000000..7bdebd3 --- /dev/null +++ b/tinycc/tests/tests2/73_arm64.expect @@ -0,0 +1,174 @@ +Arguments: +0 +12 +345 +6789 +abcde +fghijk +lmnopqr +stuvwxyz +ABCDEFGHI +JKLMNOPQRS +TUVWXYZ0123 +456789abcdef +ghijklmnopqrs +tuvwxyzABCDEFG +HIJKLMNOPQRSTUV +WXYZ0123456789ab +cdefghijklmnopqrs +11.1 +12.1 12.1 +13.1 13.2 13.3 +14.1 14.2 14.3 14.4 +21.1 +22.1 22.1 +23.1 23.2 23.3 +24.1 24.2 24.3 24.4 +31.1 +32.1 32.1 +33.1 33.2 33.3 +34.1 34.2 34.3 34.4 +stu ABC JKL TUV 456 ghi +ABC JKL TUV 456 ghi tuv +14.1 14.4 23.1 23.3 32.1 32.2 +0 14.1 14.4 12 24.1 24.4 345 34.1 34.4 +Return values: +0 +12 +345 +6789 +abcde +fghijk +lmnopqr +stuvwxyz +ABCDEFGHI +JKLMNOPQRS +TUVWXYZ0123 +456789abcdef +ghijklmnopqrs +tuvwxyzABCDEFG +HIJKLMNOPQRSTUV +WXYZ0123456789ab +cdefghijklmnopqrs +11.1 +12.1 12.2 +13.1 13.3 +14.1 14.4 +21.1 +22.1 22.2 +23.1 23.3 +24.1 24.4 +31.1 +32.1 32.2 +33.1 33.3 +34.1 34.4 +stdarg: +ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI +lmnopqr ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI ABCDEFGHI +HFA long double: +34.1,34.4 34.1,34.4 34.1,34.4 34.1,34.4 +33.1,33.3 34.1,34.4 34.1,34.4 34.1,34.4 +32.1,32.2 34.1,34.4 34.1,34.4 34.1,34.4 +31.1,31.1 34.1,34.4 34.1,34.4 34.1,34.4 +32.1,32.2 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +31.1,31.1 33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +33.1,33.3 33.1,33.3 33.1,33.3 33.1,33.3 +34.1,34.4 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2 +33.1,33.3 32.1,32.2 32.1,32.2 32.1,32.2 32.1,32.2 +34.1,34.4 32.1,32.2 31.1,31.1 31.1,31.1 31.1,31.1 31.1,31.1 +HFA double: +24.1,24.4 24.1,24.4 24.1,24.4 24.1,24.4 +23.1,23.3 24.1,24.4 24.1,24.4 24.1,24.4 +22.1,22.2 24.1,24.4 24.1,24.4 24.1,24.4 +21.1,21.1 24.1,24.4 24.1,24.4 24.1,24.4 +22.1,22.2 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +21.1,21.1 23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +23.1,23.3 23.1,23.3 23.1,23.3 23.1,23.3 +24.1,24.4 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2 +23.1,23.3 22.1,22.2 22.1,22.2 22.1,22.2 22.1,22.2 +24.1,24.4 22.1,22.2 21.1,21.1 21.1,21.1 21.1,21.1 21.1,21.1 +HFA float: +14.1,14.4 14.1,14.4 14.1,14.4 14.1,14.4 +13.1,13.3 14.1,14.4 14.1,14.4 14.1,14.4 +12.1,12.2 14.1,14.4 14.1,14.4 14.1,14.4 +11.1,11.1 14.1,14.4 14.1,14.4 14.1,14.4 +12.1,12.2 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +11.1,11.1 13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +13.1,13.3 13.1,13.3 13.1,13.3 13.1,13.3 +14.1,14.4 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2 +13.1,13.3 12.1,12.2 12.1,12.2 12.1,12.2 12.1,12.2 +14.1,14.4 12.1,12.2 11.1,11.1 11.1,11.1 11.1,11.1 11.1,11.1 +MOVI: +0 +abcd +abcd0000 +abcd00000000 +abcd000000000000 +ffffabcd +abcdffff +ffffffffffffabcd +ffffffffabcdffff +ffffabcdffffffff +abcdffffffffffff +aaaaaaaa +5555555555555555 +77777777 +3333333333333333 +f8f8f8f8 +1e1e1e1e1e1e1e1e +3f803f80 +1ff01ff01ff01ff +7fffc0 +3fff80003fff800 +7fffffffffe00 +abcd1234 +abcd00001234 +abcd000000001234 +abcd12340000 +abcd000012340000 +abcd123400000000 +ffffffffabcd1234 +ffffabcdffff1234 +abcdffffffff1234 +ffffabcd1234ffff +abcdffff1234ffff +abcd1234ffffffff +ffffef0123456789 +abcdef012345ffff +abcdef0123456789 +3e8 +3e8 +463 +36d +fffffffffffff3e9 +7b3e8 +3421 +ffffd3af +fffffc17 +fffffffffffffc18 +fffffc93 +fffffffffffffc93 +0 +3e8 +3e8 +ffffffff +3e8 +fffffffffffffc17 +e0 +3f8 +318 +3e8 +3e8 +3e8 +7d0 +0 +7d0 +0 +1f4 +0 +1f4 +0 +1f4 +0 +1f4 +0 diff --git a/tinycc/tests/tests2/75_array_in_struct_init.c b/tinycc/tests/tests2/75_array_in_struct_init.c new file mode 100644 index 0000000..234e3c4 --- /dev/null +++ b/tinycc/tests/tests2/75_array_in_struct_init.c @@ -0,0 +1,33 @@ +#include <stdio.h> + +/* This test is a snippet from the J interpreter */ + +typedef long I; +typedef struct{I c[4];I b,e,k;} PT; + +PT cases[] = { + ((I)4194304L +(I)2097152L +(I)67108864L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), -1L, 1,2,1, + ((I)+4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L, (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 2,3,2, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,2, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)524288L, -1L, 1,2,1, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)1048576L, (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), 1,3,1, + ((I)4194304L +(I)2097152L +(I)67108864L)+( (I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)262144L, (I)262144L, 1,3,1, + ((I)4194304L +(I)2097152L +(I)67108864L), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 1,2,1, + (I)33554432L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L), (I)2097152L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), -1L, 0,2,1, + (I)67108864L, ((I)1048576L +(I)524288L +(I)262144L +(((I)1L +(I)256L +(I)4L +(I)8L +(I)16L +(I)64L +(I)128L +(I)268435456L +(I)536870912L +(I)1024L +(I)4096L +(I)8192L +(I)16384L)+((I)2L +(I)131072L +(I)2048L)+(I)32L +(I)32768L +(I)65536L)), (I)134217728L, -1L, 0,2,0, +}; + +int main() { + int i, j; + + for(j=0; j < sizeof(cases)/sizeof(cases[0]); j++) { + for(i=0; i < sizeof(cases->c)/sizeof(cases->c[0]); i++) + printf("cases[%d].c[%d]=%ld\n", j, i, cases[j].c[i]); + + printf("cases[%d].b=%ld\n", j, cases[j].b); + printf("cases[%d].e=%ld\n", j, cases[j].e); + printf("cases[%d].k=%ld\n", j, cases[j].k); + printf("\n"); + } + return 0; +} diff --git a/tinycc/tests/tests2/75_array_in_struct_init.expect b/tinycc/tests/tests2/75_array_in_struct_init.expect new file mode 100644 index 0000000..2b75aa5 --- /dev/null +++ b/tinycc/tests/tests2/75_array_in_struct_init.expect @@ -0,0 +1,72 @@ +cases[0].c[0]=73400320 +cases[0].c[1]=262144 +cases[0].c[2]=805567999 +cases[0].c[3]=-1 +cases[0].b=1 +cases[0].e=2 +cases[0].k=1 + +cases[1].c[0]=879754751 +cases[1].c[1]=262144 +cases[1].c[2]=262144 +cases[1].c[3]=805567999 +cases[1].b=2 +cases[1].e=3 +cases[1].k=2 + +cases[2].c[0]=879754751 +cases[2].c[1]=805567999 +cases[2].c[2]=262144 +cases[2].c[3]=805567999 +cases[2].b=1 +cases[2].e=3 +cases[2].k=2 + +cases[3].c[0]=879754751 +cases[3].c[1]=805830143 +cases[3].c[2]=524288 +cases[3].c[3]=-1 +cases[3].b=1 +cases[3].e=2 +cases[3].k=1 + +cases[4].c[0]=879754751 +cases[4].c[1]=805830143 +cases[4].c[2]=1048576 +cases[4].c[3]=805830143 +cases[4].b=1 +cases[4].e=3 +cases[4].k=1 + +cases[5].c[0]=879754751 +cases[5].c[1]=805830143 +cases[5].c[2]=262144 +cases[5].c[3]=262144 +cases[5].b=1 +cases[5].e=3 +cases[5].k=1 + +cases[6].c[0]=73400320 +cases[6].c[1]=807403007 +cases[6].c[2]=807403007 +cases[6].c[3]=-1 +cases[6].b=1 +cases[6].e=2 +cases[6].k=1 + +cases[7].c[0]=839122431 +cases[7].c[1]=2097152 +cases[7].c[2]=807403007 +cases[7].c[3]=-1 +cases[7].b=0 +cases[7].e=2 +cases[7].k=1 + +cases[8].c[0]=67108864 +cases[8].c[1]=807403007 +cases[8].c[2]=134217728 +cases[8].c[3]=-1 +cases[8].b=0 +cases[8].e=2 +cases[8].k=0 + diff --git a/tinycc/tests/tests2/76_dollars_in_identifiers.c b/tinycc/tests/tests2/76_dollars_in_identifiers.c new file mode 100644 index 0000000..c5fcf99 --- /dev/null +++ b/tinycc/tests/tests2/76_dollars_in_identifiers.c @@ -0,0 +1,41 @@ +#include <stdio.h> + +#define $(x) x +#define $fred 10 +#define joe$ 20 +#define hen$y 30 + +#define $10(x) x*10 +#define _$10(x) x/10 + +int main() +{ + printf("fred=%d\n", $fred); + printf("joe=%d\n", joe$); + printf("henry=%d\n", hen$y); + + printf("fred2=%d\n", $($fred)); + printf("joe2=%d\n", $(joe$)); + printf("henry2=%d\n", $(hen$y)); + + printf("fred10=%d\n", $10($fred)); + printf("joe_10=%d\n", _$10(joe$)); + + int $ = 10; + int a100$ = 100; + int a$$ = 1000; + int a$c$b = 2121; + int $100 = 10000; + const char *$$$ = "money"; + + printf("local=%d\n", $); + printf("a100$=%d\n", a100$); + printf("a$$=%d\n", a$$); + printf("a$c$b=%d\n", a$c$b); + printf("$100=%d\n", $100); + printf("$$$=%s", $$$); + + return 0; +} + +/* vim: set expandtab ts=4 sw=3 sts=3 tw=80 :*/ diff --git a/tinycc/tests/tests2/76_dollars_in_identifiers.expect b/tinycc/tests/tests2/76_dollars_in_identifiers.expect new file mode 100644 index 0000000..4a20a52 --- /dev/null +++ b/tinycc/tests/tests2/76_dollars_in_identifiers.expect @@ -0,0 +1,14 @@ +fred=10 +joe=20 +henry=30 +fred2=10 +joe2=20 +henry2=30 +fred10=100 +joe_10=2 +local=10 +a100$=100 +a$$=1000 +a$c$b=2121 +$100=10000 +$$$=money diff --git a/tinycc/tests/tests2/77_push_pop_macro.c b/tinycc/tests/tests2/77_push_pop_macro.c new file mode 100644 index 0000000..d38e0bf --- /dev/null +++ b/tinycc/tests/tests2/77_push_pop_macro.c @@ -0,0 +1,30 @@ +#include <stdio.h> + +int main() +{ + /* must not affect how #pragma ppop_macro works */ + #define pop_macro foobar1 + + /* must not affect how #pragma push_macro works */ + #define push_macro foobar2 + + #undef abort + #define abort "111" + printf("abort = %s\n", abort); + + #pragma push_macro("abort") + #undef abort + #define abort "222" + printf("abort = %s\n", abort); + + #pragma push_macro("abort") + #undef abort + #define abort "333" + printf("abort = %s\n", abort); + + #pragma pop_macro("abort") + printf("abort = %s\n", abort); + + #pragma pop_macro("abort") + printf("abort = %s\n", abort); +} diff --git a/tinycc/tests/tests2/77_push_pop_macro.expect b/tinycc/tests/tests2/77_push_pop_macro.expect new file mode 100644 index 0000000..d8a5530 --- /dev/null +++ b/tinycc/tests/tests2/77_push_pop_macro.expect @@ -0,0 +1,5 @@ +abort = 111 +abort = 222 +abort = 333 +abort = 222 +abort = 111 diff --git a/tinycc/tests/tests2/78_vla_label.c b/tinycc/tests/tests2/78_vla_label.c new file mode 100644 index 0000000..4096495 --- /dev/null +++ b/tinycc/tests/tests2/78_vla_label.c @@ -0,0 +1,45 @@ +#include <stdio.h> + +/* This test segfaults as of April 27, 2015. */ +void f1(int argc) +{ + char test[argc]; + if(0) + label: + printf("boom!\n"); + if(argc-- == 0) + return; + goto label; +} + +/* This segfaulted on 2015-11-19. */ +void f2(void) +{ + goto start; + { + int a[1 && 1]; /* not a variable-length array */ + int b[1 || 1]; /* not a variable-length array */ + int c[1 ? 1 : 1]; /* not a variable-length array */ + start: + a[0] = 0; + b[0] = 0; + c[0] = 0; + } +} + +void f3(void) +{ + printf("%d\n", 0 ? printf("x1\n") : 11); + printf("%d\n", 1 ? 12 : printf("x2\n")); + printf("%d\n", 0 && printf("x3\n")); + printf("%d\n", 1 || printf("x4\n")); +} + +int main() +{ + f1(2); + f2(); + f3(); + + return 0; +} diff --git a/tinycc/tests/tests2/78_vla_label.expect b/tinycc/tests/tests2/78_vla_label.expect new file mode 100644 index 0000000..3f4063b --- /dev/null +++ b/tinycc/tests/tests2/78_vla_label.expect @@ -0,0 +1,6 @@ +boom! +boom! +11 +12 +0 +1 diff --git a/tinycc/tests/tests2/79_vla_continue.c b/tinycc/tests/tests2/79_vla_continue.c new file mode 100644 index 0000000..dd63790 --- /dev/null +++ b/tinycc/tests/tests2/79_vla_continue.c @@ -0,0 +1,119 @@ +#include <stdio.h> + +int f(void) +{ + return 5; +} + +void test1() +{ + int count = 10; + void *addr[10]; + for(;count--;) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test2() +{ + int count = 10; + void *addr[count]; + for(;count--;) { + int a[f()]; + + addr[count] = a; + + continue; + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test3() +{ + int count = 10; + void *addr[count]; + while(count--) { + int b[f()]; + if (count >= 0) { + int a[f()]; + + addr[count] = a; + + continue; + } + } + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test4() +{ + int count = 10; + void *addr[count]; + do { + int a[f()]; + + addr[--count] = a; + + continue; + } while (count); + + if(addr[9] == addr[0]) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +void test5() +{ + int count = 10; + int a[f()]; + int c[f()]; + + c[0] = 42; + + for(;count--;) { + int b[f()]; + int i; + for (i=0; i<f(); i++) { + b[i] = count; + } + } + + if (c[0] == 42) { + printf("OK\n"); + } else { + printf("NOT OK\n"); + } +} + +int main(void) +{ + test1(); + test2(); + test3(); + test4(); + test5(); + + return 0; +} diff --git a/tinycc/tests/tests2/79_vla_continue.expect b/tinycc/tests/tests2/79_vla_continue.expect new file mode 100644 index 0000000..21da4d2 --- /dev/null +++ b/tinycc/tests/tests2/79_vla_continue.expect @@ -0,0 +1,5 @@ +OK +OK +OK +OK +OK diff --git a/tinycc/tests/tests2/80_flexarray.c b/tinycc/tests/tests2/80_flexarray.c new file mode 100644 index 0000000..864d429 --- /dev/null +++ b/tinycc/tests/tests2/80_flexarray.c @@ -0,0 +1,26 @@ +#include <stdio.h> +struct wchar { + char *data; char mem[]; +}; +struct wint { + char *data; int mem[]; +}; +int f1char (void) { + char s[9]="nonono"; + struct wchar q = {"bugs"}; + return !s[0]; +} +int f1int (void) { + char s[9]="nonono"; + struct wint q = {"bugs"}; + return !s[0]; +} +int empty[] = {}; // GNU extension +int main (void) { + char s[9]="nonono"; + static struct wchar q = {"bugs", {'c'}}; + //printf ("tcc has %s %s\n", s, q.data); + if (f1char() || f1int()) + printf ("bla\n"); + return !s[0]; +} diff --git a/tinycc/tests/tests2/80_flexarray.expect b/tinycc/tests/tests2/80_flexarray.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/80_flexarray.expect diff --git a/tinycc/tests/tests2/81_types.c b/tinycc/tests/tests2/81_types.c new file mode 100644 index 0000000..0bc3bae --- /dev/null +++ b/tinycc/tests/tests2/81_types.c @@ -0,0 +1,55 @@ +/* The following are all valid decls, even though some subtypes + are incomplete. */ +enum E *e; +const enum E *e1; +enum E const *e2; +struct S *s; +const struct S *s1; +struct S const *s2; + +/* Various strangely looking declarators, which are all valid + and have to map to the same numbered typedefs. */ +typedef int (*fptr1)(); +int f1 (int (), int); +typedef int (*fptr2)(int x); +int f2 (int (int x), int); +typedef int (*fptr3)(int); +int f3 (int (int), int); +typedef int (*fptr4[4])(int); +int f4 (int (*[4])(int), int); +typedef int (*fptr5)(fptr1); +int f5 (int (int()), fptr1); +int f1 (fptr1 fp, int i) +{ + return (*fp)(i); +} +int f2 (fptr2 fp, int i) +{ + return (*fp)(i); +} +int f3 (fptr3 fp, int i) +{ + return (*fp)(i); +} +int f4 (fptr4 fp, int i) +{ + return (*fp[i])(i); +} +int f5 (fptr5 fp, fptr1 i) +{ + return fp(i); +} +typedef int intx4[4]; +int f8 (intx4, int); +int f8 (int ([4]), int); +int f8 (int y[4], int i) +{ + return y[i]; +} +int f9 (int (*)(int), int); +int f9 (int ((int)), int); +int f9 (int f(int), int i) +{ + return f(i); +} +int main () { return 0; } diff --git a/tinycc/tests/tests2/81_types.expect b/tinycc/tests/tests2/81_types.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/81_types.expect diff --git a/tinycc/tests/tests2/82_attribs_position.c b/tinycc/tests/tests2/82_attribs_position.c new file mode 100644 index 0000000..d8c9fe5 --- /dev/null +++ b/tinycc/tests/tests2/82_attribs_position.c @@ -0,0 +1,71 @@ +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +typedef union Unaligned16a { + uint16_t u; + uint8_t b[2]; +} __attribute__((packed)) Unaligned16a; + +typedef union __attribute__((packed)) Unaligned16b { + uint16_t u; + uint8_t b[2]; +} Unaligned16b; + +extern void foo (void) __attribute__((stdcall)); +void __attribute__((stdcall)) foo (void) +{ +} + +#define __stdcall __attribute__((stdcall)) +extern int some_stdcall_func (int, int, int) __stdcall; +__stdcall int __stdcall some_stdcall_func(int foo, int bar, int baz) { + //printf("Hello from stdcall: %i %i %i\n", foo, bar, baz); + return 43; +} + +/* The actual attribute isn't important, must just be + parsable. */ +#define ATTR __attribute__((__noinline__)) +int ATTR actual_function() { + return 42; +} + +int label_attribute (void) +{ +lab1: __attribute__((__unused__)); + return 0; +} + +extern int printf (const char *, ...); +static int globalvar; +int main() +{ + void *function_pointer = &actual_function; + int localvar = 42, i; + + int a = ((ATTR int(*) (void)) function_pointer)(); + printf("%i\n", a); + + /* In the following we once misparsed 'ATTR *' is a btype + and hence the whole type was garbled. */ + int b = ( (int(ATTR *)(void)) function_pointer)(); + printf("%i\n", b); + + /* All these should work and leave the stack pointer in its original + position. */ + some_stdcall_func(1, 10, 100); + ((int __stdcall (*)(int, int, int))some_stdcall_func) (2, 20, 200); + ((int(*__stdcall)(int, int, int))some_stdcall_func) (3, 30, 300); + for (i = 0; i < 1024; i++) { + globalvar = i; + /* This was once misparsed at <= gitrev 325241c0, forgetting + the stdcall attribute on the function pointer leading to + stack increment being done twice (in callee and caller). + This will clobber 'i' and 'localvar' which is how we detect + this. */ + ((int(__stdcall*)(int, int, int))some_stdcall_func) (4, 40, 400); + if (localvar != 42 || globalvar != i) + printf("error, localvar=%d i=%d globalvar=%d\n", localvar, i, globalvar); + } + return 0; +} diff --git a/tinycc/tests/tests2/82_attribs_position.expect b/tinycc/tests/tests2/82_attribs_position.expect new file mode 100644 index 0000000..daaac9e --- /dev/null +++ b/tinycc/tests/tests2/82_attribs_position.expect @@ -0,0 +1,2 @@ +42 +42 diff --git a/tinycc/tests/tests2/83_utf8_in_identifiers.c b/tinycc/tests/tests2/83_utf8_in_identifiers.c new file mode 100644 index 0000000..1f86095 --- /dev/null +++ b/tinycc/tests/tests2/83_utf8_in_identifiers.c @@ -0,0 +1,9 @@ +#include <stdio.h> +double привет=0.1; +int Lefèvre=2; +int main(){ + printf("привет=%g\n",привет); + printf("Lefèvre=%d\n",Lefèvre); + return 0; +} +// pcc & tcc only diff --git a/tinycc/tests/tests2/83_utf8_in_identifiers.expect b/tinycc/tests/tests2/83_utf8_in_identifiers.expect new file mode 100644 index 0000000..1553f5f --- /dev/null +++ b/tinycc/tests/tests2/83_utf8_in_identifiers.expect @@ -0,0 +1,2 @@ +привет=0.1 +Lefèvre=2 diff --git a/tinycc/tests/tests2/84_hex-float.c b/tinycc/tests/tests2/84_hex-float.c new file mode 100644 index 0000000..0ef09bf --- /dev/null +++ b/tinycc/tests/tests2/84_hex-float.c @@ -0,0 +1,12 @@ +extern int printf(const char *format, ...); + +#define ACPI_TYPE_INVALID 0x1E +#define NUM_NS_TYPES ACPI_TYPE_INVALID+1 +int array[NUM_NS_TYPES]; + +#define n 0xe +int main() +{ + printf("n+1 = %d\n", n+1); +// printf("n+1 = %d\n", 0xe+1); +} diff --git a/tinycc/tests/tests2/84_hex-float.expect b/tinycc/tests/tests2/84_hex-float.expect new file mode 100644 index 0000000..2175385 --- /dev/null +++ b/tinycc/tests/tests2/84_hex-float.expect @@ -0,0 +1 @@ +n+1 = 15 diff --git a/tinycc/tests/tests2/85_asm-outside-function.c b/tinycc/tests/tests2/85_asm-outside-function.c new file mode 100644 index 0000000..3d7434d --- /dev/null +++ b/tinycc/tests/tests2/85_asm-outside-function.c @@ -0,0 +1,15 @@ +#ifdef __leading_underscore +# define _ "_" +#else +# define _ +#endif + +extern int printf (const char *, ...); +extern void vide(void); +__asm__(_"vide: ret"); + +int main() { + vide(); + printf ("okay\n"); + return 0; +} diff --git a/tinycc/tests/tests2/85_asm-outside-function.expect b/tinycc/tests/tests2/85_asm-outside-function.expect new file mode 100644 index 0000000..dcf02b2 --- /dev/null +++ b/tinycc/tests/tests2/85_asm-outside-function.expect @@ -0,0 +1 @@ +okay diff --git a/tinycc/tests/tests2/86_memory-model.c b/tinycc/tests/tests2/86_memory-model.c new file mode 100644 index 0000000..744c3e2 --- /dev/null +++ b/tinycc/tests/tests2/86_memory-model.c @@ -0,0 +1,38 @@ +#include <stdio.h> + +int +main() +{ +#if defined(__LLP64__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 4 + && sizeof(long long int) == 8 + && sizeof(void*) == 8) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __LLP64__\n"); + } +#elif defined(__LP64__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 8 + && sizeof(long long int) == 8 + && sizeof(void*) == 8) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __LP64__\n"); + } +#elif defined(__ILP32__) + if (sizeof(short) == 2 + && sizeof(int) == 4 + && sizeof(long int) == 4 + && sizeof(void*) == 4) { + (void)printf("Ok\n"); + } else { + (void)printf("KO __ILP32__\n"); + } +#else + (void)printf("KO no __*LP*__ defined.\n"); +#endif +} diff --git a/tinycc/tests/tests2/86_memory-model.expect b/tinycc/tests/tests2/86_memory-model.expect new file mode 100644 index 0000000..7326d96 --- /dev/null +++ b/tinycc/tests/tests2/86_memory-model.expect @@ -0,0 +1 @@ +Ok diff --git a/tinycc/tests/tests2/87_dead_code.c b/tinycc/tests/tests2/87_dead_code.c new file mode 100644 index 0000000..369f4ba --- /dev/null +++ b/tinycc/tests/tests2/87_dead_code.c @@ -0,0 +1,165 @@ +/* This checks various ways of dead code inside if statements + where there are non-obvious ways of how the code is actually + not dead due to reachable by labels. */ +extern int printf (const char *, ...); +static void kb_wait_1(void) +{ + unsigned long timeout = 2; + do { + /* Here the else arm is a statement expression that's supposed + to be suppressed. The label inside the while would unsuppress + code generation again if not handled correctly. And that + would wreak havoc to the cond-expression because there's no + jump-around emitted, the whole statement expression really + needs to not generate code (perhaps except useless forward jumps). */ + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + int i = 1; + while (1) + while (i--) + some_label: + printf("error\n"); + goto some_label; + }) + ); + timeout--; + } while (timeout); +} + +static int global; + +static void foo(int i) +{ + global+=i; + printf ("g=%d\n", global); +} + +static int check(void) +{ + printf ("check %d\n", global); + return 1; +} + +static void dowhile(void) +{ + do { + foo(1); + if (global == 1) { + continue; + } else if (global == 2) { + continue; + } + /* The following break shouldn't disable the check() call, + as it's reachable by the continues above. */ + break; + } while (check()); +} + +static void nondead_after_dead_return(void) +{ + /* This statement expr is not entered, and hence that fact that it + doesn't fall-through should not influence the surrounding code. */ + 0 && ({ return; 0;}); + printf ("nondead works\n"); + return; +} + +int main (void) +{ + int i = 1; + kb_wait_1(); + + /* Simple test of dead code at first sight which isn't actually dead. */ + if (0) { +yeah: + printf ("yeah\n"); + } else { + printf ("boo\n"); + } + if (i--) + goto yeah; + + /* Some more non-obvious uses where the problems are loops, so that even + the first loop statements aren't actually dead. */ + i = 1; + if (0) { + while (i--) { + printf ("once\n"); +enterloop: + printf ("twice\n"); + } + } + if (i >= 0) + goto enterloop; + + /* The same with statement expressions. One might be tempted to + handle them specially by counting if inside statement exprs and + not unsuppressing code at loops at all then. + See kb_wait_1 for the other side of the medal where that wouldn't work. */ + i = ({ + int j = 1; + if (0) { + while (j--) { + printf ("SEonce\n"); + enterexprloop: + printf ("SEtwice\n"); + } + } + if (j >= 0) + goto enterexprloop; + j; }); + + /* The other two loop forms: */ + i = 1; + if (0) { + for (i = 1; i--;) { + printf ("once2\n"); +enterloop2: + printf ("twice2\n"); + } + } + if (i > 0) + goto enterloop2; + + i = 1; + if (0) { + do { + printf ("once3\n"); +enterloop3: + printf ("twice3\n"); + } while (i--); + } + if (i > 0) + goto enterloop3; + + /* And check that case and default labels have the same effect + of disabling code suppression. */ + i = 41; + switch (i) { + if (0) { + printf ("error\n"); + case 42: + printf ("error2\n"); + case 41: + printf ("caseok\n"); + } + } + + i = 41; + switch (i) { + if (0) { + printf ("error3\n"); + default: + printf ("caseok2\n"); + break; + case 42: + printf ("error4\n"); + } + } + + dowhile(); + nondead_after_dead_return(); + + return 0; +} diff --git a/tinycc/tests/tests2/87_dead_code.expect b/tinycc/tests/tests2/87_dead_code.expect new file mode 100644 index 0000000..781ff51 --- /dev/null +++ b/tinycc/tests/tests2/87_dead_code.expect @@ -0,0 +1,24 @@ +timeout=2 +timeout=1 +boo +yeah +twice +once +twice +SEtwice +SEonce +SEtwice +twice2 +once2 +twice2 +twice3 +once3 +twice3 +caseok +caseok2 +g=1 +check 1 +g=2 +check 2 +g=3 +nondead works diff --git a/tinycc/tests/tests2/88_codeopt.c b/tinycc/tests/tests2/88_codeopt.c new file mode 100644 index 0000000..3faa5fa --- /dev/null +++ b/tinycc/tests/tests2/88_codeopt.c @@ -0,0 +1,80 @@ +/* Check some way in where code suppression caused various + miscompilations. */ +extern int printf (const char *, ...); +typedef __SIZE_TYPE__ size_t; + +size_t _brk_start, _brk_end; +void * extend_brk(size_t size, size_t align) +{ + size_t mask = align - 1; + void *ret = 0; + + do { + if (__builtin_expect(!!(_brk_start == 0), 0)) + do { + printf("wrong1\n"); + } while (0); + } while (0); + _brk_end = (_brk_end + mask) & ~mask; + ret = (void *)_brk_end; + _brk_end += size; + + return ret; +} + +static void get_args (int a, int b) +{ + if (a != 1) + printf("wrong2\n"); + else + printf("okay\n"); +} + +void bla(void) +{ + int __ret = 42; + ({ + if (__builtin_expect(!!(0), 0)) { + if (__builtin_expect(!!__ret, 0)) + printf("wrong3\n"); + int x = !!(__ret); + } + __ret; + }); + get_args(!!__ret, sizeof(__ret)); +} + +int ext; + +void broken_jumpopt (int xxx) +{ + /* This was broken in 8227db3a2 by code suppression during suppressed + code :) */ + ext = (xxx || 1) || ((xxx && 1) || 1); + printf("okay: %d %d\n", xxx, ext); +} + +_Bool chk(unsigned long addr, unsigned long limit, unsigned long size) +{ + _Bool ret; + /* This just needs to compile, no runtime test. (And it doesn't compile + only with certain internal checking added that's not committed). */ + if (0) + ret = 0 != (!!(addr > limit - size)); + return 0; +} + +int main() +{ + void *r; + _brk_start = 1024; + _brk_end = 1024; + r = extend_brk (4096, 16); + if (!r) + printf("wrong4\n"); + else + printf("okay\n"); + bla(); + broken_jumpopt(42); + return 0; +} diff --git a/tinycc/tests/tests2/88_codeopt.expect b/tinycc/tests/tests2/88_codeopt.expect new file mode 100644 index 0000000..76b582b --- /dev/null +++ b/tinycc/tests/tests2/88_codeopt.expect @@ -0,0 +1,3 @@ +okay +okay +okay: 42 1 diff --git a/tinycc/tests/tests2/89_nocode_wanted.c b/tinycc/tests/tests2/89_nocode_wanted.c new file mode 100644 index 0000000..73e0a4b --- /dev/null +++ b/tinycc/tests/tests2/89_nocode_wanted.c @@ -0,0 +1,112 @@ +extern int printf(const char *format, ...); +static void kb_wait_1(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + while (1) + printf("error\n"); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + for (;;) + printf("error\n"); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2_1(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + do { + printf("error\n"); + } while (1); + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_2_2(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + label: + printf("error\n"); + goto label; + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_3(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + int i = 1; + goto label; + i = i + 2; + label: + i = i + 3; + }) + ); + timeout--; + } while (timeout); +} +static void kb_wait_4(void) +{ + unsigned long timeout = 2; + do { + (1 ? + printf("timeout=%ld\n", timeout) : + ({ + switch(timeout) { + case 2: + printf("timeout is 2"); + break; + case 1: + printf("timeout is 1"); + break; + default: + printf("timeout is 0?"); + break; + }; + // return; + }) + ); + timeout--; + } while (timeout); +} +int main() +{ + printf("begin\n"); + kb_wait_1(); + kb_wait_2(); + kb_wait_2_1(); + kb_wait_2_2(); + kb_wait_3(); + kb_wait_4(); + printf("end\n"); + return 0; +} diff --git a/tinycc/tests/tests2/89_nocode_wanted.expect b/tinycc/tests/tests2/89_nocode_wanted.expect new file mode 100644 index 0000000..c44d4ea --- /dev/null +++ b/tinycc/tests/tests2/89_nocode_wanted.expect @@ -0,0 +1,14 @@ +begin +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +timeout=2 +timeout=1 +end diff --git a/tinycc/tests/tests2/90_struct-init.c b/tinycc/tests/tests2/90_struct-init.c new file mode 100644 index 0000000..4a71a93 --- /dev/null +++ b/tinycc/tests/tests2/90_struct-init.c @@ -0,0 +1,424 @@ +typedef unsigned char u8; +typedef struct {} empty_s; +struct contains_empty { + u8 a; + empty_s empty; + u8 b; +}; +struct contains_empty ce = { { (1) }, (empty_s){}, 022, }; +/* The following decl of 'q' would demonstrate the TCC bug in init_putv when + handling copying compound literals. (Compound literals + aren't acceptable constant initializers in isoc99, but + we accept them like gcc, except for this case) +//char *q = (char *){ "trara" }; */ +struct SS {u8 a[3], b; }; +struct SS sinit16[] = { { 1 }, 2 }; +struct S +{ + u8 a,b; + u8 c[2]; +}; + +struct T +{ + u8 s[16]; + u8 a; +}; + +struct U +{ + u8 a; + struct S s; + u8 b; + struct T t; +}; + +struct V +{ + struct S s; + struct T t; + u8 a; +}; + +struct W +{ + struct V t; + struct S s[]; +}; + +struct S gs = ((struct S){1, 2, 3, 4}); +struct S gs2 = {1, 2, {3, 4}}; +struct T gt = {"hello", 42}; +struct U gu = {3, 5,6,7,8, 4, "huhu", 43}; +struct U gu2 = {3, {5,6,7,8}, 4, {"huhu", 43}}; +/* Optional braces around scalar initializers. Accepted, but with + a warning. */ +struct U gu3 = { {3}, {5,6,7,8,}, 4, {"huhu", 43}}; +/* Many superfluous braces and leaving out one initializer for U.s.c[1] */ +struct U gu4 = { 3, {5,6,7,}, 5, { "bla", {44}} }; +/* Superfluous braces and useless parens around values */ +struct S gs3 = { (1), {(2)}, {(((3))), {4}}}; +/* Superfluous braces, and leaving out braces for V.t, plus cast */ +struct V gv = {{{3},4,{5,6}}, "haha", (u8)45, 46}; +/* Compound literal */ +struct V gv2 = {(struct S){7,8,{9,10}}, {"hihi", 47}, 48}; +/* Parens around compound literal */ +struct V gv3 = {((struct S){7,8,{9,10}}), {"hoho", 49}, 50}; +/* Initialization of a flex array member (warns in GCC) */ +struct W gw = {{1,2,3,4}, {1,2,3,4,5}}; + +union UU { + u8 a; + u8 b; +}; +struct SU { + union UU u; + u8 c; +}; +struct SU gsu = {5,6}; + +/* Unnamed struct/union members aren't ISO C, but it's a widely accepted + extension. See below for further extensions to that under -fms-extension.*/ +union UV { + struct {u8 a,b;}; + struct S s; +}; +union UV guv = {{6,5}}; +union UV guv2 = {{.b = 7, .a = 8}}; +union UV guv3 = {.b = 8, .a = 7}; + +struct SSU { + int y; + struct { int x; }; +}; +struct SSU gssu1 = { .y = 5, .x = 3 }; +struct SSU gssu2 = { 5, 3 }; + +/* Under -fms-extensions also the following is valid: +union UV2 { + struct Anon {u8 a,b;}; // unnamed member, but tagged struct, ... + struct S s; +}; +struct Anon gan = { 10, 11 }; // ... which makes it available here. +union UV2 guv4 = {{4,3}}; // and the other inits from above as well +*/ + +struct in6_addr { + union { + u8 u6_addr8[16]; + unsigned short u6_addr16[8]; + } u; +}; +struct flowi6 { + struct in6_addr saddr, daddr; +}; +struct pkthdr { + struct in6_addr daddr, saddr; +}; +struct pkthdr phdr = { { { 6,5,4,3 } }, { { 9,8,7,6 } } }; + +struct Wrap { + void *func; +}; +int global; +void inc_global (void) +{ + global++; +} + +struct Wrap global_wrap[] = { + ((struct Wrap) {inc_global}), + inc_global, +}; + +#include <stdio.h> +void print_ (const char *name, const u8 *p, long size) +{ + printf ("%s:", name); + while (size--) { + printf (" %x", *p++); + } + printf ("\n"); +} +#define print(x) print_(#x, (u8*)&x, sizeof (x)) +#if 1 +void foo (struct W *w, struct pkthdr *phdr_) +{ + struct S ls = {1, 2, 3, 4}; + struct S ls2 = {1, 2, {3, 4}}; + struct T lt = {"hello", 42}; + struct U lu = {3, 5,6,7,8, 4, "huhu", 43}; + struct U lu1 = {3, ls, 4, {"huhu", 43}}; + struct U lu2 = {3, (ls), 4, {"huhu", 43}}; + const struct S *pls = &ls; + struct S ls21 = *pls; + struct U lu22 = {3, *pls, 4, {"huhu", 43}}; + /* Incomplete bracing. */ + struct U lu21 = {3, ls, 4, "huhu", 43}; + /* Optional braces around scalar initializers. Accepted, but with + a warning. */ + struct U lu3 = { 3, {5,6,7,8,}, 4, {"huhu", 43}}; + /* Many superfluous braces and leaving out one initializer for U.s.c[1] */ + struct U lu4 = { 3, {5,6,7,}, 5, { "bla", 44} }; + /* Superfluous braces and useless parens around values */ + struct S ls3 = { (1), (2), {(((3))), 4}}; + /* Superfluous braces, and leaving out braces for V.t, plus cast */ + struct V lv = {{3,4,{5,6}}, "haha", (u8)45, 46}; + /* Compound literal */ + struct V lv2 = {(struct S)w->t.s, {"hihi", 47}, 48}; + /* Parens around compound literal */ + struct V lv3 = {((struct S){7,8,{9,10}}), ((const struct W *)w)->t.t, 50}; + const struct pkthdr *phdr = phdr_; + struct flowi6 flow = { .daddr = phdr->daddr, .saddr = phdr->saddr }; + int elt = 0x42; + /* Range init, overlapping */ + struct T lt2 = { { [1 ... 5] = 9, [6 ... 10] = elt, [4 ... 7] = elt+1 }, 1 }; + struct SSU lssu1 = { 5, 3 }; + struct SSU lssu2 = { .y = 5, .x = 3 }; + /* designated initializers in GNU form */ +#if defined(__GNUC__) || defined(__TINYC__) + struct S ls4 = {a: 1, b: 2, c: {3, 4}}; +#else + struct S ls4 = {.a = 1, .b = 2, .c = {3, 4}}; +#endif + print(ls); + print(ls2); + print(lt); + print(lu); + print(lu1); + print(lu2); + print(ls21); + print(lu21); + print(lu22); + print(lu3); + print(lu4); + print(ls3); + print(lv); + print(lv2); + print(lv3); + print(lt2); + print(lssu1); + print(lssu2); + print(flow); + print(ls4); +} +#endif + +void test_compound_with_relocs (void) +{ + struct Wrap local_wrap[] = { + ((struct Wrap) {inc_global}), + inc_global, + }; + void (*p)(void); + p = global_wrap[0].func; p(); + p = global_wrap[1].func; p(); + p = local_wrap[0].func; p(); + p = local_wrap[1].func; p(); +} + +void sys_ni(void) { printf("ni\n"); } +void sys_one(void) { printf("one\n"); } +void sys_two(void) { printf("two\n"); } +void sys_three(void) { printf("three\n"); } +void sys_four(void) { printf("four\n"); } +typedef void (*fptr)(void); + +#define array_size(a) (sizeof a / sizeof a[0]) + +void test_multi_relocs(void) +{ + int i; + + static const fptr tabl1[4] = { + [0 ... 3] = &sys_ni, + [0] = sys_one, + [1] = sys_two, + [2] = sys_three, + sys_four, + [1 ... 2] = &sys_ni, + [1] = 0, + }; + for (i = 0; i < array_size(tabl1); i++) + if (tabl1[i]) + tabl1[i](); + else + printf("(0)\n"); + + const fptr tabl2[4] = { + [0 ... 3] = &sys_ni, + [0] = sys_one, + [1] = sys_two, + [2] = sys_three, + sys_four, + [1 ... 2] = &sys_ni, + [1] = 0, + }; + for (i = 0; i < array_size(tabl2); i++) + if (tabl2[i]) + tabl2[i](); + else + printf("(0)\n"); + + int c = 0; + int dd[] = { + [0 ... 1] = ++c, + [2 ... 3] = ++c + }; + for (i = 0; i < array_size(dd); i++) + printf(" %d", dd[i]); + printf("\n"); + + /* multi-dimensional flex array with range initializers */ + static char m1[][2][3] = {[0 ... 2]={{3,4,5},{6,7,8}},{{9},10},"abc"}; + char m2[][2][3] = {[0 ... 2]={{3,4,5},{6,7,8}},{{9},10},"abc"}; + int g, j, k; + for (g = 2; g-- > 0;) { + printf("mdfa %s: %d -", "locl\0glob" + g * 5, sizeof m1); + for (i = 0; i < array_size(m1); i++) + for (j = 0; j < array_size(m1[0]); j++) + for (k = 0; k < array_size(m1[0][0]); k++) + printf(" %d", (g ? m1:m2)[i][j][k]); + printf("\n"); + } +} + +void test_init_ranges(void) { + int i,c=0; + static void *gostring[] = { + [0 ... 31] = &&l_bad, [127] = &&l_bad, + [32 ... 126] = &&l_loop, + ['\\'] = &&l_esc, ['"'] = &&l_qdown, + [128 ... 191] = &&l_bad, + [192 ... 223] = &&l_utf8_2, + [224 ... 239] = &&l_utf8_3, + [240 ... 247] = &&l_utf8_4, + [248 ... 255] = &&l_bad + }; + + for (i = 0; i < 256; i++) { + goto *gostring[i]; + l_bad: c++; + l_loop: c++; + l_esc: c++; + l_qdown: c++; + l_utf8_2: c++; + l_utf8_3: c++; + l_utf8_4: c++; + } + printf ("%d\n", c); +} + + +/* Following is from GCC gcc.c-torture/execute/20050613-1.c. */ + +struct SEA { int i; int j; int k; int l; }; +struct SEB { struct SEA a; int r[1]; }; +struct SEC { struct SEA a; int r[0]; }; +struct SED { struct SEA a; int r[]; }; + +static void +test_correct_filling (struct SEA *x) +{ + static int i; + if (x->i != 0 || x->j != 5 || x->k != 0 || x->l != 0) + printf("sea_fill%d: wrong\n", i); + else + printf("sea_fill%d: okay\n", i); + i++; +} + +int +test_zero_init (void) +{ + /* The peculiarity here is that only a.j is initialized. That + means that all other members must be zero initialized. TCC + once didn't do that for sub-level designators. */ + struct SEB b = { .a.j = 5 }; + struct SEC c = { .a.j = 5 }; + struct SED d = { .a.j = 5 }; + test_correct_filling (&b.a); + test_correct_filling (&c.a); + test_correct_filling (&d.a); + return 0; +} + +void test_init_struct_from_struct(void) +{ + int i = 0; + struct S {int x,y;} + a = {1,2}, + b = {3,4}, + c[] = {a,b}, + d[] = {++i, ++i, ++i, ++i}, + e[] = {b, (struct S){5,6}} + ; + + printf("%s: %d %d %d %d - %d %d %d %d - %d %d %d %d\n", + __FUNCTION__, + c[0].x, + c[0].y, + c[1].x, + c[1].y, + d[0].x, + d[0].y, + d[1].x, + d[1].y, + e[0].x, + e[0].y, + e[1].x, + e[1].y + ); +} + +typedef struct { + unsigned int a; + unsigned int : 32; + unsigned int b; + unsigned long long : 64; + unsigned int c; +} tst_bf; + +tst_bf arr[] = { { 1, 2, 3 } }; + +void +test_init_bf(void) +{ + printf ("%s: %d %d %d\n", __FUNCTION__, arr[0].a, arr[0].b, arr[0].c); +} + + +int main() +{ + print(ce); + print(gs); + print(gs2); + print(gt); + print(gu); + print(gu2); + print(gu3); + print(gu4); + print(gs3); + print(gv); + print(gv2); + print(gv3); + print(sinit16); + print(gw); + print(gsu); + print(guv); + print(guv.b); + print(guv2); + print(guv3); + print(gssu1); + print(gssu2); + print(phdr); + foo(&gw, &phdr); + //printf("q: %s\n", q); + test_compound_with_relocs(); + test_multi_relocs(); + test_zero_init(); + test_init_ranges(); + test_init_struct_from_struct(); + test_init_bf(); + return 0; +} diff --git a/tinycc/tests/tests2/90_struct-init.expect b/tinycc/tests/tests2/90_struct-init.expect new file mode 100644 index 0000000..5014f82 --- /dev/null +++ b/tinycc/tests/tests2/90_struct-init.expect @@ -0,0 +1,59 @@ +ce: 1 12 +gs: 1 2 3 4 +gs2: 1 2 3 4 +gt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a +gu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu2: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +gu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c +gs3: 1 2 3 4 +gv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e +gv2: 7 8 9 a 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 +gv3: 7 8 9 a 68 6f 68 6f 0 0 0 0 0 0 0 0 0 0 0 0 31 32 +sinit16: 1 0 0 0 2 0 0 0 +gw: 1 2 3 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +gsu: 5 6 +guv: 6 5 0 0 +guv.b: 5 +guv2: 8 7 0 0 +guv3: 7 8 0 0 +gssu1: 5 0 0 0 3 0 0 0 +gssu2: 5 0 0 0 3 0 0 0 +phdr: 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 +ls: 1 2 3 4 +ls2: 1 2 3 4 +lt: 68 65 6c 6c 6f 0 0 0 0 0 0 0 0 0 0 0 2a +lu: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu1: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu2: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +ls21: 1 2 3 4 +lu21: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu22: 3 1 2 3 4 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu3: 3 5 6 7 8 4 68 75 68 75 0 0 0 0 0 0 0 0 0 0 0 0 2b +lu4: 3 5 6 7 0 5 62 6c 61 0 0 0 0 0 0 0 0 0 0 0 0 0 2c +ls3: 1 2 3 4 +lv: 3 4 5 6 68 61 68 61 0 0 0 0 0 0 0 0 0 0 0 0 2d 2e +lv2: 1 2 3 4 68 69 68 69 0 0 0 0 0 0 0 0 0 0 0 0 2f 30 +lv3: 7 8 9 a 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 32 +lt2: 0 9 9 9 43 43 43 43 42 42 42 0 0 0 0 0 1 +lssu1: 5 0 0 0 3 0 0 0 +lssu2: 5 0 0 0 3 0 0 0 +flow: 9 8 7 6 0 0 0 0 0 0 0 0 0 0 0 0 6 5 4 3 0 0 0 0 0 0 0 0 0 0 0 0 +ls4: 1 2 3 4 +one +(0) +ni +four +one +(0) +ni +four + 1 1 2 2 +mdfa glob: 30 - 3 4 5 6 7 8 3 4 5 6 7 8 3 4 5 6 7 8 9 0 0 10 0 0 97 98 99 0 0 0 +mdfa locl: 30 - 3 4 5 6 7 8 3 4 5 6 7 8 3 4 5 6 7 8 9 0 0 10 0 0 97 98 99 0 0 0 +sea_fill0: okay +sea_fill1: okay +sea_fill2: okay +1438 +test_init_struct_from_struct: 1 2 3 4 - 1 2 3 4 - 3 4 5 6 +test_init_bf: 1 2 3 diff --git a/tinycc/tests/tests2/91_ptr_longlong_arith32.c b/tinycc/tests/tests2/91_ptr_longlong_arith32.c new file mode 100644 index 0000000..bf07915 --- /dev/null +++ b/tinycc/tests/tests2/91_ptr_longlong_arith32.c @@ -0,0 +1,15 @@ +int printf(const char *, ...); +char t[] = "012345678"; + +int main(void) +{ + char *data = t; + unsigned long long r = 4; + unsigned a = 5; + unsigned long long b = 12; + + *(unsigned*)(data + r) += a - b; + + printf("data = \"%s\"\n", data); + return 0; +} diff --git a/tinycc/tests/tests2/91_ptr_longlong_arith32.expect b/tinycc/tests/tests2/91_ptr_longlong_arith32.expect new file mode 100644 index 0000000..f91e4b4 --- /dev/null +++ b/tinycc/tests/tests2/91_ptr_longlong_arith32.expect @@ -0,0 +1 @@ +data = "0123-5678" diff --git a/tinycc/tests/tests2/92_enum_bitfield.c b/tinycc/tests/tests2/92_enum_bitfield.c new file mode 100644 index 0000000..fb8f7a3 --- /dev/null +++ b/tinycc/tests/tests2/92_enum_bitfield.c @@ -0,0 +1,58 @@ +/* This checks if enums needing 8 bit but only having positive + values are correctly zero extended (instead of sign extended) + when stored into/loaded from a 8 bit bit-field of enum type (which + itself is implementation defined, so isn't necessarily supported by all + other compilers). */ +enum tree_code { + SOME_CODE = 148, /* has bit 7 set, and hence all further enum values as well */ + LAST_AND_UNUSED_TREE_CODE +}; +typedef union tree_node *tree; +struct tree_common +{ + union tree_node *chain; + union tree_node *type; + enum tree_code code : 8; + unsigned side_effects_flag : 1; +}; +union tree_node +{ + struct tree_common common; + }; +enum c_tree_code { + C_DUMMY_TREE_CODE = LAST_AND_UNUSED_TREE_CODE, + STMT_EXPR, + LAST_C_TREE_CODE +}; +enum cplus_tree_code { + CP_DUMMY_TREE_CODE = LAST_C_TREE_CODE, + AMBIG_CONV, + LAST_CPLUS_TREE_CODE +}; + +extern int printf(const char *, ...); +int blah(){return 0;} + +int convert_like_real (tree convs) +{ + switch (((enum tree_code) (convs)->common.code)) + { + case AMBIG_CONV: /* This has bit 7 set, which must not be the sign + bit in tree_common.code, i.e. the bitfield must + be somehow marked unsigned. */ + return blah(); + default: + break; + }; + printf("unsigned enum bit-fields broken\n"); + return 0; +} + +int main() +{ + union tree_node convs; + + convs.common.code = AMBIG_CONV; + convert_like_real (&convs); + return 0; +} diff --git a/tinycc/tests/tests2/92_enum_bitfield.expect b/tinycc/tests/tests2/92_enum_bitfield.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tinycc/tests/tests2/92_enum_bitfield.expect diff --git a/tinycc/tests/tests2/93_integer_promotion.c b/tinycc/tests/tests2/93_integer_promotion.c new file mode 100644 index 0000000..a1176fc --- /dev/null +++ b/tinycc/tests/tests2/93_integer_promotion.c @@ -0,0 +1,71 @@ +/* integer promotion */ + +int printf(const char*, ...); +#define promote(s) printf(" %ssigned : %s\n", (s) - 100 < 0 ? " " : "un", #s); + +int main (void) +{ + struct { + unsigned ub:3; + unsigned u:32; + unsigned long long ullb:35; + unsigned long long ull:64; + unsigned char c; + } s = { 1, 1, 1 }; + + promote(s.ub); + promote(s.u); + promote(s.ullb); + promote(s.ull); + promote(s.c); + printf("\n"); + + promote((1 ? s.ub : 1)); + promote((1 ? s.u : 1)); + promote((1 ? s.ullb : 1)); + promote((1 ? s.ull : 1)); + promote((1 ? s.c : 1)); + printf("\n"); + + promote(s.ub << 1); + promote(s.u << 1); + promote(s.ullb << 1); + promote(s.ull << 1); + promote(s.c << 1); + printf("\n"); + + promote(+s.ub); + promote(+s.u); + promote(+s.ullb); + promote(+s.ull); + promote(+s.c); + printf("\n"); + + promote(-s.ub); + promote(-s.u); + promote(-s.ullb); + promote(-s.ull); + promote(-s.c); + printf("\n"); + + promote(~s.ub); + promote(~s.u); + promote(~s.ullb); + promote(~s.ull); + promote(~s.c); + printf("\n"); + + promote(!s.ub); + promote(!s.u); + promote(!s.ullb); + promote(!s.ull); + promote(!s.c); + printf("\n"); + + promote(+(unsigned)s.ub); + promote(-(unsigned)s.ub); + promote(~(unsigned)s.ub); + promote(!(unsigned)s.ub); + + return 0; +} diff --git a/tinycc/tests/tests2/93_integer_promotion.expect b/tinycc/tests/tests2/93_integer_promotion.expect new file mode 100644 index 0000000..34b9c14 --- /dev/null +++ b/tinycc/tests/tests2/93_integer_promotion.expect @@ -0,0 +1,46 @@ + signed : s.ub + unsigned : s.u + signed : s.ullb + unsigned : s.ull + signed : s.c + + signed : (1 ? s.ub : 1) + unsigned : (1 ? s.u : 1) + signed : (1 ? s.ullb : 1) + unsigned : (1 ? s.ull : 1) + signed : (1 ? s.c : 1) + + signed : s.ub << 1 + unsigned : s.u << 1 + signed : s.ullb << 1 + unsigned : s.ull << 1 + signed : s.c << 1 + + signed : +s.ub + unsigned : +s.u + signed : +s.ullb + unsigned : +s.ull + signed : +s.c + + signed : -s.ub + unsigned : -s.u + signed : -s.ullb + unsigned : -s.ull + signed : -s.c + + signed : ~s.ub + unsigned : ~s.u + signed : ~s.ullb + unsigned : ~s.ull + signed : ~s.c + + signed : !s.ub + signed : !s.u + signed : !s.ullb + signed : !s.ull + signed : !s.c + + unsigned : +(unsigned)s.ub + unsigned : -(unsigned)s.ub + unsigned : ~(unsigned)s.ub + signed : !(unsigned)s.ub diff --git a/tinycc/tests/tests2/94_generic.c b/tinycc/tests/tests2/94_generic.c new file mode 100644 index 0000000..1cb0164 --- /dev/null +++ b/tinycc/tests/tests2/94_generic.c @@ -0,0 +1,122 @@ +#include <stdio.h> + +const int a = 0; + +struct a { + int a; +}; + +struct b { + int a; +}; + +int a_f() +{ + return 20; +} + +int b_f() +{ + return 10; +} + +typedef int (*fptr)(int); +typedef void (*vfptr)(int); +int foo(int i) +{ + return i; +} +void void_foo(int i) {} + +typedef int int_type1; + +#define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123); + +int main() +{ + int i = 0; + signed long int l = 2; + struct b titi; + const int * const ptr; + const char *ti; + int_type1 i2; + + i = _Generic(a, int: a_f, const int: b_f)(); + printf("%d\n", i); + i = _Generic(a, int: a_f() / 2, const int: b_f() / 2); + printf("%d\n", i); + i = _Generic(ptr, int *:1, int * const:2, default:20); + printf("%d\n", i); + i = gen_sw(a); + printf("%d\n", i); + i = _Generic(titi, struct a:1, struct b:2, default:20); + printf("%d\n", i); + i = _Generic(i2, char: 1, int : 0); + printf("%d\n", i); + i = _Generic(a, char:1, int[4]:2, default:5); + printf("%d\n", i); + i = _Generic(17, int :1, int **:2); + printf("%d\n", i); + i = _Generic(17L, int :1, long :2, long long : 3); + printf("%d\n", i); + i = _Generic("17, io", char *: 3, const char *: 1); + printf("%d\n", i); + i = _Generic(ti, const unsigned char *:1, const char *:4, char *:3, + const signed char *:2); + printf("%d\n", i); + printf("%s\n", _Generic(i + 2L, long: "long", int: "int", + long long: "long long")); + i = _Generic(l, long: 1, int: 2); + printf("%d\n", i); + i = _Generic(foo, fptr: 3, int: 4, vfptr: 5); + printf("%d\n", i); + i = _Generic(void_foo, fptr: 3, int: 4, vfptr: 5); + printf("%d\n", i); + + (void)_Generic((int(*)[2]){0}, int(*)[2]:0, int(*)[4]:0); //shouldn't match twice + + //should accept ({ }) in the controlling expr of _Generic even in const_wanted contexts + struct { _Bool x_0: _Generic(({0;}),default:1); } my_x; + + _Generic((__typeof((float const)((float const){42}))*){0}, float*: 0); //casts lose top-level qualifiers + int const x = 42; __typeof((__typeof(x))x) *xp = 0; (void)_Generic(xp, int*: 0); //casts lose top-level qualifiers + + //TEST TERNARY: + //Same type + _Generic( 0?(long*)0:(long*)0, long*: (void)0); + //combining of qualifiers + _Generic( 0?(long volatile*)0:(long const*)0, long const volatile*: (void)0); + //nul-ptr constant selects other type + _Generic( 0?(long*)0:0, long*: (void)0); + _Generic( 0?(long*)0:(void*)0, long*: (void)0); + + //void ptrs get chosen preferentially; qualifs still combine + _Generic( 0?(int volatile*)0: (void const*)1, void volatile const*: (void)0); + //but this is no null-ptr constant, so fallback to void-choice + i = 0; + _Generic( 1?(void*)(i*0LL):&i, void*:0); + //like gcc but not clang, don't treat (void* const as the null-ptr constant) + _Generic( 0?(int volatile*)0: (void const*)0, void volatile const*: (void)0); + + //ptrs to incomplete types get completed + (void)(sizeof(struct { int x:_Generic( 0?(int (*)[4])0 : (int (*)[])0, int (*)[4]:+1, int (*)[5]:(void)0); })); + (void)(sizeof(struct { int x:_Generic( 0?(int (*)[])0 : (int (*)[4])0, int (*)[4]:+1, int (*)[5]:(void)0); })); + + { + /* completion shouldn't affect the type of decl */ + char **argv; + _Generic(argv, char**: (void)0); + _Generic(0?(char const*)0:argv[0], char const*: (void)0); + _Generic(argv, char**: (void)0); + } + { + extern int (*ar)[]; + (void)(sizeof(struct { int x:_Generic( 0?(int (*)[4])0 : (int (*)[])0, int (*)[4]:+1, int (*)[5]:(void)0); })); + (void)(sizeof(struct { int x:_Generic( 0?(int (*)[])0 : (int (*)[4])0, int (*)[4]:+1, int (*)[5]:(void)0); })); + (void)(sizeof(struct { int x:_Generic( 0?ar : (int (*)[4])0, int (*)[4]:+1, int (*)[5]:(void)0); })); + (void)(sizeof(struct { int x:_Generic( 0?(int (*)[4])0 : ar, int (*)[4]:+1, int (*)[5]:(void)0); })); + (void)(sizeof(struct { int x:_Generic( 0?(int (*)[5])0 : ar, int (*)[5]:+1, int (*)[4]:(void)0); })); + } + + return 0; +} diff --git a/tinycc/tests/tests2/94_generic.expect b/tinycc/tests/tests2/94_generic.expect new file mode 100644 index 0000000..80d4ed9 --- /dev/null +++ b/tinycc/tests/tests2/94_generic.expect @@ -0,0 +1,15 @@ +20 +10 +20 +123 +2 +0 +5 +1 +2 +3 +4 +long +1 +3 +5 diff --git a/tinycc/tests/tests2/95_bitfields.c b/tinycc/tests/tests2/95_bitfields.c new file mode 100644 index 0000000..4ac38da --- /dev/null +++ b/tinycc/tests/tests2/95_bitfields.c @@ -0,0 +1,241 @@ +/* ----------------------------------------------------------------------- */ +#if TEST == 1 +{ + struct M P A __s + { + unsigned x : 12; + unsigned char y : 7; + unsigned z : 28; + unsigned a: 4; + unsigned b: 5; + }; + TEST_STRUCT(0x333,0x44,0x555555,6,7); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 2 +{ + struct M P __s + { + int x: 12; + char y: 6; + long long z:63; + A char a:4; + long long b:2; + + }; + TEST_STRUCT(3,30,0x123456789abcdef0LL,5,2); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 3 +{ + struct M P __s + { + unsigned x:5, y:5, :0, z:5; char a:5; A short b:5; + }; + TEST_STRUCT(21,23,25,6,14); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 4 +{ + struct M P __s { + int x : 3; + int : 2; + int y : 1; + int : 0; + int z : 5; + int a : 7; + unsigned int b : 7; + }; + TEST_STRUCT(3,1,15,120,120); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 5 +{ + struct M P __s { + long long x : 45; + long long : 2; + long long y : 30; + unsigned long long z : 38; + char a; short b; + }; + TEST_STRUCT(0x123456789ULL, 120<<25, 120, 0x44, 0x77); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 6 +{ + struct M P __s { + int a; + signed char b; + int x : 12, y : 4, : 0, : 4, z : 3; + char d; + }; + TEST_STRUCT(1,2,3,4,-3); +} + +/* ----------------------------------------------------------------------- */ +#elif TEST == 7 +{ +#ifdef _WIN32 + typedef long long int ll; +#else + typedef long int ll; +#endif + struct M P __s { + ll d : 16; + ll b : 16; + ll x : 16; + ll y : 1; + ll z : 2; + ll a : 11; + ll e : 1; + ll f : 1; + }; + TEST_STRUCT(1,2,3,4,5); +} + +/* ----------------------------------------------------------------------- */ +#elif defined PACK + +#if PACK +# pragma pack(push,1) +# define P //_P +#else +# define P +#endif + +printf("\n\n" + 2*top); +#define TEST 1 +#include SELF +top = 0; +#define TEST 2 +#include SELF +#define TEST 3 +#include SELF +#define TEST 4 +#include SELF +#define TEST 5 +#include SELF +#define TEST 6 +#include SELF +#define TEST 7 +#include SELF + +#if PACK +# pragma pack(pop) +#endif + +#undef P +#undef PACK + +/* ----------------------------------------------------------------------- */ +#elif defined ALIGN + +#if ALIGN +# define A _A(16) +#else +# define A +#endif + +#define PACK 0 +#include SELF +#define PACK 1 +#include SELF + +#undef A +#undef ALIGN + +/* ----------------------------------------------------------------------- */ +#elif defined MS_BF + +#if MS_BF +# ifdef __TINYC__ +# pragma comment(option, "-mms-bitfields") +# elif defined __GNUC__ +# define M __attribute__((ms_struct)) +# endif +#else +# ifdef __TINYC__ +# pragma comment(option, "-mno-ms-bitfields") +# elif defined __GNUC__ +# define M __attribute__((gcc_struct)) +# endif +#endif +#ifndef M +# define M +#endif + +#define ALIGN 0 +#include SELF +#define ALIGN 1 +#include SELF + +#undef M +#undef MS_BF + +/* ----------------------------------------------------------------------- */ +#else + +#include <stdio.h> +#include <string.h> +/* some gcc headers #define __attribute__ to empty if it's not gcc */ +#undef __attribute__ + +void dump(void *p, int s) +{ + int i; + for (i = s; --i >= 0;) + printf("%02X", ((unsigned char*)p)[i]); + printf("\n"); +} + +#define pv(m) \ + printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m) + +#define TEST_STRUCT(v1,v2,v3,v4,v5) { \ + struct __s _s, *s = & _s; \ + printf("\n---- TEST %d%s%s%s ----\n" + top, \ + TEST, MS_BF?" - MS-BITFIELDS":"", \ + PACK?" - PACKED":"", \ + ALIGN?" - WITH ALIGN":""); \ + memset(s, 0, sizeof *s); \ + s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \ + printf("bits in use : "), dump(s, sizeof *s); \ + s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \ + printf("bits as set : "), dump(s, sizeof *s); \ + printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \ + printf("align/size : %d %d\n", alignof(struct __s),sizeof(struct __s)); \ + } + +#ifdef _MSC_VER +# define _A(n) __declspec(align(n)) +# define _P +# define alignof(x) __alignof(x) +#else +# define _A(n) __attribute__((aligned(n))) +# define _P __attribute__((packed)) +# define alignof(x) __alignof__(x) +#endif + +#ifndef MS_BITFIELDS +# define MS_BITFIELDS 0 +#endif + +#define SELF "95_bitfields.c" + +int top = 1; + +int main() +{ +#define MS_BF MS_BITFIELDS +#include SELF + return 0; +} + +/* ----------------------------------------------------------------------- */ +#endif +#undef TEST diff --git a/tinycc/tests/tests2/95_bitfields.expect b/tinycc/tests/tests2/95_bitfields.expect new file mode 100644 index 0000000..215055d --- /dev/null +++ b/tinycc/tests/tests2/95_bitfields.expect @@ -0,0 +1,173 @@ +---- TEST 1 ---- +bits in use : 0000001FFFFFFFFF007F0FFF +bits as set : 000000076055555500440333 +values : 333 44 555555 06 07 +align/size : 4 12 + +---- TEST 2 ---- +bits in use : 000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF +bits as set : 0000000000000025123456789ABCDEF000000000001E0003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 8 24 + +---- TEST 3 ---- +bits in use : 001F1F1F000003FF +bits as set : 000E0619000002F5 +values : 15 17 19 06 0e +align/size : 4 8 + +---- TEST 4 ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 ---- +bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000007800000000300000000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 8 24 + +---- TEST 6 ---- +bits in use : 0000007000FFFFFFFFFFFFFF +bits as set : 00000030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 12 + +---- TEST 7 ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 01 00 ffffffff 04 05 +align/size : 8 8 + + + +---- TEST 1 - PACKED ---- +bits in use : FFFFFFFFFFFFFF +bits as set : 3B02AAAAAC4333 +values : 333 44 555555 06 07 +align/size : 1 7 + +---- TEST 2 - PACKED ---- +bits in use : 7FFFFFFFFFFFFFFFFFFFFF +bits as set : 4A48D159E26AF37BC1E003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 1 11 + +---- TEST 3 - PACKED ---- +bits in use : 7FFF000003FF +bits as set : 38D9000002F5 +values : 15 17 19 06 0e +align/size : 1 6 + +---- TEST 4 - PACKED ---- +bits in use : 07FFFF00000027 +bits as set : 078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 7 + +---- TEST 5 - PACKED ---- +bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF +bits as set : 007744000000000F18000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 1 18 + +---- TEST 6 - PACKED ---- +bits in use : 007000FFFFFFFFFFFFFF +bits as set : 0030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 10 + +---- TEST 7 - PACKED ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 01 00 ffffffff 04 05 +align/size : 1 8 + + + +---- TEST 1 - WITH ALIGN ---- +bits in use : 000000000000001FFFFFFFFF007F0FFF +bits as set : 00000000000000076055555500440333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - WITH ALIGN ---- +bits in use : 0000000000000000000000000000003F7FFFFFFFFFFFFFFF00000000003F0FFF +bits as set : 00000000000000000000000000000025123456789ABCDEF000000000001E0003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 16 32 + +---- TEST 3 - WITH ALIGN ---- +bits in use : 0000000000000000000000000000001F000000000000000000001F1F000003FF +bits as set : 0000000000000000000000000000000E000000000000000000000619000002F5 +values : 15 17 19 06 0e +align/size : 16 32 + +---- TEST 4 - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - WITH ALIGN ---- +bits in use : FFFFFF3FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000007800000000300000000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 8 24 + +---- TEST 6 - WITH ALIGN ---- +bits in use : 0000007000FFFFFFFFFFFFFF +bits as set : 00000030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 12 + +---- TEST 7 - WITH ALIGN ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 01 00 ffffffff 04 05 +align/size : 8 8 + + + +---- TEST 1 - PACKED - WITH ALIGN ---- +bits in use : 000000000000000000FFFFFFFFFFFFFF +bits as set : 0000000000000000003B02AAAAAC4333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - PACKED - WITH ALIGN ---- +bits in use : 3F01FFFFFFFFFFFFFFFFFFFF +bits as set : 250048D159E26AF37BC1E003 +values : 03 1e 123456789abcdef0 05 fffffffe +align/size : 1 12 + +---- TEST 3 - PACKED - WITH ALIGN ---- +bits in use : 1F03FF000003FF +bits as set : 0E00D9000002F5 +values : 15 17 19 06 0e +align/size : 1 7 + +---- TEST 4 - PACKED - WITH ALIGN ---- +bits in use : 07FFFF00000027 +bits as set : 078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 7 + +---- TEST 5 - PACKED - WITH ALIGN ---- +bits in use : FFFFFF07FFFFFFFFFFFFFFFF9FFFFFFFFFFF +bits as set : 007744000000000F18000000000123456789 +values : 0000000123456789 f0000000 0000000000000078 44 77 +align/size : 1 18 + +---- TEST 6 - PACKED - WITH ALIGN ---- +bits in use : 007000FFFFFFFFFFFFFF +bits as set : 0030002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 10 + +---- TEST 7 - PACKED - WITH ALIGN ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 01 00 ffffffff 04 05 +align/size : 1 8 diff --git a/tinycc/tests/tests2/95_bitfields_ms.c b/tinycc/tests/tests2/95_bitfields_ms.c new file mode 100644 index 0000000..b196fbd --- /dev/null +++ b/tinycc/tests/tests2/95_bitfields_ms.c @@ -0,0 +1,2 @@ +#define MS_BITFIELDS 1 +#include "95_bitfields.c" diff --git a/tinycc/tests/tests2/95_bitfields_ms.expect b/tinycc/tests/tests2/95_bitfields_ms.expect new file mode 100644 index 0000000..97c46be --- /dev/null +++ b/tinycc/tests/tests2/95_bitfields_ms.expect @@ -0,0 +1,173 @@ +---- TEST 1 - MS-BITFIELDS ---- +bits in use : 0000001FFFFFFFFF0000007F00000FFF +bits as set : 00000007605555550000004400000333 +values : 333 44 555555 06 07 +align/size : 4 16 + +---- TEST 2 - MS-BITFIELDS ---- +bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF +bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 8 32 + +---- TEST 3 - MS-BITFIELDS ---- +bits in use : 001F001F0000001F000003FF +bits as set : 000E000600000019000002F5 +values : 15 17 19 06 0e +align/size : 4 12 + +---- TEST 4 - MS-BITFIELDS ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - MS-BITFIELDS ---- +bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 0000000000770044000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 8 32 + +---- TEST 6 - MS-BITFIELDS ---- +bits in use : 00000000000000700000FFFF000000FFFFFFFFFF +bits as set : 000000000000003000002001000000FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 20 + +---- TEST 7 - MS-BITFIELDS ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 0000000000000001 0000000000000000 ffffffffffffffff 0000000000000004 0000000000000005 +align/size : 8 8 + + + +---- TEST 1 - MS-BITFIELDS - PACKED ---- +bits in use : 0000001FFFFFFFFF7F00000FFF +bits as set : 00000007605555554400000333 +values : 333 44 555555 06 07 +align/size : 1 13 + +---- TEST 2 - MS-BITFIELDS - PACKED ---- +bits in use : 00000000000000030F7FFFFFFFFFFFFFFF3F00000FFF +bits as set : 000000000000000205123456789ABCDEF01E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 1 22 + +---- TEST 3 - MS-BITFIELDS - PACKED ---- +bits in use : 001F1F0000001F000003FF +bits as set : 000E0600000019000002F5 +values : 15 17 19 06 0e +align/size : 1 11 + +---- TEST 4 - MS-BITFIELDS - PACKED ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 8 + +---- TEST 5 - MS-BITFIELDS - PACKED ---- +bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 1 27 + +---- TEST 6 - MS-BITFIELDS - PACKED ---- +bits in use : 00000000700000FFFFFFFFFFFFFF +bits as set : 000000003000002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 14 + +---- TEST 7 - MS-BITFIELDS - PACKED ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 0000000000000001 0000000000000000 ffffffffffffffff 0000000000000004 0000000000000005 +align/size : 1 8 + + + +---- TEST 1 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000001FFFFFFFFF0000007F00000FFF +bits as set : 00000007605555550000004400000333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000000000000003000000000000000F7FFFFFFFFFFFFFFF0000003F00000FFF +bits as set : 00000000000000020000000000000005123456789ABCDEF00000001E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 16 32 + +---- TEST 3 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0000000000000000000000000000001F000000000000001F0000001F000003FF +bits as set : 0000000000000000000000000000000E000000000000000600000019000002F5 +values : 15 17 19 06 0e +align/size : 16 32 + +---- TEST 4 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 4 8 + +---- TEST 5 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 00000000FFFF00FF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 0000000000770044000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 8 32 + +---- TEST 6 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 00000000000000700000FFFF000000FFFFFFFFFF +bits as set : 000000000000003000002001000000FD00000004 +values : 01 02 03 04 fffffffd +align/size : 4 20 + +---- TEST 7 - MS-BITFIELDS - WITH ALIGN ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 0000000000000001 0000000000000000 ffffffffffffffff 0000000000000004 0000000000000005 +align/size : 8 8 + + + +---- TEST 1 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 0000000000001FFFFFFFFF7F00000FFF +bits as set : 00000000000007605555554400000333 +values : 333 44 555555 06 07 +align/size : 16 16 + +---- TEST 2 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 00000000000000030F0000007FFFFFFFFFFFFFFF3F00000FFF +bits as set : 000000000000000205000000123456789ABCDEF01E00000003 +values : 03 1e 123456789abcdef0 05 fffffffffffffffe +align/size : 16 25 + +---- TEST 3 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 001F000000000000001F0000001F000003FF +bits as set : 000E000000000000000600000019000002F5 +values : 15 17 19 06 0e +align/size : 16 18 + +---- TEST 4 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 0007FFFF00000027 +bits as set : 00078F0F00000023 +values : 03 ffffffff 0f fffffff8 78 +align/size : 1 8 + +---- TEST 5 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : FFFFFF0000003FFFFFFFFF000000003FFFFFFF00001FFFFFFFFFFF +bits as set : 007744000000000000007800000000300000000000000123456789 +values : 0000000123456789 fffffffff0000000 0000000000000078 44 77 +align/size : 1 27 + +---- TEST 6 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 00000000700000FFFFFFFFFFFFFF +bits as set : 000000003000002001FD00000004 +values : 01 02 03 04 fffffffd +align/size : 1 14 + +---- TEST 7 - MS-BITFIELDS - PACKED - WITH ALIGN ---- +bits in use : 3FFFFFFFFFFF0000 +bits as set : 0026000100050000 +values : 0000000000000001 0000000000000000 ffffffffffffffff 0000000000000004 0000000000000005 +align/size : 1 8 diff --git a/tinycc/tests/tests2/96_nodata_wanted.c b/tinycc/tests/tests2/96_nodata_wanted.c new file mode 100644 index 0000000..95938b5 --- /dev/null +++ b/tinycc/tests/tests2/96_nodata_wanted.c @@ -0,0 +1,102 @@ +/*****************************************************************************/ +/* test 'nodata_wanted' data output suppression */ + +#if defined test_static_data_error +void foo() { + if (1) { + static short w = (int)&foo; /* initializer not computable */ + } +} + +#elif defined test_static_nodata_error +void foo() { + if (0) { + static short w = (int)&foo; /* initializer not computable */ + } +} + +#elif defined test_global_data_error +void foo(); +static short w = (int)&foo; /* initializer not computable */ + + +#elif defined test_local_data_noerror +void foo() { + short w = &foo; /* 2 cast warnings */ +} + +#elif defined test_data_suppression_off || defined test_data_suppression_on + +#if defined test_data_suppression_on +# define SKIP 1 +#else +# define SKIP 0 +#endif + +#include <stdio.h> +/* some gcc headers #define __attribute__ to empty if it's not gcc */ +#undef __attribute__ + +int main() +{ + __label__ ts0, te0, ts1, te1; + int tl, dl; + + static const char ds0 = 0; + static const char de0 = 0; + /* get reference size of empty jmp */ +ts0:; + if (!SKIP) {} +te0:; + dl = -(&de0 - &ds0); + tl = -(&&te0 - &&ts0); + + /* test data and code suppression */ + static const char ds1 = 0; +ts1:; + if (!SKIP) { + void *p = (void*)&main; + char cc[] = "static string"; + double d = 8.0; + struct +#ifndef __arm__ + __attribute__((packed)) +#endif + { + unsigned x : 12; + unsigned char y : 7; + unsigned z : 28, a: 4, b: 5; + } s = { 0x333,0x44,0x555555,6,7 }; + + printf("data:\n"); + printf(" %d - %.1f - %.1f - %s - %s\n", + sizeof 8.0, 8.0, d, __FUNCTION__, cc); + printf(" %x %x %x %x %x\n", + s.x, s.y, s.z, s.a, s.b); + } +te1:; + static const char de1 = 0; + + dl += &de1 - &ds1; + tl += &&te1 - &&ts1; + printf("size of data/text:\n %s/%s\n", + dl ? "non-zero":"zero", tl ? "non-zero":"zero"); + /*printf("# %d/%d\n", dl, tl);*/ +} + +#elif defined test_static_data + +#include <stdio.h> +int main(int argc, char **argv) +{ + goto there; + if (0) { + static int a = 1; + printf("hello\n"); /* the "hello\n" string is still suppressed */ +there: + printf("a = %d\n", a); + } + return 0; +} + +#endif diff --git a/tinycc/tests/tests2/96_nodata_wanted.expect b/tinycc/tests/tests2/96_nodata_wanted.expect new file mode 100644 index 0000000..92dc9c4 --- /dev/null +++ b/tinycc/tests/tests2/96_nodata_wanted.expect @@ -0,0 +1,26 @@ +[test_static_data_error] +96_nodata_wanted.c:7: error: initializer element is not computable at load time + +[test_static_nodata_error] +96_nodata_wanted.c:14: error: initializer element is not computable at load time + +[test_global_data_error] +96_nodata_wanted.c:20: error: initializer element is not computable at load time + +[test_local_data_noerror] +96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast +96_nodata_wanted.c:25: warning: cast between pointer and integer of different size + +[test_data_suppression_off] +data: + 8 - 8.0 - 8.0 - main - static string + 333 44 555555 6 7 +size of data/text: + non-zero/non-zero + +[test_data_suppression_on] +size of data/text: + zero/zero + +[test_static_data] +a = 1 diff --git a/tinycc/tests/tests2/97_utf8_string_literal.c b/tinycc/tests/tests2/97_utf8_string_literal.c new file mode 100644 index 0000000..5bfb6c8 --- /dev/null +++ b/tinycc/tests/tests2/97_utf8_string_literal.c @@ -0,0 +1,20 @@ +// this file contains BMP chars encoded in UTF-8 +#include <stdio.h> +#include <wchar.h> +#include <stdlib.h> +#include <string.h> + +int main() +{ + char hello_world_in_czech[] = "čau, světe"; + char hello_world_in_czech_ucn[] = "\u010dau, sv\u011bte"; + if (sizeof(hello_world_in_czech) != sizeof(hello_world_in_czech_ucn) + || strcmp(hello_world_in_czech, hello_world_in_czech_ucn)) + abort(); + + wchar_t s[] = L"hello$$你好¢¢世界€€world"; + wchar_t *p; + for (p = s; *p; p++) printf("%04X ", (unsigned) *p); + printf("\n"); + return 0; +} diff --git a/tinycc/tests/tests2/97_utf8_string_literal.expect b/tinycc/tests/tests2/97_utf8_string_literal.expect new file mode 100644 index 0000000..9a1593c --- /dev/null +++ b/tinycc/tests/tests2/97_utf8_string_literal.expect @@ -0,0 +1 @@ +0068 0065 006C 006C 006F 0024 0024 4F60 597D 00A2 00A2 4E16 754C 20AC 20AC 0077 006F 0072 006C 0064 diff --git a/tinycc/tests/tests2/98_al_ax_extend.c b/tinycc/tests/tests2/98_al_ax_extend.c new file mode 100644 index 0000000..1cd6585 --- /dev/null +++ b/tinycc/tests/tests2/98_al_ax_extend.c @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> +asm ( + ".text;" + ".globl _us;.globl _ss;.globl _uc;.globl _sc;" + "_us:;_ss:;_uc:;_sc:;" + "movl $0x1234ABCD, %eax;" + "ret;" +); + +#ifndef __leading_underscore +#define us _us +#define ss _ss +#define uc _uc +#define sc _sc +#endif + +int main() +{ + unsigned short us(void); + short ss(void); + unsigned char uc(void); + signed char sc(void); + + unsigned short (*fpus)(void) = us; + short (*fpss)(void) = ss; + unsigned char (*fpuc)(void) = uc; + signed char (*fpsc)(void) = sc; + + printf("%08X %08X\n", us() + 1, fpus() + 1); + printf("%08X %08X\n", ss() + 1, fpss() + 1); + printf("%08X %08X\n", uc() + 1, fpuc() + 1); + printf("%08X %08X\n", sc() + 1, fpsc() + 1); + printf("\n"); + printf("%08X %08X\n", fpus() + 1, us() + 1); + printf("%08X %08X\n", fpss() + 1, ss() + 1); + printf("%08X %08X\n", fpuc() + 1, uc() + 1); + printf("%08X %08X\n", fpsc() + 1, sc() + 1); + + return 0; +} diff --git a/tinycc/tests/tests2/98_al_ax_extend.expect b/tinycc/tests/tests2/98_al_ax_extend.expect new file mode 100644 index 0000000..c5752e8 --- /dev/null +++ b/tinycc/tests/tests2/98_al_ax_extend.expect @@ -0,0 +1,9 @@ +0000ABCE 0000ABCE +FFFFABCE FFFFABCE +000000CE 000000CE +FFFFFFCE FFFFFFCE + +0000ABCE 0000ABCE +FFFFABCE FFFFABCE +000000CE 000000CE +FFFFFFCE FFFFFFCE diff --git a/tinycc/tests/tests2/99_fastcall.c b/tinycc/tests/tests2/99_fastcall.c new file mode 100644 index 0000000..db97acb --- /dev/null +++ b/tinycc/tests/tests2/99_fastcall.c @@ -0,0 +1,276 @@ +#include <stdio.h> +#include <assert.h> + +#if !(defined( _WIN32) || (defined(__FreeBSD__) && defined(__i386__))) +#define __fastcall __attribute((fastcall)) +#endif + +#ifndef __leading_underscore +#define SYMBOL(x) _##x +#else +#define SYMBOL(x) x +#endif + +///////////////////////////////////////////////////////////////////////// +////////// TRAP FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// if you cast 'TRAP' to a function pointer and call it, +// it will save all 8 registers, +// and jump into C-code (previously set using 'SET_TRAP_HANDLER(x)'), +// in C-code you can pop DWORDs from stack and modify registers +// + +void *SYMBOL(trap_handler); + +extern unsigned char SYMBOL(trap)[]; +asm ( + ".text;" + "_trap:;" + "pushl %esp;" + "pusha;" + "addl $0x4, 0xc(%esp);" + "pushl %esp;" + "call *_trap_handler;" + "addl $0x4, %esp;" + "movl 0xc(%esp), %eax;" + "movl %eax, 0x20(%esp);" + "popa;" + "popl %esp;" + "ret;" +); + +struct trapframe { + unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax; +}; + + +#define M_FLOAT(addr) (*(float *)(addr)) +#define M_DWORD(addr) (*(unsigned *)(addr)) +#define M_WORD(addr) (*(unsigned short *)(addr)) +#define M_BYTE(addr) (*(unsigned char *)(addr)) +#define R_EAX ((tf)->eax) +#define R_ECX ((tf)->ecx) +#define R_EDX ((tf)->edx) +#define R_EBX ((tf)->ebx) +#define R_ESP ((tf)->esp) +#define R_EBP ((tf)->ebp) +#define R_ESI ((tf)->esi) +#define R_EDI ((tf)->edi) + +#define ARG(x) (M_DWORD(R_ESP + (x) * 4)) + +#define RETN(x) do { \ + M_DWORD(R_ESP + (x)) = M_DWORD(R_ESP); \ + R_ESP += (x); \ +} while (0) + +#define DUMP() do { \ + unsigned i; \ + printf("EAX: %08X\n", R_EAX); \ + printf("ECX: %08X\n", R_ECX); \ + printf("EDX: %08X\n", R_EDX); \ + printf("EBX: %08X\n", R_EBX); \ + printf("ESP: %08X\n", R_ESP); \ + printf("EBP: %08X\n", R_EBP); \ + printf("ESI: %08X\n", R_ESI); \ + printf("EDI: %08X\n", R_EDI); \ + printf("\n"); \ + printf("[RETADDR]: %08X\n", M_DWORD(R_ESP)); \ + for (i = 1; i <= 8; i++) { \ + printf("[ARG%4d]: %08X\n", i, ARG(i)); \ + } \ +} while (0) + +#define SET_TRAP_HANDLER(x) ((SYMBOL(trap_handler)) = (x)) +#define TRAP ((void *) &SYMBOL(trap)) + + + +///////////////////////////////////////////////////////////////////////// +////////// SAFECALL FRAMEWORK +///////////////////////////////////////////////////////////////////////// +// this framework will convert any calling convention to cdecl +// usage: first set call target with 'SET_SAFECALL_TARGET(x)' +// then cast 'SAFECALL' to target function pointer type and invoke it +// after calling, 'ESPDIFF' is the difference of old and new esp + +void *SYMBOL(sc_call_target); +unsigned SYMBOL(sc_retn_addr); +unsigned SYMBOL(sc_old_esp); +unsigned SYMBOL(sc_new_esp); + +extern unsigned char SYMBOL(safecall)[]; +asm ( + ".text;" + "_safecall:;" + "popl _sc_retn_addr;" + "movl %esp, _sc_old_esp;" + "call *_sc_call_target;" + "movl %esp, _sc_new_esp;" + "movl _sc_old_esp, %esp;" + "jmp *_sc_retn_addr;" +); + +#define SET_SAFECALL_TARGET(x) ((SYMBOL(sc_call_target)) = (x)) +#define SAFECALL ((void *) &SYMBOL(safecall)) +#define ESPDIFF (SYMBOL(sc_new_esp) - SYMBOL(sc_old_esp)) + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FASTCALL INVOKE +///////////////////////////////////////////////////////////////////////// + +void check_fastcall_invoke_0(struct trapframe *tf) +{ + //DUMP(); + RETN(0); +} + +void check_fastcall_invoke_1(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + RETN(0); +} +void check_fastcall_invoke_2(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + RETN(0); +} +void check_fastcall_invoke_3(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + RETN(1*4); +} +void check_fastcall_invoke_4(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + RETN(2*4); +} + +void check_fastcall_invoke_5(struct trapframe *tf) +{ + //DUMP(); + assert(R_ECX == 0x11111111); + assert(R_EDX == 0x22222222); + assert(ARG(1) == 0x33333333); + assert(ARG(2) == 0x44444444); + assert(ARG(3) == 0x55555555); + RETN(3*4); +} + +void test_fastcall_invoke() +{ + SET_TRAP_HANDLER(check_fastcall_invoke_0); + ((void __fastcall (*)(void)) TRAP)(); + + SET_TRAP_HANDLER(check_fastcall_invoke_1); + ((void __fastcall (*)(unsigned)) TRAP)(0x11111111); + + SET_TRAP_HANDLER(check_fastcall_invoke_2); + ((void __fastcall (*)(unsigned, unsigned)) TRAP)(0x11111111, 0x22222222); + + SET_TRAP_HANDLER(check_fastcall_invoke_3); + ((void __fastcall (*)(unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333); + + SET_TRAP_HANDLER(check_fastcall_invoke_4); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444); + + SET_TRAP_HANDLER(check_fastcall_invoke_5); + ((void __fastcall (*)(unsigned, unsigned, unsigned, unsigned, unsigned)) TRAP)(0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555); +} + + +///////////////////////////////////////////////////////////////////////// +////////// TEST FUNCTION CODE GENERATION +///////////////////////////////////////////////////////////////////////// + +int __fastcall check_fastcall_espdiff_0(void) +{ + return 0; +} + +int __fastcall check_fastcall_espdiff_1(int a) +{ + return a; +} + +int __fastcall check_fastcall_espdiff_2(int a, int b) +{ + return a + b; +} + +int __fastcall check_fastcall_espdiff_3(int a, int b, int c) +{ + return a + b + c; +} + +int __fastcall check_fastcall_espdiff_4(int a, int b, int c, int d) +{ + return a + b + c + d; +} + +int __fastcall check_fastcall_espdiff_5(int a, int b, int c, int d, int e) +{ + return a + b + c + d + e; +} + +void test_fastcall_espdiff() +{ + int x; + SET_SAFECALL_TARGET(check_fastcall_espdiff_0); + x = ((typeof(&check_fastcall_espdiff_0))SAFECALL)(); + assert(x == 0); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_1); + x = ((typeof(&check_fastcall_espdiff_1))SAFECALL)(1); + assert(x == 1); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_2); + x = ((typeof(&check_fastcall_espdiff_2))SAFECALL)(1, 2); + assert(x == 1 + 2); + assert(ESPDIFF == 0); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_3); + x = ((typeof(&check_fastcall_espdiff_3))SAFECALL)(1, 2, 3); + assert(x == 1 + 2 + 3); + assert(ESPDIFF == 1*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_4); + x = ((typeof(&check_fastcall_espdiff_4))SAFECALL)(1, 2, 3, 4); + assert(x == 1 + 2 + 3 + 4); + assert(ESPDIFF == 2*4); + + SET_SAFECALL_TARGET(check_fastcall_espdiff_5); + x = ((typeof(&check_fastcall_espdiff_5))SAFECALL)(1, 2, 3, 4, 5); + assert(x == 1 + 2 + 3 + 4 + 5); + assert(ESPDIFF == 3*4); +} + +int main() +{ +#define N 10000 + int i; + + for (i = 1; i <= N; i++) { + test_fastcall_espdiff(); + } + + for (i = 1; i <= N; i++) { + test_fastcall_invoke(); + } + + puts("TEST OK"); + return 0; +} diff --git a/tinycc/tests/tests2/99_fastcall.expect b/tinycc/tests/tests2/99_fastcall.expect new file mode 100644 index 0000000..3835d63 --- /dev/null +++ b/tinycc/tests/tests2/99_fastcall.expect @@ -0,0 +1 @@ +TEST OK diff --git a/tinycc/tests/tests2/LICENSE b/tinycc/tests/tests2/LICENSE new file mode 100644 index 0000000..b08a652 --- /dev/null +++ b/tinycc/tests/tests2/LICENSE @@ -0,0 +1,37 @@ +The tests in this directory are either directly copied from the picoc project or +are subsequently modified and added to for the purpose of TinyCC project. All +these modifications are licensed under the same terms as TinyCC as specified in +the file COPYING. + +=== picoc license === + +Copyright (c) 2009-2011, Zik Saleeba +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + * Neither the name of the Zik Saleeba nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/tinycc/tests/tests2/Makefile b/tinycc/tests/tests2/Makefile new file mode 100644 index 0000000..92da80e --- /dev/null +++ b/tinycc/tests/tests2/Makefile @@ -0,0 +1,175 @@ +TOP = ../.. +include $(TOP)/Makefile +SRC = $(TOPSRC)/tests/tests2 +VPATH = $(SRC) + +TESTS = $(patsubst %.c,%.test,\ + $(sort $(notdir $(wildcard $(SRC)/??_*.c)))\ + $(sort $(notdir $(wildcard $(SRC)/???_*.c)))) + +# some tests do not pass on all platforms, remove them for now +SKIP = 34_array_assignment.test # array assignment is not in C standard +ifeq (-$(CONFIG_arm_eabi)-$(CONFIG_arm_vfp)-,-yes--) + SKIP += 22_floating_point.test +endif +ifeq (,$(filter i386,$(ARCH))) + SKIP += 98_al_ax_extend.test 99_fastcall.test +endif +ifeq (,$(filter i386 x86_64,$(ARCH))) + SKIP += 85_asm-outside-function.test # x86 asm + SKIP += 127_asm_goto.test # hardcodes x86 asm +endif +ifeq ($(CONFIG_backtrace),no) + SKIP += 113_btdll.test + CONFIG_bcheck = no +# no bcheck without backtrace +endif +ifeq ($(CONFIG_bcheck),no) + SKIP += 112_backtrace.test + SKIP += 114_bound_signal.test + SKIP += 115_bound_setjmp.test + SKIP += 116_bound_setjmp2.test + SKIP += 117_builtins.test + SKIP += 126_bound_global.test +endif +ifeq ($(CONFIG_dll),no) + SKIP += 113_btdll.test # no shared lib support yet +endif +ifeq (-$(findstring gcc,$(CC))-,--) + SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) +endif +ifeq (-$(CONFIG_WIN32)-$(CONFIG_i386)$(CONFIG_arm)-,--yes-) + SKIP += 95_bitfields%.test # type_align is different on 32bit-non-windows +endif +ifeq (-$(CONFIG_WIN32)-,-yes-) + SKIP += 106_versym.test # No pthread support + SKIP += 114_bound_signal.test # No pthread support + SKIP += 117_builtins.test # win32 port doesn't define __builtins + SKIP += 124_atomic_counter.test # No pthread support +endif +ifneq (,$(filter OpenBSD FreeBSD NetBSD,$(TARGETOS))) + SKIP += 106_versym.test # no pthread_condattr_setpshared + SKIP += 114_bound_signal.test # libc problem signal/fork + SKIP += 116_bound_setjmp2.test # No TLS_FUNC/TLS_VAR in bcheck.c +endif + +# Some tests might need arguments +ARGS = +31_args.test : ARGS = arg1 arg2 arg3 arg4 arg5 +46_grep.test : ARGS = '[^* ]*[:a:d: ]+\:\*-/: $$' $(SRC)/46_grep.c + +# And some tests don't test the right thing with -run +NORUN = +42_function_pointer.test : NORUN = true + +# Some tests might need different flags +FLAGS = +76_dollars_in_identifiers.test : FLAGS += -fdollars-in-identifiers + +# These tests run several snippets from the same file one by one +60_errors_and_warnings.test : FLAGS += -dt +96_nodata_wanted.test : FLAGS += -dt + +# Always generate certain .expects (don't put these in the GIT), +GEN-ALWAYS = +# GEN-ALWAYS += 95_bitfields.expect # does not work + +# using the ms compiler for the really ms-compatible bitfields +95_bitfields_ms.test : GEN = $(GEN-MSC) + +# this test compiles/links two files: +104_inline.test : FLAGS += $(subst 104,104+,$1) +104_inline.test : GEN = $(GEN-TCC) + +# this test needs two files, and we want to invoke the linker +120_alias.test : FLAGS += $(subst 120,120+,$1) +120_alias.test : GEN = $(GEN-TCC) +120_alias.test : NORUN = true + +# this test needs pthread +106_versym.test: FLAGS += -pthread +106_versym.test: NORUN = true + +# constructor/destructor +108_constructor.test: NORUN = true + +112_backtrace.test: FLAGS += -dt -b +112_backtrace.test 113_btdll.test 126_bound_global.test: FILTER += \ + -e 's;[0-9A-Fa-fx]\{5,\};........;g' \ + -e 's;0x[0-9A-Fa-f]\{1,\};0x?;g' + +# this test creates two DLLs and an EXE +113_btdll.test: T1 = \ + $(TCC) -bt $1 -shared -D DLL=1 -o a1$(DLLSUF) && \ + $(TCC) -bt $1 -shared -D DLL=2 -o a2$(DLLSUF) && \ + $(TCC) -bt $1 a1$(DLLSUF) a2$(DLLSUF) -Wl,-rpath=. -o $(basename $@).exe && \ + ./$(basename $@).exe + +114_bound_signal.test: FLAGS += -b +114_bound_signal.test: NORUN = true # tcc -run does not support fork and -b and SELINUX +115_bound_setjmp.test: FLAGS += -b +116_bound_setjmp2.test: FLAGS += -b +117_builtins.test: T1 = ( $(TCC) -run $1 && $(TCC) -b -run $1 ) +ifneq ($(CONFIG_bcheck),no) +121_struct_return.test: FLAGS += -b +122_vla_reuse.test: FLAGS += -b +endif +125_atomic_misc.test: FLAGS += -dt +124_atomic_counter.test: FLAGS += -pthread +126_bound_global.test: FLAGS += -b +126_bound_global.test: NORUN = true +128_run_atexit.test: FLAGS += -dt + +# Filter source directory in warnings/errors (out-of-tree builds) +FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' + +all test tests2.all: $(filter-out $(SKIP),$(TESTS)) + @$(MAKE) clean --no-print-directory -s + +%.test: %.c %.expect + @echo Test: $*... + @$(call T1,$<) $(T3) + +T1 = $(TCC) $(FLAGS) $(T2) $(ARGS) +T2 = $(if $(NORUN),$1 -o $(basename $@).exe && ./$(basename $@).exe,-run $1) +T3 = $(FILTER) >$*.output 2>&1 || true \ + && diff -Nbu $(filter %.expect,$^) $*.output \ + && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS)) + +# run single test and update .expect file, e.g. "make tests2.37+" +tests2.%+: + @$(MAKE) $(call F2,$(call F1,$*)) --no-print-directory + +# just run tcc to see the output, e.g. "make tests2.37-" +tests2.%-: + @$(MAKE) $(call F1,$*) T3= --no-print-directory + +# run single test, e.g. "make tests2.37" +tests2.%: + @$(MAKE) $(call F1,$*) --no-print-directory + +F1 = $(or $(filter $1_%,$(TESTS)),$1_???.test) +F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)" + +# automatically generate .expect files with gcc: +%.expect : + @echo Generating: $@ + @$(call GEN,$(SRC)/$*.c) $(FILTER) >$@ 2>&1 + @rm -f *.exe *.obj *.pdb + +# using TCC for .expect if -dt in FLAGS +GEN = $(if $(filter -dt -bt -b,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) +GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o $(basename $@).exe && ./$(basename $@).exe $(ARGS) +GEN-TCC = $(T1) +GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe +MS-CC = cl + +# tell make not to delete +.PRECIOUS: %.expect + +# force .expect generation for these files +$(sort $(GEN-ALWAYS) $(UPDATE)) : force +force: + +clean : + rm -f fred.txt *.output *.exe *.dll *.so *.def $(GEN-ALWAYS) |
