diff options
Diffstat (limited to 'test/ubsan')
43 files changed, 2586 insertions, 85 deletions
diff --git a/test/ubsan/CMakeLists.txt b/test/ubsan/CMakeLists.txt index fa8b16b8093e0..351bf3b829da3 100644 --- a/test/ubsan/CMakeLists.txt +++ b/test/ubsan/CMakeLists.txt @@ -62,6 +62,31 @@ foreach(arch ${UBSAN_TEST_ARCH}) endif() endforeach() +macro(add_ubsan_device_testsuite test_mode sanitizer platform arch) + # Note we expect the caller to have already set UBSAN_TEST_TARGET_CFLAGS + set(UBSAN_LIT_TEST_MODE "${test_mode}") + set(CONFIG_NAME ${UBSAN_LIT_TEST_MODE}-${platform}-${arch}) + set(UBSAN_TEST_TARGET_ARCH ${arch}) + set(UBSAN_TEST_USE_LLD "False") + set(UBSAN_TEST_USE_THINLTO "False") + if (APPLE) + set(UBSAN_TEST_APPLE_PLATFORM "${platform}") + else() + unset(UBSAN_TEST_APPLE_PLATFORM) + endif() + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${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() + add_lit_testsuite(check-ubsan-${test_mode}-${platform}-${arch} + "UBSan ${CONFIG_NAME} tests" + ${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/ + DEPENDS ${UBSAN_TEST_DEPS}) +endmacro() + if(APPLE) foreach(arch ${UBSAN_TEST_ARCH}) set(UBSAN_TEST_TARGET_ARCH ${arch}) @@ -69,9 +94,47 @@ if(APPLE) set(UBSAN_TEST_TARGET_CFLAGS "${UBSAN_TEST_TARGET_CFLAGS} -lc++abi") add_ubsan_testsuites("StandaloneStatic" ubsan ${arch}) endforeach() + + # Device and simulator test suites. + # These are not added into "check-all", in order to run these tests, use + # "check-asan-iossim-x86_64" and similar. They also require that an extra env + # variable to select which iOS device or simulator to use, e.g.: + # SANITIZER_IOSSIM_TEST_DEVICE_IDENTIFIER="iPhone 6" + set(EXCLUDE_FROM_ALL ON) + set(UBSAN_APPLE_PLATFORMS "") + if (COMPILER_RT_ENABLE_IOS) + list(APPEND UBSAN_APPLE_PLATFORMS ios iossim) + endif() + if (COMPILER_RT_ENABLE_WATCHOS) + list(APPEND UBSAN_APPLE_PLATFORMS watchos watchossim) + endif() + if (COMPILER_RT_ENABLE_TVOS) + list(APPEND UBSAN_APPLE_PLATFORMS tvos tvossim) + endif() + foreach(platform ${UBSAN_APPLE_PLATFORMS}) + foreach(arch ${DARWIN_${platform}_ARCHS}) + get_target_flags_for_arch(${arch} UBSAN_TEST_TARGET_ARCH_FLAGS_AS_LIST) + string(REPLACE ";" " " UBSAN_TEST_TARGET_ARCH_FLAGS "${UBSAN_TEST_TARGET_ARCH_FLAGS_AS_LIST}") + set(UBSAN_TEST_TARGET_CFLAGS + "${UBSAN_TEST_TARGET_ARCH_FLAGS} -isysroot ${DARWIN_${platform}_SYSROOT}") + if (";${UBSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_device_testsuite("Standalone" ubsan ${platform} ${arch}) + endif() + + if(COMPILER_RT_HAS_ASAN AND ";${ASAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_device_testsuite("AddressSanitizer" asan ${platform} ${arch}) + endif() + + if(COMPILER_RT_HAS_TSAN AND ";${TSAN_SUPPORTED_ARCH};" MATCHES ";${arch};") + add_ubsan_device_testsuite("ThreadSanitizer" tsan ${platform} ${arch}) + endif() + endforeach() + endforeach() + set(EXCLUDE_FROM_ALL OFF) endif() add_lit_testsuite(check-ubsan "Running UndefinedBehaviorSanitizer tests" ${UBSAN_TESTSUITES} DEPENDS ${UBSAN_TEST_DEPS}) set_target_properties(check-ubsan PROPERTIES FOLDER "Compiler-RT Misc") + diff --git a/test/ubsan/TestCases/ImplicitConversion/integer-arithmetic-value-change.c b/test/ubsan/TestCases/ImplicitConversion/integer-arithmetic-value-change.c new file mode 100644 index 0000000000000..ef06fbf8398df --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/integer-arithmetic-value-change.c @@ -0,0 +1,345 @@ +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c -fsanitize=implicit-integer-arithmetic-value-change %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c++ -fsanitize=implicit-integer-arithmetic-value-change %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +#include <stdint.h> + +// Test plan: +// * Two types - int and char +// * Two signs - signed and unsigned +// * Square that - we have input and output types. +// Thus, there are total of (2*2)^2 == 16 tests. +// These are all the possible variations/combinations of casts. +// However, not all of them should result in the check. +// So here, we *only* check which should and which should not result in checks. + +uint32_t convert_unsigned_int_to_unsigned_int(uint32_t x) { +#line 100 + return x; +} + +uint8_t convert_unsigned_char_to_unsigned_char(uint8_t x) { +#line 200 + return x; +} + +int32_t convert_signed_int_to_signed_int(int32_t x) { +#line 300 + return x; +} + +int8_t convert_signed_char_to_signed_char(int8_t x) { +#line 400 + return x; +} + +uint8_t convert_unsigned_int_to_unsigned_char(uint32_t x) { +#line 500 + return x; +} + +uint32_t convert_unsigned_char_to_unsigned_int(uint8_t x) { +#line 600 + return x; +} + +int32_t convert_unsigned_char_to_signed_int(uint8_t x) { +#line 700 + return x; +} + +int32_t convert_signed_char_to_signed_int(int8_t x) { +#line 800 + return x; +} + +int32_t convert_unsigned_int_to_signed_int(uint32_t x) { +#line 900 + return x; +} + +uint32_t convert_signed_int_to_unsigned_int(int32_t x) { +#line 1000 + return x; +} + +uint8_t convert_signed_int_to_unsigned_char(int32_t x) { +#line 1100 + return x; +} + +uint8_t convert_signed_char_to_unsigned_char(int8_t x) { +#line 1200 + return x; +} + +int8_t convert_unsigned_char_to_signed_char(uint8_t x) { +#line 1300 + return x; +} + +uint32_t convert_signed_char_to_unsigned_int(int8_t x) { +#line 1400 + return x; +} + +int8_t convert_unsigned_int_to_signed_char(uint32_t x) { +#line 1500 + return x; +} + +int8_t convert_signed_int_to_signed_char(int32_t x) { +#line 1600 + return x; +} + +#line 10111 // !!! + +int main() { + // No bits set. + convert_unsigned_int_to_unsigned_int(0); + convert_unsigned_char_to_unsigned_char(0); + convert_signed_int_to_signed_int(0); + convert_signed_char_to_signed_char(0); + convert_unsigned_int_to_unsigned_char(0); + convert_unsigned_char_to_unsigned_int(0); + convert_unsigned_char_to_signed_int(0); + convert_signed_char_to_signed_int(0); + convert_unsigned_int_to_signed_int(0); + convert_signed_int_to_unsigned_int(0); + convert_signed_int_to_unsigned_char(0); + convert_signed_char_to_unsigned_char(0); + convert_unsigned_char_to_signed_char(0); + convert_signed_char_to_unsigned_int(0); + convert_unsigned_int_to_signed_char(0); + convert_signed_int_to_signed_char(0); + + // One lowest bit set. + convert_unsigned_int_to_unsigned_int(1); + convert_unsigned_char_to_unsigned_char(1); + convert_signed_int_to_signed_int(1); + convert_signed_char_to_signed_char(1); + convert_unsigned_int_to_unsigned_char(1); + convert_unsigned_char_to_unsigned_int(1); + convert_unsigned_char_to_signed_int(1); + convert_signed_char_to_signed_int(1); + convert_unsigned_int_to_signed_int(1); + convert_signed_int_to_unsigned_int(1); + convert_signed_int_to_unsigned_char(1); + convert_signed_char_to_unsigned_char(1); + convert_unsigned_char_to_signed_char(1); + convert_signed_char_to_unsigned_int(1); + convert_unsigned_int_to_signed_char(1); + convert_signed_int_to_signed_char(1); + +#if defined(V0) + // All source bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT32_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-arithmetic-value-change.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -1 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-arithmetic-value-change.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-arithmetic-value-change.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-arithmetic-value-change.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-arithmetic-value-change.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 255 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-arithmetic-value-change.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT32_MAX); +#elif defined(V1) + // Source 'Sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-arithmetic-value-change.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) +#elif defined(V2) + // All bits except the source 'Sign' bit are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-arithmetic-value-change.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-arithmetic-value-change.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V3) + // All destination bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-arithmetic-value-change.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-arithmetic-value-change.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 255 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-arithmetic-value-change.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 255 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-arithmetic-value-change.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 255 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V4) + // Destination 'sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-arithmetic-value-change.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-arithmetic-value-change.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-arithmetic-value-change.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 128 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-arithmetic-value-change.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 128 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V5) + // All bits except the destination 'sign' bit are set. + convert_unsigned_int_to_unsigned_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((~((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -129 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967167 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-arithmetic-value-change.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#elif defined(V6) + // Only the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)INT32_MIN); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-arithmetic-value-change.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V7) + // All bits except the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)))); +// CHECK-V7: {{.*}}integer-arithmetic-value-change.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-arithmetic-value-change.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-arithmetic-value-change.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#else +#error Some V* needs to be defined! +#endif + + return 0; +} diff --git a/test/ubsan/TestCases/ImplicitConversion/integer-conversion.c b/test/ubsan/TestCases/ImplicitConversion/integer-conversion.c new file mode 100644 index 0000000000000..5c1530a637868 --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/integer-conversion.c @@ -0,0 +1,351 @@ +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c -fsanitize=implicit-conversion %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c++ -fsanitize=implicit-conversion %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +#include <stdint.h> + +// Test plan: +// * Two types - int and char +// * Two signs - signed and unsigned +// * Square that - we have input and output types. +// Thus, there are total of (2*2)^2 == 16 tests. +// These are all the possible variations/combinations of casts. +// However, not all of them should result in the check. +// So here, we *only* check which should and which should not result in checks. + +uint32_t convert_unsigned_int_to_unsigned_int(uint32_t x) { +#line 100 + return x; +} + +uint8_t convert_unsigned_char_to_unsigned_char(uint8_t x) { +#line 200 + return x; +} + +int32_t convert_signed_int_to_signed_int(int32_t x) { +#line 300 + return x; +} + +int8_t convert_signed_char_to_signed_char(int8_t x) { +#line 400 + return x; +} + +uint8_t convert_unsigned_int_to_unsigned_char(uint32_t x) { +#line 500 + return x; +} + +uint32_t convert_unsigned_char_to_unsigned_int(uint8_t x) { +#line 600 + return x; +} + +int32_t convert_unsigned_char_to_signed_int(uint8_t x) { +#line 700 + return x; +} + +int32_t convert_signed_char_to_signed_int(int8_t x) { +#line 800 + return x; +} + +int32_t convert_unsigned_int_to_signed_int(uint32_t x) { +#line 900 + return x; +} + +uint32_t convert_signed_int_to_unsigned_int(int32_t x) { +#line 1000 + return x; +} + +uint8_t convert_signed_int_to_unsigned_char(int32_t x) { +#line 1100 + return x; +} + +uint8_t convert_signed_char_to_unsigned_char(int8_t x) { +#line 1200 + return x; +} + +int8_t convert_unsigned_char_to_signed_char(uint8_t x) { +#line 1300 + return x; +} + +uint32_t convert_signed_char_to_unsigned_int(int8_t x) { +#line 1400 + return x; +} + +int8_t convert_unsigned_int_to_signed_char(uint32_t x) { +#line 1500 + return x; +} + +int8_t convert_signed_int_to_signed_char(int32_t x) { +#line 1600 + return x; +} + +#line 10111 // !!! + +int main() { + // No bits set. + convert_unsigned_int_to_unsigned_int(0); + convert_unsigned_char_to_unsigned_char(0); + convert_signed_int_to_signed_int(0); + convert_signed_char_to_signed_char(0); + convert_unsigned_int_to_unsigned_char(0); + convert_unsigned_char_to_unsigned_int(0); + convert_unsigned_char_to_signed_int(0); + convert_signed_char_to_signed_int(0); + convert_unsigned_int_to_signed_int(0); + convert_signed_int_to_unsigned_int(0); + convert_signed_int_to_unsigned_char(0); + convert_signed_char_to_unsigned_char(0); + convert_unsigned_char_to_signed_char(0); + convert_signed_char_to_unsigned_int(0); + convert_unsigned_int_to_signed_char(0); + convert_signed_int_to_signed_char(0); + + // One lowest bit set. + convert_unsigned_int_to_unsigned_int(1); + convert_unsigned_char_to_unsigned_char(1); + convert_signed_int_to_signed_int(1); + convert_signed_char_to_signed_char(1); + convert_unsigned_int_to_unsigned_char(1); + convert_unsigned_char_to_unsigned_int(1); + convert_unsigned_char_to_signed_int(1); + convert_signed_char_to_signed_int(1); + convert_unsigned_int_to_signed_int(1); + convert_signed_int_to_unsigned_int(1); + convert_signed_int_to_unsigned_char(1); + convert_signed_char_to_unsigned_char(1); + convert_unsigned_char_to_signed_char(1); + convert_signed_char_to_unsigned_int(1); + convert_unsigned_int_to_signed_char(1); + convert_signed_int_to_signed_char(1); + +#if defined(V0) + // All source bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -1 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 255 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT32_MAX); +#elif defined(V1) + // Source 'Sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-conversion.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) +#elif defined(V2) + // All bits except the source 'Sign' bit are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-conversion.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-conversion.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-conversion.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V3) + // All destination bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-conversion.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-conversion.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 255 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-conversion.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 255 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-conversion.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 255 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V4) + // Destination 'sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-conversion.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-conversion.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-conversion.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 128 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-conversion.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 128 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V5) + // All bits except the destination 'sign' bit are set. + convert_unsigned_int_to_unsigned_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-conversion.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-conversion.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -129 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-conversion.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967167 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-conversion.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); +// CHECK-V5: {{.*}}integer-conversion.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); +// CHECK-V5: {{.*}}integer-conversion.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); +// CHECK-V5: {{.*}}integer-conversion.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-conversion.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#elif defined(V6) + // Only the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)); +// CHECK-V6: {{.*}}integer-conversion.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V6: {{.*}}integer-conversion.c:900:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + convert_signed_int_to_unsigned_int((int32_t)INT32_MIN); +// CHECK-V6: {{.*}}integer-conversion.c:1000:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + convert_signed_int_to_unsigned_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-conversion.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-conversion.c:1200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-conversion.c:1300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-conversion.c:1400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + convert_unsigned_int_to_signed_char((((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-conversion.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V7) + // All bits except the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-conversion.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)))); +// CHECK-V7: {{.*}}integer-conversion.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-conversion.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-conversion.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#else +#error Some V* needs to be defined! +#endif + + return 0; +} diff --git a/test/ubsan/TestCases/ImplicitConversion/integer-sign-change-blacklist.c b/test/ubsan/TestCases/ImplicitConversion/integer-sign-change-blacklist.c new file mode 100644 index 0000000000000..a3a745e5fbf6e --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/integer-sign-change-blacklist.c @@ -0,0 +1,28 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// I'm not sure this is actually *that* issue, but this seems oddly similar to the other XFAIL'ed cases. +// XFAIL: android +// UNSUPPORTED: ios + +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" + +// RUN: rm -f %tmp +// RUN: echo "[implicit-integer-sign-change]" >> %tmp +// RUN: echo "fun:implicitSignChange" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-sign-change -fno-sanitize-recover=implicit-integer-sign-change -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +#include <stdint.h> + +int32_t implicitSignChange(uint32_t argc) { + return argc; // BOOM +// CHECK: {{.*}}integer-sign-change-blacklist.c:[[@LINE-1]]:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -1 (32-bit, signed) +} + +int main(int argc, char **argv) { + return implicitSignChange(~0U); +} diff --git a/test/ubsan/TestCases/ImplicitConversion/integer-truncation-summary.cpp b/test/ubsan/TestCases/ImplicitConversion/integer-sign-change-summary.cpp index a92e01fb4ab6a..7cdc4c5a1b97a 100644 --- a/test/ubsan/TestCases/ImplicitConversion/integer-truncation-summary.cpp +++ b/test/ubsan/TestCases/ImplicitConversion/integer-sign-change-summary.cpp @@ -1,4 +1,4 @@ -// RUN: %clangxx -fsanitize=implicit-integer-truncation %s -o %t +// RUN: %clangxx -fsanitize=implicit-integer-sign-change %s -o %t // RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE // RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE // REQUIRES: !ubsan-standalone && !ubsan-standalone-static @@ -6,8 +6,8 @@ #include <stdint.h> int main() { - uint8_t t0 = (~(uint32_t(0))); + int32_t t0 = (~(uint32_t(0))); // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:16 - // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: implicit-integer-truncation {{.*}}summary.cpp:[[@LINE-2]]:16 + // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: implicit-integer-sign-change {{.*}}summary.cpp:[[@LINE-2]]:16 return 0; } diff --git a/test/ubsan/TestCases/ImplicitConversion/integer-sign-change.c b/test/ubsan/TestCases/ImplicitConversion/integer-sign-change.c new file mode 100644 index 0000000000000..192c69ade1d51 --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/integer-sign-change.c @@ -0,0 +1,297 @@ +// RUN: %clang -x c -fsanitize=implicit-integer-sign-change %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c -fsanitize=implicit-integer-sign-change %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c -fsanitize=implicit-integer-sign-change %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c -fsanitize=implicit-integer-sign-change %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c -fsanitize=implicit-integer-sign-change %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c -fsanitize=implicit-integer-sign-change %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c -fsanitize=implicit-integer-sign-change %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 + +// RUN: %clang -x c++ -fsanitize=implicit-integer-sign-change %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c++ -fsanitize=implicit-integer-sign-change %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c++ -fsanitize=implicit-integer-sign-change %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c++ -fsanitize=implicit-integer-sign-change %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c++ -fsanitize=implicit-integer-sign-change %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c++ -fsanitize=implicit-integer-sign-change %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c++ -fsanitize=implicit-integer-sign-change %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 + +#include <stdint.h> + +// Test plan: +// * Two types - int and char +// * Two signs - signed and unsigned +// * Square that - we have input and output types. +// Thus, there are total of (2*2)^2 == 16 tests. +// These are all the possible variations/combinations of casts. +// However, not all of them should result in the check. +// So here, we *only* check which should and which should not result in checks. + +//============================================================================// +// Half of the cases do not need the check. // +//============================================================================// + +uint32_t negative0_convert_unsigned_int_to_unsigned_int(uint32_t x) { + return x; +} + +uint8_t negative1_convert_unsigned_char_to_unsigned_char(uint8_t x) { + return x; +} + +int32_t negative2_convert_signed_int_to_signed_int(int32_t x) { + return x; +} + +int8_t negative3_convert_signed_char_to_signed_char(int8_t x) { + return x; +} + +uint8_t negative4_convert_unsigned_int_to_unsigned_char(uint32_t x) { + return x; +} + +uint32_t negative5_convert_unsigned_char_to_unsigned_int(uint8_t x) { + return x; +} + +int32_t negative6_convert_unsigned_char_to_signed_int(uint8_t x) { + return x; +} + +int32_t negative7_convert_signed_char_to_signed_int(int8_t x) { + return x; +} + +void test_negatives() { + // No bits set. + negative0_convert_unsigned_int_to_unsigned_int(0); + negative1_convert_unsigned_char_to_unsigned_char(0); + negative2_convert_signed_int_to_signed_int(0); + negative3_convert_signed_char_to_signed_char(0); + negative4_convert_unsigned_int_to_unsigned_char(0); + negative5_convert_unsigned_char_to_unsigned_int(0); + negative6_convert_unsigned_char_to_signed_int(0); + negative7_convert_signed_char_to_signed_int(0); + + // One lowest bit set. + negative0_convert_unsigned_int_to_unsigned_int(1); + negative1_convert_unsigned_char_to_unsigned_char(1); + negative2_convert_signed_int_to_signed_int(1); + negative3_convert_signed_char_to_signed_char(1); + negative4_convert_unsigned_int_to_unsigned_char(1); + negative5_convert_unsigned_char_to_unsigned_int(1); + negative6_convert_unsigned_char_to_signed_int(1); + negative7_convert_signed_char_to_signed_int(1); + + // All source bits set. + negative0_convert_unsigned_int_to_unsigned_int((uint32_t)UINT32_MAX); + negative1_convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + negative2_convert_signed_int_to_signed_int((int32_t)INT32_MAX); + negative3_convert_signed_char_to_signed_char((int8_t)INT8_MAX); + negative4_convert_unsigned_int_to_unsigned_char((uint32_t)UINT32_MAX); + negative5_convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + negative6_convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + negative7_convert_signed_char_to_signed_int((int8_t)INT8_MAX); + + // Source 'sign' bit set. + negative0_convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + negative1_convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + negative2_convert_signed_int_to_signed_int((int32_t)INT32_MIN); + negative3_convert_signed_char_to_signed_char((int8_t)INT8_MIN); + negative4_convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MIN); + negative5_convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + negative6_convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + negative7_convert_signed_char_to_signed_int((int8_t)INT8_MIN); +} + +//============================================================================// +// The remaining 8 cases *do* need the check. // +//============================================================================// + +int32_t positive0_convert_unsigned_int_to_signed_int(uint32_t x) { +#line 100 + return x; +} + +uint32_t positive1_convert_signed_int_to_unsigned_int(int32_t x) { +#line 200 + return x; +} + +uint8_t positive2_convert_signed_int_to_unsigned_char(int32_t x) { +#line 300 + return x; +} + +uint8_t positive3_convert_signed_char_to_unsigned_char(int8_t x) { +#line 400 + return x; +} + +int8_t positive4_convert_unsigned_char_to_signed_char(uint8_t x) { +#line 500 + return x; +} + +uint32_t positive5_convert_signed_char_to_unsigned_int(int8_t x) { +#line 600 + return x; +} + +int8_t positive6_convert_unsigned_int_to_signed_char(uint32_t x) { +#line 700 + return x; +} + +int8_t positive7_convert_signed_int_to_signed_char(int32_t x) { +#line 800 + return x; +} + +#line 1120 // !!! + +void test_positives() { + // No bits set. + positive0_convert_unsigned_int_to_signed_int(0); + positive1_convert_signed_int_to_unsigned_int(0); + positive2_convert_signed_int_to_unsigned_char(0); + positive3_convert_signed_char_to_unsigned_char(0); + positive4_convert_unsigned_char_to_signed_char(0); + positive5_convert_signed_char_to_unsigned_int(0); + positive6_convert_unsigned_int_to_signed_char(0); + positive7_convert_signed_int_to_signed_char(0); + + // One lowest bit set. + positive0_convert_unsigned_int_to_signed_int(1); + positive1_convert_signed_int_to_unsigned_int(1); + positive2_convert_signed_int_to_unsigned_char(1); + positive3_convert_signed_char_to_unsigned_char(1); + positive4_convert_unsigned_char_to_signed_char(1); + positive5_convert_signed_char_to_unsigned_int(1); + positive6_convert_unsigned_int_to_signed_char(1); + positive7_convert_signed_int_to_signed_char(1); + +#if defined(V0) + // All source bits set. + positive0_convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-sign-change.c:100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -1 (32-bit, signed) + positive1_convert_signed_int_to_unsigned_int((int32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-sign-change.c:200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + positive2_convert_signed_int_to_unsigned_char((int32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-sign-change.c:300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + positive3_convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-sign-change.c:400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + positive4_convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-sign-change.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 255 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + positive5_convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); +// CHECK-V0: {{.*}}integer-sign-change.c:600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + positive6_convert_unsigned_int_to_signed_char((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-sign-change.c:700:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + positive7_convert_signed_int_to_signed_char((int32_t)UINT32_MAX); +#elif defined(V1) + // Source 'Sign' bit set. + positive0_convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-sign-change.c:100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + positive1_convert_signed_int_to_unsigned_int((int32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-sign-change.c:200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + positive2_convert_signed_int_to_unsigned_char((int32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-sign-change.c:300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + positive3_convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-sign-change.c:400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + positive4_convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-sign-change.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + positive5_convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); +// CHECK-V1: {{.*}}integer-sign-change.c:600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + positive6_convert_unsigned_int_to_signed_char((uint32_t)INT32_MIN); + positive7_convert_signed_int_to_signed_char((int32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-sign-change.c:800:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) +#elif defined(V2) + // All bits except the source 'Sign' bit are set. + positive0_convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + positive1_convert_signed_int_to_unsigned_int((int32_t)INT32_MAX); + positive2_convert_signed_int_to_unsigned_char((int32_t)INT32_MAX); + positive3_convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + positive4_convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + positive5_convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + positive6_convert_unsigned_int_to_signed_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-sign-change.c:700:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + positive7_convert_signed_int_to_signed_char((int32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-sign-change.c:800:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V3) + // All destination bits set. + positive0_convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); +// CHECK-V3: {{.*}}integer-sign-change.c:100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -1 (32-bit, signed) + positive1_convert_signed_int_to_unsigned_int((int32_t)UINT32_MAX); +// CHECK-V3: {{.*}}integer-sign-change.c:200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + positive2_convert_signed_int_to_unsigned_char((int32_t)UINT8_MAX); + positive3_convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-sign-change.c:400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + positive4_convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-sign-change.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 255 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + positive5_convert_signed_char_to_unsigned_int((int8_t)UINT32_MAX); +// CHECK-V3: {{.*}}integer-sign-change.c:600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -1 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + positive6_convert_unsigned_int_to_signed_char((uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-sign-change.c:700:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 255 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + positive7_convert_signed_int_to_signed_char((int32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-sign-change.c:800:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 255 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V4) + // Destination 'sign' bit set. + positive0_convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V4: {{.*}}integer-sign-change.c:100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + positive1_convert_signed_int_to_unsigned_int((int32_t)INT32_MIN); +// CHECK-V4: {{.*}}integer-sign-change.c:200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + positive2_convert_signed_int_to_unsigned_char((int32_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-sign-change.c:300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -128 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + positive3_convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-sign-change.c:400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + positive4_convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-sign-change.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + positive5_convert_signed_char_to_unsigned_int((int8_t)INT32_MIN); + positive6_convert_unsigned_int_to_signed_char((uint32_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-sign-change.c:700:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967168 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + positive7_convert_signed_int_to_signed_char((int32_t)INT8_MIN); +#elif defined(V5) + // All bits except the destination 'sign' bit are set. + positive0_convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V5: {{.*}}integer-sign-change.c:100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + positive1_convert_signed_int_to_unsigned_int((int32_t)INT32_MIN); +// CHECK-V5: {{.*}}integer-sign-change.c:200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + positive2_convert_signed_int_to_unsigned_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-sign-change.c:300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + positive3_convert_signed_char_to_unsigned_char((int8_t)(INT8_MIN)); +// CHECK-V5: {{.*}}integer-sign-change.c:400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + positive4_convert_unsigned_char_to_signed_char((uint8_t)(INT8_MIN)); +// CHECK-V5: {{.*}}integer-sign-change.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + positive5_convert_signed_char_to_unsigned_int((int8_t)(INT32_MIN)); + positive6_convert_unsigned_int_to_signed_char(~((uint32_t)(uint8_t)INT8_MIN)); + positive7_convert_signed_int_to_signed_char((int32_t)(~((uint32_t)((uint8_t)INT8_MIN)))); +// CHECK-V5: {{.*}}integer-sign-change.c:800:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#elif defined(V6) + // Only the source and destination sign bits are set. + positive0_convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); +// CHECK-V6: {{.*}}integer-sign-change.c:100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'int') changed the value to -2147483648 (32-bit, signed) + positive1_convert_signed_int_to_unsigned_int((int32_t)INT32_MIN); +// CHECK-V6: {{.*}}integer-sign-change.c:200:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 2147483648 (32-bit, unsigned) + positive2_convert_signed_int_to_unsigned_char((int32_t)((uint32_t)INT32_MIN | (uint32_t)((uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-sign-change.c:300:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + positive3_convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-sign-change.c:400:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + positive4_convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-sign-change.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned char') of value 128 (8-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + positive5_convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); +// CHECK-V6: {{.*}}integer-sign-change.c:600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'signed char') of value -128 (8-bit, signed) to type '{{.*}}' (aka 'unsigned int') changed the value to 4294967168 (32-bit, unsigned) + positive6_convert_unsigned_int_to_signed_char((uint32_t)((uint32_t)INT32_MIN | (uint32_t)((uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-sign-change.c:700:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + positive7_convert_signed_int_to_signed_char((int32_t)((uint32_t)INT32_MIN | (uint32_t)((uint8_t)INT8_MIN))); +#else +#error Some V* needs to be defined! +#endif +} + +// CHECK-NOT: implicit conversion + +int main() { + test_negatives(); + test_positives(); + + return 0; +} diff --git a/test/ubsan/TestCases/ImplicitConversion/integer-truncation-blacklist.c b/test/ubsan/TestCases/ImplicitConversion/integer-truncation-blacklist.c deleted file mode 100644 index 13d4dca4ff141..0000000000000 --- a/test/ubsan/TestCases/ImplicitConversion/integer-truncation-blacklist.c +++ /dev/null @@ -1,20 +0,0 @@ -// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 -// I'm not sure this is actually *that* issue, but this seems oddly similar to the other XFAIL'ed cases. -// XFAIL: android -// UNSUPPORTED: ios - -// RUN: rm -f %tmp -// RUN: echo "[implicit-integer-truncation]" >> %tmp -// RUN: echo "fun:*implicitTruncation*" >> %tmp -// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 -// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 -// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 -// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 - -unsigned char implicitTruncation(unsigned int argc) { - return argc; // BOOM -} - -int main(int argc, char **argv) { - return implicitTruncation(~0U); -} diff --git a/test/ubsan/TestCases/ImplicitConversion/integer-truncation.c b/test/ubsan/TestCases/ImplicitConversion/integer-truncation.c index 995eb7d0faf46..157564871e454 100644 --- a/test/ubsan/TestCases/ImplicitConversion/integer-truncation.c +++ b/test/ubsan/TestCases/ImplicitConversion/integer-truncation.c @@ -1,63 +1,324 @@ -// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK -// RUN: %clangxx -x c++ -fsanitize=implicit-integer-truncation %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c -fsanitize=implicit-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c++ -fsanitize=implicit-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 #include <stdint.h> -#if !defined(__cplusplus) -#define bool _Bool -#endif +// Test plan: +// * Two types - int and char +// * Two signs - signed and unsigned +// * Square that - we have input and output types. +// Thus, there are total of (2*2)^2 == 16 tests. +// These are all the possible variations/combinations of casts. +// However, not all of them should result in the check. +// So here, we *only* check which should and which should not result in checks. -int main() { -// CHECK-NOT: integer-truncation.c +uint32_t convert_unsigned_int_to_unsigned_int(uint32_t x) { +#line 100 + return x; +} - // Negative tests. Even if they produce unexpected results, this sanitizer does not care. - int8_t n0 = (~((uint32_t)0)); // ~0 -> -1, but do not warn. - uint8_t n2 = 128; - uint8_t n3 = 255; - // Bools do not count - bool b0 = (~((uint32_t)0)); - bool b1 = 255; +uint8_t convert_unsigned_char_to_unsigned_char(uint8_t x) { +#line 200 + return x; +} - // Explicit and-ing of bits will silence it. - uint8_t nc0 = (~((uint32_t)0)) & 255; +int32_t convert_signed_int_to_signed_int(int32_t x) { +#line 300 + return x; +} - // Explicit casts - uint8_t i0 = (uint8_t)(~((uint32_t)0)); +int8_t convert_signed_char_to_signed_char(int8_t x) { +#line 400 + return x; +} -#if defined(__cplusplus) - uint8_t i1 = uint8_t(~(uint32_t(0))); - uint8_t i2 = static_cast<uint8_t>(~(uint32_t(0))); -#endif +uint8_t convert_unsigned_int_to_unsigned_char(uint32_t x) { +#line 500 + return x; +} + +uint32_t convert_unsigned_char_to_unsigned_int(uint8_t x) { +#line 600 + return x; +} + +int32_t convert_unsigned_char_to_signed_int(uint8_t x) { +#line 700 + return x; +} + +int32_t convert_signed_char_to_signed_int(int8_t x) { +#line 800 + return x; +} + +int32_t convert_unsigned_int_to_signed_int(uint32_t x) { +#line 900 + return x; +} + +uint32_t convert_signed_int_to_unsigned_int(int32_t x) { +#line 1000 + return x; +} + +uint8_t convert_signed_int_to_unsigned_char(int32_t x) { +#line 1100 + return x; +} + +uint8_t convert_signed_char_to_unsigned_char(int8_t x) { +#line 1200 + return x; +} + +int8_t convert_unsigned_char_to_signed_char(uint8_t x) { +#line 1300 + return x; +} + +uint32_t convert_signed_char_to_unsigned_int(int8_t x) { +#line 1400 + return x; +} + +int8_t convert_unsigned_int_to_signed_char(uint32_t x) { +#line 1500 + return x; +} - // Positive tests. +int8_t convert_signed_int_to_signed_char(int32_t x) { +#line 1600 + return x; +} - uint8_t t_b0 = (~((uint16_t)(0))); -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'int' of value -1 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) +#line 1111 // !!! - uint8_t t_b1 = (~((uint32_t)0)); -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) - uint16_t t_b2 = (~((uint32_t)0)); -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint32_t' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type 'uint16_t' (aka 'unsigned short') changed the value to 65535 (16-bit, unsigned) +int main() { + // No bits set. + convert_unsigned_int_to_unsigned_int(0); + convert_unsigned_char_to_unsigned_char(0); + convert_signed_int_to_signed_int(0); + convert_signed_char_to_signed_char(0); + convert_unsigned_int_to_unsigned_char(0); + convert_unsigned_char_to_unsigned_int(0); + convert_unsigned_char_to_signed_int(0); + convert_signed_char_to_signed_int(0); + convert_unsigned_int_to_signed_int(0); + convert_signed_int_to_unsigned_int(0); + convert_signed_int_to_unsigned_char(0); + convert_signed_char_to_unsigned_char(0); + convert_unsigned_char_to_signed_char(0); + convert_signed_char_to_unsigned_int(0); + convert_unsigned_int_to_signed_char(0); + convert_signed_int_to_signed_char(0); - uint8_t t_b3 = ~((uint64_t)0); -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:18: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint8_t' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) - uint16_t t_b4 = ~((uint64_t)0); -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint16_t' (aka 'unsigned short') changed the value to 65535 (16-bit, unsigned) - uint32_t t_b5 = ~((uint64_t)0); -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:19: runtime error: implicit conversion from type 'uint64_t' (aka 'unsigned long{{[^']*}}') of value 18446744073709551615 (64-bit, unsigned) to type 'uint32_t' (aka 'unsigned int') changed the value to 4294967295 (32-bit, unsigned) + // One lowest bit set. + convert_unsigned_int_to_unsigned_int(1); + convert_unsigned_char_to_unsigned_char(1); + convert_signed_int_to_signed_int(1); + convert_signed_char_to_signed_char(1); + convert_unsigned_int_to_unsigned_char(1); + convert_unsigned_char_to_unsigned_int(1); + convert_unsigned_char_to_signed_int(1); + convert_signed_char_to_signed_int(1); + convert_unsigned_int_to_signed_int(1); + convert_signed_int_to_unsigned_int(1); + convert_signed_int_to_unsigned_char(1); + convert_signed_char_to_unsigned_char(1); + convert_unsigned_char_to_signed_char(1); + convert_signed_char_to_unsigned_int(1); + convert_unsigned_int_to_signed_char(1); + convert_signed_int_to_signed_char(1); - int8_t t1 = 255; -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 255 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to -1 (8-bit, signed) - uint8_t t2 = 256; -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:16: runtime error: implicit conversion from type 'int' of value 256 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) - int8_t t3 = 256; -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 256 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to 0 (8-bit, signed) - uint8_t t4 = 257; -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:16: runtime error: implicit conversion from type 'int' of value 257 (32-bit, signed) to type 'uint8_t' (aka 'unsigned char') changed the value to 1 (8-bit, unsigned) - int8_t t5 = 257; -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 257 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to 1 (8-bit, signed) - int8_t t6 = 128; -// CHECK: {{.*}}integer-truncation.c:[[@LINE-1]]:15: runtime error: implicit conversion from type 'int' of value 128 (32-bit, signed) to type 'int8_t' (aka 'signed char') changed the value to -128 (8-bit, signed) +#if defined(V0) + // All source bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)UINT32_MAX); + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT32_MAX); +#elif defined(V1) + // Source 'Sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) +#elif defined(V2) + // All bits except the source 'Sign' bit are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V3) + // All destination bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 255 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 255 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V4) + // Destination 'sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 128 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 128 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V5) + // All bits except the destination 'sign' bit are set. + convert_unsigned_int_to_unsigned_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_unsigned_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_unsigned_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#elif defined(V6) + // Only the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)); +// CHECK-V6: {{.*}}integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V7) + // All bits except the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)))); +// CHECK-V7: {{.*}}integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#else +#error Some V* needs to be defined! +#endif return 0; } diff --git a/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-blacklist.c b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-blacklist.c new file mode 100644 index 0000000000000..229f8326077ae --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-blacklist.c @@ -0,0 +1,60 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// I'm not sure this is actually *that* issue, but this seems oddly similar to the other XFAIL'ed cases. +// XFAIL: android +// UNSUPPORTED: ios + +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" + +// RUN: rm -f %tmp +// RUN: echo "[integer]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-conversion]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-integer-truncation]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-signed-integer-truncation]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-unsigned-integer-truncation]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s + +#include <stdint.h> + +uint8_t implicitUnsignedTruncation(int32_t argc) { + return argc; // BOOM +// CHECK: {{.*}}signed-integer-truncation-blacklist.c:[[@LINE-1]]:10: runtime error: implicit conversion from type '{{.*}} (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) +} + +int main(int argc, char **argv) { + return implicitUnsignedTruncation(-1); +} diff --git a/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-or-sign-change-blacklist.c b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-or-sign-change-blacklist.c new file mode 100644 index 0000000000000..0e79df0b512c3 --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-or-sign-change-blacklist.c @@ -0,0 +1,58 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// I'm not sure this is actually *that* issue, but this seems oddly similar to the other XFAIL'ed cases. +// XFAIL: android +// UNSUPPORTED: ios + +// All of these don't actually silence it: + +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" + +// RUN: rm -f %tmp +// RUN: echo "[implicit-signed-integer-truncation]" >> %tmp +// RUN: echo "fun:implicitConversion" >> %tmp +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" + +// RUN: rm -f %tmp +// RUN: echo "[implicit-signed-integer-truncation,implicit-integer-sign-change]" >> %tmp +// RUN: echo "fun:implicitConversion" >> %tmp +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" + + +// The only two way it works: + +// RUN: rm -f %tmp +// RUN: echo "[implicit-integer-sign-change]" >> %tmp +// RUN: echo "fun:implicitConversion" >> %tmp +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-signed-integer-truncation]" >> %tmp +// RUN: echo "[implicit-integer-sign-change]" >> %tmp +// RUN: echo "fun:implicitConversion" >> %tmp +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change -fno-sanitize-recover=implicit-signed-integer-truncation,implicit-integer-sign-change -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +#include <stdint.h> + +int8_t implicitConversion(uint32_t argc) { + return argc; // BOOM +// CHECK: {{.*}}signed-integer-truncation-or-sign-change-blacklist.c:[[@LINE-1]]:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +} + +int main(int argc, char **argv) { + return implicitConversion(~0U); +} diff --git a/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-or-sign-change-summary.cpp b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-or-sign-change-summary.cpp new file mode 100644 index 0000000000000..13eaef2741571 --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-or-sign-change-summary.cpp @@ -0,0 +1,13 @@ +// RUN: %clangxx -fsanitize=implicit-signed-integer-truncation,implicit-integer-sign-change %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE +// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE +// REQUIRES: !ubsan-standalone && !ubsan-standalone-static + +#include <stdint.h> + +int main() { + int8_t t0 = (~(uint32_t(0))); + // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:15 + // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: implicit-signed-integer-truncation-or-sign-change {{.*}}summary.cpp:[[@LINE-2]]:15 + return 0; +} diff --git a/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-summary.cpp b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-summary.cpp new file mode 100644 index 0000000000000..1da9e3b41e365 --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation-summary.cpp @@ -0,0 +1,13 @@ +// RUN: %clangxx -fsanitize=implicit-signed-integer-truncation %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE +// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE +// REQUIRES: !ubsan-standalone && !ubsan-standalone-static + +#include <stdint.h> + +int main() { + uint8_t t0 = int32_t(-1); + // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:16 + // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: implicit-signed-integer-truncation {{.*}}summary.cpp:[[@LINE-2]]:16 + return 0; +} diff --git a/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation.c b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation.c new file mode 100644 index 0000000000000..1ff67eb0579b8 --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/signed-integer-truncation.c @@ -0,0 +1,318 @@ +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c -fsanitize=implicit-signed-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c++ -fsanitize=implicit-signed-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +#include <stdint.h> + +// Test plan: +// * Two types - int and char +// * Two signs - signed and unsigned +// * Square that - we have input and output types. +// Thus, there are total of (2*2)^2 == 16 tests. +// These are all the possible variations/combinations of casts. +// However, not all of them should result in the check. +// So here, we *only* check which should and which should not result in checks. + +uint32_t convert_unsigned_int_to_unsigned_int(uint32_t x) { +#line 100 + return x; +} + +uint8_t convert_unsigned_char_to_unsigned_char(uint8_t x) { +#line 200 + return x; +} + +int32_t convert_signed_int_to_signed_int(int32_t x) { +#line 300 + return x; +} + +int8_t convert_signed_char_to_signed_char(int8_t x) { +#line 400 + return x; +} + +uint8_t convert_unsigned_int_to_unsigned_char(uint32_t x) { +#line 500 + return x; +} + +uint32_t convert_unsigned_char_to_unsigned_int(uint8_t x) { +#line 600 + return x; +} + +int32_t convert_unsigned_char_to_signed_int(uint8_t x) { +#line 700 + return x; +} + +int32_t convert_signed_char_to_signed_int(int8_t x) { +#line 800 + return x; +} + +int32_t convert_unsigned_int_to_signed_int(uint32_t x) { +#line 900 + return x; +} + +uint32_t convert_signed_int_to_unsigned_int(int32_t x) { +#line 1000 + return x; +} + +uint8_t convert_signed_int_to_unsigned_char(int32_t x) { +#line 1100 + return x; +} + +uint8_t convert_signed_char_to_unsigned_char(int8_t x) { +#line 1200 + return x; +} + +int8_t convert_unsigned_char_to_signed_char(uint8_t x) { +#line 1300 + return x; +} + +uint32_t convert_signed_char_to_unsigned_int(int8_t x) { +#line 1400 + return x; +} + +int8_t convert_unsigned_int_to_signed_char(uint32_t x) { +#line 1500 + return x; +} + +int8_t convert_signed_int_to_signed_char(int32_t x) { +#line 1600 + return x; +} + +#line 1111 // !!! + +int main() { + // No bits set. + convert_unsigned_int_to_unsigned_int(0); + convert_unsigned_char_to_unsigned_char(0); + convert_signed_int_to_signed_int(0); + convert_signed_char_to_signed_char(0); + convert_unsigned_int_to_unsigned_char(0); + convert_unsigned_char_to_unsigned_int(0); + convert_unsigned_char_to_signed_int(0); + convert_signed_char_to_signed_int(0); + convert_unsigned_int_to_signed_int(0); + convert_signed_int_to_unsigned_int(0); + convert_signed_int_to_unsigned_char(0); + convert_signed_char_to_unsigned_char(0); + convert_unsigned_char_to_signed_char(0); + convert_signed_char_to_unsigned_int(0); + convert_unsigned_int_to_signed_char(0); + convert_signed_int_to_signed_char(0); + + // One lowest bit set. + convert_unsigned_int_to_unsigned_int(1); + convert_unsigned_char_to_unsigned_char(1); + convert_signed_int_to_signed_int(1); + convert_signed_char_to_signed_char(1); + convert_unsigned_int_to_unsigned_char(1); + convert_unsigned_char_to_unsigned_int(1); + convert_unsigned_char_to_signed_int(1); + convert_signed_char_to_signed_int(1); + convert_unsigned_int_to_signed_int(1); + convert_signed_int_to_unsigned_int(1); + convert_signed_int_to_unsigned_char(1); + convert_signed_char_to_unsigned_char(1); + convert_unsigned_char_to_signed_char(1); + convert_signed_char_to_unsigned_int(1); + convert_unsigned_int_to_signed_char(1); + convert_signed_int_to_signed_char(1); + +#if defined(V0) + // All source bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT32_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}signed-integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -1 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)UINT32_MAX); + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT32_MAX); +#elif defined(V1) + // Source 'Sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}signed-integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}signed-integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}signed-integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483648 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 0 (8-bit, signed) +#elif defined(V2) + // All bits except the source 'Sign' bit are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}signed-integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}signed-integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}signed-integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483647 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V3) + // All destination bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}signed-integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 255 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT8_MAX); +// CHECK-V3: {{.*}}signed-integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 255 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -1 (8-bit, signed) +#elif defined(V4) + // Destination 'sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}signed-integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 128 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); +// CHECK-V4: {{.*}}signed-integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 128 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V5) + // All bits except the destination 'sign' bit are set. + convert_unsigned_int_to_unsigned_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((~((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_unsigned_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_unsigned_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}signed-integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}signed-integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}signed-integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -129 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#elif defined(V6) + // Only the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}signed-integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}signed-integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V6: {{.*}}signed-integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value -2147483520 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to -128 (8-bit, signed) +#elif defined(V7) + // All bits except the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)))); +// CHECK-V7: {{.*}}signed-integer-truncation.c:1100:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}signed-integer-truncation.c:1500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) + convert_signed_int_to_signed_char((int32_t)~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}signed-integer-truncation.c:1600:10: runtime error: implicit conversion from type '{{.*}}' (aka 'int') of value 2147483519 (32-bit, signed) to type '{{.*}}' (aka 'signed char') changed the value to 127 (8-bit, signed) +#else +#error Some V* needs to be defined! +#endif + + return 0; +} diff --git a/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation-blacklist.c b/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation-blacklist.c new file mode 100644 index 0000000000000..938b7a8c102ca --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation-blacklist.c @@ -0,0 +1,60 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// I'm not sure this is actually *that* issue, but this seems oddly similar to the other XFAIL'ed cases. +// XFAIL: android +// UNSUPPORTED: ios + +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" + +// RUN: rm -f %tmp +// RUN: echo "[integer]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-conversion]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-integer-truncation]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-unsigned-integer-truncation]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | not FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | not FileCheck %s + +// RUN: rm -f %tmp +// RUN: echo "[implicit-signed-integer-truncation]" >> %tmp +// RUN: echo "fun:implicitUnsignedTruncation" >> %tmp +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang -fsanitize=implicit-integer-truncation -fno-sanitize-recover=implicit-integer-truncation -fsanitize-blacklist=%tmp -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s + +#include <stdint.h> + +uint8_t implicitUnsignedTruncation(uint32_t argc) { + return argc; // BOOM +// CHECK: {{.*}}unsigned-integer-truncation-blacklist.c:[[@LINE-1]]:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) +} + +int main(int argc, char **argv) { + return implicitUnsignedTruncation(~0U); +} diff --git a/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation-summary.cpp b/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation-summary.cpp new file mode 100644 index 0000000000000..5117dc2a34f3d --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation-summary.cpp @@ -0,0 +1,13 @@ +// RUN: %clangxx -fsanitize=implicit-unsigned-integer-truncation %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE +// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE +// REQUIRES: !ubsan-standalone && !ubsan-standalone-static + +#include <stdint.h> + +int main() { + uint8_t t0 = (~(uint32_t(0))); + // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:16 + // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: implicit-unsigned-integer-truncation {{.*}}summary.cpp:[[@LINE-2]]:16 + return 0; +} diff --git a/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation.c b/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation.c new file mode 100644 index 0000000000000..49d223ccda39d --- /dev/null +++ b/test/ubsan/TestCases/ImplicitConversion/unsigned-integer-truncation.c @@ -0,0 +1,304 @@ +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | not FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | not FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c -fsanitize=implicit-unsigned-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV0 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V0 +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV1 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V1 +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV2 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V2 +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV3 -o %t && %run %t 2>&1 | not FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V3 +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV4 -o %t && %run %t 2>&1 | not FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V4 +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV5 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V5 +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV6 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V6 +// RUN: %clang -x c++ -fsanitize=implicit-unsigned-integer-truncation %s -DV7 -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not="implicit conversion" --check-prefixes=CHECK-V7 + +#include <stdint.h> + +// Test plan: +// * Two types - int and char +// * Two signs - signed and unsigned +// * Square that - we have input and output types. +// Thus, there are total of (2*2)^2 == 16 tests. +// These are all the possible variations/combinations of casts. +// However, not all of them should result in the check. +// So here, we *only* check which should and which should not result in checks. + +uint32_t convert_unsigned_int_to_unsigned_int(uint32_t x) { +#line 100 + return x; +} + +uint8_t convert_unsigned_char_to_unsigned_char(uint8_t x) { +#line 200 + return x; +} + +int32_t convert_signed_int_to_signed_int(int32_t x) { +#line 300 + return x; +} + +int8_t convert_signed_char_to_signed_char(int8_t x) { +#line 400 + return x; +} + +uint8_t convert_unsigned_int_to_unsigned_char(uint32_t x) { +#line 500 + return x; +} + +uint32_t convert_unsigned_char_to_unsigned_int(uint8_t x) { +#line 600 + return x; +} + +int32_t convert_unsigned_char_to_signed_int(uint8_t x) { +#line 700 + return x; +} + +int32_t convert_signed_char_to_signed_int(int8_t x) { +#line 800 + return x; +} + +int32_t convert_unsigned_int_to_signed_int(uint32_t x) { +#line 900 + return x; +} + +uint32_t convert_signed_int_to_unsigned_int(int32_t x) { +#line 1000 + return x; +} + +uint8_t convert_signed_int_to_unsigned_char(int32_t x) { +#line 1100 + return x; +} + +uint8_t convert_signed_char_to_unsigned_char(int8_t x) { +#line 1200 + return x; +} + +int8_t convert_unsigned_char_to_signed_char(uint8_t x) { +#line 1300 + return x; +} + +uint32_t convert_signed_char_to_unsigned_int(int8_t x) { +#line 1400 + return x; +} + +int8_t convert_unsigned_int_to_signed_char(uint32_t x) { +#line 1500 + return x; +} + +int8_t convert_signed_int_to_signed_char(int32_t x) { +#line 1600 + return x; +} + +#line 1111 // !!! + +int main() { + // No bits set. + convert_unsigned_int_to_unsigned_int(0); + convert_unsigned_char_to_unsigned_char(0); + convert_signed_int_to_signed_int(0); + convert_signed_char_to_signed_char(0); + convert_unsigned_int_to_unsigned_char(0); + convert_unsigned_char_to_unsigned_int(0); + convert_unsigned_char_to_signed_int(0); + convert_signed_char_to_signed_int(0); + convert_unsigned_int_to_signed_int(0); + convert_signed_int_to_unsigned_int(0); + convert_signed_int_to_unsigned_char(0); + convert_signed_char_to_unsigned_char(0); + convert_unsigned_char_to_signed_char(0); + convert_signed_char_to_unsigned_int(0); + convert_unsigned_int_to_signed_char(0); + convert_signed_int_to_signed_char(0); + + // One lowest bit set. + convert_unsigned_int_to_unsigned_int(1); + convert_unsigned_char_to_unsigned_char(1); + convert_signed_int_to_signed_int(1); + convert_signed_char_to_signed_char(1); + convert_unsigned_int_to_unsigned_char(1); + convert_unsigned_char_to_unsigned_int(1); + convert_unsigned_char_to_signed_int(1); + convert_signed_char_to_signed_int(1); + convert_unsigned_int_to_signed_int(1); + convert_signed_int_to_unsigned_int(1); + convert_signed_int_to_unsigned_char(1); + convert_signed_char_to_unsigned_char(1); + convert_unsigned_char_to_signed_char(1); + convert_signed_char_to_unsigned_int(1); + convert_unsigned_int_to_signed_char(1); + convert_signed_int_to_signed_char(1); + +#if defined(V0) + // All source bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT32_MAX); +// CHECK-V0: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967295 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT32_MAX); + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)UINT32_MAX); + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT32_MAX); +#elif defined(V1) + // Source 'Sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MIN); +// CHECK-V1: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483648 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 0 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MIN); + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MIN); + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MIN); +#elif defined(V2) + // All bits except the source 'Sign' bit are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)INT32_MAX); +// CHECK-V2: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483647 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 255 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)INT32_MAX); + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)INT32_MAX); + convert_signed_int_to_signed_char((int32_t)(uint32_t)INT32_MAX); +#elif defined(V3) + // All destination bits set. + convert_unsigned_int_to_unsigned_int((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)UINT8_MAX); + convert_signed_int_to_signed_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_signed_char((int8_t)UINT8_MAX); + convert_unsigned_int_to_unsigned_char((uint32_t)UINT8_MAX); + convert_unsigned_char_to_unsigned_int((uint8_t)UINT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)UINT8_MAX); + convert_signed_char_to_signed_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)UINT8_MAX); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)UINT8_MAX); + convert_signed_char_to_unsigned_char((int8_t)UINT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)UINT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)UINT8_MAX); + convert_unsigned_int_to_signed_char((uint32_t)UINT8_MAX); + convert_signed_int_to_signed_char((int32_t)(uint32_t)UINT8_MAX); +#elif defined(V4) + // Destination 'sign' bit set. + convert_unsigned_int_to_unsigned_int((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((uint32_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_int((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_unsigned_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((uint32_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_char((int32_t)(uint32_t)(uint8_t)INT8_MIN); +#elif defined(V5) + // All bits except the destination 'sign' bit are set. + convert_unsigned_int_to_unsigned_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_unsigned_char_to_unsigned_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_char_to_signed_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char((~((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V5: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 4294967167 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_unsigned_int((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_unsigned_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_char_to_unsigned_char((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)(uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)(uint8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((~((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_signed_char((int32_t)(~((uint32_t)(uint8_t)INT8_MIN))); +#elif defined(V6) + // Only the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MIN); + convert_signed_int_to_signed_int((int32_t)INT32_MIN); + convert_signed_char_to_signed_char((int8_t)INT8_MIN); + convert_unsigned_int_to_unsigned_char(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)); +// CHECK-V6: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483776 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 128 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MIN); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MIN); + convert_signed_char_to_signed_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_int((uint32_t)INT32_MIN); + convert_signed_int_to_unsigned_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_char_to_unsigned_char((int8_t)INT8_MIN); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MIN); + convert_signed_char_to_unsigned_int((int8_t)INT8_MIN); + convert_unsigned_int_to_signed_char((((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_signed_char((int32_t)(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +#elif defined(V7) + // All bits except the source and destination sign bits are set. + convert_unsigned_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_unsigned_char_to_unsigned_char((uint8_t)INT8_MAX); + convert_signed_int_to_signed_int((int32_t)INT32_MAX); + convert_signed_char_to_signed_char((int8_t)INT8_MAX); + convert_unsigned_int_to_unsigned_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +// CHECK-V7: {{.*}}unsigned-integer-truncation.c:500:10: runtime error: implicit conversion from type '{{.*}}' (aka 'unsigned int') of value 2147483519 (32-bit, unsigned) to type '{{.*}}' (aka 'unsigned char') changed the value to 127 (8-bit, unsigned) + convert_unsigned_char_to_unsigned_int((uint8_t)INT8_MAX); + convert_unsigned_char_to_signed_int((uint8_t)INT8_MAX); + convert_signed_char_to_signed_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_int((uint32_t)INT32_MAX); + convert_signed_int_to_unsigned_char((int32_t)(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN)))); + convert_signed_char_to_unsigned_char((int8_t)INT8_MAX); + convert_unsigned_char_to_signed_char((uint8_t)INT8_MAX); + convert_signed_char_to_unsigned_int((int8_t)INT8_MAX); + convert_unsigned_int_to_signed_char(~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); + convert_signed_int_to_signed_char((int32_t)~(((uint32_t)INT32_MIN) | ((uint32_t)(uint8_t)INT8_MIN))); +#else +#error Some V* needs to be defined! +#endif + + return 0; +} diff --git a/test/ubsan/TestCases/Integer/no-recover.cpp b/test/ubsan/TestCases/Integer/no-recover.cpp index 515ebbd0702ed..45aeb9e752411 100644 --- a/test/ubsan/TestCases/Integer/no-recover.cpp +++ b/test/ubsan/TestCases/Integer/no-recover.cpp @@ -1,7 +1,9 @@ // RUN: %clangxx -fsanitize=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER // RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=all -fsanitize-recover=unsigned-integer-overflow %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER // RUN: %env_ubsan_opts=silence_unsigned_overflow=1 %run %t 2>&1 | FileCheck %s --check-prefix=SILENT-RECOVER --allow-empty -// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=unsigned-integer-overflow %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=ABORT +// RUN: %clangxx -fsanitize=unsigned-integer-overflow -fno-sanitize-recover=unsigned-integer-overflow %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=ABORT +// RUN: %env_ubsan_opts=silence_unsigned_overflow=1 not %run %t 2>&1 | FileCheck %s --check-prefix=ABORT #include <stdint.h> diff --git a/test/ubsan/TestCases/Misc/enum.cpp b/test/ubsan/TestCases/Misc/enum.cpp index 5dbecf1612627..8e95f8b403a93 100644 --- a/test/ubsan/TestCases/Misc/enum.cpp +++ b/test/ubsan/TestCases/Misc/enum.cpp @@ -4,7 +4,7 @@ // FIXME: UBSan fails to add the correct instrumentation code for some reason on // Windows. -// XFAIL: win32 +// XFAIL: windows-msvc 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 index 40bb35a06aaf9..23ad7e27d21f8 100644 --- a/test/ubsan/TestCases/Misc/log-path_test.cc +++ b/test/ubsan/TestCases/Misc/log-path_test.cc @@ -12,16 +12,18 @@ // Good log_path. // RUN: rm -f %t.log.* +// RUN: %device_rm -f '%t.log.*' // RUN: %env_ubsan_opts=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: %device_rm -f '%t.log.*' // RUN: %env_ubsan_opts=log_path='"%t.log"' %run %t 4 // RUN: not cat %t.log.* // FIXME: log_path is not supported on Windows yet. -// XFAIL: win32 +// XFAIL: windows-msvc #include <stdio.h> #include <stdlib.h> diff --git a/test/ubsan/TestCases/Misc/monitor.cpp b/test/ubsan/TestCases/Misc/monitor.cpp index 6c5cacfed8be2..c02702847afba 100644 --- a/test/ubsan/TestCases/Misc/monitor.cpp +++ b/test/ubsan/TestCases/Misc/monitor.cpp @@ -4,7 +4,7 @@ // __ubsan_on_report is not defined as weak. Redefining it here isn't supported // on Windows. // -// UNSUPPORTED: win32 +// UNSUPPORTED: windows-msvc // Linkage issue // XFAIL: openbsd diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp new file mode 100644 index 0000000000000..97d4b4623c2da --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp @@ -0,0 +1,36 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +typedef char *__attribute__((align_value(0x8000))) aligned_char; + +struct ac_struct { + aligned_char a; +}; + +char *load_from_ac_struct(struct ac_struct *x) { + return x->a; +} + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + struct ac_struct x; + x.a = ptr + 1; // FIXME: it is weird that this does not also have an assumption. + load_from_ac_struct(&x); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:13: runtime error: assumption of 32768 byte alignment for pointer of type 'aligned_char' (aka 'char *') failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-17]]:30: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp new file mode 100644 index 0000000000000..774ba90fbe926 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp @@ -0,0 +1,30 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +char *passthrough(__attribute__((align_value(0x8000))) char *x) { + return x; +} + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + passthrough(ptr + 1); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-7]]:10: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:34: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + // FIXME: shouldn't there be an assumption on the caller's side too? + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp new file mode 100644 index 0000000000000..c71cb1e1bc7b9 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp @@ -0,0 +1,33 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +char *__attribute__((alloc_align(2))) +passthrough(char *x, unsigned long alignment) { + return x; +} + +unsigned long alignment; + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + alignment = 0x8000; + + passthrough(ptr + 1, alignment); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-14]]:22: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp new file mode 100644 index 0000000000000..db22e3a8fcff0 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp @@ -0,0 +1,29 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +char *__attribute__((alloc_align(2))) +passthrough(char *x, unsigned long alignment) { + return x; +} + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + passthrough(ptr + 1, 0x8000); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-10]]:22: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp new file mode 100644 index 0000000000000..33aa132f601be --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp @@ -0,0 +1,28 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +char *__attribute__((assume_aligned(0x8000, 1))) passthrough(char *x) { + return x; +} + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(3); + + passthrough(ptr + 2); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment (with offset of 1 byte) for pointer of type 'char *' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:22: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp new file mode 100644 index 0000000000000..202c0ce006395 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp @@ -0,0 +1,28 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +char *__attribute__((assume_aligned(0x8000))) passthrough(char *x) { + return x; +} + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + passthrough(ptr + 1); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:22: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp new file mode 100644 index 0000000000000..c0c7b373f6237 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp @@ -0,0 +1,20 @@ +// RUN: %clang -fsanitize=alignment -fno-sanitize-recover=alignment -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " + +// RUN: rm -f %tmp +// RUN: echo "[alignment]" >> %tmp +// RUN: echo "fun:main" >> %tmp +// RUN: %clang -fsanitize=alignment -fno-sanitize-recover=alignment -fsanitize-blacklist=%tmp -O0 %s -o %t && %run %t 2>&1 + +#include <stdlib.h> + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + __builtin_assume_aligned(ptr + 1, 0x8000); + // CHECK: {{.*}}alignment-assumption-blacklist.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp new file mode 100644 index 0000000000000..cc4e1f2184da7 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp @@ -0,0 +1,27 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +volatile long offset; + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(3); + + offset = 1; + + __builtin_assume_aligned(ptr + 2, 0x8000, offset); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment (with offset of 1 byte) for pointer of type 'char *' failed + // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp new file mode 100644 index 0000000000000..724abd540e78f --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp @@ -0,0 +1,23 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(3); + + __builtin_assume_aligned(ptr + 2, 0x8000, 1); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment (with offset of 1 byte) for pointer of type 'char *' failed + // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp new file mode 100644 index 0000000000000..2737f3d08b449 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp @@ -0,0 +1,23 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + __builtin_assume_aligned(ptr + 1, 0x8000); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp new file mode 100644 index 0000000000000..482316ee254ff --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp @@ -0,0 +1,28 @@ +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +#include <stdlib.h> + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + char *data = ptr + 1; + + data[0] = 0; + +#pragma omp for simd aligned(data : 0x8000) + for(int x = 0; x < 1; x++) + data[x] = data[x]; + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-3]]:30: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp new file mode 100644 index 0000000000000..cc7769a06fe5f --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp @@ -0,0 +1,17 @@ +// RUN: %clangxx -fsanitize=alignment %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE +// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE +// REQUIRES: !ubsan-standalone && !ubsan-standalone-static + +#include <stdlib.h> + +int main(int argc, char* argv[]) { + char *ptr = (char *)malloc(2); + + __builtin_assume_aligned(ptr + 1, 0x8000); + // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:32 + // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: alignment-assumption {{.*}}summary.cpp:[[@LINE-2]]:32 + free(ptr); + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/index-overflow.cpp b/test/ubsan/TestCases/Pointer/index-overflow.cpp index eb7f95e85c2ca..f9b1fea08c940 100644 --- a/test/ubsan/TestCases/Pointer/index-overflow.cpp +++ b/test/ubsan/TestCases/Pointer/index-overflow.cpp @@ -1,7 +1,7 @@ // RUN: %clangxx -fsanitize=pointer-overflow %s -o %t -// RUN: %t 1 2>&1 | FileCheck %s --check-prefix=ERR -// RUN: %t 0 2>&1 | FileCheck %s --check-prefix=SAFE -// RUN: %t -1 2>&1 | FileCheck %s --check-prefix=SAFE +// RUN: %run %t 1 2>&1 | FileCheck %s --check-prefix=ERR +// RUN: %run %t 0 2>&1 | FileCheck %s --check-prefix=SAFE +// RUN: %run %t -1 2>&1 | FileCheck %s --check-prefix=SAFE #include <stdio.h> #include <stdint.h> diff --git a/test/ubsan/TestCases/Pointer/unsigned-index-expression.cpp b/test/ubsan/TestCases/Pointer/unsigned-index-expression.cpp index 0002c713f8660..5a1432625a54c 100644 --- a/test/ubsan/TestCases/Pointer/unsigned-index-expression.cpp +++ b/test/ubsan/TestCases/Pointer/unsigned-index-expression.cpp @@ -1,5 +1,5 @@ // RUN: %clangxx -std=c++11 -fsanitize=pointer-overflow %s -o %t -// RUN: %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s int main(int argc, char *argv[]) { char c; diff --git a/test/ubsan/TestCases/TypeCheck/Function/function.cpp b/test/ubsan/TestCases/TypeCheck/Function/function.cpp index 7b9f0982639a2..31baa2af8ca9d 100644 --- a/test/ubsan/TestCases/TypeCheck/Function/function.cpp +++ b/test/ubsan/TestCases/TypeCheck/Function/function.cpp @@ -2,7 +2,7 @@ // RUN: %run %t 2>&1 | FileCheck %s // Verify that we can disable symbolization if needed: // RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM -// XFAIL: win32,win64 +// XFAIL: windows-msvc // Unsupported function flag // UNSUPPORTED: openbsd diff --git a/test/ubsan/TestCases/TypeCheck/PR33221.cpp b/test/ubsan/TestCases/TypeCheck/PR33221.cpp index 65cbf5d000d9e..6088338a3dee4 100644 --- a/test/ubsan/TestCases/TypeCheck/PR33221.cpp +++ b/test/ubsan/TestCases/TypeCheck/PR33221.cpp @@ -2,7 +2,7 @@ // RUN: %run %t 2>&1 | FileCheck %s // REQUIRES: cxxabi -// UNSUPPORTED: win32 +// UNSUPPORTED: windows-msvc #include <string.h> diff --git a/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp b/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp index f0659f4394388..fd1e7ed779a66 100644 --- a/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp +++ b/test/ubsan/TestCases/TypeCheck/vptr-corrupted-vtable-itanium.cpp @@ -1,7 +1,7 @@ // RUN: %clangxx -frtti -fsanitize=vptr -fno-sanitize-recover=vptr,null -g %s -O3 -o %t // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-CORRUPTED-VTABLE --strict-whitespace -// UNSUPPORTED: win32 +// UNSUPPORTED: windows-msvc // REQUIRES: stable-runtime, cxxabi #include <cstddef> diff --git a/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp b/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp index 7bc19bdae8fa4..13b05238610e1 100644 --- a/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp +++ b/test/ubsan/TestCases/TypeCheck/vptr-non-unique-typeinfo.cpp @@ -3,7 +3,8 @@ // RUN: %run %t // // REQUIRES: cxxabi -// UNSUPPORTED: win32 +// UNSUPPORTED: windows-msvc +// XFAIL: i386-netbsd struct X { virtual ~X() {} diff --git a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base-construction.cpp b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base-construction.cpp index a86960d12ad70..75a5d7670fb99 100644 --- a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base-construction.cpp +++ b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base-construction.cpp @@ -2,7 +2,7 @@ // RUN: %run %t // REQUIRES: cxxabi -// UNSUPPORTED: win32 +// UNSUPPORTED: windows-msvc int volatile n; diff --git a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp index aa0123c46e9cc..925373bdee1f6 100644 --- a/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp +++ b/test/ubsan/TestCases/TypeCheck/vptr-virtual-base.cpp @@ -2,7 +2,9 @@ // RUN: not %run %t 2>&1 | FileCheck %s // REQUIRES: cxxabi -// UNSUPPORTED: win32 +// UNSUPPORTED: windows-msvc +// Nested crash reported +// UNSUPPORTED: freebsd 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 9b53e80957778..67239e82d340d 100644 --- a/test/ubsan/TestCases/TypeCheck/vptr.cpp +++ b/test/ubsan/TestCases/TypeCheck/vptr.cpp @@ -37,11 +37,13 @@ // RUN: %env_ubsan_opts=halt_on_error=1:suppressions='"%t.loc-supp"' not %run %t x- 2>&1 | FileCheck %s --check-prefix=CHECK-LOC-SUPPRESS // REQUIRES: stable-runtime, cxxabi -// UNSUPPORTED: win32 +// UNSUPPORTED: windows-msvc // Suppressions file not pushed to the device. // UNSUPPORTED: android // Compilation error // UNSUPPORTED: openbsd +// Compilation error +// UNSUPPORTED: freebsd #include <new> #include <typeinfo> #include <assert.h> diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg index e20832bd655fe..9a7a8900e3427 100644 --- a/test/ubsan/lit.common.cfg +++ b/test/ubsan/lit.common.cfg @@ -74,3 +74,8 @@ if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows', 'NetBSD', 'Su config.available_features.add('arch=' + config.target_arch) config.excludes = ['Inputs'] + +# Limit parallelism if necessary +if config.host_os == 'Darwin': + if config.apple_platform != "osx" and not config.apple_platform.endswith("sim"): + config.parallelism_group = "darwin-ios-device-sanitizer" diff --git a/test/ubsan/lit.site.cfg.in b/test/ubsan/lit.site.cfg.in index a4d7b50edafc4..60c9c84e3c100 100644 --- a/test/ubsan/lit.site.cfg.in +++ b/test/ubsan/lit.site.cfg.in @@ -7,6 +7,7 @@ config.target_cflags = "@UBSAN_TEST_TARGET_CFLAGS@" config.target_arch = "@UBSAN_TEST_TARGET_ARCH@" config.use_lld = @UBSAN_TEST_USE_LLD@ config.use_thinlto = @UBSAN_TEST_USE_THINLTO@ +config.apple_platform = "@UBSAN_TEST_APPLE_PLATFORM@" # Load common config for all compiler-rt lit tests. lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") |
