summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2018-02-21 23:16:20 +0000
committerThomas Preud'homme <robotux@celest.fr>2018-02-21 23:16:20 +0000
commite2ccf3981d78dfeb390d22c74625b60310100abb (patch)
treefc30b3b3fe20cc005634818512dab3514acf8ef4 /tests
parent3f2e65a51523fbb98a44b71c29ae3a3fcc13854b (diff)
New upstream version 0.9.27
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile99
-rw-r--r--tests/abitest.c44
-rw-r--r--tests/asm-c-connect-1.c57
-rw-r--r--tests/asm-c-connect-2.c36
-rw-r--r--tests/asmtest.S20
-rwxr-xr-x[-rw-r--r--]tests/gcctestsuite.sh0
-rw-r--r--tests/libtcc_test.c4
-rw-r--r--tests/pp/13.expect1
-rw-r--r--tests/pp/15.c6
-rw-r--r--tests/pp/15.expect2
-rw-r--r--tests/pp/18.c15
-rw-r--r--tests/pp/18.expect3
-rw-r--r--tests/pp/19.c101
-rw-r--r--tests/pp/19.expect14
-rw-r--r--tests/pp/20.c13
-rw-r--r--tests/pp/20.expect6
-rw-r--r--tests/pp/21.c36
-rw-r--r--tests/pp/21.expect8
-rw-r--r--tests/pp/Makefile21
-rw-r--r--tests/pp/pp-counter.c27
-rw-r--r--tests/pp/pp-counter.expect15
-rw-r--r--tests/tcctest.c222
-rw-r--r--tests/tcctest.py15
-rw-r--r--tests/tests2/17_enum.c43
-rw-r--r--tests/tests2/17_enum.expect1
-rw-r--r--tests/tests2/39_typedef.c18
-rw-r--r--tests/tests2/42_function_pointer.c6
-rw-r--r--tests/tests2/56_btype_excess-1.c1
-rw-r--r--tests/tests2/56_btype_excess-1.expect1
-rw-r--r--tests/tests2/57_btype_excess-2.c1
-rw-r--r--tests/tests2/57_btype_excess-2.expect1
-rw-r--r--tests/tests2/58_function_redefinition.c9
-rw-r--r--tests/tests2/58_function_redefinition.expect1
-rw-r--r--tests/tests2/59_function_array.c1
-rw-r--r--tests/tests2/59_function_array.expect1
-rw-r--r--tests/tests2/60_enum_redefinition.c4
-rw-r--r--tests/tests2/60_enum_redefinition.expect1
-rw-r--r--tests/tests2/60_errors_and_warnings.c51
-rw-r--r--tests/tests2/60_errors_and_warnings.expect28
-rw-r--r--tests/tests2/61_undefined_enum.c1
-rw-r--r--tests/tests2/61_undefined_enum.expect1
-rw-r--r--tests/tests2/62_enumerator_redefinition.c4
-rw-r--r--tests/tests2/62_enumerator_redefinition.expect1
-rw-r--r--tests/tests2/63_local_enumerator_redefinition.c14
-rw-r--r--tests/tests2/74_nocode_wanted.c1
-rw-r--r--tests/tests2/74_nocode_wanted.expect1
-rw-r--r--tests/tests2/81_types.c34
-rw-r--r--tests/tests2/82_attribs_position.c5
-rw-r--r--tests/tests2/84_hex-float.c (renamed from tests/tests2/84-hex-float.c)0
-rw-r--r--tests/tests2/84_hex-float.expect (renamed from tests/tests2/84-hex-float.expect)0
-rw-r--r--tests/tests2/85-asm-outside-function.expect0
-rw-r--r--tests/tests2/85_asm-outside-function.c (renamed from tests/tests2/85-asm-outside-function.c)2
-rw-r--r--tests/tests2/85_asm-outside-function.expect1
-rw-r--r--[-rwxr-xr-x]tests/tests2/86_memory-model.c (renamed from tests/tests2/86-memory-model.c)76
-rw-r--r--[-rwxr-xr-x]tests/tests2/86_memory-model.expect (renamed from tests/tests2/86-memory-model.expect)2
-rw-r--r--tests/tests2/87_dead_code.c2
-rw-r--r--tests/tests2/88_codeopt.c68
-rw-r--r--tests/tests2/88_codeopt.expect2
-rw-r--r--tests/tests2/89_nocode_wanted.c (renamed from tests/tests2/82_nocode_wanted.c)12
-rw-r--r--tests/tests2/89_nocode_wanted.expect (renamed from tests/tests2/82_nocode_wanted.expect)0
-rw-r--r--tests/tests2/90_struct-init.c (renamed from tests/tests2/86-struct-init.c)38
-rw-r--r--tests/tests2/90_struct-init.expect (renamed from tests/tests2/86-struct-init.expect)3
-rw-r--r--tests/tests2/91_ptr_longlong_arith32.c (renamed from tests/tests2/87_ptr_longlong_arith32.c)0
-rw-r--r--tests/tests2/91_ptr_longlong_arith32.expect (renamed from tests/tests2/87_ptr_longlong_arith32.expect)0
-rw-r--r--tests/tests2/92_enum_bitfield.c57
-rw-r--r--tests/tests2/92_enum_bitfield.expect (renamed from tests/tests2/63_local_enumerator_redefinition.expect)0
-rw-r--r--tests/tests2/93_integer_promotion.c71
-rw-r--r--tests/tests2/93_integer_promotion.expect46
-rw-r--r--tests/tests2/94_generic.c64
-rw-r--r--tests/tests2/94_generic.expect13
-rw-r--r--tests/tests2/95_bitfields.c218
-rw-r--r--tests/tests2/95_bitfields.expect149
-rw-r--r--tests/tests2/95_bitfields_ms.c2
-rw-r--r--tests/tests2/95_bitfields_ms.expect149
-rw-r--r--tests/tests2/96_nodata_wanted.c84
-rw-r--r--tests/tests2/96_nodata_wanted.expect23
-rw-r--r--tests/tests2/97_utf8_string_literal.c12
-rw-r--r--tests/tests2/97_utf8_string_literal.expect1
-rw-r--r--tests/tests2/98_al_ax_extend.c41
-rw-r--r--tests/tests2/98_al_ax_extend.expect9
-rw-r--r--tests/tests2/99_fastcall.c276
-rw-r--r--tests/tests2/99_fastcall.expect1
-rw-r--r--tests/tests2/Makefile97
83 files changed, 2306 insertions, 208 deletions
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 <stdarg.h>\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 <stdio.h>
+
+#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 <stdio.h>
+
+#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
index f3cc538..f3cc538 100644..100755
--- a/tests/gcctestsuite.sh
+++ b/tests/gcctestsuite.sh
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 <tcclib.h>\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/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/84-hex-float.c b/tests/tests2/84_hex-float.c
index 0ef09bf..0ef09bf 100644
--- a/tests/tests2/84-hex-float.c
+++ b/tests/tests2/84_hex-float.c
diff --git a/tests/tests2/84-hex-float.expect b/tests/tests2/84_hex-float.expect
index 2175385..2175385 100644
--- a/tests/tests2/84-hex-float.expect
+++ b/tests/tests2/84_hex-float.expect
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
--- a/tests/tests2/85-asm-outside-function.expect
+++ /dev/null
diff --git a/tests/tests2/85-asm-outside-function.c b/tests/tests2/85_asm-outside-function.c
index 0aa7e33..dc5639a 100644
--- a/tests/tests2/85-asm-outside-function.c
+++ b/tests/tests2/85_asm-outside-function.c
@@ -1,7 +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
index ca30737..744c3e2 100755..100644
--- a/tests/tests2/86-memory-model.c
+++ b/tests/tests2/86_memory-model.c
@@ -1,38 +1,38 @@
-#include <stdio.h>
-
-int
-main()
-{
-#if defined(__LLP64__)
- if (sizeof(short) == 2
- && sizeof(int) == 4
- && sizeof(long int) == 4
- && sizeof(long long int) == 8
- && sizeof(void*) == 8) {
- (void)printf("Ok\n");
- } else {
- (void)printf("KO __LLP64__\n");
- }
-#elif defined(__LP64__)
- if (sizeof(short) == 2
- && sizeof(int) == 4
- && sizeof(long int) == 8
- && sizeof(long long int) == 8
- && sizeof(void*) == 8) {
- (void)printf("Ok\n");
- } else {
- (void)printf("KO __LP64__\n");
- }
-#elif defined(__ILP32__)
- if (sizeof(short) == 2
- && sizeof(int) == 4
- && sizeof(long int) == 4
- && sizeof(void*) == 4) {
- (void)printf("Ok\n");
- } else {
- (void)printf("KO __ILP32__\n");
- }
-#else
- (void)printf("KO no __*LP*__ defined.\n");
-#endif
-}
+#include <stdio.h>
+
+int
+main()
+{
+#if defined(__LLP64__)
+ if (sizeof(short) == 2
+ && sizeof(int) == 4
+ && sizeof(long int) == 4
+ && sizeof(long long int) == 8
+ && sizeof(void*) == 8) {
+ (void)printf("Ok\n");
+ } else {
+ (void)printf("KO __LLP64__\n");
+ }
+#elif defined(__LP64__)
+ if (sizeof(short) == 2
+ && sizeof(int) == 4
+ && sizeof(long int) == 8
+ && sizeof(long long int) == 8
+ && sizeof(void*) == 8) {
+ (void)printf("Ok\n");
+ } else {
+ (void)printf("KO __LP64__\n");
+ }
+#elif defined(__ILP32__)
+ if (sizeof(short) == 2
+ && sizeof(int) == 4
+ && sizeof(long int) == 4
+ && sizeof(void*) == 4) {
+ (void)printf("Ok\n");
+ } else {
+ (void)printf("KO __ILP32__\n");
+ }
+#else
+ (void)printf("KO no __*LP*__ defined.\n");
+#endif
+}
diff --git a/tests/tests2/86-memory-model.expect b/tests/tests2/86_memory-model.expect
index a28de60..7326d96 100755..100644
--- a/tests/tests2/86-memory-model.expect
+++ b/tests/tests2/86_memory-model.expect
@@ -1 +1 @@
-Ok
+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/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/82_nocode_wanted.c b/tests/tests2/89_nocode_wanted.c
index a0ec890..73e0a4b 100644
--- a/tests/tests2/82_nocode_wanted.c
+++ b/tests/tests2/89_nocode_wanted.c
@@ -3,7 +3,7 @@ static void kb_wait_1(void)
{
unsigned long timeout = 2;
do {
- (1 ?
+ (1 ?
printf("timeout=%ld\n", timeout) :
({
while (1)
@@ -17,7 +17,7 @@ static void kb_wait_2(void)
{
unsigned long timeout = 2;
do {
- (1 ?
+ (1 ?
printf("timeout=%ld\n", timeout) :
({
for (;;)
@@ -31,7 +31,7 @@ static void kb_wait_2_1(void)
{
unsigned long timeout = 2;
do {
- (1 ?
+ (1 ?
printf("timeout=%ld\n", timeout) :
({
do {
@@ -46,7 +46,7 @@ static void kb_wait_2_2(void)
{
unsigned long timeout = 2;
do {
- (1 ?
+ (1 ?
printf("timeout=%ld\n", timeout) :
({
label:
@@ -61,7 +61,7 @@ static void kb_wait_3(void)
{
unsigned long timeout = 2;
do {
- (1 ?
+ (1 ?
printf("timeout=%ld\n", timeout) :
({
int i = 1;
@@ -78,7 +78,7 @@ static void kb_wait_4(void)
{
unsigned long timeout = 2;
do {
- (1 ?
+ (1 ?
printf("timeout=%ld\n", timeout) :
({
switch(timeout) {
diff --git a/tests/tests2/82_nocode_wanted.expect b/tests/tests2/89_nocode_wanted.expect
index c44d4ea..c44d4ea 100644
--- a/tests/tests2/82_nocode_wanted.expect
+++ b/tests/tests2/89_nocode_wanted.expect
diff --git a/tests/tests2/86-struct-init.c b/tests/tests2/90_struct-init.c
index fd212ba..d931e23 100644
--- a/tests/tests2/86-struct-init.c
+++ b/tests/tests2/90_struct-init.c
@@ -60,7 +60,7 @@ struct U gu4 = { 3, {5,6,7,}, 5, { "bla", {44}} };
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 */
+/* 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};
@@ -157,7 +157,7 @@ void foo (struct W *w, struct pkthdr *phdr_)
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 */
+ /* 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};
@@ -217,7 +217,40 @@ void test_multi_relocs(void)
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);
@@ -244,5 +277,6 @@ int main()
//printf("q: %s\n", q);
test_compound_with_relocs();
test_multi_relocs();
+ test_zero_init();
return 0;
}
diff --git a/tests/tests2/86-struct-init.expect b/tests/tests2/90_struct-init.expect
index adda76d..e366121 100644
--- a/tests/tests2/86-struct-init.expect
+++ b/tests/tests2/90_struct-init.expect
@@ -38,3 +38,6 @@ 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/87_ptr_longlong_arith32.c b/tests/tests2/91_ptr_longlong_arith32.c
index bf07915..bf07915 100644
--- a/tests/tests2/87_ptr_longlong_arith32.c
+++ b/tests/tests2/91_ptr_longlong_arith32.c
diff --git a/tests/tests2/87_ptr_longlong_arith32.expect b/tests/tests2/91_ptr_longlong_arith32.expect
index f91e4b4..f91e4b4 100644
--- a/tests/tests2/87_ptr_longlong_arith32.expect
+++ b/tests/tests2/91_ptr_longlong_arith32.expect
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/63_local_enumerator_redefinition.expect b/tests/tests2/92_enum_bitfield.expect
index e69de29..e69de29 100644
--- a/tests/tests2/63_local_enumerator_redefinition.expect
+++ b/tests/tests2/92_enum_bitfield.expect
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 <stdio.h>
+
+const int a = 0;
+
+struct a {
+ int a;
+};
+
+struct b {
+ int a;
+};
+
+int a_f()
+{
+ return 20;
+}
+
+int b_f()
+{
+ return 10;
+}
+
+typedef int 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 <stdio.h>
+#include <string.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+void dump(void *p, int s)
+{
+ int i;
+ for (i = s; --i >= 0;)
+ printf("%02X", ((unsigned char*)p)[i]);
+ printf("\n");
+}
+
+#define pv(m) \
+ printf(sizeof (s->m + 0) == 8 ? " %016llx" : " %02x", s->m)
+
+#define TEST_STRUCT(v1,v2,v3,v4,v5) { \
+ struct __s _s, *s = & _s; \
+ printf("\n---- TEST %d%s%s%s ----\n" + top, \
+ TEST, MS_BF?" - MS-BITFIELDS":"", \
+ PACK?" - PACKED":"", \
+ ALIGN?" - WITH ALIGN":""); \
+ memset(s, 0, sizeof *s); \
+ s->x = -1, s->y = -1, s->z = -1, s->a = -1, s->b = -1; \
+ printf("bits in use : "), dump(s, sizeof *s); \
+ s->x = v1, s->y = v2, s->z = v3, s->a += v4, ++s->a, s->b = v5; \
+ printf("bits as set : "), dump(s, sizeof *s); \
+ printf("values :"), pv(x), pv(y), pv(z), pv(a), pv(b), printf("\n"); \
+ printf("align/size : %d %d\n", alignof(struct __s),sizeof(struct __s)); \
+ }
+
+#ifdef _MSC_VER
+# define _A(n) __declspec(align(n))
+# define _P
+# define alignof(x) __alignof(x)
+#else
+# define _A(n) __attribute__((aligned(n)))
+# define _P __attribute__((packed))
+# define alignof(x) __alignof__(x)
+#endif
+
+#ifndef MS_BITFIELDS
+# define MS_BITFIELDS 0
+#endif
+
+#define SELF "95_bitfields.c"
+
+int top = 1;
+
+int main()
+{
+#define MS_BF MS_BITFIELDS
+#include SELF
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+#endif
+#undef TEST
diff --git a/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 <stdio.h>
+/* some gcc headers #define __attribute__ to empty if it's not gcc */
+#undef __attribute__
+
+int main()
+{
+ __label__ ts0, te0, ts1, te1;
+ int tl, dl;
+
+ static 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 <stdio.h>
+#include <wchar.h>
+
+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 <stdio.h>
+#include <stdlib.h>
+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 <stdio.h>
+#include <assert.h>
+
+#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)