From e2ccf3981d78dfeb390d22c74625b60310100abb Mon Sep 17 00:00:00 2001 From: Thomas Preud'homme Date: Wed, 21 Feb 2018 23:16:20 +0000 Subject: New upstream version 0.9.27 --- tests/Makefile | 99 +++++--- tests/abitest.c | 44 +++- tests/asm-c-connect-1.c | 57 +++++ tests/asm-c-connect-2.c | 36 +++ tests/asmtest.S | 20 ++ tests/gcctestsuite.sh | 0 tests/libtcc_test.c | 4 + tests/pp/13.expect | 1 - tests/pp/15.c | 6 +- tests/pp/15.expect | 2 - tests/pp/18.c | 15 ++ tests/pp/18.expect | 3 + tests/pp/19.c | 101 ++++++++ tests/pp/19.expect | 14 + tests/pp/20.c | 13 + tests/pp/20.expect | 6 + tests/pp/21.c | 36 +++ tests/pp/21.expect | 8 + tests/pp/Makefile | 21 +- tests/pp/pp-counter.c | 27 ++ tests/pp/pp-counter.expect | 15 ++ tests/tcctest.c | 222 ++++++++++++++-- tests/tcctest.py | 15 -- tests/tests2/17_enum.c | 43 ++++ tests/tests2/17_enum.expect | 1 + tests/tests2/39_typedef.c | 18 ++ tests/tests2/42_function_pointer.c | 6 +- tests/tests2/56_btype_excess-1.c | 1 - tests/tests2/56_btype_excess-1.expect | 1 - tests/tests2/57_btype_excess-2.c | 1 - tests/tests2/57_btype_excess-2.expect | 1 - tests/tests2/58_function_redefinition.c | 9 - tests/tests2/58_function_redefinition.expect | 1 - tests/tests2/59_function_array.c | 1 - tests/tests2/59_function_array.expect | 1 - tests/tests2/60_enum_redefinition.c | 4 - tests/tests2/60_enum_redefinition.expect | 1 - tests/tests2/60_errors_and_warnings.c | 51 ++++ tests/tests2/60_errors_and_warnings.expect | 28 ++ tests/tests2/61_undefined_enum.c | 1 - tests/tests2/61_undefined_enum.expect | 1 - tests/tests2/62_enumerator_redefinition.c | 4 - tests/tests2/62_enumerator_redefinition.expect | 1 - tests/tests2/63_local_enumerator_redefinition.c | 14 - .../tests2/63_local_enumerator_redefinition.expect | 0 tests/tests2/74_nocode_wanted.c | 1 - tests/tests2/74_nocode_wanted.expect | 1 - tests/tests2/81_types.c | 34 +++ tests/tests2/82_attribs_position.c | 5 + tests/tests2/82_nocode_wanted.c | 112 -------- tests/tests2/82_nocode_wanted.expect | 14 - tests/tests2/84-hex-float.c | 12 - tests/tests2/84-hex-float.expect | 1 - tests/tests2/84_hex-float.c | 12 + tests/tests2/84_hex-float.expect | 1 + tests/tests2/85-asm-outside-function.c | 7 - tests/tests2/85-asm-outside-function.expect | 0 tests/tests2/85_asm-outside-function.c | 9 + tests/tests2/85_asm-outside-function.expect | 1 + tests/tests2/86-memory-model.c | 38 --- tests/tests2/86-memory-model.expect | 1 - tests/tests2/86-struct-init.c | 248 ------------------ tests/tests2/86-struct-init.expect | 40 --- tests/tests2/86_memory-model.c | 38 +++ tests/tests2/86_memory-model.expect | 1 + tests/tests2/87_dead_code.c | 2 +- tests/tests2/87_ptr_longlong_arith32.c | 15 -- tests/tests2/87_ptr_longlong_arith32.expect | 1 - tests/tests2/88_codeopt.c | 68 +++++ tests/tests2/88_codeopt.expect | 2 + tests/tests2/89_nocode_wanted.c | 112 ++++++++ tests/tests2/89_nocode_wanted.expect | 14 + tests/tests2/90_struct-init.c | 282 +++++++++++++++++++++ tests/tests2/90_struct-init.expect | 43 ++++ tests/tests2/91_ptr_longlong_arith32.c | 15 ++ tests/tests2/91_ptr_longlong_arith32.expect | 1 + tests/tests2/92_enum_bitfield.c | 57 +++++ tests/tests2/92_enum_bitfield.expect | 0 tests/tests2/93_integer_promotion.c | 71 ++++++ tests/tests2/93_integer_promotion.expect | 46 ++++ tests/tests2/94_generic.c | 64 +++++ tests/tests2/94_generic.expect | 13 + tests/tests2/95_bitfields.c | 218 ++++++++++++++++ tests/tests2/95_bitfields.expect | 149 +++++++++++ tests/tests2/95_bitfields_ms.c | 2 + tests/tests2/95_bitfields_ms.expect | 149 +++++++++++ tests/tests2/96_nodata_wanted.c | 84 ++++++ tests/tests2/96_nodata_wanted.expect | 23 ++ tests/tests2/97_utf8_string_literal.c | 12 + tests/tests2/97_utf8_string_literal.expect | 1 + tests/tests2/98_al_ax_extend.c | 41 +++ tests/tests2/98_al_ax_extend.expect | 9 + tests/tests2/99_fastcall.c | 276 ++++++++++++++++++++ tests/tests2/99_fastcall.expect | 1 + tests/tests2/Makefile | 97 +++++-- 95 files changed, 2748 insertions(+), 650 deletions(-) create mode 100644 tests/asm-c-connect-1.c create mode 100644 tests/asm-c-connect-2.c mode change 100644 => 100755 tests/gcctestsuite.sh create mode 100644 tests/pp/18.c create mode 100644 tests/pp/18.expect create mode 100644 tests/pp/19.c create mode 100644 tests/pp/19.expect create mode 100644 tests/pp/20.c create mode 100644 tests/pp/20.expect create mode 100644 tests/pp/21.c create mode 100644 tests/pp/21.expect create mode 100644 tests/pp/pp-counter.c create mode 100644 tests/pp/pp-counter.expect delete mode 100644 tests/tcctest.py delete mode 100644 tests/tests2/56_btype_excess-1.c delete mode 100644 tests/tests2/56_btype_excess-1.expect delete mode 100644 tests/tests2/57_btype_excess-2.c delete mode 100644 tests/tests2/57_btype_excess-2.expect delete mode 100644 tests/tests2/58_function_redefinition.c delete mode 100644 tests/tests2/58_function_redefinition.expect delete mode 100644 tests/tests2/59_function_array.c delete mode 100644 tests/tests2/59_function_array.expect delete mode 100644 tests/tests2/60_enum_redefinition.c delete mode 100644 tests/tests2/60_enum_redefinition.expect create mode 100644 tests/tests2/60_errors_and_warnings.c create mode 100644 tests/tests2/60_errors_and_warnings.expect delete mode 100644 tests/tests2/61_undefined_enum.c delete mode 100644 tests/tests2/61_undefined_enum.expect delete mode 100644 tests/tests2/62_enumerator_redefinition.c delete mode 100644 tests/tests2/62_enumerator_redefinition.expect delete mode 100644 tests/tests2/63_local_enumerator_redefinition.c delete mode 100644 tests/tests2/63_local_enumerator_redefinition.expect delete mode 100644 tests/tests2/74_nocode_wanted.c delete mode 100644 tests/tests2/74_nocode_wanted.expect delete mode 100644 tests/tests2/82_nocode_wanted.c delete mode 100644 tests/tests2/82_nocode_wanted.expect delete mode 100644 tests/tests2/84-hex-float.c delete mode 100644 tests/tests2/84-hex-float.expect create mode 100644 tests/tests2/84_hex-float.c create mode 100644 tests/tests2/84_hex-float.expect delete mode 100644 tests/tests2/85-asm-outside-function.c delete mode 100644 tests/tests2/85-asm-outside-function.expect create mode 100644 tests/tests2/85_asm-outside-function.c create mode 100644 tests/tests2/85_asm-outside-function.expect delete mode 100755 tests/tests2/86-memory-model.c delete mode 100755 tests/tests2/86-memory-model.expect delete mode 100644 tests/tests2/86-struct-init.c delete mode 100644 tests/tests2/86-struct-init.expect create mode 100644 tests/tests2/86_memory-model.c create mode 100644 tests/tests2/86_memory-model.expect delete mode 100644 tests/tests2/87_ptr_longlong_arith32.c delete mode 100644 tests/tests2/87_ptr_longlong_arith32.expect create mode 100644 tests/tests2/88_codeopt.c create mode 100644 tests/tests2/88_codeopt.expect create mode 100644 tests/tests2/89_nocode_wanted.c create mode 100644 tests/tests2/89_nocode_wanted.expect create mode 100644 tests/tests2/90_struct-init.c create mode 100644 tests/tests2/90_struct-init.expect create mode 100644 tests/tests2/91_ptr_longlong_arith32.c create mode 100644 tests/tests2/91_ptr_longlong_arith32.expect create mode 100644 tests/tests2/92_enum_bitfield.c create mode 100644 tests/tests2/92_enum_bitfield.expect create mode 100644 tests/tests2/93_integer_promotion.c create mode 100644 tests/tests2/93_integer_promotion.expect create mode 100644 tests/tests2/94_generic.c create mode 100644 tests/tests2/94_generic.expect create mode 100644 tests/tests2/95_bitfields.c create mode 100644 tests/tests2/95_bitfields.expect create mode 100644 tests/tests2/95_bitfields_ms.c create mode 100644 tests/tests2/95_bitfields_ms.expect create mode 100644 tests/tests2/96_nodata_wanted.c create mode 100644 tests/tests2/96_nodata_wanted.expect create mode 100644 tests/tests2/97_utf8_string_literal.c create mode 100644 tests/tests2/97_utf8_string_literal.expect create mode 100644 tests/tests2/98_al_ax_extend.c create mode 100644 tests/tests2/98_al_ax_extend.expect create mode 100644 tests/tests2/99_fastcall.c create mode 100644 tests/tests2/99_fastcall.expect (limited to 'tests') diff --git a/tests/Makefile b/tests/Makefile index a86e8a2..5f6777d 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -5,7 +5,7 @@ TOP = .. include $(TOP)/Makefile VPATH = $(TOPSRC)/tests $(TOPSRC) $(TOP) -CFLAGS = -I$(TOPSRC) -I$(TOP) +CFLAGS := $(filter-out -W% -g% -O%,$(CFLAGS)) -I$(TOPSRC) $(LDFLAGS) # what tests to run TESTS = \ @@ -13,9 +13,12 @@ TESTS = \ hello-run \ libtest \ test3 \ + memtest \ dlltest \ abitest \ + asm-c-connect-test \ vla_test-run \ + cross-test \ tests2-dir \ pp-dir @@ -32,46 +35,39 @@ endif ifdef CONFIG_WIN32 TESTS := $(filter-out $(BTESTS),$(TESTS)) endif -ifeq ($(TARGETOS),Darwin) - TESTS := $(filter-out hello-exe test3 $(BTESTS),$(TESTS)) +ifdef CONFIG_OSX # -run only + TESTS := hello-run libtest tests2-dir pp-dir endif -ifeq (,$(filter arm64 i386 x86-64,$(ARCH))) +ifeq (,$(filter arm64 i386 x86_64,$(ARCH))) TESTS := $(filter-out vla_test-run,$(TESTS)) endif ifeq ($(CONFIG_arm_eabi),yes) TESTS := $(filter-out test3,$(TESTS)) endif -ifeq (,$(filter i386 x86-64,$(ARCH))) - TESTS := $(filter-out dlltest,$(TESTS)) +ifeq (,$(filter i386 x86_64,$(ARCH))) + TESTS := $(filter-out dlltest asm-c-connect-test,$(TESTS)) endif - -# run local version of tcc with local libraries and includes -TCCFLAGS = -B$(TOP) -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -ifdef CONFIG_WIN32 - TCCFLAGS = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -I$(TOPSRC) -I$(TOP) -L$(TOP) - PATH := $(CURDIR)/$(TOP):$(PATH) # for libtcc_test to find libtcc.dll +ifndef CONFIG_cross + TESTS := $(filter-out cross-%,$(TESTS)) endif -TCC = $(TOP)/tcc $(TCCFLAGS) -RUN_TCC = $(NATIVE_DEFINES) -DONE_SOURCE -run $(TOPSRC)/tcc.c $(TCCFLAGS) - -ifeq ($(TARGETOS),Darwin) - CFLAGS += -Wl,-flat_namespace,-undefined,warning - TCCFLAGS += -D_ANSI_SOURCE - export MACOSX_DEPLOYMENT_TARGET:=10.2 +ifeq ($(OS),Windows_NT) # for libtcc_test to find libtcc.dll + PATH := $(CURDIR)/$(TOP)$(if $(findstring :\,$(PATH)),;,:)$(PATH) endif +RUN_TCC = $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) DISAS = objdump -d +DUMPTCC = (set -x; $(TOP)/tcc -vv; ldd $(TOP)/tcc; exit 1) all test : clean-s $(TESTS) hello-exe: ../examples/ex1.c @echo ------------ $@ ------------ - $(TCC) $< -o hello$(EXESUF) || ($(TOP)/tcc -vv; exit 1) && ./hello$(EXESUF) + $(TCC) $< -o hello$(EXESUF) && ./hello$(EXESUF) || $(DUMPTCC) hello-run: ../examples/ex1.c @echo ------------ $@ ------------ - $(TCC) -run $< + $(TCC) -run $< || $(DUMPTCC) libtest: libtcc_test$(EXESUF) @echo ------------ $@ ------------ @@ -133,18 +129,24 @@ test4: tcctest.c test.ref # use tcc to create libtcc.so/.dll and the tcc(.exe) frontend and run them dlltest: @echo ------------ $@ ------------ - $(TCC) -DONE_SOURCE $(NATIVE_DEFINES) -DLIBTCC_AS_DLL ../libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF) - $(TCC) $(NATIVE_DEFINES) ../tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF) - ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run ../examples/ex1.c + $(TCC) $(NATIVE_DEFINES) -DLIBTCC_AS_DLL $(TOPSRC)/libtcc.c $(LIBS) -shared -o libtcc2$(DLLSUF) + $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF) + ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c ifndef CONFIG_WIN32 @echo ------------ $@ with PIC ------------ - $(CC) $(CFLAGS) -fPIC -DONE_SOURCE $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c ../libtcc.c + $(CC) $(CFLAGS) -fPIC $(NATIVE_DEFINES) -DLIBTCC_AS_DLL -c $(TOPSRC)/libtcc.c $(TCC) libtcc.o $(LIBS) -shared -o libtcc2$(DLLSUF) - $(TCC) $(NATIVE_DEFINES) ../tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF) - ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run ../examples/ex1.c + $(TCC) $(NATIVE_DEFINES) -DONE_SOURCE=0 $(TOPSRC)/tcc.c libtcc2$(DLLSUF) $(LIBS) -Wl,-rpath=. -o tcc2$(EXESUF) + ./tcc2$(EXESUF) $(TCCFLAGS) $(RUN_TCC) -run $(TOPSRC)/examples/ex1.c endif @rm tcc2$(EXESUF) libtcc2$(DLLSUF) +memtest: + @echo ------------ $@ ------------ + $(CC) $(CFLAGS) $(NATIVE_DEFINES) -DMEM_DEBUG=2 $(TOPSRC)/tcc.c $(LIBS) -o memtest-tcc$(EXESUF) + ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) $(TOPSRC)/tcc.c $(LIBS) + ./memtest-tcc$(EXESUF) $(TCCFLAGS) $(NATIVE_DEFINES) -run $(TOPSRC)/tcc.c $(TCCFLAGS) $(TOPSRC)/tests/tcctest.c + # memory and bound check auto test BOUNDS_OK = 1 4 8 10 14 @@ -180,7 +182,7 @@ speedtest: ex2 ex3 weaktest: tcctest.c test.ref $(TCC) -c $< -o weaktest.tcc.o - $(CC) -c $< -o weaktest.gcc.o -I. $(CFLAGS) + $(CC) -c $< -o weaktest.gcc.o $(NATIVE_DEFINES) $(CFLAGS) -w -O0 -std=gnu99 -fno-omit-frame-pointer objdump -t weaktest.tcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.tcc.o.txt objdump -t weaktest.gcc.o | grep ' w ' | sed -e 's/.* \([a-zA-Z0-9_]*\)$$/\1/' | LC_ALL=C sort > weaktest.gcc.o.txt diff weaktest.gcc.o.txt weaktest.tcc.o.txt && echo "Weak Auto Test OK" @@ -208,7 +210,7 @@ abitest-cc$(EXESUF): abitest.c $(LIBTCC) $(CC) -o $@ $^ $(CFLAGS) $(LIBS) -w abitest-tcc$(EXESUF): abitest.c libtcc.c - $(TCC) -o $@ $^ $(NATIVE_DEFINES) -DONE_SOURCE $(LIBS) + $(TCC) -o $@ $^ $(NATIVE_DEFINES) $(LIBS) ABITESTS := abitest-cc$(EXESUF) ifneq ($(CONFIG_arm_eabi),yes) # not ARM soft-float @@ -229,6 +231,35 @@ vla_test-run: vla_test$(EXESUF) @echo ------------ $@ ------------ ./vla_test$(EXESUF) +asm-c-connect$(EXESUF): asm-c-connect-1.c asm-c-connect-2.c + $(TCC) -o $@ $^ + +asm-c-connect-%.o: asm-c-connect-%.c + $(TCC) -c -o $@ $< + +asm-c-connect-sep$(EXESUF): asm-c-connect-1.o asm-c-connect-2.o + $(TCC) -o $@ $^ + +asm-c-connect-test: asm-c-connect$(EXESUF) asm-c-connect-sep$(EXESUF) + @echo ------------ $@ ------------ + ./asm-c-connect$(EXESUF) > asm-c-connect.out1 && cat asm-c-connect.out1 + ./asm-c-connect-sep$(EXESUF) > asm-c-connect.out2 && cat asm-c-connect.out2 + @diff -u asm-c-connect.out1 asm-c-connect.out2 && echo "ok" + +cross-test : + @echo ------------ $@ ------------ + $(TOP)/i386-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/x86_64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/arm-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/arm64-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/c67-tcc$(EXESUF) $(TCCFLAGS-unx) -c $(TOPSRC)/examples/ex3.c && echo "ok" + $(TOP)/i386-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" + $(TOP)/x86_64-win32-tcc$(EXESUF) $(TCCFLAGS-win) $(TOPSRC)/win32/examples/hello_win.c && echo "ok" + $(TOP)/arm-wince-tcc$(EXESUF) $(TCCFLAGS-win) -c $(TOPSRC)/win32/examples/hello_win.c && echo "ok" + # targets for development %.bin: %.c tcc $(TCC) -g -o $@ $< @@ -246,10 +277,12 @@ cache: tcc_g # clean clean: - rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc \ -*-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234] ex? tcc_g - $(MAKE) -C tests2 $@ - $(MAKE) -C pp $@ + rm -f *~ *.o *.a *.bin *.i *.ref *.out *.out? *.out?b *.cc *.gcc + rm -f *-cc *-gcc *-tcc *.exe hello libtcc_test vla_test tcctest[1234] + rm -f asm-c-connect$(EXESUF) + rm -f ex? tcc_g weaktest.*.txt *.def + @$(MAKE) -C tests2 $@ + @$(MAKE) -C pp $@ # silent clean, used before running tests clean-s: diff --git a/tests/abitest.c b/tests/abitest.c index 896e97b..4a192bd 100644 --- a/tests/abitest.c +++ b/tests/abitest.c @@ -425,7 +425,7 @@ static int two_member_union_test(void) { } /* - * Win64 calling convetntion test. + * Win64 calling convention test. */ typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type; @@ -558,6 +558,36 @@ static int stdarg_test(void) { return run_callback(src, stdarg_test_callback); } +typedef struct {long long a, b;} stdarg_many_test_struct_type; +typedef void (*stdarg_many_test_function_type) (int, int, int, int, int, + stdarg_many_test_struct_type, + int, int, ...); + +static int stdarg_many_test_callback(void *ptr) +{ + stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr; + int x; + stdarg_many_test_struct_type l = {10, 11}; + f(1, 2, 3, 4, 5, l, 6, 7, &x, 44); + return x == 44 ? 0 : -1; +} + +static int stdarg_many_test(void) +{ + const char *src = + "#include \n" + "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n" + "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n" + " va_list ap;\n" + " int *p;\n" + " va_start (ap, g);\n" + " p = va_arg(ap, int*);\n" + " *p = va_arg(ap, int);\n" + " va_end (ap);\n" + "}\n"; + return run_callback(src, stdarg_many_test_callback); +} + /* * Test Win32 stdarg handling, since the calling convention will pass a pointer * to the struct and the stdarg pointer must point to that pointer initially. @@ -637,10 +667,13 @@ int main(int argc, char **argv) { RUN_TEST(ret_longdouble_test); RUN_TEST(ret_2float_test); RUN_TEST(ret_2double_test); - /* RUN_TEST(ret_8plus2double_test); currently broken on x86_64 */ - /* RUN_TEST(ret_6plus2longlong_test); currently broken on x86_64 */ - /* RUN_TEST(ret_mixed_test); currently broken on x86_64 */ - /* RUN_TEST(ret_mixed2_test); currently broken on x86_64 */ + RUN_TEST(ret_8plus2double_test); + RUN_TEST(ret_6plus2longlong_test); +#if !defined __x86_64__ || defined _WIN32 + /* currently broken on x86_64 linux */ + RUN_TEST(ret_mixed_test); + RUN_TEST(ret_mixed2_test); +#endif RUN_TEST(ret_mixed3_test); RUN_TEST(reg_pack_test); RUN_TEST(reg_pack_longlong_test); @@ -651,6 +684,7 @@ int main(int argc, char **argv) { RUN_TEST(many_struct_test_2); RUN_TEST(many_struct_test_3); RUN_TEST(stdarg_test); + RUN_TEST(stdarg_many_test); RUN_TEST(stdarg_struct_test); RUN_TEST(arg_align_test); return retval; diff --git a/tests/asm-c-connect-1.c b/tests/asm-c-connect-1.c new file mode 100644 index 0000000..8a28d78 --- /dev/null +++ b/tests/asm-c-connect-1.c @@ -0,0 +1,57 @@ +#include + +#if defined _WIN32 && !defined __TINYC__ +# define _ "_" +#else +# define _ +#endif + +static int x1_c(void) +{ + printf(" x1"); + return 1; +} + +asm(".text;"_"x1: call "_"x1_c; ret"); + +void callx4(void); +void callx5_again(void); + +void x6() +{ + printf(" x6-1"); +} + +int main(int argc, char *argv[]) +{ + printf("*"); + asm("call "_"x1"); + asm("call "_"x2"); + asm("call "_"x3"); + callx4(); + asm("call "_"x5"); + callx5_again(); + x6(); + printf(" *\n"); + return 0; +} + +static +int x2(void) +{ + printf(" x2"); + return 2; +} + +extern int x3(void); + +void x4(void) +{ + printf(" x4"); +} + +void x5(void); +void x5(void) +{ + printf(" x5"); +} diff --git a/tests/asm-c-connect-2.c b/tests/asm-c-connect-2.c new file mode 100644 index 0000000..3440b40 --- /dev/null +++ b/tests/asm-c-connect-2.c @@ -0,0 +1,36 @@ +#include + +#if defined _WIN32 && !defined __TINYC__ +# define _ "_" +#else +# define _ +#endif + +int x3(void) +{ + printf(" x3"); + return 3; +} + +/* That callx4 is defined globally (as if ".globl callx4") + is a TCC extension. GCC doesn't behave like this. */ +void callx4(void); +__asm__(_"callx4: call "_"x4; ret;" +#ifndef __TINYC__ + " .global "_"callx4" +#endif +); + +extern void x5(void); + +void callx5_again(void); +void callx5_again(void) +{ + x5(); + asm("call "_"x6"); +} + +static void x6() +{ + printf(" x6-2"); +} diff --git a/tests/asmtest.S b/tests/asmtest.S index 280aeaf..e9c0e32 100644 --- a/tests/asmtest.S +++ b/tests/asmtest.S @@ -114,12 +114,21 @@ notl %r15d movzb 0x1000, %eax movzb 0x1000, %ax + mov $0x12345678,%eax + #ifdef __x86_64__ movzb 0x1000, %rax movzbq 0x1000, %rbx movsbq 0x1000, %rdx movzwq 0x1000, %rdi movswq 0x1000, %rdx + movslq %eax, %rcx + mov $0x12345678,%rax + mov $0x12345678,%rdx + mov $0x12345678,%r10 + mov $0x123456789abcdef0,%rax + mov $0x123456789abcdef0,%rcx + mov $0x123456789abcdef0,%r11 #endif #ifdef __i386__ @@ -546,6 +555,7 @@ invlpg 0x1000 cmpxchg8b 0x1002 #ifdef __x86_64__ cmpxchg16b (%rax) +cmpxchg16b (%r10,%r11) #endif fcmovb %st(5), %st @@ -567,9 +577,13 @@ fucomip %st(5), %st cmovs 0x1000, %eax cmovns %edx, %edi cmovne %ax, %si + cmovbw %ax, %di + cmovnbel %edx, %ecx #ifdef __x86_64__ bswapq %rsi + bswapq %r10 cmovz %rdi,%rbx + cmovpeq %rsi, %rdx #endif int $3 @@ -675,7 +689,9 @@ int $0x10 prefetchw (%rdi) clflush 0x1000(%rax,%rcx) fxsaveq (%rdx) + fxsaveq (%r11) fxrstorq (%rcx) + fxrstorq (%r10) #endif @@ -751,6 +767,9 @@ int $0x10 sidtq 0x1000 swapgs + + str %rdx + str %r9 #endif lmsw 0x1000 @@ -879,6 +898,7 @@ overrideme: #ifdef __x86_64__ movq %rcx, %mm1 movq %rdx, %xmm2 + movq %r13, %xmm3 /* movq mem64->xmm is encoded as f30f7e by GAS, but as 660f6e by tcc (which really is a movd and would need a REX.W prefix to be movq). */ diff --git a/tests/gcctestsuite.sh b/tests/gcctestsuite.sh old mode 100644 new mode 100755 diff --git a/tests/libtcc_test.c b/tests/libtcc_test.c index be5db61..480d314 100644 --- a/tests/libtcc_test.c +++ b/tests/libtcc_test.c @@ -15,11 +15,15 @@ int add(int a, int b) return a + b; } +/* this strinc is referenced by the generated code */ const char hello[] = "Hello World!"; char my_program[] = "#include \n" /* include the "Simple libc header for TCC" */ "extern int add(int a, int b);\n" +"#ifdef _WIN32\n" /* dynamically linked data needs 'dllimport' */ +" __attribute__((dllimport))\n" +"#endif\n" "extern const char hello[];\n" "int fib(int n)\n" "{\n" diff --git a/tests/pp/13.expect b/tests/pp/13.expect index 6eb2bec..c7a3230 100644 --- a/tests/pp/13.expect +++ b/tests/pp/13.expect @@ -1,3 +1,2 @@ -# `modelist' label. Each video mode record looks like: .text endtext: diff --git a/tests/pp/15.c b/tests/pp/15.c index d989bee..cf13f9a 100644 --- a/tests/pp/15.c +++ b/tests/pp/15.c @@ -12,7 +12,7 @@ return n(A)n(++)n(+)n(+)n(B); return n(0x1E)n(-1); // unlike gcc but correct -XXX: return n(x)+n(x)-n(1)+n(1)-2; +// XXX: return n(x)+n(x)-n(1)+n(1)-2; -// unlile gcc, but cannot appear in valid C -XXX: return n(x)n(x)n(1)n(2)n(x); +// unlike gcc, but cannot appear in valid C +// XXX: return n(x)n(x)n(1)n(2)n(x); diff --git a/tests/pp/15.expect b/tests/pp/15.expect index f652240..b4f885e 100644 --- a/tests/pp/15.expect +++ b/tests/pp/15.expect @@ -3,5 +3,3 @@ return A+++B; return A+ ++B; return A+++ +B; return 0x1E -1; -XXX: return x+x-1 +1 -2; -XXX: return x x 1 2 x; diff --git a/tests/pp/18.c b/tests/pp/18.c new file mode 100644 index 0000000..0961426 --- /dev/null +++ b/tests/pp/18.c @@ -0,0 +1,15 @@ +#define M_RETI_ARG27(x,y,z,aa, ...) aa +#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__) +#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 1, 1, 0, useless) +#define M_EMPTYI_DETECT(...) 0, 1, +#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ () ) +#define EX +#define empty(x) +#define fnlike(x) yeah x +/* If the following macro is called with empty arg (X183), the use + of 'x' between fnlike and '(' doesn't hinder the recognition of this + being a further fnlike macro invocation. */ +#define usefnlike(x) fnlike x (x) +X181 M_EMPTYI_P_C1() +X182 M_EMPTYI_P_C1(x) +X183 usefnlike() diff --git a/tests/pp/18.expect b/tests/pp/18.expect new file mode 100644 index 0000000..447a9b2 --- /dev/null +++ b/tests/pp/18.expect @@ -0,0 +1,3 @@ +X181 1 +X182 0 +X183 yeah diff --git a/tests/pp/19.c b/tests/pp/19.c new file mode 100644 index 0000000..aa91abe --- /dev/null +++ b/tests/pp/19.c @@ -0,0 +1,101 @@ +#define M_C2I(a, ...) a ## __VA_ARGS__ +#define M_C(a, ...) M_C2I(a, __VA_ARGS__) +#define M_C3I(a, b, ...) a ## b ## __VA_ARGS__ +#define M_C3(a, b, ...) M_C3I(a ,b, __VA_ARGS__) + +#define M_RETI_ARG2(a, b, ...) b +#define M_RET_ARG2(...) M_RETI_ARG2(__VA_ARGS__) +#define M_RETI_ARG27(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,aa, ...) aa +#define M_RET_ARG27(...) M_RETI_ARG27(__VA_ARGS__) + +#define M_TOBOOLI_0 1, 0, +#define M_BOOL(x) M_RET_ARG2(M_C(M_TOBOOLI_, x), 1, useless) + +#define M_IFI_0(true_macro, ...) __VA_ARGS__ +#define M_IFI_1(true_macro, ...) true_macro +#define M_IF(c) M_C(M_IFI_, M_BOOL(c)) + +#define M_FLAT(...) __VA_ARGS__ +#define M_INVI_0 1 +#define M_INVI_1 0 +#define M_INV(x) M_C(M_INVI_, x) + +#define M_ANDI_00 0 +#define M_ANDI_01 0 +#define M_ANDI_10 0 +#define M_ANDI_11 1 +#define M_AND(x,y) M_C3(M_ANDI_, x, y) + +#define M_ORI_00 0 +#define M_ORI_01 1 +#define M_ORI_10 1 +#define M_ORI_11 1 +#define M_OR(x,y) M_C3(M_ORI_, x, y) + +#define M_COMMA_P(...) M_RET_ARG27(__VA_ARGS__, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, useless) + +#define M_EMPTYI_DETECT(...) 0, 1, +#define M_EMPTYI_P_C1(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__ ()) +#define M_EMPTYI_P_C2(...) M_COMMA_P(M_EMPTYI_DETECT __VA_ARGS__) +#define M_EMPTYI_P_C3(...) M_COMMA_P(__VA_ARGS__ () ) +#define M_EMPTY_P(...) M_AND(M_EMPTYI_P_C1(__VA_ARGS__), M_INV(M_OR(M_OR(M_EMPTYI_P_C2(__VA_ARGS__), M_COMMA_P(__VA_ARGS__)),M_EMPTYI_P_C3(__VA_ARGS__)))) +#define M_APPLY_FUNC2B(func, arg1, arg2) \ + M_IF(M_EMPTY_P(arg2))(,func(arg1, arg2)) +#define M_MAP2B_0(func, data, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z,...) \ + M_APPLY_FUNC2B(func, data, a) M_APPLY_FUNC2B(func, data, b) M_APPLY_FUNC2B(func, data, c) \ + M_APPLY_FUNC2B(func, data, d) M_APPLY_FUNC2B(func, data, e) M_APPLY_FUNC2B(func, data, f) \ + M_APPLY_FUNC2B(func, data, g) M_APPLY_FUNC2B(func, data, h) M_APPLY_FUNC2B(func, data, i) \ + M_APPLY_FUNC2B(func, data, j) M_APPLY_FUNC2B(func, data, k) M_APPLY_FUNC2B(func, data, l) \ + M_APPLY_FUNC2B(func, data, m) M_APPLY_FUNC2B(func, data, n) M_APPLY_FUNC2B(func, data, o) \ + M_APPLY_FUNC2B(func, data, p) M_APPLY_FUNC2B(func, data, q) M_APPLY_FUNC2B(func, data, r) \ + M_APPLY_FUNC2B(func, data, s) M_APPLY_FUNC2B(func, data, t) M_APPLY_FUNC2B(func, data, u) \ + M_APPLY_FUNC2B(func, data, v) M_APPLY_FUNC2B(func, data, w) M_APPLY_FUNC2B(func, data, x) \ + M_APPLY_FUNC2B(func, data, y) M_APPLY_FUNC2B(func, data, z) +#define M_MAP2B(f, ...) M_MAP2B_0(f, __VA_ARGS__, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ) +#define M_INIT_INIT(a) ,a, + +#define M_GET_METHOD(method, method_default, ...) \ + M_RET_ARG2 (M_MAP2B(M_C, M_C3(M_, method, _), __VA_ARGS__), method_default,) + +#define M_TEST_METHOD_P(method, oplist) \ + M_BOOL(M_GET_METHOD (method, 0, M_FLAT oplist)) + +#define TRUE 1 +#define TEST1(n) \ + M_IF(n)(ok,nok) +#define TEST2(op) \ + M_TEST_METHOD_P(INIT, op) +#define TEST3(op) \ + M_IF(M_TEST_METHOD_P(INIT, op))(ok, nok) +#define TEST4(op) \ + TEST1(TEST2(op)) +#define KO(a) ((void)1) + +/* This checks that the various expansions that ultimately lead to + something like 'KO(arg,arg)', where 'KO' comes from a macro + expansion reducing from a large macro chain do not are regarded + as funclike macro invocation of KO. E.g. X93 and X94 expand to 'KO', + but X95 must not consume the (a,b) arguments outside the M_IF() + invocation to reduce the 'KO' macro to an invocation. Instead + X95 should reduce via M_IF(KO)(a,b) to 'a'. + + The other lines here are variations on this scheme, with X1 to + X6 coming from the bug report at + http://lists.nongnu.org/archive/html/tinycc-devel/2017-07/msg00017.html */ +X92 M_IF(KO) +X93 M_GET_METHOD(INIT, 0, INIT(KO)) +X94 M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))) +X95 M_IF(M_GET_METHOD(INIT, 0, INIT(KO)))(a,b) +X96 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO)))) +X97 M_IF(M_GET_METHOD(INIT, 0, M_FLAT (INIT(KO))))(ok,nok) +X98 (M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok) +X99 M_IF(M_TEST_METHOD_P(INIT, (INIT(KO))))(ok, nok) +// test begins +X1 TEST1(TRUE) // ==> expect ok, get ok +// First test with a token which is not a macro +X2 TEST2((INIT(ok))) // ==> expect 1, get 1 +X3 TEST3((INIT(ok))) // ==> expect ok, get ok +// Then test with a token which is a macro, but should not be expanded. +X4 TEST2((INIT(KO))) // ==> expect 1, get 1 +X5 TEST4(INIT(KO)) +X6 TEST3((INIT(KO))) // ==> expect ok, get "error: macro 'KO' used with too many args" diff --git a/tests/pp/19.expect b/tests/pp/19.expect new file mode 100644 index 0000000..08c0858 --- /dev/null +++ b/tests/pp/19.expect @@ -0,0 +1,14 @@ +X92 M_IFI_1 +X93 KO +X94 KO +X95 a +X96 M_IFI_1 +X97 ok +X98 (1)(ok, nok) +X99 ok +X1 ok +X2 1 +X3 ok +X4 1 +X5 nok +X6 ok diff --git a/tests/pp/20.c b/tests/pp/20.c new file mode 100644 index 0000000..7944d62 --- /dev/null +++ b/tests/pp/20.c @@ -0,0 +1,13 @@ +/* Various things I encountered while hacking the pre processor */ +#define wrap(x) x +#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__) +#define pr_warn(x,y) pr_warning(x,y) +#define net_ratelimited_function(function, ...) function(__VA_ARGS__) +X1 net_ratelimited_function(pr_warn, "pipapo", bla); +X2 net_ratelimited_function(wrap(pr_warn), "bla", foo); +#define two m n +#define chain4(a,b,c,d) a ## b ## c ## d +X2 chain4(two,o,p,q) +X3 chain4(o,two,p,q) +X4 chain4(o,p,two,q) +X5 chain4(o,p,q,two) diff --git a/tests/pp/20.expect b/tests/pp/20.expect new file mode 100644 index 0000000..d19405d --- /dev/null +++ b/tests/pp/20.expect @@ -0,0 +1,6 @@ +X1 printk(KERN_WARNING "pipapo",bla); +X2 printk(KERN_WARNING "bla",foo); +X2 twoopq +X3 otwopq +X4 optwoq +X5 opqtwo diff --git a/tests/pp/21.c b/tests/pp/21.c new file mode 100644 index 0000000..1316226 --- /dev/null +++ b/tests/pp/21.c @@ -0,0 +1,36 @@ +/* accept 'defined' as result of substitution */ + +----- 1 ------ +#define AAA 2 +#define BBB +#define CCC (defined ( AAA ) && AAA > 1 && !defined BBB) +#if !CCC +OK +#else +NOT OK +#endif + +----- 2 ------ +#undef BBB +#if CCC +OK +#else +NOT OK +#endif + +----- 3 ------ +#define DEFINED defined +#define DDD (DEFINED ( AAA ) && AAA > 1 && !DEFINED BBB) +#if (DDD) +OK +#else +NOT OK +#endif + +----- 4 ------ +#undef AAA +#if !(DDD) +OK +#else +NOT OK +#endif diff --git a/tests/pp/21.expect b/tests/pp/21.expect new file mode 100644 index 0000000..5a1376b --- /dev/null +++ b/tests/pp/21.expect @@ -0,0 +1,8 @@ +----- 1 ------ +OK +----- 2 ------ +OK +----- 3 ------ +OK +----- 4 ------ +OK diff --git a/tests/pp/Makefile b/tests/pp/Makefile index 4a77035..687aa52 100644 --- a/tests/pp/Makefile +++ b/tests/pp/Makefile @@ -3,36 +3,35 @@ # TOP = ../.. -include $(TOP)/config.mak +include $(TOP)/Makefile SRC = $(TOPSRC)/tests/pp VPATH = $(SRC) -TCC = ../../tcc files = $(patsubst %.$1,%.test,$(notdir $(wildcard $(SRC)/*.$1))) TESTS = $(call files,c) $(call files,S) all test : $(sort $(TESTS)) -DIFF_OPTS = -Nu -b -B -I "^\#" +DIFF_OPTS = -Nu -b -B + +# Filter source directory in warnings/errors (out-of-tree builds) +FILTER = 2>&1 | sed 's,$(SRC)/,,g' %.test: %.c %.expect @echo PPTest $* ... - -@$(TCC) -E -P $< >$*.output 2>&1 ; \ + -@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \ diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \ && rm -f $*.output %.test: %.S %.expect @echo PPTest $* ... - -@$(TCC) -E -P $< >$*.output 2>&1 ; \ + -@$(TCC) -E -P $< $(FILTER) >$*.output 2>&1 ; \ diff $(DIFF_OPTS) $(SRC)/$*.expect $*.output \ && rm -f $*.output # automatically generate .expect files with gcc: -%.expect: %.c - gcc -E -P $< >$*.expect 2>&1 - -%.expect: %.S - gcc -E -P $< >$*.expect 2>&1 +%.expect: # %.c + gcc -E -P $*.[cS] >$*.expect 2>&1 # tell make not to delete .PRECIOUS: %.expect @@ -41,7 +40,7 @@ clean: rm -f *.output 02.test : DIFF_OPTS += -w -15.test : DIFF_OPTS += -I"^XXX:" +# 15.test : DIFF_OPTS += -I"^XXX:" # diff options: # -b ighore space changes diff --git a/tests/pp/pp-counter.c b/tests/pp/pp-counter.c new file mode 100644 index 0000000..3978e1a --- /dev/null +++ b/tests/pp/pp-counter.c @@ -0,0 +1,27 @@ +X1 __COUNTER__ +X2 __COUNTER__ +#if __COUNTER__ +X3 __COUNTER__ +#endif +#define pass(x) x +#define a x __COUNTER__ y +#define a2 pass(__COUNTER__) +#define f(c) c __COUNTER__ +#define apply(d) d d __COUNTER__ x2 f(d) y2 __COUNTER__ +#define _paste(a,b) a ## b +#define paste(a,b) _paste(a,b) +#define _paste3(a,b,c) a ## b ## c +#define doublepaste(a,b) _paste3(a,b,b) +#define str(x) #x +X4 a +X5 f(a) +X6 f(b) +X7 f(__COUNTER__) +X8 apply(a) +X9 apply(f(a)) +X10 apply(__COUNTER__) +X11 apply(a2) +X12 str(__COUNTER__) +X13 paste(x,__COUNTER__) +X14 _paste(x,__COUNTER__) +X15 doublepaste(x,__COUNTER__) diff --git a/tests/pp/pp-counter.expect b/tests/pp/pp-counter.expect new file mode 100644 index 0000000..02fc535 --- /dev/null +++ b/tests/pp/pp-counter.expect @@ -0,0 +1,15 @@ +X1 0 +X2 1 +X3 3 +X4 x 4 y +X5 x 5 y 6 +X6 b 7 +X7 8 9 +X8 x 10 y x 10 y 11 x2 x 10 y 12 y2 13 +X9 x 14 y 15 x 14 y 15 16 x2 x 14 y 15 17 y2 18 +X10 19 19 20 x2 19 21 y2 22 +X11 23 23 24 x2 23 25 y2 26 +X12 "__COUNTER__" +X13 x27 +X14 x__COUNTER__ +X15 x2828 diff --git a/tests/tcctest.c b/tests/tcctest.c index 0f71482..57670be 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -176,6 +176,11 @@ static int onetwothree = 123; #define B3 4 #endif +#ifdef __TINYC__ +/* We try to handle this syntax. Make at least sure it doesn't segfault. */ +char invalid_function_def()[] {} +#endif + #define __INT64_C(c) c ## LL #define INT64_MIN (-__INT64_C(9223372036854775807)-1) @@ -379,7 +384,7 @@ void macro_test(void) MF_s("hi"); MF_t("hi"); - /* test macro substituion inside args (should not eat stream) */ + /* test macro substitution inside args (should not eat stream) */ printf("qq=%d\n", qq(qq)(2)); /* test zero argument case. NOTE: gcc 2.95.x does not accept a @@ -399,7 +404,7 @@ comment substituted */ TEST2(); - /* And again when the name and parenthes are separated by a + /* And again when the name and parentheses are separated by a comment. */ TEST2 /* the comment */ (); @@ -1045,8 +1050,8 @@ int pad1; but __alignof__ returns the wrong result (4) because we can't store the alignment yet when specified on symbols directly (it's stored in the type so we'd need to make - a copy of it). -struct aligntest7 altest7[2] __attribute__((aligned(16)));*/ + a copy of it). -- FIXED */ +struct aligntest7 altest7[2] __attribute__((aligned(16))); struct aligntest8 { @@ -1156,8 +1161,8 @@ void struct_test() sizeof(altest5), __alignof__(altest5)); printf("altest6 sizeof=%d alignof=%d\n", sizeof(altest6), __alignof__(altest6)); - /*printf("altest7 sizeof=%d alignof=%d\n", - sizeof(altest7), __alignof__(altest7));*/ + printf("altest7 sizeof=%d alignof=%d\n", + sizeof(altest7), __alignof__(altest7)); /* empty structures (GCC extension) */ printf("sizeof(struct empty) = %d\n", sizeof(struct empty)); @@ -1404,6 +1409,15 @@ void optimize_out(void) if (defined_function() && 0) refer_to_undefined(); + if (0) { + (void)sizeof( ({ + do { } while (0); + 0; + }) ); + undefined_function(); + } + + /* Leave the "if(1)return; printf()" in this order and last in the function */ if (1) return; printf ("oor:%d\n", undefined_function()); @@ -1738,6 +1752,8 @@ arrtype2 sinit22 = {5,6,7}; int sinit23[2] = { "astring" ? sizeof("astring") : -1, &sinit23 ? 42 : -1 }; +extern int external_inited = 42; + void init_test(void) { int linit1 = 2; @@ -2028,13 +2044,6 @@ void bitfield_test(void) else printf("st1.f2 != -1\n"); -#ifndef __i386__ - /* on i386 we don't correctly support long long bit-fields. - The bitfields can straddle long long boundaries (at least with - GCC bitfield layout) and code generation isn't prepared for this - (would have to work with two words in that case). */ - /* bit sizes below must be bigger than 32 since GCC doesn't allow - long-long bitfields whose size is not bigger than int */ struct sbf2 { long long f1 : 45; long long : 2; @@ -2047,7 +2056,7 @@ void bitfield_test(void) st2.f3 = a; st2.f2++; printf("%lld %lld %lld\n", st2.f1, st2.f2, st2.f3); -#endif + #if 0 Disabled for now until further clarification re GCC compatibility struct sbf3 { @@ -2060,6 +2069,26 @@ void bitfield_test(void) } st3; printf("sizeof(st3) = %d\n", sizeof(st3)); #endif + + struct sbf4 { + int x : 31; + char y : 2; + } st4; + st4.y = 1; + printf("st4.y == %d\n", st4.y); + struct sbf5 { + int a; + char b; + int x : 12, y : 4, : 0, : 4, z : 3; + char c; + } st5 = { 1, 2, 3, 4, -3, 6 }; + printf("st5 = %d %d %d %d %d %d\n", st5.a, st5.b, st5.x, st5.y, st5.z, st5.c); + struct sbf6 { + short x : 12; + unsigned char y : 2; + } st6; + st6.y = 1; + printf("st6.y == %d\n", st6.y); } #ifdef __x86_64__ @@ -2658,6 +2687,9 @@ int reltab[3] = { 1, 2, 3 }; int *rel1 = &reltab[1]; int *rel2 = &reltab[2]; +#ifdef _WIN64 +void relocation_test(void) {} +#else void getmyaddress(void) { printf("in getmyaddress\n"); @@ -2686,6 +2718,7 @@ void relocation_test(void) printf("pa_symbol=0x%lx\n", __pa_symbol() >> 63); #endif } +#endif void old_style_f(a,b,c) int a, b; @@ -2866,6 +2899,11 @@ struct hlist_head { struct hlist_node *first, *last; }; +void consume_ulong (unsigned long i) +{ + i = 0; +} + void statement_expr_test(void) { int a, i; @@ -2921,6 +2959,9 @@ void statement_expr_test(void) }); printf ("stmtexpr: %d %d %d\n", t, b, c); printf ("stmtexpr: %ld %ld\n", (long)h.first, (long)h.last); + + /* Test that we can give out addresses of local labels. */ + consume_ulong(({ __label__ __here; __here: (unsigned long)&&__here; })); } void local_label_test(void) @@ -3076,7 +3117,7 @@ static __inline__ unsigned long long inc64(unsigned long long a) unsigned long long res; #ifdef __x86_64__ /* Using the A constraint is wrong, and increments are tested - elsewere. */ + elsewhere. */ res = a + 1; #else __asm__("addl $1, %%eax ; adcl $0, %%edx" : "=A" (res) : "A" (a)); @@ -3118,10 +3159,13 @@ void other_constraints_test(void) { unsigned long ret; int var; +#ifndef _WIN64 __asm__ volatile ("mov %P1,%0" : "=r" (ret) : "p" (&var)); printf ("oc1: %d\n", ret == (unsigned long)&var); +#endif } +#ifndef _WIN32 /* Test global asm blocks playing with aliases. */ void base_func(void) { @@ -3162,6 +3206,36 @@ char * get_asm_string (void) return str; } +/* This checks another constructs with local labels. */ +extern unsigned char alld_stuff[]; +asm(".data\n" + ".byte 41\n" + "alld_stuff:\n" + "661:\n" + ".byte 42\n" + "662:\n" + ".pushsection .data.ignore\n" + ".long 661b - .\n" /* This reference to 661 generates an external sym + which shouldn't somehow overwrite the offset that's + already determined for it. */ + ".popsection\n" + ".byte 662b - 661b\n" /* So that this value is undeniably 1. */); + +void asm_local_label_diff (void) +{ + printf ("asm_local_label_diff: %d %d\n", alld_stuff[0], alld_stuff[1]); +} + +/* This checks that static local variables are available from assembler. */ +void asm_local_statics (void) +{ + static int localint = 41; + asm("incl %0" : "+m" (localint)); + printf ("asm_local_statics: %d\n", localint); +} +#endif + +static unsigned int set; void fancy_copy (unsigned *in, unsigned *out) @@ -3174,7 +3248,7 @@ void fancy_copy2 (unsigned *in, unsigned *out) asm volatile ("mov %0,(%1)" : : "r" (*in), "r" (out) : "memory"); } -#ifdef __x86_64__ +#if defined __x86_64__ && !defined _WIN64 void clobber_r12(void) { asm volatile("mov $1, %%r12" ::: "r12"); @@ -3183,7 +3257,7 @@ void clobber_r12(void) void test_high_clobbers(void) { -#ifdef __x86_64__ +#if defined __x86_64__ && !defined _WIN64 register long val asm("r12"); long val2; /* This tests if asm clobbers correctly save/restore callee saved @@ -3249,6 +3323,84 @@ void trace_console(long len, long len2) } #endif } + +void test_asm_dead_code(void) +{ + long rdi; + /* Try to make sure that xdi contains a zero, and hence will + lead to a segfault if the next asm is evaluated without + arguments being set up. */ + asm volatile ("" : "=D" (rdi) : "0" (0)); + (void)sizeof (({ + int var; + /* This shouldn't trigger a segfault, either the argument + registers need to be set up and the asm emitted despite + this being in an unevaluated context, or both the argument + setup _and_ the asm emission need to be suppressed. The latter + is better. Disabling asm code gen when suppression is on + also fixes the above trace_console bug, but that came earlier + than asm suppression. */ + asm volatile ("movl $0,(%0)" : : "D" (&var) : "memory"); + var; + })); +} + +void test_asm_call(void) +{ +#if defined __x86_64__ && !defined _WIN64 + static char str[] = "PATH"; + char *s; + /* This tests if a reference to an undefined symbol from an asm + block, which isn't otherwise referenced in this file, is correctly + regarded as global symbol, so that it's resolved by other object files + or libraries. We chose getenv here, which isn't used anywhere else + in this file. (If we used e.g. printf, which is used we already + would have a global symbol entry, not triggering the bug which is + tested here). */ + /* two pushes so stack remains aligned */ + asm volatile ("push %%rdi; push %%rdi; mov %0, %%rdi;" +#if 1 && !defined(__TINYC__) && (defined(__PIC__) || defined(__PIE__)) + "call getenv@plt;" +#else + "call getenv;" +#endif + "pop %%rdi; pop %%rdi" + : "=a" (s) : "r" (str)); + printf("asmd: %s\n", s); +#endif +} + +#if defined __x86_64__ +# define RX "(%rip)" +#else +# define RX +#endif + +void asm_dot_test(void) +{ + int x; + for (x = 1;; ++x) { + int r = x; + switch (x) { + case 1: + asm(".text; lea S"RX",%eax; lea ."RX",%ecx; sub %ecx,%eax; S=.; jmp p0"); + case 2: + asm(".text; jmp .+6; .int 123; mov .-4"RX",%eax; jmp p0"); + case 3: + asm(".data; Y=.; .int 999; X=Y; .int 456; X=.-4"); + asm(".text; mov X"RX",%eax; jmp p0"); + case 4: + asm(".data; X=.; .int 789; Y=.; .int 999"); + asm(".text; mov X"RX",%eax; X=Y; jmp p0"); + case 0: + asm(".text; p0=.; mov %%eax,%0;" : "=m"(r)); break; + } + if (r == x) + break; + printf("asm_dot_test %d: %d\n", x, r); + } +} + void asm_test(void) { char buf[128]; @@ -3301,12 +3453,17 @@ void asm_test(void) printf("set=0x%x\n", set); val = 0x01020304; printf("swab32(0x%08x) = 0x%0x\n", val, swab32(val)); +#ifndef _WIN32 override_func1(); override_func2(); /* The base_func ref from the following inline asm should find the global one, not the local decl from this function. */ asm volatile(".weak override_func3\n.set override_func3, base_func"); override_func3(); + printf("asmstr: %s\n", get_asm_string()); + asm_local_label_diff(); + asm_local_statics(); +#endif /* Check that we can also load structs of appropriate layout into registers. */ asm volatile("" : "=r" (asmret) : "0"(s2)); @@ -3319,7 +3476,6 @@ void asm_test(void) if (!somebool) printf("asmbool: failed\n"); #endif - printf("asmstr: %s\n", get_asm_string()); val = 43; fancy_copy (&val, &val2); printf ("fancycpy(%d)=%d\n", val, val2); @@ -3330,6 +3486,9 @@ void asm_test(void) printf ("regvar=%x\n", regvar); test_high_clobbers(); trace_console(8, 8); + test_asm_dead_code(); + test_asm_call(); + asm_dot_test(); return; label1: goto label2; @@ -3387,7 +3546,7 @@ void builtin_test(void) i = sizeof (__builtin_choose_expr (0, ll, s)); printf("bce: %d\n", i); - printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); + //printf("bera: %p\n", __builtin_extract_return_addr((void*)43)); } #ifndef _WIN32 @@ -3657,8 +3816,6 @@ typedef struct __attribute__((__packed__)) { int c; } Spacked2; Spacked2 spacked2; -/* This doesn't work for now. Requires adjusting field offsets/sizes - after parsing the struct members. */ typedef struct Spacked3_s { char a; short b; @@ -3677,10 +3834,12 @@ typedef struct gate_struct64 gate_desc; gate_desc a_gate_desc; void attrib_test(void) { +#ifndef _WIN32 printf("attr: %d %d %d %d\n", sizeof(struct Spacked), sizeof(spacked), sizeof(Spacked2), sizeof(spacked2)); printf("attr: %d %d\n", sizeof(Spacked3), sizeof(spacked3)); printf("attr: %d %d\n", sizeof(gate_desc), sizeof(a_gate_desc)); +#endif } extern __attribute__((__unused__)) char * __attribute__((__unused__)) * strange_attrib_placement (void); @@ -3689,3 +3848,24 @@ void * __attribute__((__unused__)) get_void_ptr (void *a) { return a; } + +/* This part checks for a bug in TOK_GET (used for inline expansion), + where the large long long constant left the the high bits set for + the integer constant token. */ +static inline +int __get_order(unsigned long long size) +{ + int order; + size -= 0xffff880000000000ULL; // this const left high bits set in the token + { + struct S { int i : 1; } s; // constructed for this '1' + } + order = size; + return order; +} + +/* This just forces the above inline function to be actually emitted. */ +int force_get_order(unsigned long s) +{ + return __get_order(s); +} diff --git a/tests/tcctest.py b/tests/tcctest.py deleted file mode 100644 index 817250f..0000000 --- a/tests/tcctest.py +++ /dev/null @@ -1,15 +0,0 @@ -import subprocess -import sys -import difflib - -def main(): - reference = subprocess.check_output([sys.argv[1]]) - compare = subprocess.check_output(sys.argv[2:]) - failed = False - for line in difflib.unified_diff(reference.split('\n'), compare.split('\n'), fromfile='cc', tofile='tcc', lineterm=''): - failed = True - print line - sys.exit(1 if failed else 0) - -if __name__ == '__main__': - main() diff --git a/tests/tests2/17_enum.c b/tests/tests2/17_enum.c index 0853c42..e2bc736 100644 --- a/tests/tests2/17_enum.c +++ b/tests/tests2/17_enum.c @@ -12,9 +12,49 @@ enum fred 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); */ @@ -23,6 +63,9 @@ int main() frod = e; printf("%d\n", frod); + /* Following should compile without warning. */ + printf ("enum to int: %u\n", deref_uintptr(&epos)); + return 0; } diff --git a/tests/tests2/17_enum.expect b/tests/tests2/17_enum.expect index 0c4e153..d453a61 100644 --- a/tests/tests2/17_enum.expect +++ b/tests/tests2/17_enum.expect @@ -1,3 +1,4 @@ 0 1 2 3 54 73 74 75 12 54 +enum to int: 1 diff --git a/tests/tests2/39_typedef.c b/tests/tests2/39_typedef.c index 3878b9c..da73f71 100644 --- a/tests/tests2/39_typedef.c +++ b/tests/tests2/39_typedef.c @@ -44,4 +44,22 @@ 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/tests/tests2/42_function_pointer.c b/tests/tests2/42_function_pointer.c index 49c331b..697bd79 100644 --- a/tests/tests2/42_function_pointer.c +++ b/tests/tests2/42_function_pointer.c @@ -8,9 +8,13 @@ int fred(int p) 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() { - printf("%d\n", (*f)(24)); + fprintfptr(stdout, "%d\n", (*f)(24)); return 0; } diff --git a/tests/tests2/56_btype_excess-1.c b/tests/tests2/56_btype_excess-1.c deleted file mode 100644 index 06eabe7..0000000 --- a/tests/tests2/56_btype_excess-1.c +++ /dev/null @@ -1 +0,0 @@ -struct A {} int i; diff --git a/tests/tests2/56_btype_excess-1.expect b/tests/tests2/56_btype_excess-1.expect deleted file mode 100644 index 4e6d2d7..0000000 --- a/tests/tests2/56_btype_excess-1.expect +++ /dev/null @@ -1 +0,0 @@ -56_btype_excess-1.c:1: error: too many basic types diff --git a/tests/tests2/57_btype_excess-2.c b/tests/tests2/57_btype_excess-2.c deleted file mode 100644 index ab95c3e..0000000 --- a/tests/tests2/57_btype_excess-2.c +++ /dev/null @@ -1 +0,0 @@ -char int i; diff --git a/tests/tests2/57_btype_excess-2.expect b/tests/tests2/57_btype_excess-2.expect deleted file mode 100644 index c12ef81..0000000 --- a/tests/tests2/57_btype_excess-2.expect +++ /dev/null @@ -1 +0,0 @@ -57_btype_excess-2.c:1: error: too many basic types diff --git a/tests/tests2/58_function_redefinition.c b/tests/tests2/58_function_redefinition.c deleted file mode 100644 index 33f16ee..0000000 --- a/tests/tests2/58_function_redefinition.c +++ /dev/null @@ -1,9 +0,0 @@ -int f(void) -{ - return 0; -} - -int f(void) -{ - return 1; -} diff --git a/tests/tests2/58_function_redefinition.expect b/tests/tests2/58_function_redefinition.expect deleted file mode 100644 index a95a3f0..0000000 --- a/tests/tests2/58_function_redefinition.expect +++ /dev/null @@ -1 +0,0 @@ -58_function_redefinition.c:7: error: redefinition of 'f' diff --git a/tests/tests2/59_function_array.c b/tests/tests2/59_function_array.c deleted file mode 100644 index 9fcc12d..0000000 --- a/tests/tests2/59_function_array.c +++ /dev/null @@ -1 +0,0 @@ -int (*fct)[42](int x); diff --git a/tests/tests2/59_function_array.expect b/tests/tests2/59_function_array.expect deleted file mode 100644 index bf62c6e..0000000 --- a/tests/tests2/59_function_array.expect +++ /dev/null @@ -1 +0,0 @@ -59_function_array.c:1: error: declaration of an array of functions diff --git a/tests/tests2/60_enum_redefinition.c b/tests/tests2/60_enum_redefinition.c deleted file mode 100644 index 2601560..0000000 --- a/tests/tests2/60_enum_redefinition.c +++ /dev/null @@ -1,4 +0,0 @@ -enum color {RED, GREEN, BLUE}; -enum color {R, G, B}; - -enum color c; diff --git a/tests/tests2/60_enum_redefinition.expect b/tests/tests2/60_enum_redefinition.expect deleted file mode 100644 index 5cb41bc..0000000 --- a/tests/tests2/60_enum_redefinition.expect +++ /dev/null @@ -1 +0,0 @@ -60_enum_redefinition.c:2: error: struct/union/enum already defined diff --git a/tests/tests2/60_errors_and_warnings.c b/tests/tests2/60_errors_and_warnings.c new file mode 100644 index 0000000..0028caf --- /dev/null +++ b/tests/tests2/60_errors_and_warnings.c @@ -0,0 +1,51 @@ +#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++; + +#endif diff --git a/tests/tests2/60_errors_and_warnings.expect b/tests/tests2/60_errors_and_warnings.expect new file mode 100644 index 0000000..ed6a690 --- /dev/null +++ b/tests/tests2/60_errors_and_warnings.expect @@ -0,0 +1,28 @@ +[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] + +[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 diff --git a/tests/tests2/61_undefined_enum.c b/tests/tests2/61_undefined_enum.c deleted file mode 100644 index bc7c6ea..0000000 --- a/tests/tests2/61_undefined_enum.c +++ /dev/null @@ -1 +0,0 @@ -enum rgb c = 42; diff --git a/tests/tests2/61_undefined_enum.expect b/tests/tests2/61_undefined_enum.expect deleted file mode 100644 index eb8b774..0000000 --- a/tests/tests2/61_undefined_enum.expect +++ /dev/null @@ -1 +0,0 @@ -61_undefined_enum.c:1: error: unknown type size diff --git a/tests/tests2/62_enumerator_redefinition.c b/tests/tests2/62_enumerator_redefinition.c deleted file mode 100644 index 3da85ae..0000000 --- a/tests/tests2/62_enumerator_redefinition.c +++ /dev/null @@ -1,4 +0,0 @@ -enum color {RED, GREEN, BLUE}; -enum rgb {RED, G, B}; - -enum color c = RED; diff --git a/tests/tests2/62_enumerator_redefinition.expect b/tests/tests2/62_enumerator_redefinition.expect deleted file mode 100644 index 3d0e879..0000000 --- a/tests/tests2/62_enumerator_redefinition.expect +++ /dev/null @@ -1 +0,0 @@ -62_enumerator_redefinition.c:2: error: redefinition of enumerator 'RED' diff --git a/tests/tests2/63_local_enumerator_redefinition.c b/tests/tests2/63_local_enumerator_redefinition.c deleted file mode 100644 index dd4d8e0..0000000 --- a/tests/tests2/63_local_enumerator_redefinition.c +++ /dev/null @@ -1,14 +0,0 @@ -enum { - FOO, - BAR -}; - -int main(void) -{ - enum { - FOO = 2, - BAR - }; - - return BAR - FOO; -} diff --git a/tests/tests2/63_local_enumerator_redefinition.expect b/tests/tests2/63_local_enumerator_redefinition.expect deleted file mode 100644 index e69de29..0000000 diff --git a/tests/tests2/74_nocode_wanted.c b/tests/tests2/74_nocode_wanted.c deleted file mode 100644 index e824d02..0000000 --- a/tests/tests2/74_nocode_wanted.c +++ /dev/null @@ -1 +0,0 @@ -int i = i++; diff --git a/tests/tests2/74_nocode_wanted.expect b/tests/tests2/74_nocode_wanted.expect deleted file mode 100644 index f060ef4..0000000 --- a/tests/tests2/74_nocode_wanted.expect +++ /dev/null @@ -1 +0,0 @@ -74_nocode_wanted.c:1: error: initializer element is not constant diff --git a/tests/tests2/81_types.c b/tests/tests2/81_types.c index 542d066..fd6d71b 100644 --- a/tests/tests2/81_types.c +++ b/tests/tests2/81_types.c @@ -6,4 +6,38 @@ 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); +} +int f8 (int ([4]), int); int main () { return 0; } diff --git a/tests/tests2/82_attribs_position.c b/tests/tests2/82_attribs_position.c index 45039b3..7c9f987 100644 --- a/tests/tests2/82_attribs_position.c +++ b/tests/tests2/82_attribs_position.c @@ -11,4 +11,9 @@ typedef union __attribute__((packed)) Unaligned16b { uint8_t b[2]; } Unaligned16b; +extern void foo (void) __attribute__((stdcall)); +void __attribute__((stdcall)) foo (void) +{ +} + int main () { return 0; } diff --git a/tests/tests2/82_nocode_wanted.c b/tests/tests2/82_nocode_wanted.c deleted file mode 100644 index a0ec890..0000000 --- a/tests/tests2/82_nocode_wanted.c +++ /dev/null @@ -1,112 +0,0 @@ -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/tests/tests2/82_nocode_wanted.expect b/tests/tests2/82_nocode_wanted.expect deleted file mode 100644 index c44d4ea..0000000 --- a/tests/tests2/82_nocode_wanted.expect +++ /dev/null @@ -1,14 +0,0 @@ -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/tests/tests2/84-hex-float.c b/tests/tests2/84-hex-float.c deleted file mode 100644 index 0ef09bf..0000000 --- a/tests/tests2/84-hex-float.c +++ /dev/null @@ -1,12 +0,0 @@ -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/tests/tests2/84-hex-float.expect b/tests/tests2/84-hex-float.expect deleted file mode 100644 index 2175385..0000000 --- a/tests/tests2/84-hex-float.expect +++ /dev/null @@ -1 +0,0 @@ -n+1 = 15 diff --git a/tests/tests2/84_hex-float.c b/tests/tests2/84_hex-float.c new file mode 100644 index 0000000..0ef09bf --- /dev/null +++ b/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/tests/tests2/84_hex-float.expect b/tests/tests2/84_hex-float.expect new file mode 100644 index 0000000..2175385 --- /dev/null +++ b/tests/tests2/84_hex-float.expect @@ -0,0 +1 @@ +n+1 = 15 diff --git a/tests/tests2/85-asm-outside-function.c b/tests/tests2/85-asm-outside-function.c deleted file mode 100644 index 0aa7e33..0000000 --- a/tests/tests2/85-asm-outside-function.c +++ /dev/null @@ -1,7 +0,0 @@ -extern void vide(void); -__asm__("vide: ret"); - -int main() { - vide(); - return 0; -} diff --git a/tests/tests2/85-asm-outside-function.expect b/tests/tests2/85-asm-outside-function.expect deleted file mode 100644 index e69de29..0000000 diff --git a/tests/tests2/85_asm-outside-function.c b/tests/tests2/85_asm-outside-function.c new file mode 100644 index 0000000..dc5639a --- /dev/null +++ b/tests/tests2/85_asm-outside-function.c @@ -0,0 +1,9 @@ +extern int printf (const char *, ...); +extern void vide(void); +__asm__("vide: ret"); + +int main() { + vide(); + printf ("okay\n"); + return 0; +} diff --git a/tests/tests2/85_asm-outside-function.expect b/tests/tests2/85_asm-outside-function.expect new file mode 100644 index 0000000..dcf02b2 --- /dev/null +++ b/tests/tests2/85_asm-outside-function.expect @@ -0,0 +1 @@ +okay diff --git a/tests/tests2/86-memory-model.c b/tests/tests2/86-memory-model.c deleted file mode 100755 index ca30737..0000000 --- a/tests/tests2/86-memory-model.c +++ /dev/null @@ -1,38 +0,0 @@ -#include - -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/tests/tests2/86-memory-model.expect b/tests/tests2/86-memory-model.expect deleted file mode 100755 index a28de60..0000000 --- a/tests/tests2/86-memory-model.expect +++ /dev/null @@ -1 +0,0 @@ -Ok diff --git a/tests/tests2/86-struct-init.c b/tests/tests2/86-struct-init.c deleted file mode 100644 index fd212ba..0000000 --- a/tests/tests2/86-struct-init.c +++ /dev/null @@ -1,248 +0,0 @@ -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}; -/* Compund 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}; - -/* 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 -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}; - /* Compund 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 }; - 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(flow); -} -#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"); } -typedef void (*fptr)(void); -const fptr table[3] = { - [0 ... 2] = &sys_ni, - [0] = sys_one, - [1] = sys_two, - [2] = sys_three, -}; - -void test_multi_relocs(void) -{ - int i; - for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) - table[i](); -} - -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(phdr); - foo(&gw, &phdr); - //printf("q: %s\n", q); - test_compound_with_relocs(); - test_multi_relocs(); - return 0; -} diff --git a/tests/tests2/86-struct-init.expect b/tests/tests2/86-struct-init.expect deleted file mode 100644 index adda76d..0000000 --- a/tests/tests2/86-struct-init.expect +++ /dev/null @@ -1,40 +0,0 @@ -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 -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 -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 -one -two -three diff --git a/tests/tests2/86_memory-model.c b/tests/tests2/86_memory-model.c new file mode 100644 index 0000000..744c3e2 --- /dev/null +++ b/tests/tests2/86_memory-model.c @@ -0,0 +1,38 @@ +#include + +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/tests/tests2/86_memory-model.expect b/tests/tests2/86_memory-model.expect new file mode 100644 index 0000000..7326d96 --- /dev/null +++ b/tests/tests2/86_memory-model.expect @@ -0,0 +1 @@ +Ok diff --git a/tests/tests2/87_dead_code.c b/tests/tests2/87_dead_code.c index 92983f5..98d4566 100644 --- a/tests/tests2/87_dead_code.c +++ b/tests/tests2/87_dead_code.c @@ -9,7 +9,7 @@ static void kb_wait_1(void) /* 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 havok to the cond-expression because there's no + 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 ? diff --git a/tests/tests2/87_ptr_longlong_arith32.c b/tests/tests2/87_ptr_longlong_arith32.c deleted file mode 100644 index bf07915..0000000 --- a/tests/tests2/87_ptr_longlong_arith32.c +++ /dev/null @@ -1,15 +0,0 @@ -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/tests/tests2/87_ptr_longlong_arith32.expect b/tests/tests2/87_ptr_longlong_arith32.expect deleted file mode 100644 index f91e4b4..0000000 --- a/tests/tests2/87_ptr_longlong_arith32.expect +++ /dev/null @@ -1 +0,0 @@ -data = "0123-5678" diff --git a/tests/tests2/88_codeopt.c b/tests/tests2/88_codeopt.c new file mode 100644 index 0000000..647626f --- /dev/null +++ b/tests/tests2/88_codeopt.c @@ -0,0 +1,68 @@ +/* Check some way in where code suppression caused various + miscompilations. */ +extern int printf (const char *, ...); +typedef unsigned long 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)); +} + +_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)); +} + +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(); + return 0; +} diff --git a/tests/tests2/88_codeopt.expect b/tests/tests2/88_codeopt.expect new file mode 100644 index 0000000..439edfd --- /dev/null +++ b/tests/tests2/88_codeopt.expect @@ -0,0 +1,2 @@ +okay +okay diff --git a/tests/tests2/89_nocode_wanted.c b/tests/tests2/89_nocode_wanted.c new file mode 100644 index 0000000..73e0a4b --- /dev/null +++ b/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/tests/tests2/89_nocode_wanted.expect b/tests/tests2/89_nocode_wanted.expect new file mode 100644 index 0000000..c44d4ea --- /dev/null +++ b/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/tests/tests2/90_struct-init.c b/tests/tests2/90_struct-init.c new file mode 100644 index 0000000..d931e23 --- /dev/null +++ b/tests/tests2/90_struct-init.c @@ -0,0 +1,282 @@ +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}; + +/* 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 +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 }; + 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(flow); +} +#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"); } +typedef void (*fptr)(void); +const fptr table[3] = { + [0 ... 2] = &sys_ni, + [0] = sys_one, + [1] = sys_two, + [2] = sys_three, +}; + +void test_multi_relocs(void) +{ + int i; + for (i = 0; i < sizeof(table)/sizeof(table[0]); i++) + table[i](); +} + +/* 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; +} + +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(phdr); + foo(&gw, &phdr); + //printf("q: %s\n", q); + test_compound_with_relocs(); + test_multi_relocs(); + test_zero_init(); + return 0; +} diff --git a/tests/tests2/90_struct-init.expect b/tests/tests2/90_struct-init.expect new file mode 100644 index 0000000..e366121 --- /dev/null +++ b/tests/tests2/90_struct-init.expect @@ -0,0 +1,43 @@ +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 +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 +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 +one +two +three +sea_fill0: okay +sea_fill1: okay +sea_fill2: okay diff --git a/tests/tests2/91_ptr_longlong_arith32.c b/tests/tests2/91_ptr_longlong_arith32.c new file mode 100644 index 0000000..bf07915 --- /dev/null +++ b/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/tests/tests2/91_ptr_longlong_arith32.expect b/tests/tests2/91_ptr_longlong_arith32.expect new file mode 100644 index 0000000..f91e4b4 --- /dev/null +++ b/tests/tests2/91_ptr_longlong_arith32.expect @@ -0,0 +1 @@ +data = "0123-5678" diff --git a/tests/tests2/92_enum_bitfield.c b/tests/tests2/92_enum_bitfield.c new file mode 100644 index 0000000..bb6dc35 --- /dev/null +++ b/tests/tests2/92_enum_bitfield.c @@ -0,0 +1,57 @@ +/* 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"); +} + +int main() +{ + union tree_node convs; + + convs.common.code = AMBIG_CONV; + convert_like_real (&convs); + return 0; +} diff --git a/tests/tests2/92_enum_bitfield.expect b/tests/tests2/92_enum_bitfield.expect new file mode 100644 index 0000000..e69de29 diff --git a/tests/tests2/93_integer_promotion.c b/tests/tests2/93_integer_promotion.c new file mode 100644 index 0000000..a1176fc --- /dev/null +++ b/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/tests/tests2/93_integer_promotion.expect b/tests/tests2/93_integer_promotion.expect new file mode 100644 index 0000000..34b9c14 --- /dev/null +++ b/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/tests/tests2/94_generic.c b/tests/tests2/94_generic.c new file mode 100644 index 0000000..d7fb5fc --- /dev/null +++ b/tests/tests2/94_generic.c @@ -0,0 +1,64 @@ +#include + +const int a = 0; + +struct a { + int a; +}; + +struct b { + int a; +}; + +int a_f() +{ + return 20; +} + +int b_f() +{ + return 10; +} + +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); + return 0; +} diff --git a/tests/tests2/94_generic.expect b/tests/tests2/94_generic.expect new file mode 100644 index 0000000..9aa9275 --- /dev/null +++ b/tests/tests2/94_generic.expect @@ -0,0 +1,13 @@ +20 +10 +20 +123 +2 +0 +5 +1 +2 +3 +4 +long +1 \ No newline at end of file diff --git a/tests/tests2/95_bitfields.c b/tests/tests2/95_bitfields.c new file mode 100644 index 0000000..f025c57 --- /dev/null +++ b/tests/tests2/95_bitfields.c @@ -0,0 +1,218 @@ +/* ----------------------------------------------------------------------- */ +#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 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 + +#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 +#include +/* 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/tests/tests2/95_bitfields.expect b/tests/tests2/95_bitfields.expect new file mode 100644 index 0000000..6a8fd9a --- /dev/null +++ b/tests/tests2/95_bitfields.expect @@ -0,0 +1,149 @@ +---- 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 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 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 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 diff --git a/tests/tests2/95_bitfields_ms.c b/tests/tests2/95_bitfields_ms.c new file mode 100644 index 0000000..b196fbd --- /dev/null +++ b/tests/tests2/95_bitfields_ms.c @@ -0,0 +1,2 @@ +#define MS_BITFIELDS 1 +#include "95_bitfields.c" diff --git a/tests/tests2/95_bitfields_ms.expect b/tests/tests2/95_bitfields_ms.expect new file mode 100644 index 0000000..8ccafb7 --- /dev/null +++ b/tests/tests2/95_bitfields_ms.expect @@ -0,0 +1,149 @@ +---- 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 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 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 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 diff --git a/tests/tests2/96_nodata_wanted.c b/tests/tests2/96_nodata_wanted.c new file mode 100644 index 0000000..cc211d3 --- /dev/null +++ b/tests/tests2/96_nodata_wanted.c @@ -0,0 +1,84 @@ +/*****************************************************************************/ +/* 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 +/* 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 char ds0 = 0; + static 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 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)) { + 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 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);*/ +} + +#endif diff --git a/tests/tests2/96_nodata_wanted.expect b/tests/tests2/96_nodata_wanted.expect new file mode 100644 index 0000000..2749109 --- /dev/null +++ b/tests/tests2/96_nodata_wanted.expect @@ -0,0 +1,23 @@ +[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: nonportable conversion from pointer to char/short + +[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 diff --git a/tests/tests2/97_utf8_string_literal.c b/tests/tests2/97_utf8_string_literal.c new file mode 100644 index 0000000..96fbab0 --- /dev/null +++ b/tests/tests2/97_utf8_string_literal.c @@ -0,0 +1,12 @@ +// this file contains BMP chars encoded in UTF-8 +#include +#include + +int main() +{ + 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/tests/tests2/97_utf8_string_literal.expect b/tests/tests2/97_utf8_string_literal.expect new file mode 100644 index 0000000..9a1593c --- /dev/null +++ b/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/tests/tests2/98_al_ax_extend.c b/tests/tests2/98_al_ax_extend.c new file mode 100644 index 0000000..9b4e02f --- /dev/null +++ b/tests/tests2/98_al_ax_extend.c @@ -0,0 +1,41 @@ +#include +#include +asm ( + ".text;" + ".globl _us;.globl _ss;.globl _uc;.globl _sc;" + "_us:;_ss:;_uc:;_sc:;" + "movl $0x1234ABCD, %eax;" + "ret;" +); + +#if 1 +#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/tests/tests2/98_al_ax_extend.expect b/tests/tests2/98_al_ax_extend.expect new file mode 100644 index 0000000..c5752e8 --- /dev/null +++ b/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/tests/tests2/99_fastcall.c b/tests/tests2/99_fastcall.c new file mode 100644 index 0000000..ee4b67d --- /dev/null +++ b/tests/tests2/99_fastcall.c @@ -0,0 +1,276 @@ +#include +#include + +#ifndef _WIN32 +#define __fastcall __attribute((fastcall)) +#endif + +#if 1 +#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/tests/tests2/99_fastcall.expect b/tests/tests2/99_fastcall.expect new file mode 100644 index 0000000..3835d63 --- /dev/null +++ b/tests/tests2/99_fastcall.expect @@ -0,0 +1 @@ +TEST OK diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 2434215..190b2d9 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -1,32 +1,33 @@ TOP = ../.. -include $(TOP)/config.mak +include $(TOP)/Makefile SRC = $(TOPSRC)/tests/tests2 VPATH = $(SRC) -# run local version of tcc with local libraries and includes -TCCFLAGS = -B$(TOP) -I$(TOPSRC)/include -ifdef CONFIG_WIN32 - TCCFLAGS = -B$(TOPSRC)/win32 -I$(TOPSRC)/include -L$(TOP) -endif -TCC = $(TOP)/tcc $(TCCFLAGS) - TESTS = $(patsubst %.c,%.test,$(sort $(notdir $(wildcard $(SRC)/*.c)))) -# 34_array_assignment.test -- array assignment is not in C standard -SKIP = 34_array_assignment.test - # 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),yes) # not ARM soft-float SKIP += 22_floating_point.test endif -ifeq ($(TARGETOS),Darwin) - SKIP += 40_stdio.test +ifdef CONFIG_OSX + SKIP += 40_stdio.test 42_function_pointer.test + FLAGS += -w endif -ifeq ($(ARCH),x86-64) +ifeq ($(ARCH),x86_64) SKIP += 73_arm64.test endif -ifeq (,$(filter i386 x86-64,$(ARCH))) - SKIP += 85-asm-outside-function.test +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 +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 # Some tests might need arguments @@ -34,8 +35,24 @@ 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 -76_dollars_in_identifiers.test : TCCFLAGS += -fdollars-in-identifiers +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) # Filter source directory in warnings/errors (out-of-tree builds) FILTER = 2>&1 | sed 's,$(SRC)/,,g' @@ -44,20 +61,52 @@ ifeq (-$(findstring arm,$(ARCH))-,-arm-) FILTER += 2>&1 | grep -v 'warning: soft float ABI currently not supported' endif -all test: $(filter-out $(SKIP),$(TESTS)) +all test tests2.all: $(filter-out $(SKIP),$(TESTS)) ; %.test: %.c %.expect @echo Test: $*... -# test -run - @$(TCC) -run $< $(ARGS) $(FILTER) >$*.output 2>&1 || true - @diff -Nbu $(SRC)/$*.expect $*.output && rm -f $*.output + @$(if $(NORUN),$(T1),$(T2)) $(if $(NODIFF),,$(T3)) + +T1 = $(TCC) $(FLAGS) $< -o a.exe && ./a.exe $(ARGS) +T2 = $(TCC) $(FLAGS) -run $< $(ARGS) +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,$*) NODIFF=true --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 : %.c - (gcc -w $*.c -o a.exe && ./a.exe $(ARGS)) >$*.expect 2>&1; rm -f a.exe +%.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,$(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-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 a.exe + rm -f fred.txt *.output a.exe $(GEN-ALWAYS) -- cgit v1.2.3