diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 18:41:23 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-09-06 18:41:23 +0000 |
commit | f31bcc68c72371a2bf63aead9f3373a1ff2053b6 (patch) | |
tree | b259e5d585da0f8cde9579939a74d5ef44c72abd /test/ubsan | |
parent | cd2dd3df15523e2be8d2bbace27641d6ac9fa40d (diff) | |
download | src-f31bcc68c72371a2bf63aead9f3373a1ff2053b6.tar.gz src-f31bcc68c72371a2bf63aead9f3373a1ff2053b6.zip |
Import compiler-rt 3.7.0 release (r246257).vendor/compiler-rt/compiler-rt-release_370-r246257
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=287516
svn path=/vendor/compiler-rt/compiler-rt-release_370-r246257/; revision=287517; tag=vendor/compiler-rt/compiler-rt-release_370-r246257
Diffstat (limited to 'test/ubsan')
29 files changed, 306 insertions, 177 deletions
diff --git a/test/ubsan/CMakeLists.txt b/test/ubsan/CMakeLists.txt index 1c0c92903298..cd197c7aed46 100644 --- a/test/ubsan/CMakeLists.txt +++ b/test/ubsan/CMakeLists.txt @@ -1,25 +1,43 @@ set(UBSAN_LIT_TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(UBSAN_LIT_TEST_MODE "Standalone") -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/UbsanConfig/lit.site.cfg) -set(UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/UbsanConfig) +set(UBSAN_TESTSUITES) +set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -if(COMPILER_RT_HAS_ASAN) - set(UBSAN_LIT_TEST_MODE "AddressSanitizer") +macro(add_ubsan_testsuite test_mode sanitizer arch) + set(UBSAN_LIT_TEST_MODE "${test_mode}") + set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${arch}) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/AsanConfig/lit.site.cfg) - list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/AsanConfig) -endif() + ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg) + list(APPEND UBSAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}) + if(NOT COMPILER_RT_STANDALONE_BUILD) + list(APPEND UBSAN_TEST_DEPS ${sanitizer}) + endif() +endmacro() -set(UBSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) -if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND UBSAN_TEST_DEPS ubsan asan) -endif() +foreach(arch ${UBSAN_SUPPORTED_ARCH}) + set(UBSAN_TEST_TARGET_ARCH ${arch}) + if(${arch} MATCHES "arm|aarch64") + # This is only true if we're cross-compiling. + set(UBSAN_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS}) + else() + get_target_flags_for_arch(${arch} UBSAN_TEST_TARGET_CFLAGS) + string(REPLACE ";" " " UBSAN_TEST_TARGET_CFLAGS "${UBSAN_TEST_TARGET_CFLAGS}") + endif() + add_ubsan_testsuite("Standalone" ubsan ${arch}) + + if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_testsuite("AddressSanitizer" asan ${arch}) + endif() + if(COMPILER_RT_HAS_MSAN AND ";${MSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_testsuite("MemorySanitizer" msan ${arch}) + endif() + if(COMPILER_RT_HAS_TSAN AND ";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_testsuite("ThreadSanitizer" tsan ${arch}) + endif() +endforeach() add_lit_testsuite(check-ubsan "Running UndefinedBehaviorSanitizer tests" ${UBSAN_TESTSUITES} DEPENDS ${UBSAN_TEST_DEPS}) -set_target_properties(check-ubsan PROPERTIES FOLDER "UBSan unittests") +set_target_properties(check-ubsan PROPERTIES FOLDER "UBSan tests") diff --git a/test/ubsan/TestCases/Float/cast-overflow.cpp b/test/ubsan/TestCases/Float/cast-overflow.cpp index 526817153d02..eda087442450 100644 --- a/test/ubsan/TestCases/Float/cast-overflow.cpp +++ b/test/ubsan/TestCases/Float/cast-overflow.cpp @@ -1,7 +1,6 @@ -// FIXME: run this (and other) UBSan tests in both 32- and 64-bit modes (?). -// RUN: %clangxx -fsanitize=float-cast-overflow %s -o %t +// RUN: %clangxx -fsanitize=float-cast-overflow -g %s -o %t // RUN: %run %t _ -// RUN: %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-0 +// RUN: env UBSAN_OPTIONS=print_summary=1 %run %t 0 2>&1 | FileCheck %s --check-prefix=CHECK-0 // RUN: %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-1 // RUN: %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-2 // RUN: %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK-3 @@ -13,8 +12,6 @@ // RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK-9 // This test assumes float and double are IEEE-754 single- and double-precision. -// XFAIL: armv7l-unknown-linux-gnueabihf -// XFAIL: aarch64 #if defined(__APPLE__) # include <machine/endian.h> @@ -26,6 +23,10 @@ # define BYTE_ORDER _BYTE_ORDER # define BIG_ENDIAN _BIG_ENDIAN # define LITTLE_ENDIAN _LITTLE_ENDIAN +#elif defined(_WIN32) +# define BYTE_ORDER 0 +# define BIG_ENDIAN 1 +# define LITTLE_ENDIAN 0 #else # include <endian.h> # define BYTE_ORDER __BYTE_ORDER @@ -82,40 +83,53 @@ int main(int argc, char **argv) { // FIXME: Produce a source location for these checks and test for it here. // Floating point -> integer overflow. - case '0': + case '0': { // Note that values between 0x7ffffe00 and 0x80000000 may or may not // successfully round-trip, depending on the rounding mode. // CHECK-0: runtime error: value 2.14748{{.*}} is outside the range of representable values of type 'int' - return MaxFloatRepresentableAsInt + 0x80; - case '1': + static int test_int = MaxFloatRepresentableAsInt + 0x80; + // CHECK-0: SUMMARY: {{.*}}Sanitizer: undefined-behavior {{.*}}cast-overflow.cpp:[[@LINE-1]] + return 0; + } + case '1': { // CHECK-1: runtime error: value -2.14748{{.*}} is outside the range of representable values of type 'int' - return MinFloatRepresentableAsInt - 0x100; + static int test_int = MinFloatRepresentableAsInt - 0x100; + return 0; + } case '2': { // CHECK-2: runtime error: value -1 is outside the range of representable values of type 'unsigned int' volatile float f = -1.0; volatile unsigned u = (unsigned)f; return 0; } - case '3': + case '3': { // CHECK-3: runtime error: value 4.2949{{.*}} is outside the range of representable values of type 'unsigned int' - return (unsigned)(MaxFloatRepresentableAsUInt + 0x100); + static int test_int = (unsigned)(MaxFloatRepresentableAsUInt + 0x100); + return 0; + } - case '4': + case '4': { // CHECK-4: runtime error: value {{.*}} is outside the range of representable values of type 'int' - return Inf; - case '5': + static int test_int = Inf; + return 0; + } + case '5': { // CHECK-5: runtime error: value {{.*}} is outside the range of representable values of type 'int' - return NaN; + static int test_int = NaN; + return 0; + } // Integer -> floating point overflow. - case '6': + case '6': { // CHECK-6: {{runtime error: value 0xffffff00000000000000000000000001 is outside the range of representable values of type 'float'|__int128 not supported}} -#ifdef __SIZEOF_INT128__ - return (float)(FloatMaxAsUInt128 + 1); +#if defined(__SIZEOF_INT128__) && !defined(_WIN32) + static int test_int = (float)(FloatMaxAsUInt128 + 1); + return 0; #else puts("__int128 not supported"); return 0; #endif + } // FIXME: The backend cannot lower __fp16 operations on x86 yet. //case '7': // (__fp16)65504; // ok diff --git a/test/ubsan/TestCases/Integer/add-overflow.cpp b/test/ubsan/TestCases/Integer/add-overflow.cpp index d3425828ec88..301941b852b4 100644 --- a/test/ubsan/TestCases/Integer/add-overflow.cpp +++ b/test/ubsan/TestCases/Integer/add-overflow.cpp @@ -1,6 +1,6 @@ -// RUN: %clangxx -DADD_I32 -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I32 -// RUN: %clangxx -DADD_I64 -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I64 -// RUN: %clangxx -DADD_I128 -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I128 +// RUN: %clangxx -DADD_I32 -fsanitize=signed-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I32 +// RUN: %clangxx -DADD_I64 -fsanitize=signed-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I64 +// RUN: %clangxx -DADD_I128 -fsanitize=signed-integer-overflow %s -o %t3 && %run %t3 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I128 #include <stdint.h> #include <stdio.h> @@ -22,7 +22,7 @@ int main() { #endif #ifdef ADD_I128 -# ifdef __SIZEOF_INT128__ +# if defined(__SIZEOF_INT128__) && !defined(_WIN32) (void)((__int128_t(1) << 126) + (__int128_t(1) << 126)); # else puts("__int128 not supported"); diff --git a/test/ubsan/TestCases/Integer/div-zero.cpp b/test/ubsan/TestCases/Integer/div-zero.cpp index 9a223312e8e7..68b01afab218 100644 --- a/test/ubsan/TestCases/Integer/div-zero.cpp +++ b/test/ubsan/TestCases/Integer/div-zero.cpp @@ -3,7 +3,7 @@ // RUN: %clangxx -fsanitize=float-divide-by-zero -DDIVIDEND=1.5 %s -o %t && %run %t 2>&1 | FileCheck %s // RUN: %clangxx -fsanitize=integer-divide-by-zero -DDIVIDEND='intmax(123)' %s -o %t && %run %t 2>&1 | FileCheck %s -#ifdef __SIZEOF_INT128__ +#if defined(__SIZEOF_INT128__) && !defined(_WIN32) typedef __int128 intmax; #else typedef long long intmax; diff --git a/test/ubsan/TestCases/Integer/incdec-overflow.cpp b/test/ubsan/TestCases/Integer/incdec-overflow.cpp index fc7141c803d8..06090300af3b 100644 --- a/test/ubsan/TestCases/Integer/incdec-overflow.cpp +++ b/test/ubsan/TestCases/Integer/incdec-overflow.cpp @@ -1,7 +1,7 @@ -// RUN: %clangxx -DOP=n++ -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s -// RUN: %clangxx -DOP=++n -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s -// RUN: %clangxx -DOP=m-- -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s -// RUN: %clangxx -DOP=--m -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s +// RUN: %clangxx -DOP=n++ -fsanitize=signed-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=PLUS +// RUN: %clangxx -DOP=++n -fsanitize=signed-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck %s --check-prefix=PLUS +// RUN: %clangxx -DOP=m-- -fsanitize=signed-integer-overflow %s -o %t3 && %run %t3 2>&1 | FileCheck %s --check-prefix=MINUS +// RUN: %clangxx -DOP=--m -fsanitize=signed-integer-overflow %s -o %t4 && %run %t4 2>&1 | FileCheck %s --check-prefix=MINUS #include <stdint.h> @@ -10,7 +10,7 @@ int main() { n++; n++; int m = -n - 1; - // CHECK: incdec-overflow.cpp:15:3: runtime error: signed integer overflow: [[MINUS:-?]]214748364 - // CHECK: + [[MINUS]]1 cannot be represented in type 'int' OP; + // PLUS: incdec-overflow.cpp:[[@LINE-1]]:3: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' + // MINUS: incdec-overflow.cpp:[[@LINE-2]]:3: runtime error: signed integer overflow: -2147483648 - 1 cannot be represented in type 'int' } diff --git a/test/ubsan/TestCases/Integer/negate-overflow.cpp b/test/ubsan/TestCases/Integer/negate-overflow.cpp index bde0bdabb292..628291eb4b95 100644 --- a/test/ubsan/TestCases/Integer/negate-overflow.cpp +++ b/test/ubsan/TestCases/Integer/negate-overflow.cpp @@ -1,5 +1,5 @@ -// RUN: %clangxx -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECKS -// RUN: %clangxx -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECKU +// RUN: %clangxx -fsanitize=signed-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=CHECKS +// RUN: %clangxx -fsanitize=unsigned-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck %s --check-prefix=CHECKU int main() { // CHECKS-NOT: runtime error diff --git a/test/ubsan/TestCases/Integer/shift.cpp b/test/ubsan/TestCases/Integer/shift.cpp index e86fac8d574a..50db16dac18e 100644 --- a/test/ubsan/TestCases/Integer/shift.cpp +++ b/test/ubsan/TestCases/Integer/shift.cpp @@ -1,13 +1,20 @@ -// RUN: %clangxx -DLSH_OVERFLOW -DOP='<<' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-LSH_OVERFLOW -// RUN: %clangxx -DLSH_OVERFLOW -DOP='<<=' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-LSH_OVERFLOW -// RUN: %clangxx -DTOO_LOW -DOP='<<' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW -// RUN: %clangxx -DTOO_LOW -DOP='>>' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW -// RUN: %clangxx -DTOO_LOW -DOP='<<=' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW -// RUN: %clangxx -DTOO_LOW -DOP='>>=' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW -// RUN: %clangxx -DTOO_HIGH -DOP='<<' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH -// RUN: %clangxx -DTOO_HIGH -DOP='>>' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH -// RUN: %clangxx -DTOO_HIGH -DOP='<<=' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH -// RUN: %clangxx -DTOO_HIGH -DOP='>>=' -fsanitize=shift %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH +// RUN: %clangxx -DLSH_OVERFLOW -DOP='<<' -fsanitize=shift-base -fno-sanitize-recover=shift %s -o %t1 && not %run %t1 2>&1 | FileCheck %s --check-prefix=CHECK-LSH_OVERFLOW +// RUN: %clangxx -DLSH_OVERFLOW -DOP='<<=' -fsanitize=shift -fno-sanitize-recover=shift %s -o %t2 && not %run %t2 2>&1 | FileCheck %s --check-prefix=CHECK-LSH_OVERFLOW +// RUN: %clangxx -DTOO_LOW -DOP='<<' -fsanitize=shift-exponent -fno-sanitize-recover=shift %s -o %t3 && not %run %t3 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW +// RUN: %clangxx -DTOO_LOW -DOP='>>' -fsanitize=shift -fno-sanitize-recover=shift %s -o %t4 && not %run %t4 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW +// RUN: %clangxx -DTOO_LOW -DOP='<<=' -fsanitize=shift -fno-sanitize-recover=shift %s -o %t5 && not %run %t5 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW +// RUN: %clangxx -DTOO_LOW -DOP='>>=' -fsanitize=shift -fno-sanitize-recover=shift %s -o %t6 && not %run %t6 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_LOW +// RUN: %clangxx -DTOO_HIGH -DOP='<<' -fsanitize=shift-exponent -fno-sanitize-recover=shift %s -o %t7 && not %run %t7 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH +// RUN: %clangxx -DTOO_HIGH -DOP='>>' -fsanitize=shift -fno-sanitize-recover=shift %s -o %t8 && not %run %t8 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH +// RUN: %clangxx -DTOO_HIGH -DOP='<<=' -fsanitize=shift -fno-sanitize-recover=shift %s -o %t9 && not %run %t9 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH +// RUN: %clangxx -DTOO_HIGH -DOP='>>=' -fsanitize=shift -fno-sanitize-recover=shift %s -o %t10 && not %run %t10 2>&1 | FileCheck %s --check-prefix=CHECK-TOO_HIGH + +// RUN: %clangxx -DLSH_OVERFLOW -DOP='<<' -fsanitize=shift-exponent -fno-sanitize-recover=shift %s -o %t12 && %run %t12 +// RUN: %clangxx -DLSH_OVERFLOW -DOP='>>' -fsanitize=shift-exponent -fno-sanitize-recover=shift %s -o %t13 && %run %t13 +// RUN: %clangxx -DTOO_LOW -DOP='<<' -fsanitize=shift-base -fno-sanitize-recover=shift %s -o %t14 && %run %t14 +// RUN: %clangxx -DTOO_LOW -DOP='>>' -fsanitize=shift-base -fno-sanitize-recover=shift %s -o %t15 && %run %t15 +// RUN: %clangxx -DTOO_HIGH -DOP='<<' -fsanitize=shift-base -fno-sanitize-recover=shift %s -o %t16 && %run %t16 +// RUN: %clangxx -DTOO_HIGH -DOP='>>' -fsanitize=shift-base -fno-sanitize-recover=shift %s -o %t17 && %run %t17 #include <stdint.h> @@ -20,18 +27,19 @@ int main() { b <<= 1; // still ok, unsigned #ifdef LSH_OVERFLOW - // CHECK-LSH_OVERFLOW: shift.cpp:24:5: runtime error: left shift of negative value -2147483648 + // CHECK-LSH_OVERFLOW: shift.cpp:[[@LINE+1]]:5: runtime error: left shift of negative value -2147483648 a OP 1; #endif #ifdef TOO_LOW - // CHECK-TOO_LOW: shift.cpp:29:5: runtime error: shift exponent -3 is negative + a = 0; + // CHECK-TOO_LOW: shift.cpp:[[@LINE+1]]:5: runtime error: shift exponent -3 is negative a OP (-3); #endif #ifdef TOO_HIGH a = 0; - // CHECK-TOO_HIGH: shift.cpp:35:5: runtime error: shift exponent 32 is too large for 32-bit type 'int' + // CHECK-TOO_HIGH: shift.cpp:[[@LINE+1]]:5: runtime error: shift exponent 32 is too large for 32-bit type 'int' a OP 32; #endif } diff --git a/test/ubsan/TestCases/Integer/sub-overflow.cpp b/test/ubsan/TestCases/Integer/sub-overflow.cpp index 15e64d951603..54ec4b5cd3c6 100644 --- a/test/ubsan/TestCases/Integer/sub-overflow.cpp +++ b/test/ubsan/TestCases/Integer/sub-overflow.cpp @@ -1,6 +1,6 @@ -// RUN: %clangxx -DSUB_I32 -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I32 -// RUN: %clangxx -DSUB_I64 -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I64 -// RUN: %clangxx -DSUB_I128 -fsanitize=signed-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I128 +// RUN: %clangxx -DSUB_I32 -fsanitize=signed-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I32 +// RUN: %clangxx -DSUB_I64 -fsanitize=signed-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I64 +// RUN: %clangxx -DSUB_I128 -fsanitize=signed-integer-overflow %s -o %t3 && %run %t3 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I128 #include <stdint.h> #include <stdio.h> @@ -21,7 +21,7 @@ int main() { #endif #ifdef SUB_I128 -# ifdef __SIZEOF_INT128__ +# if defined(__SIZEOF_INT128__) && !defined(_WIN32) (void)(-(__int128_t(1) << 126) - (__int128_t(1) << 126) - 1); # else puts("__int128 not supported"); diff --git a/test/ubsan/TestCases/Integer/summary.cpp b/test/ubsan/TestCases/Integer/summary.cpp index 6e9aec63ca74..21f537b92767 100644 --- a/test/ubsan/TestCases/Integer/summary.cpp +++ b/test/ubsan/TestCases/Integer/summary.cpp @@ -5,6 +5,6 @@ int main() { (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull)); - // CHECK: SUMMARY: AddressSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]] + // CHECK: SUMMARY: AddressSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:44 return 0; } diff --git a/test/ubsan/TestCases/Integer/uadd-overflow.cpp b/test/ubsan/TestCases/Integer/uadd-overflow.cpp index 7a96880fe636..8ef8983b56e0 100644 --- a/test/ubsan/TestCases/Integer/uadd-overflow.cpp +++ b/test/ubsan/TestCases/Integer/uadd-overflow.cpp @@ -1,6 +1,6 @@ -// RUN: %clangxx -DADD_I32 -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I32 -// RUN: %clangxx -DADD_I64 -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I64 -// RUN: %clangxx -DADD_I128 -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I128 +// RUN: %clangxx -DADD_I32 -fsanitize=unsigned-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I32 +// RUN: %clangxx -DADD_I64 -fsanitize=unsigned-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I64 +// RUN: %clangxx -DADD_I128 -fsanitize=unsigned-integer-overflow %s -o %t3 && %run %t3 2>&1 | FileCheck %s --check-prefix=CHECK-ADD_I128 #include <stdint.h> #include <stdio.h> @@ -22,7 +22,7 @@ int main() { #endif #ifdef ADD_I128 -# ifdef __SIZEOF_INT128__ +# if defined(__SIZEOF_INT128__) && !defined(_WIN32) (void)((__uint128_t(1) << 127) + (__uint128_t(1) << 127)); # else puts("__int128 not supported"); diff --git a/test/ubsan/TestCases/Integer/uincdec-overflow.cpp b/test/ubsan/TestCases/Integer/uincdec-overflow.cpp index a236d21fcf1f..4cc73972dacd 100644 --- a/test/ubsan/TestCases/Integer/uincdec-overflow.cpp +++ b/test/ubsan/TestCases/Integer/uincdec-overflow.cpp @@ -1,7 +1,7 @@ -// RUN: %clangxx -DOP=n++ -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck --check-prefix=CHECK-INC %s -// RUN: %clangxx -DOP=++n -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck --check-prefix=CHECK-INC %s -// RUN: %clangxx -DOP=m-- -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck --check-prefix=CHECK-DEC %s -// RUN: %clangxx -DOP=--m -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck --check-prefix=CHECK-DEC %s +// RUN: %clangxx -DOP=n++ -fsanitize=unsigned-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck --check-prefix=CHECK-INC %s +// RUN: %clangxx -DOP=++n -fsanitize=unsigned-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck --check-prefix=CHECK-INC %s +// RUN: %clangxx -DOP=m-- -fsanitize=unsigned-integer-overflow %s -o %t3 && %run %t3 2>&1 | FileCheck --check-prefix=CHECK-DEC %s +// RUN: %clangxx -DOP=--m -fsanitize=unsigned-integer-overflow %s -o %t4 && %run %t4 2>&1 | FileCheck --check-prefix=CHECK-DEC %s #include <stdint.h> diff --git a/test/ubsan/TestCases/Integer/usub-overflow.cpp b/test/ubsan/TestCases/Integer/usub-overflow.cpp index e5de7de54eaa..fb671b003af7 100644 --- a/test/ubsan/TestCases/Integer/usub-overflow.cpp +++ b/test/ubsan/TestCases/Integer/usub-overflow.cpp @@ -1,6 +1,6 @@ -// RUN: %clangxx -DSUB_I32 -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I32 -// RUN: %clangxx -DSUB_I64 -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I64 -// RUN: %clangxx -DSUB_I128 -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I128 +// RUN: %clangxx -DSUB_I32 -fsanitize=unsigned-integer-overflow %s -o %t1 && %run %t1 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I32 +// RUN: %clangxx -DSUB_I64 -fsanitize=unsigned-integer-overflow %s -o %t2 && %run %t2 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I64 +// RUN: %clangxx -DSUB_I128 -fsanitize=unsigned-integer-overflow %s -o %t3 && %run %t3 2>&1 | FileCheck %s --check-prefix=CHECK-SUB_I128 #include <stdint.h> #include <stdio.h> @@ -21,7 +21,7 @@ int main() { #endif #ifdef SUB_I128 -# ifdef __SIZEOF_INT128__ +# if defined(__SIZEOF_INT128__) && !defined(_WIN32) (void)((__uint128_t(1) << 126) - (__uint128_t(1) << 127)); # else puts("__int128 not supported\n"); diff --git a/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc b/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc new file mode 100644 index 000000000000..df6e835dd9df --- /dev/null +++ b/test/ubsan/TestCases/Misc/Linux/coverage-levels.cc @@ -0,0 +1,39 @@ +// Test various levels of coverage +// +// RUN: mkdir -p %T/coverage-levels +// RUN: OPT=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels +// RUN: %clangxx -fsanitize=shift -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func %s -o %t +// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN +// RUN: %clangxx -fsanitize=undefined -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=func %s -o %t +// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN + +// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=func %s -o %t +// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN +// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=bb %s -o %t +// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN +// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=edge %s -o %t +// RUN: UBSAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN + +// Coverage is not yet implemented in TSan. +// XFAIL: ubsan-tsan + +volatile int sink; +int main(int argc, char **argv) { + int shift = argc * 32; +#if GOOD_SHIFT + shift = 3; +#endif + if ((argc << shift) == 16) // False. + return 1; + return 0; +} + +// CHECK_WARN: shift exponent 32 is too large +// CHECK_NOWARN-NOT: ERROR +// FIXME: Currently, coverage instrumentation kicks in after ubsan, so we get +// more than the minimal number of instrumented blocks. +// FIXME: Currently, ubsan with -fno-sanitize-recover and w/o asan will fail +// to dump coverage. +// CHECK1: 1 PCs written +// CHECK2: 3 PCs written +// CHECK3: 4 PCs written diff --git a/test/ubsan/TestCases/Misc/Linux/lit.local.cfg b/test/ubsan/TestCases/Misc/Linux/lit.local.cfg new file mode 100644 index 000000000000..57271b8078a4 --- /dev/null +++ b/test/ubsan/TestCases/Misc/Linux/lit.local.cfg @@ -0,0 +1,9 @@ +def getRoot(config): + if not config.parent: + return config + return getRoot(config.parent) + +root = getRoot(config) + +if root.host_os not in ['Linux']: + config.unsupported = True diff --git a/test/ubsan/TestCases/Misc/Linux/ubsan_options.cc b/test/ubsan/TestCases/Misc/Linux/ubsan_options.cc new file mode 100644 index 000000000000..2be8792cce96 --- /dev/null +++ b/test/ubsan/TestCases/Misc/Linux/ubsan_options.cc @@ -0,0 +1,18 @@ +// RUN: %clangxx -fsanitize=integer -fsanitize-recover=integer %s -o %t +// RUN: not %t 2>&1 | FileCheck %s + +// __ubsan_default_options() doesn't work on Darwin. +// XFAIL: darwin + +#include <stdint.h> + +extern "C" const char *__ubsan_default_options() { + return "halt_on_error=1"; +} + +int main() { + (void)(uint64_t(10000000000000000000ull) + uint64_t(9000000000000000000ull)); + // CHECK: ubsan_options.cc:[[@LINE-1]]:44: runtime error: unsigned integer overflow + return 0; +} + diff --git a/test/ubsan/TestCases/Misc/bounds.cpp b/test/ubsan/TestCases/Misc/bounds.cpp index ffcac528be90..199690dad2a2 100644 --- a/test/ubsan/TestCases/Misc/bounds.cpp +++ b/test/ubsan/TestCases/Misc/bounds.cpp @@ -1,7 +1,7 @@ // RUN: %clangxx -fsanitize=bounds %s -O3 -o %t // RUN: %run %t 0 0 0 // RUN: %run %t 1 2 3 -// RUN: not --crash %run %t 2 0 0 2>&1 | FileCheck %s --check-prefix=CHECK-A-2 +// RUN: %expect_crash %run %t 2 0 0 2>&1 | FileCheck %s --check-prefix=CHECK-A-2 // RUN: %run %t 0 3 0 2>&1 | FileCheck %s --check-prefix=CHECK-B-3 // RUN: %run %t 0 0 4 2>&1 | FileCheck %s --check-prefix=CHECK-C-4 diff --git a/test/ubsan/TestCases/Misc/coverage-levels.cc b/test/ubsan/TestCases/Misc/coverage-levels.cc deleted file mode 100644 index 2fe12ffefd4b..000000000000 --- a/test/ubsan/TestCases/Misc/coverage-levels.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Test various levels of coverage -// -// RUN: mkdir -p %T/coverage-levels -// RUN: OPT=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels -// RUN: %clangxx -fsanitize=shift -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1 %s -o %t -// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN -// RUN: %clangxx -fsanitize=undefined -DGOOD_SHIFT=1 -O1 -fsanitize-coverage=1 %s -o %t -// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN - -// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=1 %s -o %t -// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN -// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=2 %s -o %t -// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN -// RUN: %clangxx -fsanitize=shift -O1 -fsanitize-coverage=3 %s -o %t -// RUN: UBSAN_OPTIONS=$OPT ASAN_OPTIONS=$OPT %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN - -// XFAIL: darwin - -volatile int sink; -int main(int argc, char **argv) { - int shift = argc * 32; -#if GOOD_SHIFT - shift = 3; -#endif - if ((argc << shift) == 16) // False. - return 1; - return 0; -} - -// CHECK_WARN: shift exponent 32 is too large -// CHECK_NOWARN-NOT: ERROR -// FIXME: Currently, coverage instrumentation kicks in after ubsan, so we get -// more than the minimal number of instrumented blocks. -// FIXME: Currently, ubsan with -fno-sanitize-recover and w/o asan will fail -// to dump coverage. -// CHECK1: 1 PCs written -// CHECK2: 3 PCs written -// CHECK3: 4 PCs written diff --git a/test/ubsan/TestCases/Misc/deduplication.cpp b/test/ubsan/TestCases/Misc/deduplication.cpp index 7d7b0bd58c6e..4b02590fa0ac 100644 --- a/test/ubsan/TestCases/Misc/deduplication.cpp +++ b/test/ubsan/TestCases/Misc/deduplication.cpp @@ -11,6 +11,7 @@ void overflow() { int main() { // CHECK: Start fprintf(stderr, "Start\n"); + fflush(stderr); // CHECK: runtime error // CHECK-NOT: runtime error diff --git a/test/ubsan/TestCases/Misc/enum.cpp b/test/ubsan/TestCases/Misc/enum.cpp index 49ac7c6bb187..5dbecf161262 100644 --- a/test/ubsan/TestCases/Misc/enum.cpp +++ b/test/ubsan/TestCases/Misc/enum.cpp @@ -2,6 +2,10 @@ // RUN: %clangxx -fsanitize=enum -std=c++11 -DE="class E" %s -O3 -o %t && %run %t // RUN: %clangxx -fsanitize=enum -std=c++11 -DE="class E : bool" %s -O3 -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-BOOL +// FIXME: UBSan fails to add the correct instrumentation code for some reason on +// Windows. +// XFAIL: win32 + enum E { a = 1 } e; #undef E diff --git a/test/ubsan/TestCases/Misc/log-path_test.cc b/test/ubsan/TestCases/Misc/log-path_test.cc new file mode 100644 index 000000000000..b39e1b077e27 --- /dev/null +++ b/test/ubsan/TestCases/Misc/log-path_test.cc @@ -0,0 +1,33 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// XFAIL: android + +// RUN: %clangxx -fsanitize=undefined %s -O1 -o %t + +// Regular run. +// RUN: %run %t -4 2> %t.out +// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.out + +// Good log_path. +// RUN: rm -f %t.log.* +// RUN: env UBSAN_OPTIONS=log_path=%t.log %run %t -4 2> %t.out +// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.log.* + +// Run w/o errors should not produce any log. +// RUN: rm -f %t.log.* +// RUN: env UBSAN_OPTIONS=log_path=%t.log %run %t 4 +// RUN: not cat %t.log.* + +// FIXME: log_path is not supported on Windows yet. +// XFAIL: win32 + +#include <stdio.h> +#include <stdlib.h> +int main(int argc, char *argv[]) { + double a = atof(argv[1]); + unsigned int ai = (unsigned int) a; + printf("%f %u\n", a, ai); + return 0; +} + +// CHECK-ERROR: runtime error: value -4 is outside the range of representable values of type 'unsigned int' + diff --git a/test/ubsan/TestCases/Misc/missing_return.cpp b/test/ubsan/TestCases/Misc/missing_return.cpp index 5d3d54de17dd..75e26df536a6 100644 --- a/test/ubsan/TestCases/Misc/missing_return.cpp +++ b/test/ubsan/TestCases/Misc/missing_return.cpp @@ -1,15 +1,13 @@ // RUN: %clangxx -fsanitize=return -g %s -O3 -o %t // RUN: not %run %t 2>&1 | FileCheck %s -// RUN: UBSAN_OPTIONS=print_stacktrace=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os-STACKTRACE +// RUN: env UBSAN_OPTIONS=print_stacktrace=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-%os-STACKTRACE // CHECK: missing_return.cpp:[[@LINE+1]]:5: runtime error: execution reached the end of a value-returning function without returning a value int f() { -// Slow stack unwinding is disabled on Darwin for now, see +// Slow stack unwinding is not available on Darwin for now, see // https://code.google.com/p/address-sanitizer/issues/detail?id=137 -// CHECK-Linux-STACKTRACE: #0 {{.*}} in f(){{.*}}missing_return.cpp:[[@LINE-3]] -// CHECK-FreeBSD-STACKTRACE: #0 {{.*}} in f(void){{.*}}missing_return.cpp:[[@LINE-4]] -// Check for already checked line to avoid lit error reports. -// CHECK-Darwin-STACKTRACE: missing_return.cpp +// CHECK-Linux-STACKTRACE: #0 {{.*}}f(){{.*}}missing_return.cpp:[[@LINE-3]] +// CHECK-FreeBSD-STACKTRACE: #0 {{.*}}f(void){{.*}}missing_return.cpp:[[@LINE-4]] } int main(int, char **argv) { diff --git a/test/ubsan/TestCases/TypeCheck/Function/function.cpp b/test/ubsan/TestCases/TypeCheck/Function/function.cpp index 2609c6a8f666..5a2fda4c9d46 100644 --- a/test/ubsan/TestCases/TypeCheck/Function/function.cpp +++ b/test/ubsan/TestCases/TypeCheck/Function/function.cpp @@ -1,7 +1,7 @@ // RUN: %clangxx -fsanitize=function %s -O3 -g -o %t // RUN: %run %t 2>&1 | FileCheck %s // Verify that we can disable symbolization if needed: -// RUN: UBSAN_OPTIONS=symbolize=0 ASAN_OPTIONS=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM +// RUN: UBSAN_OPTIONS=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM // -fsanitize=function is unsupported on Darwin yet. // XFAIL: darwin diff --git a/test/ubsan/TestCases/TypeCheck/misaligned.cpp b/test/ubsan/TestCases/TypeCheck/misaligned.cpp index 9c8455d5f1c3..1b0abad747bc 100644 --- a/test/ubsan/TestCases/TypeCheck/misaligned.cpp +++ b/test/ubsan/TestCases/TypeCheck/misaligned.cpp @@ -7,7 +7,7 @@ // RUN: %run %t f1 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN // RUN: %run %t n1 2>&1 | FileCheck %s --check-prefix=CHECK-NEW // RUN: %run %t u1 2>&1 | FileCheck %s --check-prefix=CHECK-UPCAST -// RUN: UBSAN_OPTIONS=print_stacktrace=1 %run %t l1 2>&1 | FileCheck %s --check-prefix=CHECK-LOAD --check-prefix=CHECK-%os-STACK-LOAD +// RUN: env UBSAN_OPTIONS=print_stacktrace=1 %run %t l1 2>&1 | FileCheck %s --check-prefix=CHECK-LOAD --check-prefix=CHECK-%os-STACK-LOAD // RUN: %clangxx -fsanitize=alignment -fno-sanitize-recover=alignment %s -O3 -o %t // RUN: not %run %t w1 2>&1 | FileCheck %s --check-prefix=CHECK-WILD @@ -38,19 +38,19 @@ int main(int, char **argv) { switch (argv[1][0]) { case 'l': - // CHECK-LOAD: misaligned.cpp:[[@LINE+4]]:12: runtime error: load of misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment + // CHECK-LOAD: misaligned.cpp:[[@LINE+4]]{{(:12)?}}: runtime error: load of misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment // CHECK-LOAD-NEXT: [[PTR]]: note: pointer points here // CHECK-LOAD-NEXT: {{^ 00 00 00 01 02 03 04 05}} // CHECK-LOAD-NEXT: {{^ \^}} return *p && 0; // Slow stack unwinding is disabled on Darwin for now, see // https://code.google.com/p/address-sanitizer/issues/detail?id=137 - // CHECK-Linux-STACK-LOAD: #0 {{.*}} in main{{.*}}misaligned.cpp + // CHECK-Linux-STACK-LOAD: #0 {{.*}}main{{.*}}misaligned.cpp // Check for the already checked line to avoid lit error reports. // CHECK-Darwin-STACK-LOAD: {{ }} case 's': - // CHECK-STORE: misaligned.cpp:[[@LINE+4]]:5: runtime error: store to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment + // CHECK-STORE: misaligned.cpp:[[@LINE+4]]{{(:5)?}}: runtime error: store to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment // CHECK-STORE-NEXT: [[PTR]]: note: pointer points here // CHECK-STORE-NEXT: {{^ 00 00 00 01 02 03 04 05}} // CHECK-STORE-NEXT: {{^ \^}} @@ -58,7 +58,7 @@ int main(int, char **argv) { break; case 'r': - // CHECK-REFERENCE: misaligned.cpp:[[@LINE+4]]:15: runtime error: reference binding to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment + // CHECK-REFERENCE: misaligned.cpp:[[@LINE+4]]{{(:(5|15))?}}: runtime error: reference binding to misaligned address [[PTR:0x[0-9a-f]*]] for type 'int', which requires 4 byte alignment // CHECK-REFERENCE-NEXT: [[PTR]]: note: pointer points here // CHECK-REFERENCE-NEXT: {{^ 00 00 00 01 02 03 04 05}} // CHECK-REFERENCE-NEXT: {{^ \^}} @@ -66,28 +66,28 @@ int main(int, char **argv) { break; case 'm': - // CHECK-MEMBER: misaligned.cpp:[[@LINE+4]]:15: runtime error: member access within misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment + // CHECK-MEMBER: misaligned.cpp:[[@LINE+4]]{{(:15)?}}: runtime error: member access within misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment // CHECK-MEMBER-NEXT: [[PTR]]: note: pointer points here // CHECK-MEMBER-NEXT: {{^ 00 00 00 01 02 03 04 05}} // CHECK-MEMBER-NEXT: {{^ \^}} return s->k && 0; case 'f': - // CHECK-MEMFUN: misaligned.cpp:[[@LINE+4]]:12: runtime error: member call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment + // CHECK-MEMFUN: misaligned.cpp:[[@LINE+4]]{{(:12)?}}: runtime error: member call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment // CHECK-MEMFUN-NEXT: [[PTR]]: note: pointer points here // CHECK-MEMFUN-NEXT: {{^ 00 00 00 01 02 03 04 05}} // CHECK-MEMFUN-NEXT: {{^ \^}} return s->f() && 0; case 'n': - // CHECK-NEW: misaligned.cpp:[[@LINE+4]]:21: runtime error: constructor call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment + // CHECK-NEW: misaligned.cpp:[[@LINE+4]]{{(:21)?}}: runtime error: constructor call on misaligned address [[PTR:0x[0-9a-f]*]] for type 'S', which requires 4 byte alignment // CHECK-NEW-NEXT: [[PTR]]: note: pointer points here // CHECK-NEW-NEXT: {{^ 00 00 00 01 02 03 04 05}} // CHECK-NEW-NEXT: {{^ \^}} return (new (s) S)->k && 0; case 'u': { - // CHECK-UPCAST: misaligned.cpp:[[@LINE+4]]:17: runtime error: upcast of misaligned address [[PTR:0x[0-9a-f]*]] for type 'T', which requires 4 byte alignment + // CHECK-UPCAST: misaligned.cpp:[[@LINE+4]]{{(:17)?}}: runtime error: upcast of misaligned address [[PTR:0x[0-9a-f]*]] for type 'T', which requires 4 byte alignment // CHECK-UPCAST-NEXT: [[PTR]]: note: pointer points here // CHECK-UPCAST-NEXT: {{^ 00 00 00 01 02 03 04 05}} // CHECK-UPCAST-NEXT: {{^ \^}} @@ -96,7 +96,7 @@ int main(int, char **argv) { } case 'w': - // CHECK-WILD: misaligned.cpp:[[@LINE+3]]:35: runtime error: member access within misaligned address 0x{{0+}}123 for type 'S', which requires 4 byte alignment + // CHECK-WILD: misaligned.cpp:[[@LINE+3]]{{(:35)?}}: runtime error: member access within misaligned address 0x{{0+}}123 for type 'S', which requires 4 byte alignment // CHECK-WILD-NEXT: 0x{{0+}}123: note: pointer points here // CHECK-WILD-NEXT: <memory cannot be printed> return static_cast<S*>(wild)->k; diff --git a/test/ubsan/TestCases/TypeCheck/null.cpp b/test/ubsan/TestCases/TypeCheck/null.cpp index 190dc30e5dfe..1e179559d5df 100644 --- a/test/ubsan/TestCases/TypeCheck/null.cpp +++ b/test/ubsan/TestCases/TypeCheck/null.cpp @@ -1,6 +1,6 @@ // RUN: %clangxx -fsanitize=null %s -O3 -o %t // RUN: %run %t l 2>&1 | FileCheck %s --check-prefix=CHECK-LOAD -// RUN: not --crash %run %t s 2>&1 | FileCheck %s --check-prefix=CHECK-STORE +// RUN: %expect_crash %run %t s 2>&1 | FileCheck %s --check-prefix=CHECK-STORE // RUN: %run %t r 2>&1 | FileCheck %s --check-prefix=CHECK-REFERENCE // RUN: %run %t m 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER // RUN: %run %t f 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN diff --git a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base-construction.cpp b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base-construction.cpp new file mode 100644 index 000000000000..dc27d9f39ce3 --- /dev/null +++ b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base-construction.cpp @@ -0,0 +1,13 @@ +// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr %s -o %t +// RUN: %run %t + +// REQUIRES: cxxabi + +int volatile n; + +struct A { virtual ~A() {} }; +struct B: virtual A {}; +struct C: virtual A { ~C() { n = 0; } }; +struct D: virtual B, virtual C {}; + +int main() { delete new D; } diff --git a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp index 806e45c7d357..09deac143724 100644 --- a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp +++ b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp @@ -1,8 +1,7 @@ // RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t // RUN: not %run %t 2>&1 | FileCheck %s -// FIXME: This test produces linker errors on Darwin. -// XFAIL: darwin +// REQUIRES: cxxabi struct S { virtual int f() { return 0; } }; struct T : virtual S {}; diff --git a/test/ubsan/TestCases/TypeCheck/vptr.cpp b/test/ubsan/TestCases/TypeCheck/vptr.cpp index 1f8ee02641a8..a95edf918c95 100644 --- a/test/ubsan/TestCases/TypeCheck/vptr.cpp +++ b/test/ubsan/TestCases/TypeCheck/vptr.cpp @@ -1,37 +1,33 @@ -// RUN: %clangxx -frtti -fsanitize=vptr -g %s -O3 -o %t +// RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr -g %s -O3 -o %t +// RUN: export UBSAN_OPTIONS=print_stacktrace=1 // RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT // RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU // RUN: %run %t rS && %run %t rV && %run %t oV -// RUN: %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace -// RUN: %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace -// RUN: %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace -// RUN: %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --strict-whitespace -// RUN: %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace -// RUN: %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --strict-whitespace -// RUN: %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --strict-whitespace -// RUN: %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --strict-whitespace +// RUN: not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace +// RUN: not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace +// RUN: not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace +// RUN: not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace +// RUN: not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace +// RUN: not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace +// RUN: not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace +// RUN: not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace // RUN: (echo "vptr_check:S"; echo "vptr_check:T"; echo "vptr_check:U") > %t.supp -// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mS 2>&1 -// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fS 2>&1 -// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cS 2>&1 -// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t mV 2>&1 -// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t fV 2>&1 -// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t cV 2>&1 -// RUN: UBSAN_OPTIONS="suppressions='%t.supp':halt_on_error=1" %run %t oU 2>&1 +// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t mS +// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t fS +// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t cS +// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t mV +// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t fV +// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t cV +// RUN: UBSAN_OPTIONS="suppressions='%t.supp'" %run %t oU // RUN: echo "vptr_check:S" > %t.loc-supp -// RUN: UBSAN_OPTIONS="suppressions='%t.loc-supp':halt_on_error=1" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS +// RUN: UBSAN_OPTIONS="suppressions='%t.loc-supp'" not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS -// FIXME: This test produces linker errors on Darwin. -// XFAIL: darwin -// REQUIRES: stable-runtime - -extern "C" { -const char *__ubsan_default_options() { - return "print_stacktrace=1"; -} -} +// REQUIRES: stable-runtime, cxxabi +#include <new> +#include <assert.h> +#include <stdio.h> struct S { S() : a(0) {} @@ -57,7 +53,9 @@ T *p = 0; int access_p(T *p, char type); -int main(int, char **argv) { +int main(int argc, char **argv) { + assert(argc > 1); + fprintf(stderr, "Test case: %s\n", argv[1]); T t; (void)t.a; (void)t.b; @@ -76,12 +74,15 @@ int main(int, char **argv) { (void)((T&)u).S::v(); char Buffer[sizeof(U)] = {}; + char TStorage[sizeof(T)]; switch (argv[1][1]) { case '0': p = reinterpret_cast<T*>(Buffer); break; case 'S': - p = reinterpret_cast<T*>(new S); + // Make sure p points to the memory chunk of sufficient size to prevent ASan + // reports about out-of-bounds access. + p = reinterpret_cast<T*>(new(TStorage) S); break; case 'T': p = new T; @@ -103,7 +104,7 @@ int access_p(T *p, char type) { case 'r': // Binding a reference to storage of appropriate size and alignment is OK. {T &r = *p;} - break; + return 0; case 'x': for (int i = 0; i < 2; i++) { @@ -124,7 +125,7 @@ int access_p(T *p, char type) { // CHECK-MEMBER-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }} // CHECK-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} // CHECK-MEMBER-NEXT: {{^ vptr for}} [[DYN_TYPE]] - // CHECK-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]] + // CHECK-Linux-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]] return p->b; // CHECK-NULL-MEMBER: vptr.cpp:[[@LINE-2]]:15: runtime error: member access within address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' @@ -132,7 +133,7 @@ int access_p(T *p, char type) { // CHECK-NULL-MEMBER-NEXT: {{^ ?.. .. .. .. ?00 00 00 00 ?00 00 00 00 ?}} // CHECK-NULL-MEMBER-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} // CHECK-NULL-MEMBER-NEXT: {{^ invalid vptr}} - // CHECK-NULL-MEMBER-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE-7]] + // CHECK-Linux-NULL-MEMBER: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE-7]] case 'f': // CHECK-MEMFUN: vptr.cpp:[[@LINE+6]]:12: runtime error: member call on address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' @@ -149,17 +150,18 @@ int access_p(T *p, char type) { // CHECK-OFFSET-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. }} // CHECK-OFFSET-NEXT: {{^ \^ ( ~~~~~~~~~~~~)?~~~~~~~~~~~ *$}} // CHECK-OFFSET-NEXT: {{^ ( )?vptr for}} 'T' base class of [[DYN_TYPE]] - // CHECK-OFFSET-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]] + // CHECK-Linux-OFFSET: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]] return reinterpret_cast<U*>(p)->v() - 2; case 'c': - // CHECK-DOWNCAST: vptr.cpp:[[@LINE+6]]:5: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' + // CHECK-DOWNCAST: vptr.cpp:[[@LINE+6]]:11: runtime error: downcast of address [[PTR:0x[0-9a-f]*]] which does not point to an object of type 'T' // CHECK-DOWNCAST-NEXT: [[PTR]]: note: object is of type [[DYN_TYPE:'S'|'U']] // CHECK-DOWNCAST-NEXT: {{^ .. .. .. .. .. .. .. .. .. .. .. .. }} // CHECK-DOWNCAST-NEXT: {{^ \^~~~~~~~~~~(~~~~~~~~~~~~)? *$}} // CHECK-DOWNCAST-NEXT: {{^ vptr for}} [[DYN_TYPE]] - // CHECK-DOWNCAST-NEXT: #0 {{.*}} in access_p{{.*}}vptr.cpp:[[@LINE+1]] - static_cast<T*>(reinterpret_cast<S*>(p)); + // CHECK-Linux-DOWNCAST: #0 {{.*}}access_p{{.*}}vptr.cpp:[[@LINE+1]] + (void)static_cast<T*>(reinterpret_cast<S*>(p)); return 0; } + return 0; } diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg index d28733a61cf8..7ae078a8625c 100644 --- a/test/ubsan/lit.common.cfg +++ b/test/ubsan/lit.common.cfg @@ -17,18 +17,22 @@ config.test_source_root = os.path.dirname(__file__) # Choose between standalone and UBSan+ASan modes. ubsan_lit_test_mode = get_required_attr(config, 'ubsan_lit_test_mode') if ubsan_lit_test_mode == "Standalone": - config.name = 'UndefinedBehaviorSanitizer-Standalone' + config.name = 'UBSan-Standalone-' + config.target_arch config.available_features.add("ubsan-standalone") clang_ubsan_cflags = [] elif ubsan_lit_test_mode == "AddressSanitizer": - if config.host_os == 'Darwin': - # ubsan-asan doesn't yet work on Darwin, - # see http://llvm.org/bugs/show_bug.cgi?id=21112. - config.unsupported = True - config.name = 'UndefinedBehaviorSanitizer-AddressSanitizer' + config.name = 'UBSan-ASan-' + config.target_arch config.available_features.add("ubsan-asan") clang_ubsan_cflags = ["-fsanitize=address"] config.environment['ASAN_OPTIONS'] = 'detect_leaks=0' +elif ubsan_lit_test_mode == "MemorySanitizer": + config.name = 'UBSan-MSan-' + config.target_arch + config.available_features.add("ubsan-msan") + clang_ubsan_cflags = ["-fsanitize=memory"] +elif ubsan_lit_test_mode == "ThreadSanitizer": + config.name = 'UBSan-TSan-' + config.target_arch + config.available_features.add("ubsan-tsan") + clang_ubsan_cflags = ["-fsanitize=thread"] else: lit_config.fatal("Unknown UBSan test mode: %r" % ubsan_lit_test_mode) @@ -47,9 +51,14 @@ config.substitutions.append( ("%clangxx ", build_invocation(clang_ubsan_cxxflags config.suffixes = ['.c', '.cc', '.cpp'] # Check that the host supports UndefinedBehaviorSanitizer tests -if config.host_os not in ['Linux', 'Darwin', 'FreeBSD']: +if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows']: config.unsupported = True +if config.host_os == 'Windows': + # We do not currently support enough of the Microsoft ABI for UBSan to work on + # Windows. + config.available_features.remove('cxxabi') + # Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL # because the test hangs or fails on one configuration and not the other. if config.target_arch.startswith('arm') == False: diff --git a/test/ubsan/lit.site.cfg.in b/test/ubsan/lit.site.cfg.in index ef72d2bbb42f..1b06881b3527 100644 --- a/test/ubsan/lit.site.cfg.in +++ b/test/ubsan/lit.site.cfg.in @@ -3,6 +3,8 @@ lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configu # Tool-specific config options. config.ubsan_lit_test_mode = "@UBSAN_LIT_TEST_MODE@" +config.target_cflags = "@UBSAN_TEST_TARGET_CFLAGS@" +config.target_arch = "@UBSAN_TEST_TARGET_ARCH@" # Load tool-specific config that would do the real work. lit_config.load_config(config, "@UBSAN_LIT_TESTS_DIR@/lit.common.cfg") |