diff options
Diffstat (limited to 'tests/tests2')
70 files changed, 2635 insertions, 35 deletions
diff --git a/tests/tests2/03_struct.c b/tests/tests2/03_struct.c index c5d48c5..fd73133 100644 --- a/tests/tests2/03_struct.c +++ b/tests/tests2/03_struct.c @@ -1,6 +1,13 @@ -#include <stdio.h> +extern int printf(const char*, ...); -struct fred +struct fred; + +void fred$(struct fred* this) +{ + printf("~fred()\n"); +} + +struct __attribute__((__cleanup__(fred$))) fred { int boris; int natasha; @@ -8,7 +15,7 @@ struct fred int main() { - struct fred bloggs; + struct fred __attribute__((__cleanup__(fred$))) bloggs; bloggs.boris = 12; bloggs.natasha = 34; diff --git a/tests/tests2/03_struct.expect b/tests/tests2/03_struct.expect index ecbf589..be8df37 100644 --- a/tests/tests2/03_struct.expect +++ b/tests/tests2/03_struct.expect @@ -1,6 +1,8 @@ +03_struct.c:14: warning: attribute '__cleanup__' ignored on type 12 34 12 34 56 78 +~fred() diff --git a/tests/tests2/07_function.c b/tests/tests2/07_function.c index 0477ce1..006e0a7 100644 --- a/tests/tests2/07_function.c +++ b/tests/tests2/07_function.c @@ -15,6 +15,11 @@ void qfunc() printf("qfunc()\n"); } +void zfunc() +{ + ((void (*)(void))0) (); +} + int main() { printf("%d\n", myfunc(3)); diff --git a/tests/tests2/100_c99array-decls.c b/tests/tests2/100_c99array-decls.c new file mode 100644 index 0000000..46950aa --- /dev/null +++ b/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/tests/tests2/100_c99array-decls.expect b/tests/tests2/100_c99array-decls.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tests2/100_c99array-decls.expect diff --git a/tests/tests2/101_cleanup.c b/tests/tests2/101_cleanup.c new file mode 100644 index 0000000..de5dca2 --- /dev/null +++ b/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/tests/tests2/101_cleanup.expect b/tests/tests2/101_cleanup.expect new file mode 100644 index 0000000..84960cd --- /dev/null +++ b/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/tests/tests2/102_alignas.c b/tests/tests2/102_alignas.c new file mode 100644 index 0000000..62d3ed2 --- /dev/null +++ b/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/tests/tests2/102_alignas.expect b/tests/tests2/102_alignas.expect new file mode 100644 index 0000000..ac6474a --- /dev/null +++ b/tests/tests2/102_alignas.expect @@ -0,0 +1 @@ +1 1 1 1 diff --git a/tests/tests2/103_implicit_memmove.c b/tests/tests2/103_implicit_memmove.c new file mode 100644 index 0000000..1592fb2 --- /dev/null +++ b/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/tests/tests2/103_implicit_memmove.expect b/tests/tests2/103_implicit_memmove.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tests2/103_implicit_memmove.expect diff --git a/tests/tests2/104+_inline.c b/tests/tests2/104+_inline.c new file mode 100644 index 0000000..1209fd4 --- /dev/null +++ b/tests/tests2/104+_inline.c @@ -0,0 +1,54 @@ + +#define GOT(f) \ + __attribute__((weak)) void f(void); \ + printf("%d %s\n", !!f, #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/tests/tests2/104_inline.c b/tests/tests2/104_inline.c new file mode 100644 index 0000000..766f94a --- /dev/null +++ b/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/tests/tests2/104_inline.expect b/tests/tests2/104_inline.expect new file mode 100644 index 0000000..bdb0994 --- /dev/null +++ b/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/tests/tests2/105_local_extern.c b/tests/tests2/105_local_extern.c new file mode 100644 index 0000000..a248bb4 --- /dev/null +++ b/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/tests/tests2/105_local_extern.expect b/tests/tests2/105_local_extern.expect new file mode 100644 index 0000000..445ae74 --- /dev/null +++ b/tests/tests2/105_local_extern.expect @@ -0,0 +1,2 @@ +f +f diff --git a/tests/tests2/106_pthread.c b/tests/tests2/106_pthread.c new file mode 100644 index 0000000..09308ed --- /dev/null +++ b/tests/tests2/106_pthread.c @@ -0,0 +1,17 @@ +#include <stdio.h> +#include <pthread.h> +#include <errno.h> + +int +main(void) +{ + int ret; + pthread_condattr_t attr; + pthread_cond_t condition; + + 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/tests/tests2/106_pthread.expect b/tests/tests2/106_pthread.expect new file mode 100644 index 0000000..9766475 --- /dev/null +++ b/tests/tests2/106_pthread.expect @@ -0,0 +1 @@ +ok diff --git a/tests/tests2/107_stack_safe.c b/tests/tests2/107_stack_safe.c new file mode 100644 index 0000000..479c84d --- /dev/null +++ b/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/tests/tests2/107_stack_safe.expect b/tests/tests2/107_stack_safe.expect new file mode 100644 index 0000000..e9e9cd7 --- /dev/null +++ b/tests/tests2/107_stack_safe.expect @@ -0,0 +1 @@ +1 2 3 4
\ No newline at end of file diff --git a/tests/tests2/108_constructor.c b/tests/tests2/108_constructor.c new file mode 100644 index 0000000..145d0da --- /dev/null +++ b/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/tests/tests2/108_constructor.expect b/tests/tests2/108_constructor.expect new file mode 100644 index 0000000..167ca51 --- /dev/null +++ b/tests/tests2/108_constructor.expect @@ -0,0 +1,3 @@ +constructor +main +destructor diff --git a/tests/tests2/109_float_struct_calling.c b/tests/tests2/109_float_struct_calling.c new file mode 100644 index 0000000..90fc045 --- /dev/null +++ b/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/tests/tests2/109_float_struct_calling.expect b/tests/tests2/109_float_struct_calling.expect new file mode 100644 index 0000000..eaa6787 --- /dev/null +++ b/tests/tests2/109_float_struct_calling.expect @@ -0,0 +1 @@ +5.000000 diff --git a/tests/tests2/110_average.c b/tests/tests2/110_average.c new file mode 100644 index 0000000..273b511 --- /dev/null +++ b/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/tests/tests2/110_average.expect b/tests/tests2/110_average.expect new file mode 100644 index 0000000..4955335 --- /dev/null +++ b/tests/tests2/110_average.expect @@ -0,0 +1 @@ +15 2 diff --git a/tests/tests2/111_conversion.c b/tests/tests2/111_conversion.c new file mode 100644 index 0000000..c0815e1 --- /dev/null +++ b/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/tests/tests2/111_conversion.expect b/tests/tests2/111_conversion.expect new file mode 100644 index 0000000..d81cc07 --- /dev/null +++ b/tests/tests2/111_conversion.expect @@ -0,0 +1 @@ +42 diff --git a/tests/tests2/112_backtrace.c b/tests/tests2/112_backtrace.c new file mode 100644 index 0000000..8489bd3 --- /dev/null +++ b/tests/tests2/112_backtrace.c @@ -0,0 +1,165 @@ +#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 + strchr(&b[0], 'a'); +#elif defined test_bcheck_127 + free(strdup(&b[0])); +#endif +} +/* ------------------------------------------------------- */ +#endif diff --git a/tests/tests2/112_backtrace.expect b/tests/tests2/112_backtrace.expect new file mode 100644 index 0000000..68986c6 --- /dev/null +++ b/tests/tests2/112_backtrace.expect @@ -0,0 +1,142 @@ +[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 strchr +[returns 255] + +[test_bcheck_127] +112_backtrace.c:161: at main: BCHECK: invalid pointer ........, size 0x? in strdup +[returns 255] diff --git a/tests/tests2/113_btdll.c b/tests/tests2/113_btdll.c new file mode 100644 index 0000000..8ae8981 --- /dev/null +++ b/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/tests/tests2/113_btdll.expect b/tests/tests2/113_btdll.expect new file mode 100644 index 0000000..34de481 --- /dev/null +++ b/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/tests/tests2/114_bound_signal.c b/tests/tests2/114_bound_signal.c new file mode 100644 index 0000000..d7d7feb --- /dev/null +++ b/tests/tests2/114_bound_signal.c @@ -0,0 +1,110 @@ +#include <stdio.h> +#include <pthread.h> +#include <semaphore.h> +#include <signal.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> +#include <errno.h> +#include <setjmp.h> + +/* See tcc-doc.info */ +#if defined(__TINYC__) && __BOUNDS_CHECKING_ON +#undef __attribute__ +extern void __bound_checking (int no_check); +#define BOUNDS_CHECKING_OFF __bound_checking(1) +#define BOUNDS_CHECKING_ON __bound_checking(-1) +#define BOUNDS_NO_CHECKING __attribute__((bound_no_checking)) +#else +#define BOUNDS_CHECKING_OFF +#define BOUNDS_CHECKING_ON +#define BOUNDS_NO_CHECKING +#endif + +static volatile int run = 1; +static int dummy[10]; +static sem_t sem; + +static void +add (void) BOUNDS_NO_CHECKING +{ + int i; + + for (i = 0; i < (sizeof(dummy)/sizeof(dummy[0])); i++) { + dummy[i]++; + } + /* Should not be translated into __bound_memset */ + memset (&dummy[0], 0, sizeof(dummy)); +} + +static void * +high_load (void *unused) +{ + while (run) { + add(); + } + return NULL; +} + +static void * +do_signal (void *unused) +{ + while (run) { + kill (getpid(), SIGUSR1); + while (sem_wait(&sem) < 0 && errno == EINTR); + } + return NULL; +} + +static void signal_handler(int sig) BOUNDS_NO_CHECKING +{ + add(); + sem_post (&sem); +} + +int +main (void) +{ + int i; + pthread_t id1, id2; + 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); + + sem_init (&sem, 1, 0); + pthread_create(&id1, NULL, high_load, NULL); + pthread_create(&id2, NULL, do_signal, NULL); + + printf ("start\n"); + /* sleep does not work !!! */ + end = time(NULL) + 2; + while (time(NULL) < end) ; + run = 0; + printf ("end\n"); + + pthread_join(id1, NULL); + pthread_join(id2, NULL); + sem_destroy (&sem); + + 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/tests/tests2/114_bound_signal.expect b/tests/tests2/114_bound_signal.expect new file mode 100644 index 0000000..5d0fb3b --- /dev/null +++ b/tests/tests2/114_bound_signal.expect @@ -0,0 +1,2 @@ +start +end diff --git a/tests/tests2/115_bound_setjmp.c b/tests/tests2/115_bound_setjmp.c new file mode 100644 index 0000000..c402144 --- /dev/null +++ b/tests/tests2/115_bound_setjmp.c @@ -0,0 +1,169 @@ +#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) { + case 0: + jump (0); + 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/tests/tests2/115_bound_setjmp.expect b/tests/tests2/115_bound_setjmp.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tests2/115_bound_setjmp.expect diff --git a/tests/tests2/116_bound_setjmp2.c b/tests/tests2/116_bound_setjmp2.c new file mode 100644 index 0000000..151114d --- /dev/null +++ b/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/tests/tests2/116_bound_setjmp2.expect b/tests/tests2/116_bound_setjmp2.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tests2/116_bound_setjmp2.expect diff --git a/tests/tests2/117_gcc_test.c b/tests/tests2/117_gcc_test.c new file mode 100644 index 0000000..aed62e2 --- /dev/null +++ b/tests/tests2/117_gcc_test.c @@ -0,0 +1,158 @@ +#include <stdio.h> + +void tst_branch(void) +{ + goto *&&a; + printf ("dummy"); +a: ; +} + +void tst_void_ptr(void *pv, int i) +{ + i ? *pv : *pv; // dr106 +} + +void tst_shift(void) +{ + int i = 1; + 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) { +#if !defined(__riscv) + *(int *)0x20000000 += 42; +#endif + munmap (addr, 4096); + } +} +#endif + +struct zero_struct {}; + +struct zero_struct tst_zero_struct(void) +{ + struct zero_struct ret; + + return ret; +} + +struct big_struct { char a[262144]; }; + +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); +} + +static const char str[] = "abcdefghijklmnopqrstuvwxyz"; + +void tst_builtin(void) +{ + char *p; + char tmp[100]; + + if (__builtin_offsetof(struct big_struct, a) != 0) __builtin_abort(); + + p = __builtin_memcpy (tmp, str, sizeof(str)); + if (p != tmp) __builtin_abort(); + + if (__builtin_memcmp (p, str, sizeof(str))) __builtin_abort(); + + p = __builtin_memmove(tmp, str, sizeof(str)); + if (__builtin_memcmp (p, str, sizeof(str))) __builtin_abort(); + + p = __builtin_memset(tmp, 0, sizeof (tmp)); + if (p != tmp || tmp[0] != 0 || tmp[99] != 0) __builtin_abort(); + + if (__builtin_strlen(str) != sizeof(str) - 1) __builtin_abort(); + + p = __builtin_strcpy(tmp, str); + if (__builtin_memcmp (p, str, sizeof(str))) __builtin_abort(); + + p = __builtin_strncpy(tmp, str, sizeof(str)); + if (__builtin_memcmp (p, str, sizeof(str))) __builtin_abort(); + + if (__builtin_strcmp (p, str)) __builtin_abort(); + + if (__builtin_strncmp (p, str, sizeof(str))) __builtin_abort(); + + tmp[0] = '\0'; + p = __builtin_strcat(tmp, str); + if (__builtin_memcmp (p, str, sizeof(str))) __builtin_abort(); + + if (__builtin_strchr(p, 'z') != &p[25]) __builtin_abort(); + + p = __builtin_strdup (str); + if (__builtin_memcmp (p, str, sizeof(str))) __builtin_abort(); + __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 +} + +int tst(void) +{ + long value = 3; + return -value; +} + +void tst_compare(void) +{ + /* This failed on risc64 */ + if (tst() > 0) printf ("error\n"); +} + +#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; + if (j.f != i.f) printf("error\n"); +} + +int +main (void) +{ + struct big_struct big; + + 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_builtin(); + tst_compare(); + tst_pack(); +} diff --git a/tests/tests2/117_gcc_test.expect b/tests/tests2/117_gcc_test.expect new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tests/tests2/117_gcc_test.expect diff --git a/tests/tests2/11_precedence.c b/tests/tests2/11_precedence.c index db2049d..845b6bf 100644 --- a/tests/tests2/11_precedence.c +++ b/tests/tests2/11_precedence.c @@ -1,4 +1,5 @@ -#include <stdio.h> +//#include <stdio.h> +extern int printf(const char *, ...); int main() { diff --git a/tests/tests2/22_floating_point.c b/tests/tests2/22_floating_point.c index e3491f5..2eb062c 100644 --- a/tests/tests2/22_floating_point.c +++ b/tests/tests2/22_floating_point.c @@ -1,6 +1,19 @@ #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() { // variables diff --git a/tests/tests2/33_ternary_op.c b/tests/tests2/33_ternary_op.c index 8579b50..1e6b56d 100644 --- a/tests/tests2/33_ternary_op.c +++ b/tests/tests2/33_ternary_op.c @@ -1,4 +1,43 @@ -#include <stdio.h> +#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 main() { @@ -9,6 +48,32 @@ int main() 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; + } + + return 0; } diff --git a/tests/tests2/33_ternary_op.expect b/tests/tests2/33_ternary_op.expect index 45ea507..497be0e 100644 --- a/tests/tests2/33_ternary_op.expect +++ b/tests/tests2/33_ternary_op.expect @@ -1,3 +1,4 @@ +33_ternary_op.c:26: warning: pointer/integer mismatch in conditional expression 0 1 4 @@ -8,3 +9,4 @@ 21 24 27 +152 diff --git a/tests/tests2/46_grep.c b/tests/tests2/46_grep.c index 049dfb1..acda793 100644 --- a/tests/tests2/46_grep.c +++ b/tests/tests2/46_grep.c @@ -456,11 +456,13 @@ char *pmatch(char *line, char *pattern) while (*l && (e = pmatch(l, p))) l = e; /* Get longest match */ while (*p++ != ENDPAT); /* Skip over pattern */ - while (l >= are) { /* Try to match rest */ + 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: diff --git a/tests/tests2/60_errors_and_warnings.c b/tests/tests2/60_errors_and_warnings.c index 0028caf..fd4367a 100644 --- a/tests/tests2/60_errors_and_warnings.c +++ b/tests/tests2/60_errors_and_warnings.c @@ -48,4 +48,302 @@ 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"); + _Static_assert(ONE == 1, "ONE is not 1"); + +#elif defined test_static_assert_2 + _Static_assert(1, "1"" is 1"); + _Static_assert(0, "0"" is 0"); + +#elif defined test_static_assert_c2x + _Static_assert(1); + _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" } }; + #endif diff --git a/tests/tests2/60_errors_and_warnings.expect b/tests/tests2/60_errors_and_warnings.expect index ed6a690..984e4c1 100644 --- a/tests/tests2/60_errors_and_warnings.expect +++ b/tests/tests2/60_errors_and_warnings.expect @@ -20,9 +20,145 @@ 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_void_array] +60_errors_and_warnings.c:205: error: declaration of an array of incomplete type elements + +[test_incomplete_enum_array] +60_errors_and_warnings.c:208: error: declaration of an array of incomplete type elements + +[test_incomplete_struct_array] +60_errors_and_warnings.c:211: error: declaration of an array of incomplete type elements + +[test_const_fun_array] +60_errors_and_warnings.c:215: error: declaration of an array of functions + +[test_incomplete_array_array] + +[test_extern_array] +60_errors_and_warnings.c:231: 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:261: 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:261: error: incompatible types for redefinition of 'hello' + +[test_func_6] +60_errors_and_warnings.c:249: 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:293: error: incompatible types for redefinition of 'xxx' + +[test_var_4] + +[test_long_double_type_for_win32] +60_errors_and_warnings.c:324: warning: assignment from incompatible pointer type + +[test_stray_backslash] +60_errors_and_warnings.c:330: error: stray '\' in program + +[test_stray_backslash2] +\n + +[test_var_array] +60_errors_and_warnings.c:345: warning: initializer-string for array is too long diff --git a/tests/tests2/61_integers.c b/tests/tests2/61_integers.c new file mode 100644 index 0000000..de29b3c --- /dev/null +++ b/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/tests/tests2/61_integers.expect b/tests/tests2/61_integers.expect new file mode 100644 index 0000000..22c8d1b --- /dev/null +++ b/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/tests/tests2/73_arm64.c b/tests/tests2/73_arm64.c index 8de61b3..855c476 100644 --- a/tests/tests2/73_arm64.c +++ b/tests/tests2/73_arm64.c @@ -230,6 +230,17 @@ void ret(void) 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; diff --git a/tests/tests2/81_types.c b/tests/tests2/81_types.c index fd6d71b..0bc3bae 100644 --- a/tests/tests2/81_types.c +++ b/tests/tests2/81_types.c @@ -39,5 +39,17 @@ 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/tests/tests2/82_attribs_position.c b/tests/tests2/82_attribs_position.c index 7c9f987..fd3f2c4 100644 --- a/tests/tests2/82_attribs_position.c +++ b/tests/tests2/82_attribs_position.c @@ -16,4 +16,50 @@ void __attribute__((stdcall)) foo (void) { } -int main () { return 0; } +#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; +} + +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/tests/tests2/82_attribs_position.expect b/tests/tests2/82_attribs_position.expect index e69de29..daaac9e 100644 --- a/tests/tests2/82_attribs_position.expect +++ b/tests/tests2/82_attribs_position.expect @@ -0,0 +1,2 @@ +42 +42 diff --git a/tests/tests2/85_asm-outside-function.c b/tests/tests2/85_asm-outside-function.c index dc5639a..3d7434d 100644 --- a/tests/tests2/85_asm-outside-function.c +++ b/tests/tests2/85_asm-outside-function.c @@ -1,6 +1,12 @@ +#ifdef __leading_underscore +# define _ "_" +#else +# define _ +#endif + extern int printf (const char *, ...); extern void vide(void); -__asm__("vide: ret"); +__asm__(_"vide: ret"); int main() { vide(); diff --git a/tests/tests2/87_dead_code.c b/tests/tests2/87_dead_code.c index 98d4566..0d5a64c 100644 --- a/tests/tests2/87_dead_code.c +++ b/tests/tests2/87_dead_code.c @@ -26,6 +26,36 @@ static void kb_wait_1(void) 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()); +} + int main (void) { int i = 1; @@ -118,5 +148,8 @@ enterloop3: printf ("error4\n"); } } + + dowhile(); + return 0; } diff --git a/tests/tests2/87_dead_code.expect b/tests/tests2/87_dead_code.expect index 0b3ec1d..a8c93bd 100644 --- a/tests/tests2/87_dead_code.expect +++ b/tests/tests2/87_dead_code.expect @@ -16,3 +16,8 @@ once3 twice3 caseok caseok2 +g=1 +check 1 +g=2 +check 2 +g=3 diff --git a/tests/tests2/88_codeopt.c b/tests/tests2/88_codeopt.c index 647626f..2ab4c8a 100644 --- a/tests/tests2/88_codeopt.c +++ b/tests/tests2/88_codeopt.c @@ -1,7 +1,7 @@ /* Check some way in where code suppression caused various miscompilations. */ extern int printf (const char *, ...); -typedef unsigned long size_t; +typedef __SIZE_TYPE__ size_t; size_t _brk_start, _brk_end; void * extend_brk(size_t size, size_t align) @@ -51,6 +51,7 @@ _Bool chk(unsigned long addr, unsigned long limit, unsigned long size) only with certain internal checking added that's not committed). */ if (0) ret = 0 != (!!(addr > limit - size)); + return 0; } int main() diff --git a/tests/tests2/90_struct-init.c b/tests/tests2/90_struct-init.c index d931e23..ade7fad 100644 --- a/tests/tests2/90_struct-init.c +++ b/tests/tests2/90_struct-init.c @@ -87,6 +87,13 @@ 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, ... @@ -166,6 +173,14 @@ void foo (struct W *w, struct pkthdr *phdr_) 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); @@ -182,7 +197,10 @@ void foo (struct W *w, struct pkthdr *phdr_) print(lv2); print(lv3); print(lt2); + print(lssu1); + print(lssu2); print(flow); + print(ls4); } #endif @@ -272,6 +290,8 @@ int main() print(guv.b); print(guv2); print(guv3); + print(gssu1); + print(gssu2); print(phdr); foo(&gw, &phdr); //printf("q: %s\n", q); diff --git a/tests/tests2/90_struct-init.expect b/tests/tests2/90_struct-init.expect index e366121..c55cb47 100644 --- a/tests/tests2/90_struct-init.expect +++ b/tests/tests2/90_struct-init.expect @@ -17,6 +17,8 @@ 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 @@ -34,7 +36,10 @@ 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 two three diff --git a/tests/tests2/92_enum_bitfield.c b/tests/tests2/92_enum_bitfield.c index bb6dc35..fb8f7a3 100644 --- a/tests/tests2/92_enum_bitfield.c +++ b/tests/tests2/92_enum_bitfield.c @@ -45,6 +45,7 @@ int convert_like_real (tree convs) break; }; printf("unsigned enum bit-fields broken\n"); + return 0; } int main() diff --git a/tests/tests2/94_generic.c b/tests/tests2/94_generic.c index d7fb5fc..6e85c02 100644 --- a/tests/tests2/94_generic.c +++ b/tests/tests2/94_generic.c @@ -20,6 +20,12 @@ int b_f() return 10; } +typedef int (*fptr)(int); +int foo(int i) +{ + return i; +} + typedef int int_type1; #define gen_sw(a) _Generic(a, const char *: 1, default: 8, int: 123); @@ -60,5 +66,50 @@ int main() long long: "long long")); i = _Generic(l, long: 1, int: 2); printf("%d\n", i); + i = _Generic(foo, fptr: 3, int: 4); + 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); + //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/tests/tests2/94_generic.expect b/tests/tests2/94_generic.expect index 9aa9275..748d78f 100644 --- a/tests/tests2/94_generic.expect +++ b/tests/tests2/94_generic.expect @@ -10,4 +10,5 @@ 3 4 long -1
\ No newline at end of file +1 +3 diff --git a/tests/tests2/95_bitfields.c b/tests/tests2/95_bitfields.c index f025c57..4ac38da 100644 --- a/tests/tests2/95_bitfields.c +++ b/tests/tests2/95_bitfields.c @@ -78,6 +78,27 @@ } /* ----------------------------------------------------------------------- */ +#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 @@ -101,6 +122,8 @@ top = 0; #include SELF #define TEST 6 #include SELF +#define TEST 7 +#include SELF #if PACK # pragma pack(pop) diff --git a/tests/tests2/95_bitfields.expect b/tests/tests2/95_bitfields.expect index 6a8fd9a..215055d 100644 --- a/tests/tests2/95_bitfields.expect +++ b/tests/tests2/95_bitfields.expect @@ -34,6 +34,12 @@ 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 ---- @@ -72,6 +78,12 @@ 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 ---- @@ -110,6 +122,12 @@ 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 ---- @@ -147,3 +165,9 @@ 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/tests/tests2/95_bitfields_ms.expect b/tests/tests2/95_bitfields_ms.expect index 8ccafb7..97c46be 100644 --- a/tests/tests2/95_bitfields_ms.expect +++ b/tests/tests2/95_bitfields_ms.expect @@ -34,6 +34,12 @@ 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 ---- @@ -72,6 +78,12 @@ 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 ---- @@ -110,6 +122,12 @@ 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 ---- @@ -147,3 +165,9 @@ 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/tests/tests2/96_nodata_wanted.c b/tests/tests2/96_nodata_wanted.c index cc211d3..790b431 100644 --- a/tests/tests2/96_nodata_wanted.c +++ b/tests/tests2/96_nodata_wanted.c @@ -55,11 +55,10 @@ te0:; static char ds1 = 0; ts1:; if (!SKIP) { - static void *p = (void*)&main; - static char cc[] = "static string"; - static double d = 8.0; - - static struct __attribute__((packed)) { + void *p = (void*)&main; + char cc[] = "static string"; + double d = 8.0; + struct __attribute__((packed)) { unsigned x : 12; unsigned char y : 7; unsigned z : 28, a: 4, b: 5; @@ -81,4 +80,19 @@ te1:; /*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/tests/tests2/96_nodata_wanted.expect b/tests/tests2/96_nodata_wanted.expect index 2749109..92dc9c4 100644 --- a/tests/tests2/96_nodata_wanted.expect +++ b/tests/tests2/96_nodata_wanted.expect @@ -9,7 +9,7 @@ [test_local_data_noerror] 96_nodata_wanted.c:25: warning: assignment makes integer from pointer without a cast -96_nodata_wanted.c:25: warning: nonportable conversion from pointer to char/short +96_nodata_wanted.c:25: warning: cast between pointer and integer of different size [test_data_suppression_off] data: @@ -21,3 +21,6 @@ size of data/text: [test_data_suppression_on] size of data/text: zero/zero + +[test_static_data] +a = 1 diff --git a/tests/tests2/98_al_ax_extend.c b/tests/tests2/98_al_ax_extend.c index 9b4e02f..1cd6585 100644 --- a/tests/tests2/98_al_ax_extend.c +++ b/tests/tests2/98_al_ax_extend.c @@ -8,7 +8,7 @@ asm ( "ret;" ); -#if 1 +#ifndef __leading_underscore #define us _us #define ss _ss #define uc _uc diff --git a/tests/tests2/99_fastcall.c b/tests/tests2/99_fastcall.c index ee4b67d..8fbc904 100644 --- a/tests/tests2/99_fastcall.c +++ b/tests/tests2/99_fastcall.c @@ -5,7 +5,7 @@ #define __fastcall __attribute((fastcall)) #endif -#if 1 +#ifndef __leading_underscore #define SYMBOL(x) _##x #else #define SYMBOL(x) x diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 190b2d9..8b169b4 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -3,7 +3,9 @@ include $(TOP)/Makefile SRC = $(TOPSRC)/tests/tests2 VPATH = $(SRC) -TESTS = $(patsubst %.c,%.test,$(sort $(notdir $(wildcard $(SRC)/*.c)))) +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 @@ -12,7 +14,7 @@ ifeq ($(CONFIG_arm_eabi),yes) # not ARM soft-float endif ifdef CONFIG_OSX SKIP += 40_stdio.test 42_function_pointer.test - FLAGS += -w + SKIP += 113_btdll.test # no shared lib support yet endif ifeq ($(ARCH),x86_64) SKIP += 73_arm64.test @@ -21,7 +23,17 @@ 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 + SKIP += 85_asm-outside-function.test # x86 asm + SKIP += 113_btdll.test # dll support needed +endif +ifeq (,$(filter i386 x86_64 arm arm64 riscv64,$(ARCH))) + SKIP += 112_backtrace.test + SKIP += 114_bound_signal.test + SKIP += 115_bound_setjmp.test + SKIP += 116_bound_setjmp2.test +endif +ifeq (-$(CONFIG_musl)-,-yes-) + SKIP += 112_backtrace.test endif ifeq (-$(findstring gcc,$(CC))-,--) SKIP += $(patsubst %.expect,%.test,$(GEN-ALWAYS)) @@ -29,6 +41,10 @@ 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_pthread.test # No pthread support + SKIP += 114_bound_signal.test # No pthread support +endif # Some tests might need arguments ARGS = @@ -54,21 +70,47 @@ GEN-ALWAYS = # 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 pthread +106_pthread.test: FLAGS += -pthread +106_pthread.test: NORUN = true + +# constructor/destructor +108_constructor.test: NORUN = true + +112_backtrace.test: FLAGS += -dt -b +112_backtrace.test 113_btdll.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: NORUN = true +113_btdll.test: FLAGS += \ + -bt $1 -shared -D DLL=1 -o a1$(DLLSUF) && $(TCC) \ + -bt $1 -shared -D DLL=2 -o a2$(DLLSUF) && $(TCC) \ + -bt a1$(DLLSUF) a2$(DLLSUF) -Wl,-rpath=. + +114_bound_signal.test: FLAGS += -b +115_bound_setjmp.test: FLAGS += -b +116_bound_setjmp2.test: FLAGS += -b + +117_gcc_test.test: FLAGS += $(T2) && $(TCC) -b + # Filter source directory in warnings/errors (out-of-tree builds) -FILTER = 2>&1 | sed 's,$(SRC)/,,g' -# Filter some always-warning -ifeq (-$(findstring arm,$(ARCH))-,-arm-) -FILTER += 2>&1 | grep -v 'warning: soft float ABI currently not supported' -endif +FILTER = 2>&1 | sed -e 's,$(SRC)/,,g' -all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ; +all test tests2.all: $(filter-out $(SKIP),$(TESTS)) + @$(MAKE) clean --no-print-directory -s %.test: %.c %.expect @echo Test: $*... - @$(if $(NORUN),$(T1),$(T2)) $(if $(NODIFF),,$(T3)) + @$(call T1,$<) $(T3) -T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS) -T2 = $(TCC) $(FLAGS) -run $< $(ARGS) +T1 = $(TCC) $(FLAGS) $(T2) $(ARGS) +T2 = $(if $(NORUN),$1 -o a.exe && ./a.exe,-run $1) T3 = $(FILTER) >$*.output 2>&1 || true \ && diff -Nbu $(filter %.expect,$^) $*.output \ && rm -f $*.output $(filter $*.expect,$(GEN-ALWAYS)) @@ -79,7 +121,7 @@ tests2.%+: # just run tcc to see the output, e.g. "make tests2.37-" tests2.%-: - @$(MAKE) $(call F1,$*) NODIFF=true --no-print-directory + @$(MAKE) $(call F1,$*) T3= --no-print-directory # run single test, e.g. "make tests2.37" tests2.%: @@ -95,9 +137,9 @@ F2 = $1 UPDATE="$(patsubst %.test,%.expect,$1)" @rm -f *.exe *.obj *.pdb # using TCC for .expect if -dt in FLAGS -GEN = $(if $(filter -dt,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) +GEN = $(if $(filter -dt -bt -b,$(FLAGS)),$(GEN-TCC),$(GEN-CC)) GEN-CC = $(CC) -w -std=gnu99 $(FLAGS) $1 -o a.exe && ./a.exe $(ARGS) -GEN-TCC = $(TCC) $(FLAGS) -run $1 $(ARGS) +GEN-TCC = $(T1) GEN-MSC = $(MS-CC) $1 && ./$(basename $@).exe MS-CC = cl @@ -108,5 +150,5 @@ MS-CC = cl $(sort $(GEN-ALWAYS) $(UPDATE)) : force force: -clean: - rm -f fred.txt *.output a.exe $(GEN-ALWAYS) +clean : + rm -f fred.txt *.output a.exe *.dll *.so *.def $(GEN-ALWAYS) |