aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CMakeLists.txt15
-rw-r--r--tests/Makefile11
-rw-r--r--tests/vla_test.c84
3 files changed, 105 insertions, 5 deletions
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index bcd37cd..cf5caf8 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -15,11 +15,16 @@ add_test(NAME abitest-cc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND abitest-c
set(ABITEST_TCC abitest-tcc${CMAKE_EXECUTABLE_SUFFIX})
get_property(LIBTCC_LIB TARGET libtcc PROPERTY LOCATION)
-add_custom_command(OUTPUT ${ABITEST_TCC} COMMAND tcc ${TCC_CFLAGS} -g ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c ${LIBTCC_LDFLAGS} ${LIBTCC_LIB} -o ${ABITEST_TCC} DEPENDS tcc abitest.c)
+add_custom_command(OUTPUT ${ABITEST_TCC} COMMAND tcc ${TCC_CFLAGS} -g ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c ${LIBTCC_LDFLAGS} ${LIBTCC_LIB} -o ${ABITEST_TCC} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c)
add_custom_target(abitest-tcc-exe ALL DEPENDS ${ABITEST_TCC})
add_test(NAME abitest-tcc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${ABITEST_TCC} lib_path=${CMAKE_BINARY_DIR} include=${CMAKE_SOURCE_DIR}/include)
+set(VLA_TEST vla_test${CMAKE_EXECUTABLE_SUFFIX})
+add_custom_command(OUTPUT ${VLA_TEST} COMMAND tcc ${TCC_CFLAGS} -g ${CMAKE_CURRENT_SOURCE_DIR}/vla_test.c -o ${VLA_TEST} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/vla_test.c)
+add_custom_target(vla_test-exe ALL DEPENDS ${VLA_TEST})
+add_test(vla_test vla_test)
+
add_executable(tcctest-cc tcctest.c)
target_link_libraries(tcctest-cc libtcc)
set_target_properties(tcctest-cc PROPERTIES COMPILE_FLAGS -std=gnu99)
@@ -41,21 +46,21 @@ if(PYTHONINTERP_FOUND)
# Object + link output
set(TEST4 test4${CMAKE_EXECUTABLE_SUFFIX})
- add_custom_command(OUTPUT test4.o COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -c -o test4.o DEPENDS tcc tcctest.c)
+ add_custom_command(OUTPUT test4.o COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -c -o test4.o DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_command(OUTPUT ${TEST4} COMMAND tcc ${TCC_TEST_CFLAGS} test4.o -o ${TEST4} DEPENDS tcc test4.o)
add_custom_target(test4-exe ALL DEPENDS ${TEST4})
add_test(test4 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST4})
# Dynamic output
set(TEST5 test5${CMAKE_EXECUTABLE_SUFFIX})
- add_custom_command(OUTPUT ${TEST5} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -o ${TEST5} DEPENDS tcc tcctest.c)
+ add_custom_command(OUTPUT ${TEST5} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -o ${TEST5} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_target(test5-exe ALL DEPENDS ${TEST5})
add_test(test5 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST5})
if(TCC_BCHECK)
# Dynamic output + bound check
set(TEST6 test6${CMAKE_EXECUTABLE_SUFFIX})
- add_custom_command(OUTPUT ${TEST5} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -b -o ${TEST6} DEPENDS tcc tcctest.c)
+ add_custom_command(OUTPUT ${TEST6} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -b -o ${TEST6} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_target(test6-exe ALL DEPENDS ${TEST6})
add_test(test6 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST6})
endif()
@@ -63,7 +68,7 @@ if(PYTHONINTERP_FOUND)
if(0)
# Static output
set(TEST7 test7${CMAKE_EXECUTABLE_SUFFIX})
- add_custom_command(OUTPUT ${TEST7} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -static -o ${TEST7} DEPENDS tcc tcctest.c)
+ add_custom_command(OUTPUT ${TEST7} COMMAND tcc ${TCC_TEST_CFLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c -static -o ${TEST7} DEPENDS tcc ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c)
add_custom_target(test7-exe ALL DEPENDS ${TEST7})
add_test(test7 ${TCCTEST_PY} ${CMAKE_CURRENT_BINARY_DIR}/${TEST7})
endif()
diff --git a/tests/Makefile b/tests/Makefile
index edb581c..08dfa42 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -14,6 +14,7 @@ TESTS = \
libtest \
test3 \
abitest \
+ vla_test-run \
moretests
# test4 -- problem with -static
@@ -31,6 +32,10 @@ endif
ifeq ($(TARGETOS),Darwin)
TESTS := $(filter-out hello-exe test3 btest,$(TESTS))
endif
+ifeq ($(ARCH),i386)
+else ifneq ($(ARCH),x86-64)
+ TESTS := $(filter-out vla_test-run,$(TESTS))
+endif
ifdef DISABLE_STATIC
export LD_LIBRARY_PATH:=$(CURDIR)/..
@@ -190,6 +195,12 @@ abitest: abitest-cc$(EXESUF) abitest-tcc$(EXESUF)
./abitest-cc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
./abitest-tcc$(EXESUF) lib_path=.. include="$(top_srcdir)/include"
+vla_test$(EXESUF): vla_test.c
+ $(TCC) -o $@ $^ $(CPPFLAGS) $(CFLAGS)
+vla_test-run: vla_test$(EXESUF)
+ @echo ------------ $@ ------------
+ ./vla_test$(EXESUF)
+
# targets for development
%.bin: %.c tcc
$(TCC) -g -o $@ $<
diff --git a/tests/vla_test.c b/tests/vla_test.c
new file mode 100644
index 0000000..3616c46
--- /dev/null
+++ b/tests/vla_test.c
@@ -0,0 +1,84 @@
+/*
+ * Test that allocating a variable length array in a loop
+ * does not use up a linear amount of memory
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define LOOP_COUNT 1000
+#define ARRAY_SIZE 100
+
+/* Overwrite a VLA. This will overwrite the return address if SP is incorrect */
+void smash(char *p, int n) {
+ memset(p, 0, n);
+}
+
+int test1(int n) {
+ int i;
+ char *array_ptrs[LOOP_COUNT];
+
+ for (i = 0; i < LOOP_COUNT; ++i) {
+ char test[n];
+ smash(test, n);
+ array_ptrs[i] = test;
+ }
+
+ return (array_ptrs[0]-array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+/* ensure goto does not circumvent array free */
+int test2(int n) {
+ char *array_ptrs[LOOP_COUNT];
+
+ int i = 0;
+loop:;
+ char test[n];
+ smash(test, n);
+ if (i >= LOOP_COUNT)
+ goto end;
+ array_ptrs[i] = test;
+ ++i;
+ goto loop;
+
+end:
+ smash(test, n);
+ char test2[n];
+ smash(test2, n);
+ return (array_ptrs[0] - array_ptrs[LOOP_COUNT-1] < n) ? 0 : 1;
+}
+
+int test3(int n) {
+ char test[n];
+ smash(test, n);
+ goto label;
+label:
+ smash(test, n);
+ char test2[n];
+ smash(test2, n);
+ return (test-test2 >= n) ? 0 : 1;
+}
+
+#define RUN_TEST(t) \
+ if (!testname || (strcmp(#t, testname) == 0)) { \
+ fputs(#t "... ", stdout); \
+ fflush(stdout); \
+ if (t(ARRAY_SIZE) == 0) { \
+ fputs("success\n", stdout); \
+ } else { \
+ fputs("failure\n", stdout); \
+ retval = EXIT_FAILURE; \
+ } \
+ }
+
+int main(int argc, char **argv) {
+ const char *testname = NULL;
+ int retval = EXIT_SUCCESS;
+ if (argc > 1)
+ testname = argv[1];
+ RUN_TEST(test1)
+ RUN_TEST(test2)
+ RUN_TEST(test3)
+ return retval;
+}