diff options
Diffstat (limited to 'test')
519 files changed, 5750 insertions, 1280 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 85a1735b1cf9..b4fea075c399 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -24,6 +24,9 @@ if(NOT ANDROID) if (COMPILER_RT_HAS_PROFILE) list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS profile) endif() + if (WIN32) + list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS KillTheDoctor) + endif() endif() if(UNIX) list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS SanitizerLintCheck) @@ -58,6 +61,9 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS) add_subdirectory(ubsan) endif() add_subdirectory(cfi) + if(COMPILER_RT_HAS_SAFESTACK) + add_subdirectory(safestack) + endif() endif() if(COMPILER_RT_STANDALONE_BUILD) diff --git a/test/asan/CMakeLists.txt b/test/asan/CMakeLists.txt index e1b81264604d..aff54db1e77a 100644 --- a/test/asan/CMakeLists.txt +++ b/test/asan/CMakeLists.txt @@ -5,9 +5,9 @@ set(ASAN_DYNAMIC_TESTSUITES) macro(get_bits_for_arch arch bits) if (${arch} MATCHES "i386|i686|arm|mips|mipsel") - set(bits 32) + set(${bits} 32) elseif (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|mips64|mips64el") - set(bits 64) + set(${bits} 64) else() message(FATAL_ERROR "Unknown target architecture: ${arch}") endif() @@ -28,6 +28,7 @@ foreach(arch ${ASAN_SUPPORTED_ARCH}) set(ASAN_TEST_TARGET_CFLAGS ${COMPILER_RT_TEST_COMPILER_CFLAGS}) else() get_target_flags_for_arch(${arch} ASAN_TEST_TARGET_CFLAGS) + string(REPLACE ";" " " ASAN_TEST_TARGET_CFLAGS "${ASAN_TEST_TARGET_CFLAGS}") endif() if(ANDROID) set(ASAN_TEST_DYNAMIC True) diff --git a/test/asan/TestCases/Android/coverage-android.cc b/test/asan/TestCases/Android/coverage-android.cc index e243059fbbec..5f2631605595 100644 --- a/test/asan/TestCases/Android/coverage-android.cc +++ b/test/asan/TestCases/Android/coverage-android.cc @@ -1,15 +1,15 @@ // Test for direct coverage writing with dlopen. // Test normal exit, coverage level 1. -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%device\" %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func -DSO_DIR=\"%device\" %s -o %t // RUN: adb shell rm -rf %device/coverage-android // RUN: rm -rf %T/coverage-android // RUN: adb shell mkdir -p %device/coverage-android/direct // RUN: mkdir -p %T/coverage-android/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t // RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct // RUN: ls; pwd // RUN: cd %T/coverage-android/direct @@ -18,15 +18,15 @@ // Test sudden death, coverage level 1. -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%device\" %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func -DSO_DIR=\"%device\" %s -o %t // RUN: adb shell rm -rf %device/coverage-android-kill // RUN: rm -rf %T/coverage-android-kill // RUN: adb shell mkdir -p %device/coverage-android-kill/direct // RUN: mkdir -p %T/coverage-android-kill/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t // RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct // RUN: ls; pwd // RUN: cd %T/coverage-android-kill/direct @@ -35,15 +35,15 @@ // Test normal exit, coverage level 2. -// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%device\" %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=bb -DSO_DIR=\"%device\" %s -o %t // RUN: adb shell rm -rf %device/coverage-android // RUN: rm -rf %T/coverage-android // RUN: adb shell mkdir -p %device/coverage-android/direct // RUN: mkdir -p %T/coverage-android/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t // RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct // RUN: ls; pwd // RUN: cd %T/coverage-android/direct @@ -52,15 +52,15 @@ // Test sudden death, coverage level 2. -// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%device\" %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=bb -DSO_DIR=\"%device\" %s -o %t // RUN: adb shell rm -rf %device/coverage-android-kill // RUN: rm -rf %T/coverage-android-kill // RUN: adb shell mkdir -p %device/coverage-android-kill/direct // RUN: mkdir -p %T/coverage-android-kill/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t // RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct // RUN: ls; pwd // RUN: cd %T/coverage-android-kill/direct @@ -69,15 +69,15 @@ // Test normal exit, coverage level 3. -// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%device\" %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=edge -DSHARED %s -shared -o %T/libcoverage_android_test_1.so -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=edge -DSO_DIR=\"%device\" %s -o %t // RUN: adb shell rm -rf %device/coverage-android // RUN: rm -rf %T/coverage-android // RUN: adb shell mkdir -p %device/coverage-android/direct // RUN: mkdir -p %T/coverage-android/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android/direct:verbosity=1 %run %t // RUN: adb pull %device/coverage-android/direct %T/coverage-android/direct // RUN: ls; pwd // RUN: cd %T/coverage-android/direct @@ -86,15 +86,15 @@ // Test sudden death, coverage level 3. -// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%device\" %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=edge -DSHARED -DKILL %s -shared -o %T/libcoverage_android_test_1.so -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=edge -DSO_DIR=\"%device\" %s -o %t // RUN: adb shell rm -rf %device/coverage-android-kill // RUN: rm -rf %T/coverage-android-kill // RUN: adb shell mkdir -p %device/coverage-android-kill/direct // RUN: mkdir -p %T/coverage-android-kill/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%device/coverage-android-kill/direct:verbosity=1 not %run %t // RUN: adb pull %device/coverage-android-kill/direct %T/coverage-android-kill/direct // RUN: ls; pwd // RUN: cd %T/coverage-android-kill/direct diff --git a/test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc b/test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc new file mode 100644 index 000000000000..f6070188d8e5 --- /dev/null +++ b/test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc @@ -0,0 +1,26 @@ +// Check that when having a DYLD_ROOT_PATH set, the symbolizer still works. +// RUN: env DYLD_ROOT_PATH="/" ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 ASAN_SYMBOLIZER_PATH=$(which atos) \ +// RUN: not %run %t 2>&1 | FileCheck %s +// +// Due to a bug in atos, this only works on x86_64. +// REQUIRES: x86_64 + +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + char *x = (char*)malloc(10 * sizeof(char)); + memset(x, 0, 10); + int res = x[argc]; + free(x); + free(x + argc - 1); // BOOM + // CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0 + // CHECK: Using atos at user-specified path: + // CHECK: #0 0x{{.*}} in {{.*}}free + // CHECK: #1 0x{{.*}} in main {{.*}}atos-symbolizer.cc:[[@LINE-4]] + // CHECK: freed by thread T0 here: + // CHECK: #0 0x{{.*}} in {{.*}}free + // CHECK: #1 0x{{.*}} in main {{.*}}atos-symbolizer.cc:[[@LINE-8]] + // CHECK: allocated by thread T0 here: + // CHECK: atos-symbolizer.cc:[[@LINE-13]] + return res; +} diff --git a/test/asan/TestCases/Darwin/atos-symbolizer.cc b/test/asan/TestCases/Darwin/atos-symbolizer.cc new file mode 100644 index 000000000000..03cadf92d16a --- /dev/null +++ b/test/asan/TestCases/Darwin/atos-symbolizer.cc @@ -0,0 +1,24 @@ +// Check that the `atos` symbolizer works. + +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 ASAN_SYMBOLIZER_PATH=$(which atos) not %run %t 2>&1 | FileCheck %s + +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + char *x = (char*)malloc(10 * sizeof(char)); + memset(x, 0, 10); + int res = x[argc]; + free(x); + free(x + argc - 1); // BOOM + // CHECK: AddressSanitizer: attempting double-free{{.*}}in thread T0 + // CHECK: Using atos at user-specified path: + // CHECK: #0 0x{{.*}} in {{.*}}free + // CHECK: #1 0x{{.*}} in main {{.*}}atos-symbolizer.cc:[[@LINE-4]] + // CHECK: freed by thread T0 here: + // CHECK: #0 0x{{.*}} in {{.*}}free + // CHECK: #1 0x{{.*}} in main {{.*}}atos-symbolizer.cc:[[@LINE-8]] + // CHECK: allocated by thread T0 here: + // CHECK: atos-symbolizer.cc:[[@LINE-13]] + return res; +} diff --git a/test/asan/TestCases/Darwin/dladdr-demangling.cc b/test/asan/TestCases/Darwin/dladdr-demangling.cc new file mode 100644 index 000000000000..3d36c4f96355 --- /dev/null +++ b/test/asan/TestCases/Darwin/dladdr-demangling.cc @@ -0,0 +1,33 @@ +// In a non-forking sandbox, we fallback to dladdr(). Test that we provide +// properly demangled C++ names in that case. + +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-DLADDR + +#include <stdlib.h> + +class MyClass { + public: + int my_function(int n) { + char *x = (char*)malloc(n * sizeof(char)); + free(x); + return x[5]; + // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK-DLADDR: Using dladdr symbolizer + // CHECK-DLADDR: failed to fork external symbolizer + // CHECK: {{ #0 0x.* in MyClass::my_function\(int\)}} + // CHECK: {{freed by thread T0 here:}} + // CHECK: {{ #0 0x.* in wrap_free}} + // CHECK: {{ #1 0x.* in MyClass::my_function\(int\)}} + // CHECK: {{previously allocated by thread T0 here:}} + // CHECK: {{ #0 0x.* in wrap_malloc}} + // CHECK: {{ #1 0x.* in MyClass::my_function\(int\)}} + } +}; + +int main() { + MyClass o; + return o.my_function(10); +} diff --git a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc index 0bd4170a353c..486223473d47 100644 --- a/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc +++ b/test/asan/TestCases/Darwin/dyld_insert_libraries_reexec.cc @@ -7,11 +7,25 @@ // RUN: | sed -e 's/.*"\(.*libclang_rt.asan_osx_dynamic.dylib\)".*/\1/'` \ // RUN: %T/dyld_insert_libraries_reexec/libclang_rt.asan_osx_dynamic.dylib // RUN: %clangxx_asan %s -o %T/dyld_insert_libraries_reexec/a.out -// RUN: DYLD_INSERT_LIBRARIES=@executable_path/libclang_rt.asan_osx_dynamic.dylib \ -// RUN: ASAN_OPTIONS=verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \ + +// RUN: env DYLD_INSERT_LIBRARIES=@executable_path/libclang_rt.asan_osx_dynamic.dylib \ +// RUN: ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \ // RUN: | FileCheck %s -// RUN: ASAN_OPTIONS=verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \ -// RUN: | FileCheck --check-prefix=CHECK-NOINSERT %s + +// RUN: IS_OSX_10_11_OR_HIGHER=$([ `sw_vers -productVersion | cut -d'.' -f2` -lt 11 ]; echo $?) + +// On OS X 10.10 and lower, if the dylib is not DYLD-inserted, ASan will re-exec. +// RUN: if [ $IS_OSX_10_11_OR_HIGHER == 0 ]; then \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-NOINSERT %s; \ +// RUN: fi + +// On OS X 10.11 and higher, we don't need to DYLD-insert anymore, and the interceptors +// still installed correctly. Let's just check that things work and we don't try to re-exec. +// RUN: if [ $IS_OSX_10_11_OR_HIGHER == 1 ]; then \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %T/dyld_insert_libraries_reexec/a.out 2>&1 \ +// RUN: | FileCheck %s; \ +// RUN: fi #include <stdio.h> diff --git a/test/asan/TestCases/Darwin/empty-section.cc b/test/asan/TestCases/Darwin/empty-section.cc new file mode 100644 index 000000000000..5b006b545488 --- /dev/null +++ b/test/asan/TestCases/Darwin/empty-section.cc @@ -0,0 +1,12 @@ +// Regression test with an empty (length = 0) custom section. + +// RUN: %clangxx_asan -g -O0 %s -c -o %t.o +// RUN: %clangxx_asan -g -O0 %t.o -o %t -sectcreate mysegment mysection /dev/null +// RUN: %run %t 2>&1 | FileCheck %s + +#include <stdio.h> + +int main() { + printf("Hello, world!\n"); + // CHECK: Hello, world! +} diff --git a/test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc b/test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc deleted file mode 100644 index 028683d2fc41..000000000000 --- a/test/asan/TestCases/Darwin/interception-in-shared-lib-test.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Check that memset() call from a shared library gets intercepted. -// Please always keep this file in sync with -// ../Linux/interception-in-shared-lib-test.cc. - -// RUN: %clangxx_asan -O0 %s -DSHARED_LIB \ -// RUN: -shared -o %t-so.so \ -// RUN: -fPIC -install_name @rpath/interception-in-shared-lib-test.cc.tmp-so.so -// TODO(glider): figure out how to set rpath in a more portable way and unite -// this test with ../Linux/interception-in-shared-lib-test.cc. -// RUN: %clangxx_asan -O0 %s -o %t -Wl,-rpath,@executable_path %t-so.so && \ -// RUN: not %run %t 2>&1 | FileCheck %s - -#include <stdio.h> -#include <string.h> - -#if defined(SHARED_LIB) -extern "C" -void my_memset(void *p, size_t sz) { - memset(p, 0, sz); -} -#else -extern "C" void my_memset(void *p, size_t sz); - -int main(int argc, char *argv[]) { - char buf[10]; - my_memset(buf, 11); - // CHECK: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} - // CHECK: {{WRITE of size 11 at 0x.* thread T0}} - // CHECK: {{0x.* in my_memset .*interception-in-shared-lib-test.cc:19}} - return 0; -} -#endif diff --git a/test/asan/TestCases/Darwin/interface_symbols_darwin.c b/test/asan/TestCases/Darwin/interface_symbols_darwin.c index a75044d491fb..bd9bbee84a92 100644 --- a/test/asan/TestCases/Darwin/interface_symbols_darwin.c +++ b/test/asan/TestCases/Darwin/interface_symbols_darwin.c @@ -29,6 +29,18 @@ // RUN: echo __asan_report_store16 >> %t.interface // RUN: echo __asan_report_load_n >> %t.interface // RUN: echo __asan_report_store_n >> %t.interface +// RUN: echo __asan_report_exp_load1 >> %t.interface +// RUN: echo __asan_report_exp_load2 >> %t.interface +// RUN: echo __asan_report_exp_load4 >> %t.interface +// RUN: echo __asan_report_exp_load8 >> %t.interface +// RUN: echo __asan_report_exp_load16 >> %t.interface +// RUN: echo __asan_report_exp_store1 >> %t.interface +// RUN: echo __asan_report_exp_store2 >> %t.interface +// RUN: echo __asan_report_exp_store4 >> %t.interface +// RUN: echo __asan_report_exp_store8 >> %t.interface +// RUN: echo __asan_report_exp_store16 >> %t.interface +// RUN: echo __asan_report_exp_load_n >> %t.interface +// RUN: echo __asan_report_exp_store_n >> %t.interface // RUN: echo __asan_get_current_fake_stack >> %t.interface // RUN: echo __asan_addr_is_in_fake_stack >> %t.interface // RUN: echo __asan_mz_calloc >> %t.interface diff --git a/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc b/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc index 59ddd634b400..aa4d92b00a01 100644 --- a/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc +++ b/test/asan/TestCases/Darwin/reexec-insert-libraries-env.cc @@ -7,7 +7,7 @@ // RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib // FIXME: the following command line may hang in the case of a regression. -// RUN: DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \ +// RUN: env DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \ // RUN: %run %t 2>&1 | FileCheck %s || exit 1 #if !defined(SHARED_LIB) diff --git a/test/asan/TestCases/Darwin/sandbox-symbolizer.cc b/test/asan/TestCases/Darwin/sandbox-symbolizer.cc new file mode 100644 index 000000000000..4310f9c599e3 --- /dev/null +++ b/test/asan/TestCases/Darwin/sandbox-symbolizer.cc @@ -0,0 +1,29 @@ +// In a non-forking sandbox, we can't spawn an external symbolizer, but dladdr() +// should still work and provide function names. No line numbers though. +// Second, `atos` symbolizer can't inspect a process that has an inaccessible +// task port, in which case we should again fallback to dladdr gracefully. + +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s +// RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s +// RUN: env ASAN_SYMBOLIZER_PATH="" not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -o %t +// RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny process-fork)' %t 2>&1 | FileCheck %s +// RUN: not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s +// RUN: env ASAN_SYMBOLIZER_PATH="" not %run sandbox-exec -p '(version 1)(allow default)(deny mach-priv-task-port)' %t 2>&1 | FileCheck %s + +#include <stdlib.h> +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return x[5]; + // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK: {{READ of size 1 at 0x.* thread T0}} + // CHECK: {{ #0 0x.* in main}} + // CHECK: {{freed by thread T0 here:}} + // CHECK: {{ #0 0x.* in wrap_free}} + // CHECK: {{ #1 0x.* in main}} + // CHECK: {{previously allocated by thread T0 here:}} + // CHECK: {{ #0 0x.* in wrap_malloc}} + // CHECK: {{ #1 0x.* in main}} +} diff --git a/test/asan/TestCases/Darwin/suppressions-darwin.cc b/test/asan/TestCases/Darwin/suppressions-darwin.cc index fb37296d404f..488bff140225 100644 --- a/test/asan/TestCases/Darwin/suppressions-darwin.cc +++ b/test/asan/TestCases/Darwin/suppressions-darwin.cc @@ -4,17 +4,17 @@ // Check that suppressing the interceptor by name works. // RUN: echo "interceptor_name:memmove" > %t.supp -// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s // Check that suppressing by interceptor name works even without the symbolizer -// RUN: ASAN_OPTIONS="suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s // Check that suppressing all reports from a library works. // RUN: echo "interceptor_via_lib:CoreFoundation" > %t.supp -// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s // Check that suppressing library works even without the symbolizer. -// RUN: ASAN_OPTIONS="suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp':symbolize=false" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s #include <CoreFoundation/CoreFoundation.h> diff --git a/test/asan/TestCases/Darwin/suppressions-sandbox.cc b/test/asan/TestCases/Darwin/suppressions-sandbox.cc new file mode 100644 index 000000000000..47d80f80db2b --- /dev/null +++ b/test/asan/TestCases/Darwin/suppressions-sandbox.cc @@ -0,0 +1,26 @@ +// Check that without suppressions, we catch the issue. +// RUN: %clangxx_asan -O0 %s -o %t -framework Foundation +// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s + +// Check that suppressing a function name works within a no-fork sandbox +// RUN: echo "interceptor_via_fun:CFStringCreateWithBytes" > %t.supp +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:suppressions=%t.supp \ +// RUN: sandbox-exec -p '(version 1)(allow default)(deny process-fork)' \ +// RUN: %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s + +#include <CoreFoundation/CoreFoundation.h> + +int main() { + char *a = (char *)malloc(6); + strcpy(a, "hello"); + CFStringRef str = + CFStringCreateWithBytes(kCFAllocatorDefault, (unsigned char *)a, 10, + kCFStringEncodingUTF8, FALSE); // BOOM + fprintf(stderr, "Ignored.\n"); + free(a); +} + +// CHECK-CRASH: AddressSanitizer: heap-buffer-overflow +// CHECK-CRASH-NOT: Ignored. +// CHECK-IGNORE-NOT: AddressSanitizer: heap-buffer-overflow +// CHECK-IGNORE: Ignored. diff --git a/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc b/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc index ed476b223af3..f8a330ad5fe0 100644 --- a/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc +++ b/test/asan/TestCases/Darwin/unset-insert-libraries-on-exec.cc @@ -10,7 +10,7 @@ // execl(). // RUN: %run %t %T/echo-env >/dev/null 2>&1 -// RUN: DYLD_INSERT_LIBRARIES=%t-darwin-dummy-shared-lib-so.dylib \ +// RUN: env DYLD_INSERT_LIBRARIES=%t-darwin-dummy-shared-lib-so.dylib \ // RUN: %run %t %T/echo-env 2>&1 | FileCheck %s || exit 1 #if !defined(SHARED_LIB) diff --git a/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc b/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc index d4606f0afb52..54f26f16724c 100644 --- a/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc +++ b/test/asan/TestCases/Helpers/init-order-pthread-create-extra.cc @@ -1,2 +1,2 @@ -void *bar(void *input); -void *glob2 = bar((void*)0x2345); +void *bar(void *input, bool sleep_before_init); +void *glob2 = bar((void*)0x2345, true); diff --git a/test/asan/TestCases/Linux/asan_default_suppressions.cc b/test/asan/TestCases/Linux/asan_default_suppressions.cc new file mode 100644 index 000000000000..5ff59c1dfe7f --- /dev/null +++ b/test/asan/TestCases/Linux/asan_default_suppressions.cc @@ -0,0 +1,7 @@ +// Test that we use the suppressions from __asan_default_suppressions. +// RUN: %clangxx_asan %s -o %t && not %run %t 2>&1 | FileCheck %s +extern "C" { + const char *__asan_default_suppressions() { return "FooBar"; } +} +// CHECK: AddressSanitizer: failed to parse suppressions +int main() {} diff --git a/test/asan/TestCases/Linux/asan_prelink_test.cc b/test/asan/TestCases/Linux/asan_prelink_test.cc index 6145c01f7342..9e58f83d40c6 100644 --- a/test/asan/TestCases/Linux/asan_prelink_test.cc +++ b/test/asan/TestCases/Linux/asan_prelink_test.cc @@ -7,7 +7,7 @@ // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext-segment=0x3600000000 ||\ // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -Wl,-Ttext=0x3600000000 // RUN: %clangxx_asan %t.o %t.so -Wl,-R. -o %t -// RUN: ASAN_OPTIONS=verbosity=1 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %t 2>&1 | FileCheck %s // GNU driver doesn't handle .so files properly. // REQUIRES: x86_64-supported-target, asan-64-bits, Clang diff --git a/test/asan/TestCases/Linux/asan_preload_test-1.cc b/test/asan/TestCases/Linux/asan_preload_test-1.cc index e5eab5545b83..4e365b5633f3 100644 --- a/test/asan/TestCases/Linux/asan_preload_test-1.cc +++ b/test/asan/TestCases/Linux/asan_preload_test-1.cc @@ -5,7 +5,7 @@ // RUN: %clangxx %s %t.so -o %t // // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so -// RUN: LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s +// RUN: env LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s // REQUIRES: asan-dynamic-runtime diff --git a/test/asan/TestCases/Linux/asan_preload_test-2.cc b/test/asan/TestCases/Linux/asan_preload_test-2.cc index 0f22264cf1fb..488fd52e682a 100644 --- a/test/asan/TestCases/Linux/asan_preload_test-2.cc +++ b/test/asan/TestCases/Linux/asan_preload_test-2.cc @@ -1,7 +1,7 @@ // Test that preloaded runtime works with unsanitized executables. // // RUN: %clangxx %s -o %t -// RUN: LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s +// RUN: env LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s // REQUIRES: asan-dynamic-runtime diff --git a/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc b/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc index 30f1c17700c8..8cf761c905f8 100644 --- a/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc +++ b/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc @@ -2,7 +2,7 @@ // executable is prohibited. // // RUN: %clangxx_asan_static %s -o %t -// RUN: LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s +// RUN: env LD_PRELOAD=%shared_libasan not %run %t 2>&1 | FileCheck %s // REQUIRES: asan-dynamic-runtime // XFAIL: android diff --git a/test/asan/TestCases/Linux/clang_gcc_abi.cc b/test/asan/TestCases/Linux/clang_gcc_abi.cc index e833881661d2..669d1524077c 100644 --- a/test/asan/TestCases/Linux/clang_gcc_abi.cc +++ b/test/asan/TestCases/Linux/clang_gcc_abi.cc @@ -8,9 +8,10 @@ #include <stdlib.h> +__attribute__((noinline)) int boom() { volatile int three = 3; - char *s = (char *)malloc(three); + char * volatile s = (char *)malloc(three); // CHECK: #1 0x{{.*}} in boom {{.*}}clang_gcc_abi.cc:[[@LINE-1]] return s[three]; //BOOM } diff --git a/test/asan/TestCases/Linux/coverage-levels.cc b/test/asan/TestCases/Linux/coverage-levels.cc deleted file mode 100644 index cc196c5a9e18..000000000000 --- a/test/asan/TestCases/Linux/coverage-levels.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Test various levels of coverage -// -// RUN: %clangxx_asan -O1 -fsanitize-coverage=1 %s -o %t -// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 -// RUN: %clangxx_asan -O1 -fsanitize-coverage=2 %s -o %t -// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 -// RUN: %clangxx_asan -O1 -fsanitize-coverage=3 %s -o %t -// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 - -// RUN: ASAN_OPTIONS=coverage=1:coverage_bitset=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET -// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET -// RUN: ASAN_OPTIONS=coverage=1:coverage_pcs=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOPCS -// -// REQUIRES: asan-64-bits - -volatile int sink; -int main(int argc, char **argv) { - if (argc == 0) - sink = 0; -} - -// CHECK1: CovDump: bitset of 1 bits written, 1 bits are set -// CHECK1: 1 PCs written -// CHECK2: CovDump: bitset of 3 bits written, 2 bits are set -// CHECK2: 2 PCs written -// CHECK3: CovDump: bitset of 4 bits written, 3 bits are set -// CHECK3: 3 PCs written -// CHECK3_NOBITSET-NOT: bitset of -// CHECK3_NOPCS-NOT: PCs written diff --git a/test/asan/TestCases/Linux/coverage-missing.cc b/test/asan/TestCases/Linux/coverage-missing.cc new file mode 100644 index 000000000000..36f33b505e27 --- /dev/null +++ b/test/asan/TestCases/Linux/coverage-missing.cc @@ -0,0 +1,84 @@ +// Test for "sancov.py missing ...". + +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_dir=%T/coverage-missing + +// First case: coverage from executable. main() is called on every code path. +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t -DFOOBAR -DMAIN +// RUN: rm -rf %T/coverage-missing +// RUN: mkdir -p %T/coverage-missing +// RUN: cd %T/coverage-missing +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t +// RUN: %sancov print *.sancov > main.txt +// RUN: rm *.sancov +// RUN: [ $(cat main.txt | wc -l) == 1 ] +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x +// RUN: %sancov print *.sancov > foo.txt +// RUN: rm *.sancov +// RUN: [ $(cat foo.txt | wc -l) == 3 ] +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x x +// RUN: %sancov print *.sancov > bar.txt +// RUN: rm *.sancov +// RUN: [ $(cat bar.txt | wc -l) == 4 ] +// RUN: %sancov missing %t < foo.txt > foo-missing.txt +// RUN: sort main.txt foo-missing.txt -o foo-missing-with-main.txt +// The "missing from foo" set may contain a few bogus PCs from the sanitizer +// runtime, but it must include the entire "bar" code path as a subset. Sorted +// lists can be tested for set inclusion with diff + grep. +// RUN: ( diff bar.txt foo-missing-with-main.txt || true ) | not grep "^<" + +// Second case: coverage from DSO. +// cd %T +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %dynamiclib -DFOOBAR -shared -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func %s %dynamiclib -o %t -DMAIN +// RUN: export LIBNAME=`basename %dynamiclib` +// RUN: rm -rf %T/coverage-missing +// RUN: mkdir -p %T/coverage-missing +// RUN: cd %T/coverage-missing +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x +// RUN: %sancov print $LIBNAME.*.sancov > foo.txt +// RUN: rm *.sancov +// RUN: [ $(cat foo.txt | wc -l) == 2 ] +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS %t x x +// RUN: %sancov print $LIBNAME.*.sancov > bar.txt +// RUN: rm *.sancov +// RUN: [ $(cat bar.txt | wc -l) == 3 ] +// RUN: %sancov missing %dynamiclib < foo.txt > foo-missing.txt +// RUN: ( diff bar.txt foo-missing.txt || true ) | not grep "^<" + +// REQUIRES: x86_64-supported-target, i386-supported-target +// XFAIL: android + +#include <stdio.h> + +void foo1(); +void foo2(); +void bar1(); +void bar2(); +void bar3(); + +#if defined(FOOBAR) +void foo1() { fprintf(stderr, "foo1\n"); } +void foo2() { fprintf(stderr, "foo2\n"); } + +void bar1() { fprintf(stderr, "bar1\n"); } +void bar2() { fprintf(stderr, "bar2\n"); } +void bar3() { fprintf(stderr, "bar3\n"); } +#endif + +#if defined(MAIN) +int main(int argc, char **argv) { + switch (argc) { + case 1: + break; + case 2: + foo1(); + foo2(); + break; + case 3: + bar1(); + bar2(); + bar3(); + break; + } +} +#endif diff --git a/test/asan/TestCases/Linux/coverage-tracing.cc b/test/asan/TestCases/Linux/coverage-tracing.cc deleted file mode 100644 index 49dbb5e9528b..000000000000 --- a/test/asan/TestCases/Linux/coverage-tracing.cc +++ /dev/null @@ -1,50 +0,0 @@ -// Test -mllvm -sanitizer-coverage-experimental-tracing -// -// RUN: %clangxx_asan -O1 -fsanitize-coverage=1 -mllvm -sanitizer-coverage-experimental-tracing %s -o %t -// RUN: rm -rf %T/coverage-tracing -// RUN: mkdir %T/coverage-tracing -// RUN: cd %T/coverage-tracing -// RUN: A=x; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1; mv trace-points.*.sancov $A.points -// RUN: A=f; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points -// RUN: A=b; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points -// RUN: A=bf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points -// RUN: A=fb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points -// RUN: A=ffb; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points -// RUN: A=fff; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points -// RUN: A=bbf; ASAN_OPTIONS=coverage=1:verbosity=1 %run %t $A 100 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK301; mv trace-points.*.sancov $A.points -// RUN: diff f.points fff.points -// RUN: diff bf.points fb.points -// RUN: diff bf.points ffb.points -// RUN: diff bf.points bbf.points -// RUN: not diff x.points f.points -// RUN: not diff x.points b.points -// RUN: not diff x.points bf.points -// RUN: not diff f.points b.points -// RUN: not diff f.points bf.points -// RUN: not diff b.points bf.points -// RUN: rm -rf %T/coverage-tracing -// -// REQUIRES: asan-64-bits - -#include <stdlib.h> -volatile int sink; -__attribute__((noinline)) void foo() { sink++; } -__attribute__((noinline)) void bar() { sink++; } - -int main(int argc, char **argv) { - if (argc != 3) return 0; - int n = strtol(argv[2], 0, 10); - while (n-- > 0) { - for (int i = 0; argv[1][i]; i++) { - if (argv[1][i] == 'f') foo(); - else if (argv[1][i] == 'b') bar(); - } - } -} - -// CHECK: CovDump: Trace: 3 PCs written -// CHECK1: CovDump: Trace: 1 Events written -// CHECK2: CovDump: Trace: 2 Events written -// CHECK3: CovDump: Trace: 3 Events written -// CHECK4: CovDump: Trace: 4 Events written -// CHECK301: CovDump: Trace: 301 Events written diff --git a/test/asan/TestCases/Linux/init-order-dlopen.cc b/test/asan/TestCases/Linux/init-order-dlopen.cc new file mode 100644 index 000000000000..fcfb5d143df6 --- /dev/null +++ b/test/asan/TestCases/Linux/init-order-dlopen.cc @@ -0,0 +1,47 @@ +// Regression test for +// https://code.google.com/p/address-sanitizer/issues/detail?id=178 + +// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so +// RUN: %clangxx_asan -O0 %s %libdl -Wl,--export-dynamic -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true %run %t 2>&1 + +// dlopen() can not be intercepted on Android, making strict_init_order nearly +// useless there. +// UNSUPPORTED: android + +#if defined(SHARED_LIB) +#include <stdio.h> + +struct Bar { + Bar(int val) : val(val) { printf("Bar::Bar(%d)\n", val); } + int val; +}; + +int get_foo_val(); +Bar global_bar(get_foo_val()); +#else // SHARED LIB +#include <dlfcn.h> +#include <stdio.h> +#include <string> +struct Foo { + Foo() : val(42) { printf("Foo::Foo()\n"); } + int val; +}; + +Foo global_foo; + +int get_foo_val() { + return global_foo.val; +} + +int main(int argc, char *argv[]) { + std::string path = std::string(argv[0]) + "-so.so"; + void *handle = dlopen(path.c_str(), RTLD_NOW); + if (!handle) { + printf("error in dlopen(): %s\n", dlerror()); + return 1; + } + printf("%d\n", get_foo_val()); + return 0; +} +#endif // SHARED_LIB diff --git a/test/asan/TestCases/Linux/initialization-bug-any-order.cc b/test/asan/TestCases/Linux/initialization-bug-any-order.cc index a462f4a163f1..0f2fccae79bb 100644 --- a/test/asan/TestCases/Linux/initialization-bug-any-order.cc +++ b/test/asan/TestCases/Linux/initialization-bug-any-order.cc @@ -4,9 +4,9 @@ // strict init-order checking). // RUN: %clangxx_asan -O0 %s %p/../Helpers/initialization-bug-extra.cc -o %t -// RUN: ASAN_OPTIONS=strict_init_order=true not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O0 %p/../Helpers/initialization-bug-extra.cc %s -o %t -// RUN: ASAN_OPTIONS=strict_init_order=true not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true not %run %t 2>&1 | FileCheck %s // Do not test with optimization -- the error may be optimized away. diff --git a/test/asan/TestCases/Linux/interface_symbols_linux.c b/test/asan/TestCases/Linux/interface_symbols_linux.c index a616732ff9f8..9e876799d384 100644 --- a/test/asan/TestCases/Linux/interface_symbols_linux.c +++ b/test/asan/TestCases/Linux/interface_symbols_linux.c @@ -24,8 +24,22 @@ // RUN: echo __asan_report_store16 >> %t.interface // RUN: echo __asan_report_load_n >> %t.interface // RUN: echo __asan_report_store_n >> %t.interface +// RUN: echo __asan_report_exp_load1 >> %t.interface +// RUN: echo __asan_report_exp_load2 >> %t.interface +// RUN: echo __asan_report_exp_load4 >> %t.interface +// RUN: echo __asan_report_exp_load8 >> %t.interface +// RUN: echo __asan_report_exp_load16 >> %t.interface +// RUN: echo __asan_report_exp_store1 >> %t.interface +// RUN: echo __asan_report_exp_store2 >> %t.interface +// RUN: echo __asan_report_exp_store4 >> %t.interface +// RUN: echo __asan_report_exp_store8 >> %t.interface +// RUN: echo __asan_report_exp_store16 >> %t.interface +// RUN: echo __asan_report_exp_load_n >> %t.interface +// RUN: echo __asan_report_exp_store_n >> %t.interface // RUN: echo __asan_get_current_fake_stack >> %t.interface // RUN: echo __asan_addr_is_in_fake_stack >> %t.interface +// RUN: echo __asan_alloca_poison >> %t.interface +// RUN: echo __asan_allocas_unpoison >> %t.interface // RUN: cat %t.interface | sort -u | diff %t.symbols - // FIXME: nm -D on powerpc somewhy shows ASan interface symbols residing diff --git a/test/asan/TestCases/Linux/kernel-area.cc b/test/asan/TestCases/Linux/kernel-area.cc index 8dd509f84975..8d3f7d6f8e88 100644 --- a/test/asan/TestCases/Linux/kernel-area.cc +++ b/test/asan/TestCases/Linux/kernel-area.cc @@ -4,19 +4,19 @@ // Test that kernel area is not sanitized on 32-bit machines. // // RUN: %clangxx_asan %s -o %t -// RUN: ASAN_OPTIONS=verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits -// RUN: ASAN_OPTIONS=verbosity=1:full_address_space=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits -// RUN: ASAN_OPTIONS=verbosity=1:full_address_space=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-kernel-64-bits +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1:full_address_space=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%kernel_bits +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1:full_address_space=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-kernel-64-bits // -// CHECK-kernel-32-bits: || `[0x38000000, 0xbfffffff]` || HighMem || -// CHECK-kernel-32-bits: || `[0x27000000, 0x37ffffff]` || HighShadow || -// CHECK-kernel-32-bits: || `[0x24000000, 0x26ffffff]` || ShadowGap || +// CHECK-kernel-32-bits: || `[0x38{{0+}}, 0xb{{f+}}]` || HighMem || +// CHECK-kernel-32-bits: || `[0x27{{0+}}, 0x37{{f+}}]` || HighShadow || +// CHECK-kernel-32-bits: || `[0x24{{0+}}, 0x26{{f+}}]` || ShadowGap || // -// CHECK-kernel-64-bits: || `[0x40000000, 0xffffffff]` || HighMem || -// CHECK-kernel-64-bits: || `[0x28000000, 0x3fffffff]` || HighShadow || -// CHECK-kernel-64-bits: || `[0x24000000, 0x27ffffff]` || ShadowGap || +// CHECK-kernel-64-bits: || `[0x4{{0+}}, 0x{{f+}}]` || HighMem || +// CHECK-kernel-64-bits: || `[0x28{{0+}}, 0x3{{f+}}]` || HighShadow || +// CHECK-kernel-64-bits: || `[0x24{{0+}}, 0x27{{f+}}]` || ShadowGap || // -// REQUIRES: asan-32-bits +// REQUIRES: asan-32-bits,i386-supported-target int main() { return 0; diff --git a/test/asan/TestCases/Linux/leak.cc b/test/asan/TestCases/Linux/leak.cc index 36dc6ddb8adf..15c03b45e4c9 100644 --- a/test/asan/TestCases/Linux/leak.cc +++ b/test/asan/TestCases/Linux/leak.cc @@ -2,9 +2,9 @@ // REQUIRES: leak-detection // // RUN: %clangxx_asan %s -o %t -// RUN: ASAN_OPTIONS=detect_leaks=1 not %run %t 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS="" not %run %t 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=detect_leaks=0 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_leaks=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_leaks=0 %run %t #include <stdio.h> int *t; diff --git a/test/asan/TestCases/Linux/leak_check_segv.cc b/test/asan/TestCases/Linux/leak_check_segv.cc new file mode 100644 index 000000000000..8160d5fe56bb --- /dev/null +++ b/test/asan/TestCases/Linux/leak_check_segv.cc @@ -0,0 +1,23 @@ +// Test that SIGSEGV during leak checking does not crash the process. +// RUN: %clangxx_asan -O1 %s -o %t && LSAN_OPTIONS="verbosity=1" not %run %t 2>&1 +// REQUIRES: leak-detection +#include <stdlib.h> +#include <stdio.h> +#include <sys/mman.h> +#include <sanitizer/lsan_interface.h> + +char data[10 * 1024 * 1024]; + +int main() { + void *p = malloc(10 * 1024 * 1024); + // surprise-surprise! + mprotect((void*)(((unsigned long)p + 4095) & ~4095), 16 * 1024, PROT_NONE); + mprotect((void*)(((unsigned long)data + 4095) & ~4095), 16 * 1024, PROT_NONE); + __lsan_do_leak_check(); + fprintf(stderr, "DONE\n"); +} + +// CHECK: Tracer caught signal 11 +// CHECK: LeakSanitizer has encountered a fatal error +// CHECK-NOT: DONE + diff --git a/test/asan/TestCases/Linux/malloc-in-qsort.cc b/test/asan/TestCases/Linux/malloc-in-qsort.cc index 80af409d66a9..f7c7c5fe3df7 100644 --- a/test/asan/TestCases/Linux/malloc-in-qsort.cc +++ b/test/asan/TestCases/Linux/malloc-in-qsort.cc @@ -1,6 +1,6 @@ // RUN: %clangxx_asan -O2 %s -o %t -// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST -// RUN: ASAN_OPTIONS=fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW // Test how well we unwind in presence of qsort in the stack // (i.e. if we can unwind through a function compiled w/o frame pointers). diff --git a/test/asan/TestCases/Linux/malloc_delete_mismatch.cc b/test/asan/TestCases/Linux/malloc_delete_mismatch.cc index 18d65ce0008f..33d0ede15f3c 100644 --- a/test/asan/TestCases/Linux/malloc_delete_mismatch.cc +++ b/test/asan/TestCases/Linux/malloc_delete_mismatch.cc @@ -4,14 +4,14 @@ // RUN: %clangxx_asan -g %s -o %t 2>&1 // Find error and provide malloc context. -// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALLOC-STACK +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=ALLOC-STACK // No error here. -// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=0 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=0 %run %t // Also works if no malloc context is available. -// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:alloc_dealloc_mismatch=1:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s // XFAIL: arm-linux-gnueabi // XFAIL: armv7l-unknown-linux-gnueabihf #include <stdlib.h> diff --git a/test/asan/TestCases/Linux/nohugepage_test.cc b/test/asan/TestCases/Linux/nohugepage_test.cc index b549f3bc2119..aeb70c94ec99 100644 --- a/test/asan/TestCases/Linux/nohugepage_test.cc +++ b/test/asan/TestCases/Linux/nohugepage_test.cc @@ -3,8 +3,8 @@ // where asan consumed too much RAM due to transparent hugetables. // // RUN: %clangxx_asan -g %s -o %t -// RUN: ASAN_OPTIONS=no_huge_pages_for_shadow=1 %run %t 2>&1 | FileCheck %s -// RUN: %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:no_huge_pages_for_shadow=1 %run %t 2>&1 | FileCheck %s +// RUN: %run %t 2>&1 | FileCheck %s // // Would be great to run the test with no_huge_pages_for_shadow=0, but // the result will depend on the OS version and settings... @@ -22,15 +22,31 @@ #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> +#include <errno.h> #include <sanitizer/asan_interface.h> -char FileContents[1 << 14]; +char FileContents[1 << 16]; void FileToString(const char *path) { FileContents[0] = 0; int fd = open(path, 0); if (fd < 0) return; - ssize_t res = read(fd, FileContents, sizeof(FileContents) - 1); + char *p = FileContents; + ssize_t size = sizeof(FileContents) - 1; + ssize_t res = 0; + do { + ssize_t got = read (fd, p, size); + if (got == 0) + break; + else if (got > 0) + { + p += got; + res += got; + size -= got; + } + else if (errno != EINTR) + break; + } while (size > 0 && res < sizeof(FileContents)); if (res >= 0) FileContents[res] = 0; } diff --git a/test/asan/TestCases/Linux/odr-violation.cc b/test/asan/TestCases/Linux/odr-violation.cc index ddc68a2db0f1..e9311d16bd5f 100644 --- a/test/asan/TestCases/Linux/odr-violation.cc +++ b/test/asan/TestCases/Linux/odr-violation.cc @@ -1,19 +1,27 @@ // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 // XFAIL: android // +// We use fast_unwind_on_malloc=0 to have full unwinding even w/o frame +// pointers. This setting is not on by default because it's too expensive. +// // Different size: detect a bug if detect_odr_violation>=1 // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so // RUN: %clangxx_asan %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE -// RUN: ASAN_OPTIONS=detect_odr_violation=1 not %run %t-ODR-EXE 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=detect_odr_violation=0 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED -// RUN: not %run %t-ODR-EXE 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=1 not %run %t-ODR-EXE 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=0 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s // // Same size: report a bug only if detect_odr_violation>=2. // RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so -DSZ=100 -// RUN: ASAN_OPTIONS=detect_odr_violation=1 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED -// RUN: ASAN_OPTIONS=detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s -// RUN: not %run %t-ODR-EXE 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=1 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s +// RUN: echo "odr_violation:foo::ZZZ" > %t.supp +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2:suppressions=%t.supp not %run %t-ODR-EXE 2>&1 | FileCheck %s +// RUN: echo "odr_violation:foo::G" > %t.supp +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_malloc=0:detect_odr_violation=2:suppressions=%t.supp %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED +// RUN: rm -f %t.supp // GNU driver doesn't handle .so files properly. // REQUIRES: Clang diff --git a/test/asan/TestCases/Linux/overflow-in-qsort.cc b/test/asan/TestCases/Linux/overflow-in-qsort.cc index 21bdff60cd30..26fe67d60729 100644 --- a/test/asan/TestCases/Linux/overflow-in-qsort.cc +++ b/test/asan/TestCases/Linux/overflow-in-qsort.cc @@ -1,6 +1,6 @@ // RUN: %clangxx_asan -O2 %s -o %t -// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST -// RUN: ASAN_OPTIONS=fast_unwind_on_fatal=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_fatal=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FAST +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:fast_unwind_on_fatal=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SLOW // Test how well we unwind in presence of qsort in the stack // (i.e. if we can unwind through a function compiled w/o frame pointers). diff --git a/test/asan/TestCases/Linux/ptrace.cc b/test/asan/TestCases/Linux/ptrace.cc index 7e5acb64c7a1..6840ebe28bfd 100644 --- a/test/asan/TestCases/Linux/ptrace.cc +++ b/test/asan/TestCases/Linux/ptrace.cc @@ -31,8 +31,8 @@ int main(void) { // CHECK: AddressSanitizer: stack-buffer-overflow // CHECK: {{.*ptrace.cc:}}[[@LINE-2]] assert(!res); -#if __WORDSIZE == 64 - printf("%zx\n", regs.rip); +#ifdef __x86_64__ + printf("%lx\n", (unsigned long)regs.rip); #else printf("%lx\n", regs.eip); #endif @@ -42,7 +42,7 @@ int main(void) { assert(!res); printf("%lx\n", (unsigned long)fpregs.cwd); -#if __WORDSIZE == 32 +#ifndef __x86_64__ user_fpxregs_struct fpxregs; res = ptrace(PTRACE_GETFPXREGS, pid, NULL, &fpxregs); assert(!res); diff --git a/test/asan/TestCases/Linux/quarantine_size_mb.cc b/test/asan/TestCases/Linux/quarantine_size_mb.cc index 4499992444f9..1820cb90c4ef 100644 --- a/test/asan/TestCases/Linux/quarantine_size_mb.cc +++ b/test/asan/TestCases/Linux/quarantine_size_mb.cc @@ -1,10 +1,10 @@ // Test quarantine_size_mb (and the deprecated quarantine_size) // RUN: %clangxx_asan %s -o %t -// RUN: ASAN_OPTIONS=quarantine_size=10485760:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10 -// RUN: ASAN_OPTIONS=quarantine_size_mb=10:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10 -// RUN: ASAN_OPTIONS=quarantine_size_mb=10:quarantine_size=20:verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=BOTH -// RUN: ASAN_OPTIONS=quarantine_size_mb=1000:hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT -// RUN: ASAN_OPTIONS=hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size=10485760:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=10:verbosity=1:hard_rss_limit_mb=50 %run %t 2>&1 | FileCheck %s --check-prefix=Q10 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=10:quarantine_size=20:verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=BOTH +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=1000:hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:hard_rss_limit_mb=50 not %run %t 2>&1 | FileCheck %s --check-prefix=RSS_LIMIT #include <string.h> char *g; diff --git a/test/asan/TestCases/Linux/read_binary_name_regtest.c b/test/asan/TestCases/Linux/read_binary_name_regtest.c new file mode 100644 index 000000000000..0e408d0e366d --- /dev/null +++ b/test/asan/TestCases/Linux/read_binary_name_regtest.c @@ -0,0 +1,50 @@ +// Regression test for https://crbug.com/502974, where ASan was unable to read +// the binary name because of sandbox restrictions. +// This test uses seccomp-BPF to restrict the readlink() system call and makes +// sure ASan is still able to +// RUN: not ls /usr/include/linux/seccomp.h || ( %clang_asan %s -o %t && not %run %t 2>&1 | FileCheck %s ) +// UNSUPPORTED: android + +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/prctl.h> +#include <sys/syscall.h> +#include <linux/filter.h> +#include <linux/seccomp.h> + +#define syscall_nr (offsetof(struct seccomp_data, nr)) + +void corrupt() { + void *p = malloc(10); + free(p); + free(p); +} + +int main() { + prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); + + struct sock_filter filter[] = { + /* Grab the system call number */ + BPF_STMT(BPF_LD + BPF_W + BPF_ABS, syscall_nr), + // If this is __NR_readlink, + BPF_JUMP(BPF_JMP + BPF_JEQ + BPF_K, __NR_readlink, 0, 1), + // return with EPERM, + BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ERRNO | EPERM), + // otherwise allow the syscall. + BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_ALLOW) + }; + struct sock_fprog prog; + prog.len = (unsigned short)(sizeof(filter)/sizeof(filter[0])); + prog.filter = filter; + + int res = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog, 0, 0); + if (res != 0) { + fprintf(stderr, "PR_SET_SECCOMP unsupported!\n"); + } + corrupt(); + // CHECK: AddressSanitizer + // CHECK-NOT: reading executable name failed + return 0; +} diff --git a/test/asan/TestCases/Linux/signal_during_stop_the_world.cc b/test/asan/TestCases/Linux/signal_during_stop_the_world.cc new file mode 100644 index 000000000000..b1a41fe20c05 --- /dev/null +++ b/test/asan/TestCases/Linux/signal_during_stop_the_world.cc @@ -0,0 +1,60 @@ +// Test StopTheWorld behavior during signal storm. +// Historically StopTheWorld crashed because did not handle EINTR properly. +// The test is somewhat convoluted, but that's what caused crashes previously. + +// RUN: %clangxx_asan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/prctl.h> +#include <sys/wait.h> +#include <time.h> +#include <pthread.h> +#include <sanitizer/lsan_interface.h> + +static void handler(int signo); +static void *thr(void *arg); + +int main() { + struct sigaction act = {}; + act.sa_handler = handler; + sigaction(SIGPROF, &act, 0); + + pid_t pid = fork(); + if (pid < 0) { + fprintf(stderr, "failed to fork\n"); + exit(1); + } + if (pid == 0) { + // Child constantly sends signals to parent to cause spurious return from + // waitpid in StopTheWorld. + prctl(PR_SET_PDEATHSIG, SIGTERM, 0, 0, 0); + pid_t parent = getppid(); + for (;;) { + // There is no strong reason for these two particular signals, + // but at least one of them ought to unblock waitpid. + kill(parent, SIGCHLD); + kill(parent, SIGPROF); + } + } + usleep(10000); // Let the child start. + __lsan_do_leak_check(); + // Kill and join the child. + kill(pid, SIGTERM); + waitpid(pid, 0, 0); + sleep(1); // If the tracer thread still runs, give it time to crash. + fprintf(stderr, "DONE\n"); +// CHECK: DONE +} + +static void handler(int signo) { +} + +static void *thr(void *arg) { + for (;;) + sleep(1); + return 0; +} diff --git a/test/asan/TestCases/Linux/sized_delete_test.cc b/test/asan/TestCases/Linux/sized_delete_test.cc index 343cb0a86fed..1146b8239d8c 100644 --- a/test/asan/TestCases/Linux/sized_delete_test.cc +++ b/test/asan/TestCases/Linux/sized_delete_test.cc @@ -1,14 +1,10 @@ -// RUN: %clangxx_asan -Xclang -fsized-deallocation -O0 %s -o %t -// RUN: not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR -// RUN: ASAN_OPTIONS=new_delete_type_mismatch=1 not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR -// RUN: not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY -// RUN: ASAN_OPTIONS=new_delete_type_mismatch=1 not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY -// RUN: ASAN_OPTIONS=new_delete_type_mismatch=0 %run %t scalar -// RUN: ASAN_OPTIONS=new_delete_type_mismatch=0 %run %t array - -// Sized-delete is implemented with a weak delete() definition. -// Weak symbols are kind of broken on Android. -// XFAIL: android, asan-dynamic-runtime +// RUN: %clangxx_asan -fsized-deallocation -O0 %s -o %t +// RUN: not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=1 not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR +// RUN: not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=1 not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=0 %run %t scalar +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:new_delete_type_mismatch=0 %run %t array #include <new> #include <stdio.h> diff --git a/test/asan/TestCases/Linux/stack-overflow-sigbus.cc b/test/asan/TestCases/Linux/stack-overflow-sigbus.cc index 5f597e9c51f0..23c4d23ce406 100644 --- a/test/asan/TestCases/Linux/stack-overflow-sigbus.cc +++ b/test/asan/TestCases/Linux/stack-overflow-sigbus.cc @@ -1,6 +1,6 @@ // Test ASan detection of stack-overflow condition when Linux sends SIGBUS. -// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s #include <assert.h> #include <stdio.h> diff --git a/test/asan/TestCases/Linux/stack-trace-dlclose.cc b/test/asan/TestCases/Linux/stack-trace-dlclose.cc index b3bd9f7780f5..f207a94ae65e 100644 --- a/test/asan/TestCases/Linux/stack-trace-dlclose.cc +++ b/test/asan/TestCases/Linux/stack-trace-dlclose.cc @@ -3,7 +3,7 @@ // // RUN: %clangxx_asan -DSHARED %s -shared -o %T/stack_trace_dlclose.so -fPIC // RUN: %clangxx_asan -DSO_DIR=\"%T\" %s %libdl -o %t -// RUN: ASAN_OPTIONS=exitcode=0 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:exitcode=0 %run %t 2>&1 | FileCheck %s // XFAIL: arm-linux-gnueabi // XFAIL: armv7l-unknown-linux-gnueabihf @@ -40,6 +40,6 @@ int main(int argc, char **argv) { } #endif -// CHECK: {{ #0 0x.* in malloc}} +// CHECK: {{ #0 0x.* in (__interceptor_)?malloc}} // CHECK: {{ #1 0x.* \(<unknown module>\)}} // CHECK: {{ #2 0x.* in main}} diff --git a/test/asan/TestCases/Linux/static_tls.cc b/test/asan/TestCases/Linux/static_tls.cc new file mode 100644 index 000000000000..785228b29238 --- /dev/null +++ b/test/asan/TestCases/Linux/static_tls.cc @@ -0,0 +1,29 @@ +// REQUIRES: asan-64-bits +// Regression test: __tls_get_addr interceptor must recognize static TLS. +// +// RUN: %clangxx_asan -DSHARED %s -shared -o %t-so.so -fPIC +// RUN: %clangxx_asan %s -ldl -pthread -o %t %t-so.so +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 %run %t 2>&1 | FileCheck %s + +// CHECK: before +// CHECK: __tls_get_addr: static tls +// CHECK: after + +// XFAIL: powerpc64 + +#ifndef SHARED +#include <stdio.h> + +unsigned *f(); +int main(int argc, char *argv[]) { + fprintf(stderr, "before\n"); + f(); + fprintf(stderr, "after\n"); + return 0; +} +#else // SHARED +static __thread unsigned ThreadLocal; +unsigned *f() { + return &ThreadLocal; +} +#endif diff --git a/test/asan/TestCases/Linux/stress_dtls.c b/test/asan/TestCases/Linux/stress_dtls.c index cb901ee59953..7af33b9457ea 100644 --- a/test/asan/TestCases/Linux/stress_dtls.c +++ b/test/asan/TestCases/Linux/stress_dtls.c @@ -12,9 +12,9 @@ // RUN: %clangxx_asan %s -ldl -pthread -o %t // RUN: %run %t 0 3 // RUN: %run %t 2 3 -// RUN: ASAN_OPTIONS=verbosity=2 %run %t 10 2 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=verbosity=2:intercept_tls_get_addr=1 %run %t 10 2 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=verbosity=2:intercept_tls_get_addr=0 %run %t 10 2 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 %run %t 10 2 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2:intercept_tls_get_addr=1 %run %t 10 2 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2:intercept_tls_get_addr=0 %run %t 10 2 2>&1 | FileCheck %s --check-prefix=CHECK0 // CHECK: __tls_get_addr // CHECK: Creating thread 0 // CHECK: __tls_get_addr diff --git a/test/asan/TestCases/Posix/allow_user_segv.cc b/test/asan/TestCases/Posix/allow_user_segv.cc index b6443fab85df..b299ae8cb21e 100644 --- a/test/asan/TestCases/Posix/allow_user_segv.cc +++ b/test/asan/TestCases/Posix/allow_user_segv.cc @@ -1,8 +1,8 @@ // Regression test for // https://code.google.com/p/address-sanitizer/issues/detail?id=180 -// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O2 %s -o %t && ASAN_OPTIONS=allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O2 %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_segv_handler=true not %run %t 2>&1 | FileCheck %s #include <signal.h> #include <stdio.h> diff --git a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc index 3ce6446eca22..043130f9e549 100644 --- a/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc +++ b/test/asan/TestCases/Posix/asan-symbolize-sanity-test.cc @@ -6,7 +6,7 @@ // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so // RUN: %clangxx_asan -O0 %s %libdl -o %t -// RUN: env ASAN_OPTIONS=symbolize=0 not %run %t 2>&1 | %asan_symbolize | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:symbolize=0 not %run %t 2>&1 | %asan_symbolize | FileCheck %s // XFAIL: arm-linux-gnueabi // XFAIL: armv7l-unknown-linux-gnueabihf diff --git a/test/asan/TestCases/Linux/coverage-direct-activation.cc b/test/asan/TestCases/Posix/coverage-direct-activation.cc index 9b2a0d8897c8..af73f5d2952d 100644 --- a/test/asan/TestCases/Linux/coverage-direct-activation.cc +++ b/test/asan/TestCases/Posix/coverage-direct-activation.cc @@ -1,18 +1,18 @@ // Test for direct coverage writing enabled at activation time. -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_direct_activation_test_1.so -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib -fPIC // RUN: %clangxx -c -DSO_DIR=\"%T\" %s -o %t.o -// RUN: %clangxx_asan -fsanitize-coverage=1 %t.o %libdl -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func %t.o %libdl -o %t // RUN: rm -rf %T/coverage-direct-activation // RUN: mkdir -p %T/coverage-direct-activation/normal -// RUN: ASAN_OPTIONS=coverage=1,coverage_direct=0,coverage_dir=%T/coverage-direct-activation/normal:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1,coverage_direct=0,coverage_dir=%T/coverage-direct-activation/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct-activation/normal/*.sancov >%T/coverage-direct-activation/normal/out.txt // RUN: mkdir -p %T/coverage-direct-activation/direct -// RUN: ASAN_OPTIONS=start_deactivated=1,coverage_direct=1,verbosity=1 \ -// RUN: ASAN_ACTIVATION_OPTIONS=coverage=1,coverage_dir=%T/coverage-direct-activation/direct %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,coverage_direct=1,verbosity=1 \ +// RUN: ASAN_ACTIVATION_OPTIONS=coverage=1,coverage_dir=%T/coverage-direct-activation/direct %run %t %dynamiclib // RUN: cd %T/coverage-direct-activation/direct // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt @@ -23,8 +23,8 @@ // RUN: diff -u coverage-direct-activation/normal/out.txt coverage-direct-activation/direct/out.txt // RUN: mkdir -p %T/coverage-direct-activation/direct2 -// RUN: ASAN_OPTIONS=start_deactivated=1,coverage=1,coverage_direct=1,verbosity=1 \ -// RUN: ASAN_ACTIVATION_OPTIONS=coverage_dir=%T/coverage-direct-activation/direct2 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,coverage=1,coverage_direct=1,verbosity=1 \ +// RUN: ASAN_ACTIVATION_OPTIONS=coverage_dir=%T/coverage-direct-activation/direct2 %run %t %dynamiclib // RUN: cd %T/coverage-direct-activation/direct2 // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt @@ -47,8 +47,8 @@ void bar() { printf("bar\n"); } int main(int argc, char **argv) { fprintf(stderr, "PID: %d\n", getpid()); - void *handle1 = - dlopen(SO_DIR "/libcoverage_direct_activation_test_1.so", RTLD_LAZY); + assert(argc > 1); + void *handle1 = dlopen(argv[1], RTLD_LAZY); // %dynamiclib assert(handle1); void (*bar1)() = (void (*)())dlsym(handle1, "bar"); assert(bar1); diff --git a/test/asan/TestCases/Linux/coverage-direct-large.cc b/test/asan/TestCases/Posix/coverage-direct-large.cc index 25c950e0bb30..2769172c39ab 100644 --- a/test/asan/TestCases/Linux/coverage-direct-large.cc +++ b/test/asan/TestCases/Posix/coverage-direct-large.cc @@ -2,18 +2,18 @@ // Current implementation maps output file in chunks of 64K. This test overflows // 1 chunk. -// RUN: %clangxx_asan -fsanitize-coverage=1 -O0 -DSHARED %s -shared -o %T/libcoverage_direct_large_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 -O0 -DSO_DIR=\"%T\" %s %libdl -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func -O0 -DSHARED %s -shared -o %dynamiclib -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func -O0 %s %libdl -o %t // RUN: rm -rf %T/coverage-direct-large // RUN: mkdir -p %T/coverage-direct-large/normal && cd %T/coverage-direct-large/normal -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:verbosity=1 %run %t %dynamiclib // RUN: %sancov print *.sancov >out.txt // RUN: cd ../.. // RUN: mkdir -p %T/coverage-direct-large/direct && cd %T/coverage-direct-large/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:verbosity=1 %run %t %dynamiclib // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt // RUN: cd ../.. @@ -49,11 +49,11 @@ extern "C" void so_entry() { #include <assert.h> #include <dlfcn.h> -int main(void) { +#include <stdio.h> +int main(int argc, char **argv) { F4(CALL, f) - - void *handle1 = - dlopen(SO_DIR "/libcoverage_direct_large_test_1.so", RTLD_LAZY); + assert(argc > 1); + void *handle1 = dlopen(argv[1], RTLD_LAZY); // %dynamiclib assert(handle1); void (*so_entry)() = (void (*)())dlsym(handle1, "so_entry"); assert(so_entry); diff --git a/test/asan/TestCases/Linux/coverage-direct.cc b/test/asan/TestCases/Posix/coverage-direct.cc index 45222fa1a03e..5371a859c24f 100644 --- a/test/asan/TestCases/Linux/coverage-direct.cc +++ b/test/asan/TestCases/Posix/coverage-direct.cc @@ -1,16 +1,16 @@ // Test for direct coverage writing with dlopen at coverage level 1 to 3. -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_direct_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%T\" %s %libdl -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func %s %libdl -o %t // RUN: rm -rf %T/coverage-direct // RUN: mkdir -p %T/coverage-direct/normal -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt // RUN: mkdir -p %T/coverage-direct/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib // RUN: cd %T/coverage-direct/direct // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt @@ -19,17 +19,17 @@ // RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt -// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %T/libcoverage_direct_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=2 -DSO_DIR=\"%T\" %s %libdl -o %t +// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED %s -shared -o %dynamiclib -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=bb -DSO_DIR=\"%T\" %s %libdl -o %t // RUN: rm -rf %T/coverage-direct // RUN: mkdir -p %T/coverage-direct/normal -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt // RUN: mkdir -p %T/coverage-direct/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib // RUN: cd %T/coverage-direct/direct // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt @@ -38,17 +38,17 @@ // RUN: diff -u coverage-direct/normal/out.txt coverage-direct/direct/out.txt -// RUN: %clangxx_asan -fsanitize-coverage=3 -DSHARED %s -shared -o %T/libcoverage_direct_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=3 -DSO_DIR=\"%T\" %s %libdl -o %t +// RUN: %clangxx_asan -fsanitize-coverage=edge -DSHARED %s -shared -o %dynamiclib -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=edge -DSO_DIR=\"%T\" %s %libdl -o %t // RUN: rm -rf %T/coverage-direct // RUN: mkdir -p %T/coverage-direct/normal -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:coverage_dir=%T/coverage-direct/normal:verbosity=1 %run %t %dynamiclib // RUN: %sancov print %T/coverage-direct/normal/*.sancov >%T/coverage-direct/normal/out.txt // RUN: mkdir -p %T/coverage-direct/direct -// RUN: ASAN_OPTIONS=coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:coverage_dir=%T/coverage-direct/direct:verbosity=1 %run %t %dynamiclib // RUN: cd %T/coverage-direct/direct // RUN: %sancov rawunpack *.sancov.raw // RUN: %sancov print *.sancov >out.txt @@ -71,8 +71,8 @@ void bar() { printf("bar\n"); } int main(int argc, char **argv) { fprintf(stderr, "PID: %d\n", getpid()); - void *handle1 = - dlopen(SO_DIR "/libcoverage_direct_test_1.so", RTLD_LAZY); + assert(argc > 1); + void *handle1 = dlopen(argv[1], RTLD_LAZY); assert(handle1); void (*bar1)() = (void (*)())dlsym(handle1, "bar"); assert(bar1); diff --git a/test/asan/TestCases/Linux/coverage-fork-direct.cc b/test/asan/TestCases/Posix/coverage-fork-direct.cc index 51cbbd821b8e..39363911fec3 100644 --- a/test/asan/TestCases/Linux/coverage-fork-direct.cc +++ b/test/asan/TestCases/Posix/coverage-fork-direct.cc @@ -1,7 +1,7 @@ -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t // RUN: rm -rf %T/coverage-fork-direct // RUN: mkdir -p %T/coverage-fork-direct && cd %T/coverage-fork-direct -// RUN: (ASAN_OPTIONS=coverage=1:coverage_direct=1:verbosity=1 %run %t; \ +// RUN: (ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=1:verbosity=1 %run %t; \ // RUN: %sancov rawunpack *.sancov.raw; %sancov print *.sancov) 2>&1 // // XFAIL: android diff --git a/test/asan/TestCases/Linux/coverage-fork.cc b/test/asan/TestCases/Posix/coverage-fork.cc index 38c200942609..c1f0fc3a84b8 100644 --- a/test/asan/TestCases/Linux/coverage-fork.cc +++ b/test/asan/TestCases/Posix/coverage-fork.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t -// RUN: export ASAN_OPTIONS=coverage=1:coverage_direct=0:verbosity=1 +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_direct=0:verbosity=1 // RUN: rm -rf %T/coverage-fork // RUN: mkdir -p %T/coverage-fork && cd %T/coverage-fork // RUN: %run %t 2>&1 | FileCheck %s diff --git a/test/asan/TestCases/Linux/coverage-module-unloaded.cc b/test/asan/TestCases/Posix/coverage-module-unloaded.cc index f8d9c57f81be..fe08bdd792b1 100644 --- a/test/asan/TestCases/Linux/coverage-module-unloaded.cc +++ b/test/asan/TestCases/Posix/coverage-module-unloaded.cc @@ -1,13 +1,13 @@ // Check that unloading a module doesn't break coverage dumping for remaining // modules. -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_module_unloaded_test_1.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_module_unloaded_test_2.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSO_DIR=\"%T\" %s %libdl -o %t -// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1 +// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib1 -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib2 -fPIC +// RUN: %clangxx_asan -fsanitize-coverage=func %s %libdl -o %t +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 // RUN: mkdir -p %T/coverage-module-unloaded && cd %T/coverage-module-unloaded -// RUN: %run %t 2>&1 | FileCheck %s -// RUN: %run %t foo 2>&1 | FileCheck %s -// RUN: cd .. && rm coverage-module-unloaded -r +// RUN: %run %t %dynamiclib1 %dynamiclib2 2>&1 | FileCheck %s +// RUN: %run %t %dynamiclib1 %dynamiclib2 foo 2>&1 | FileCheck %s +// RUN: rm -r %T/coverage-module-unloaded // // https://code.google.com/p/address-sanitizer/issues/detail?id=263 // XFAIL: android @@ -25,14 +25,13 @@ void bar() { printf("bar\n"); } int main(int argc, char **argv) { fprintf(stderr, "PID: %d\n", getpid()); - void *handle1 = - dlopen(SO_DIR "/libcoverage_module_unloaded_test_1.so", RTLD_LAZY); + assert(argc > 2); + void *handle1 = dlopen(argv[1], RTLD_LAZY); // %dynamiclib1 assert(handle1); void (*bar1)() = (void (*)())dlsym(handle1, "bar"); assert(bar1); bar1(); - void *handle2 = - dlopen(SO_DIR "/libcoverage_module_unloaded_test_2.so", RTLD_LAZY); + void *handle2 = dlopen(argv[2], RTLD_LAZY); // %dynamiclib2 assert(handle2); void (*bar2)() = (void (*)())dlsym(handle2, "bar"); assert(bar2); @@ -50,7 +49,7 @@ int main(int argc, char **argv) { // CHECK: PID: [[PID:[0-9]+]] // CHECK: [[PID]].sancov: 1 PCs written -// CHECK: .so.[[PID]] -// If we get coverage for both DSOs, it means the module wasn't unloaded and -// this test is useless. -// CHECK-NOT: .so.[[PID]] +// CHECK: coverage-module-unloaded{{.*}}1.[[PID]] +// CHECK: coverage-module-unloaded{{.*}}2.[[PID]] +// Even though we've unloaded one of the libs we still dump the coverage file +// for that lib (although the data will be inaccurate, if at all useful) diff --git a/test/asan/TestCases/Linux/coverage-sandboxing.cc b/test/asan/TestCases/Posix/coverage-sandboxing.cc index 1a72c6bb9a6e..dd2c1ec43be5 100644 --- a/test/asan/TestCases/Linux/coverage-sandboxing.cc +++ b/test/asan/TestCases/Posix/coverage-sandboxing.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_asan -fsanitize-coverage=2 -DSHARED %s -shared -o %T/libcoverage_sandboxing_test.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t -Wl,-R,\$ORIGIN -L%T -lcoverage_sandboxing_test -// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1 +// RUN: %clangxx_asan -fsanitize-coverage=bb -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t %ld_flags_rpath_exe +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 // RUN: rm -rf %T/coverage_sandboxing_test // RUN: mkdir %T/coverage_sandboxing_test && cd %T/coverage_sandboxing_test // RUN: mkdir vanilla && cd vanilla @@ -12,12 +12,12 @@ // RUN: %run %t a b 2>&1 | FileCheck %s --check-prefix=CHECK-sandbox // RUN: %sancov unpack coverage_sandboxing_test.sancov.packed // RUN: cd .. -// RUN: %sancov print vanilla/libcoverage_sandboxing_test.so.*.sancov > vanilla.txt -// RUN: %sancov print sandbox1/libcoverage_sandboxing_test.so.*.sancov > sandbox1.txt -// RUN: %sancov print sandbox2/libcoverage_sandboxing_test.so.*.sancov > sandbox2.txt +// RUN: %sancov print vanilla/`basename %dynamiclib`*.sancov > vanilla.txt +// RUN: %sancov print sandbox1/`basename %dynamiclib`*.sancov > sandbox1.txt +// RUN: %sancov print sandbox2/`basename %dynamiclib`*.sancov > sandbox2.txt // RUN: diff vanilla.txt sandbox1.txt // RUN: diff vanilla.txt sandbox2.txt -// RUN: cd ../ && rm coverage_sandboxing_test -r +// RUN: rm -r %T/coverage_sandboxing_test // https://code.google.com/p/address-sanitizer/issues/detail?id=263 // XFAIL: android @@ -78,8 +78,8 @@ int main(int argc, char **argv) { #endif // CHECK-vanilla: PID: [[PID:[0-9]+]] -// CHECK-vanilla: [[PID]].sancov: 1 PCs written // CHECK-vanilla: .so.[[PID]].sancov: 258 PCs written +// CHECK-vanilla: [[PID]].sancov: 1 PCs written // CHECK-sandbox: PID: [[PID:[0-9]+]] // CHECK-sandbox: 258 PCs written to packed file diff --git a/test/asan/TestCases/Linux/coverage.cc b/test/asan/TestCases/Posix/coverage.cc index 06fe1a295eaf..99e348fdaf9d 100644 --- a/test/asan/TestCases/Linux/coverage.cc +++ b/test/asan/TestCases/Posix/coverage.cc @@ -1,14 +1,21 @@ -// RUN: %clangxx_asan -fsanitize-coverage=1 -DSHARED %s -shared -o %T/libcoverage_test.so -fPIC -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t -Wl,-R,\$ORIGIN -L%T -lcoverage_test -// RUN: export ASAN_OPTIONS=coverage=1:verbosity=1 -// RUN: mkdir -p %T/coverage && cd %T/coverage +// RUN: %clangxx_asan -fsanitize-coverage=func -DSHARED %s -shared -o %dynamiclib -fPIC %ld_flags_rpath_so +// RUN: %clangxx_asan -fsanitize-coverage=func %s %ld_flags_rpath_exe -o %t +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 +// RUN: rm -rf %T/coverage && mkdir -p %T/coverage && cd %T/coverage // RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-main +// RUN: %sancov print `ls coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1 // RUN: %run %t foo 2>&1 | FileCheck %s --check-prefix=CHECK-foo +// RUN: %sancov print `ls coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 // RUN: %run %t bar 2>&1 | FileCheck %s --check-prefix=CHECK-bar +// RUN: %sancov print `ls *coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 // RUN: %run %t foo bar 2>&1 | FileCheck %s --check-prefix=CHECK-foo-bar +// RUN: %sancov print `ls *coverage.*sancov | grep -v '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 +// RUN: %sancov print `ls *coverage.*sancov | grep '.so'` 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV1 +// RUN: %sancov merge `ls *coverage.*sancov | grep -v '.so'` > merged-cov +// RUN: %sancov print merged-cov 2>&1 | FileCheck %s --check-prefix=CHECK-SANCOV2 // RUN: not %run %t foo bar 4 2>&1 | FileCheck %s --check-prefix=CHECK-report // RUN: not %run %t foo bar 4 5 2>&1 | FileCheck %s --check-prefix=CHECK-segv -// RUN: cd .. && rm coverage -r +// RUN: rm -r %T/coverage // // https://code.google.com/p/address-sanitizer/issues/detail?id=263 // XFAIL: android @@ -57,15 +64,18 @@ int main(int argc, char **argv) { // CHECK-foo-NOT: .so.[[PID]] // // CHECK-bar: PID: [[PID:[0-9]+]] -// CHECK-bar: [[PID]].sancov: 1 PCs written // CHECK-bar: .so.[[PID]].sancov: 1 PCs written +// CHECK-bar: [[PID]].sancov: 1 PCs written // // CHECK-foo-bar: PID: [[PID:[0-9]+]] -// CHECK-foo-bar: [[PID]].sancov: 2 PCs written // CHECK-foo-bar: so.[[PID]].sancov: 1 PCs written +// CHECK-foo-bar: [[PID]].sancov: 2 PCs written // // CHECK-report: AddressSanitizer: global-buffer-overflow // CHECK-report: PCs written // // CHECK-segv: AddressSanitizer: SEGV // CHECK-segv: PCs written +// +// CHECK-SANCOV1: 1 PCs total +// CHECK-SANCOV2: 2 PCs total diff --git a/test/asan/TestCases/Posix/init-order-dlopen.cc b/test/asan/TestCases/Posix/init-order-dlopen.cc deleted file mode 100644 index 3c6f093b03d1..000000000000 --- a/test/asan/TestCases/Posix/init-order-dlopen.cc +++ /dev/null @@ -1,72 +0,0 @@ -// Regression test for -// https://code.google.com/p/address-sanitizer/issues/detail?id=178 - -// Assume we're on Darwin and try to pass -U to the linker. If this flag is -// unsupported, don't use it. -// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \ -// RUN: -fPIC -shared -o %t-so.so -Wl,-U,_inc_global || \ -// RUN: %clangxx_asan -O0 -DSHARED_LIB %s \ -// RUN: -fPIC -shared -o %t-so.so -// If the linker doesn't support --export-dynamic (which is ELF-specific), -// try to link without that option. -// FIXME: find a better solution. -// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t -Wl,--export-dynamic || \ -// RUN: %clangxx_asan -O0 %s -pthread %libdl -o %t -// RUN: ASAN_OPTIONS=strict_init_order=true %run %t 2>&1 | FileCheck %s -#if !defined(SHARED_LIB) -#include <dlfcn.h> -#include <pthread.h> -#include <stdio.h> -#include <unistd.h> - -#include <string> - -using std::string; - -int foo() { - return 42; -} -int global = foo(); - -__attribute__((visibility("default"))) -extern "C" -void inc_global() { - global++; -} - -void *global_poller(void *arg) { - while (true) { - if (global != 42) - break; - usleep(100); - } - return 0; -} - -int main(int argc, char *argv[]) { - pthread_t p; - pthread_create(&p, 0, global_poller, 0); - string path = string(argv[0]) + "-so.so"; - if (0 == dlopen(path.c_str(), RTLD_NOW)) { - fprintf(stderr, "dlerror: %s\n", dlerror()); - return 1; - } - pthread_join(p, 0); - printf("PASSED\n"); - // CHECK: PASSED - return 0; -} -#else // SHARED_LIB -#include <stdio.h> -#include <unistd.h> - -extern "C" void inc_global(); - -int slow_init() { - sleep(1); - inc_global(); - return 42; -} - -int slowly_init_glob = slow_init(); -#endif // SHARED_LIB diff --git a/test/asan/TestCases/Linux/interception-in-shared-lib-test.cc b/test/asan/TestCases/Posix/interception-in-shared-lib-test.cc index b828d5524ee0..a7d2bfb9b43c 100644 --- a/test/asan/TestCases/Linux/interception-in-shared-lib-test.cc +++ b/test/asan/TestCases/Posix/interception-in-shared-lib-test.cc @@ -1,13 +1,8 @@ // Check that memset() call from a shared library gets intercepted. -// Please always keep this file in sync with -// ../Darwin/interception-in-shared-lib-test.cc. // RUN: %clangxx_asan -O0 %s -DSHARED_LIB \ -// RUN: -shared -o %T/libinterception-in-shared-lib-test.so \ -// RUN: -fPIC -// TODO(glider): figure out how to set rpath in a more portable way and unite -// this test with ../Darwin/interception-in-shared-lib-test.cc. -// RUN: %clangxx_asan -O0 %s -o %t -Wl,-R,\$ORIGIN -L%T -linterception-in-shared-lib-test && \ +// RUN: -shared -o %dynamiclib -fPIC %ld_flags_rpath_so +// RUN: %clangxx_asan -O0 %s -o %t %ld_flags_rpath_exe && \ // RUN: not %run %t 2>&1 | FileCheck %s #include <stdio.h> @@ -26,7 +21,7 @@ int main(int argc, char *argv[]) { my_memset(buf, 11); // CHECK: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} // CHECK: {{WRITE of size 11 at 0x.* thread T0}} - // CHECK: {{0x.* in my_memset .*interception-in-shared-lib-test.cc:19}} + // CHECK: {{0x.* in my_memset .*interception-in-shared-lib-test.cc:}}[[@LINE-10]] return 0; } #endif diff --git a/test/asan/TestCases/Posix/ioctl.cc b/test/asan/TestCases/Posix/ioctl.cc index 78f152fe93fe..d25f6ecbee1f 100644 --- a/test/asan/TestCases/Posix/ioctl.cc +++ b/test/asan/TestCases/Posix/ioctl.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_asan -O0 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 -g %s -o %t && ASAN_OPTIONS=handle_ioctl=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 -g %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:handle_ioctl=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 -g %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:handle_ioctl=1 not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O0 -g %s -o %t && %run %t // RUN: %clangxx_asan -O3 -g %s -o %t && %run %t diff --git a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc index f852a62ea9a3..b1c99430c75d 100644 --- a/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc +++ b/test/asan/TestCases/Posix/large_allocator_unpoisons_on_free.cc @@ -2,7 +2,7 @@ // RUN: %clangxx_asan %s -o %t // The memory is released only when the deallocated chunk leaves the quarantine, // otherwise the mmap(p, ...) call overwrites the malloc header. -// RUN: ASAN_OPTIONS=quarantine_size_mb=0 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=0 %run %t #include <assert.h> #include <string.h> diff --git a/test/asan/TestCases/log_path_fork_test.cc.disabled b/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled index cfe90dfb54d3..9f09b78f41c7 100644 --- a/test/asan/TestCases/log_path_fork_test.cc.disabled +++ b/test/asan/TestCases/Posix/log_path_fork_test.cc.disabled @@ -1,7 +1,7 @@ // RUN: %clangxx_asan %s -o %t // RUN: rm -f %t.log.* // Set verbosity to 1 so that the log files are opened prior to fork(). -// RUN: env ASAN_OPTIONS="log_path=%t.log verbosity=1" not %run %t 2> %t.out +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:log_path=%t.log verbosity=1" not %run %t 2> %t.out // RUN: for f in %t.log.* ; do FileCheck %s < $f; done // RUN: [ `ls %t.log.* | wc -l` == 2 ] diff --git a/test/asan/TestCases/Posix/new_array_cookie_test.cc b/test/asan/TestCases/Posix/new_array_cookie_test.cc index 85d51f361835..bc681857ae67 100644 --- a/test/asan/TestCases/Posix/new_array_cookie_test.cc +++ b/test/asan/TestCases/Posix/new_array_cookie_test.cc @@ -1,8 +1,8 @@ // REQUIRES: asan-64-bits // RUN: %clangxx_asan -O3 %s -o %t // RUN: not %run %t 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s -// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE #include <stdio.h> #include <stdlib.h> struct C { diff --git a/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc b/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc index c35ccebb8c79..5998d06756d7 100644 --- a/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc +++ b/test/asan/TestCases/Posix/new_array_cookie_uaf_test.cc @@ -1,7 +1,7 @@ // REQUIRES: asan-64-bits // RUN: %clangxx_asan -O3 %s -o %t -// RUN: ASAN_OPTIONS=poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s --check-prefix=COOKIE -// RUN: ASAN_OPTIONS=poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=1 not %run %t 2>&1 | FileCheck %s --check-prefix=COOKIE +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_array_cookie=0 not %run %t 2>&1 | FileCheck %s --check-prefix=NO_COOKIE #include <stdio.h> #include <stdlib.h> #include <assert.h> diff --git a/test/asan/TestCases/Posix/start-deactivated.cc b/test/asan/TestCases/Posix/start-deactivated.cc index d7e0dfc98e6d..2ca8015fc742 100644 --- a/test/asan/TestCases/Posix/start-deactivated.cc +++ b/test/asan/TestCases/Posix/start-deactivated.cc @@ -5,21 +5,20 @@ // RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so // RUN: %clangxx -O0 %s -c -o %t.o // RUN: %clangxx_asan -O0 %t.o %libdl -o %t -// RUN: ASAN_OPTIONS=start_deactivated=1,allocator_may_return_null=0 \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,allocator_may_return_null=0 \ // RUN: ASAN_ACTIVATION_OPTIONS=allocator_may_return_null=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK -// RUN: ASAN_OPTIONS=start_deactivated=1 \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HELP -// RUN: ASAN_OPTIONS=start_deactivated=1,verbosity=1 \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1,verbosity=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED -// RUN: ASAN_OPTIONS=start_deactivated=1 \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED-V0 // Check that verbosity=1 in activation flags affects reporting of unrecognized activation flags. -// RUN: ASAN_OPTIONS=start_deactivated=1 \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:start_deactivated=1 \ // RUN: ASAN_ACTIVATION_OPTIONS=help=1,handle_segv=0,verbosity=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-UNSUPPORTED // XFAIL: arm-linux-gnueabi -// XFAIL: armv7l-unknown-linux-gnueabihf #if !defined(SHARED_LIB) #include <assert.h> diff --git a/test/asan/TestCases/Posix/tsd_dtor_leak.cc b/test/asan/TestCases/Posix/tsd_dtor_leak.cc index 6952245227b4..69d28194fb9e 100644 --- a/test/asan/TestCases/Posix/tsd_dtor_leak.cc +++ b/test/asan/TestCases/Posix/tsd_dtor_leak.cc @@ -1,7 +1,7 @@ // Regression test for a leak in tsd: // https://code.google.com/p/address-sanitizer/issues/detail?id=233 // RUN: %clangxx_asan -O1 %s -pthread -o %t -// RUN: ASAN_OPTIONS=quarantine_size_mb=0 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:quarantine_size_mb=0 %run %t #include <pthread.h> #include <stdio.h> #include <stdlib.h> diff --git a/test/asan/TestCases/Windows/bind_io_completion_callback.cc b/test/asan/TestCases/Windows/bind_io_completion_callback.cc new file mode 100644 index 000000000000..c062a799fdcc --- /dev/null +++ b/test/asan/TestCases/Windows/bind_io_completion_callback.cc @@ -0,0 +1,70 @@ +// Make sure we can throw exceptions from work items executed via +// BindIoCompletionCallback. +// +// Clang doesn't support exceptions on Windows yet, so for the time being we +// build this program in two parts: the code with exceptions is built with CL, +// the rest is built with Clang. This represents the typical scenario when we +// build a large project using "clang-cl -fallback -fsanitize=address". +// +// RUN: cl -c %s -Fo%t.obj +// RUN: %clangxx_asan -o %t.exe %s %t.obj +// RUN: %run %t.exe 2>&1 | FileCheck %s + +#include <windows.h> +#include <stdio.h> + +void ThrowAndCatch(); + +#if !defined(__clang__) +__declspec(noinline) +void Throw() { + fprintf(stderr, "Throw\n"); +// CHECK: Throw + throw 1; +} + +void ThrowAndCatch() { + int local; + try { + Throw(); + } catch(...) { + fprintf(stderr, "Catch\n"); +// CHECK: Catch + } +} +#else + +char buffer[65536]; +HANDLE done; +OVERLAPPED ov; + +void CALLBACK completion_callback(DWORD error, DWORD bytesRead, + LPOVERLAPPED pov) { + ThrowAndCatch(); + SetEvent(done); +} + +int main(int argc, char **argv) { + done = CreateEvent(0, false, false, "job is done"); + if (!done) + return 1; + HANDLE file = CreateFile( + argv[0], GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_NO_BUFFERING | FILE_FLAG_OVERLAPPED, + NULL); + if (!file) + return 2; + if (!BindIoCompletionCallback(file, completion_callback, 0)) + return 3; + + if (!ReadFile(file, buffer, sizeof(buffer), NULL, &ov) && + GetLastError() != ERROR_IO_PENDING) + return 4; + + if (WAIT_OBJECT_0 != WaitForSingleObject(done, INFINITE)) + return 5; + fprintf(stderr, "Done!\n"); +// CHECK: Done! +} +#endif diff --git a/test/asan/TestCases/Windows/coverage-basic.cc b/test/asan/TestCases/Windows/coverage-basic.cc new file mode 100644 index 000000000000..44b499fcb4cd --- /dev/null +++ b/test/asan/TestCases/Windows/coverage-basic.cc @@ -0,0 +1,25 @@ +// RUN: rm -rf %T/coverage-basic +// RUN: mkdir %T/coverage-basic && cd %T/coverage-basic +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o test.exe +// RUN: env ASAN_OPTIONS=coverage=1 %run ./test.exe +// +// RUN: %sancov print *.sancov | FileCheck %s +#include <stdio.h> + +void foo() { fprintf(stderr, "FOO\n"); } +void bar() { fprintf(stderr, "BAR\n"); } + +int main(int argc, char **argv) { + if (argc == 2) { + foo(); + bar(); + } else { + bar(); + foo(); + } +} + +// CHECK: 0x{{[0-9a-f]*}} +// CHECK: 0x{{[0-9a-f]*}} +// CHECK: 0x{{[0-9a-f]*}} +// CHECK-NOT: 0x{{[0-9a-f]*}} diff --git a/test/asan/TestCases/Windows/default_options.cc b/test/asan/TestCases/Windows/default_options.cc new file mode 100644 index 000000000000..6e0a28f33692 --- /dev/null +++ b/test/asan/TestCases/Windows/default_options.cc @@ -0,0 +1,18 @@ +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s + +// FIXME: merge this with the common default_options test when we can run common +// tests on Windows. + +const char *kAsanDefaultOptions="verbosity=1 help=1"; + +extern "C" +__attribute__((no_sanitize_address)) +const char *__asan_default_options() { + // CHECK: Available flags for AddressSanitizer: + return kAsanDefaultOptions; +} + +int main() { + return 0; +} diff --git a/test/asan/TestCases/Windows/dll_noreturn.cc b/test/asan/TestCases/Windows/dll_noreturn.cc index 6ec90725145f..79f923eccf84 100644 --- a/test/asan/TestCases/Windows/dll_noreturn.cc +++ b/test/asan/TestCases/Windows/dll_noreturn.cc @@ -9,7 +9,7 @@ void noreturn_f() { char buffer[42]; buffer[subscript] = 42; _exit(1); -// CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: AddressSanitizer: stack-buffer-underflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 1 at [[ADDR]] thread T0 // CHECK-NEXT: noreturn_f {{.*}}dll_noreturn.cc:[[@LINE-4]] // CHECK-NEXT: test_function {{.*}}dll_noreturn.cc diff --git a/test/asan/TestCases/Windows/dll_report_globals_symbolization_at_startup.cc b/test/asan/TestCases/Windows/dll_report_globals_symbolization_at_startup.cc new file mode 100644 index 000000000000..fbdb1c145bbe --- /dev/null +++ b/test/asan/TestCases/Windows/dll_report_globals_symbolization_at_startup.cc @@ -0,0 +1,40 @@ +// RUN: %clang_cl_asan -LD -O0 -DDLL %s -Fe%t.dll +// RUN: %clang_cl_asan -O0 -DEXE %s %t.lib -Fe%te.exe +// RUN: env ASAN_OPTIONS=report_globals=2 %run %te.exe 2>&1 | FileCheck %s + +// FIXME: Currently, the MT runtime build crashes on startup due to dbghelp.dll +// initialization failure. +// REQUIRES: asan-dynamic-runtime + +#include <windows.h> +#include <stdio.h> + +extern "C" { +#if defined(EXE) +__declspec(dllimport) int foo_from_dll(); + +// CHECK: in DLL(reason=1) +int main(int argc, char **argv) { + foo_from_dll(); +// CHECK: hello! + printf("hello!\n"); + fflush(0); +// CHECK: in DLL(reason=0) +} +#elif defined(DLL) +// This global is registered at startup. +int x[42]; + +__declspec(dllexport) int foo_from_dll() { + return x[2]; +} + +BOOL WINAPI DllMain(HMODULE, DWORD reason, LPVOID) { + printf("in DLL(reason=%d)\n", (int)reason); + fflush(0); + return TRUE; +} +#else +# error oops! +#endif +} diff --git a/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc b/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc index 8f53623419ce..04d3e2ec554b 100644 --- a/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc +++ b/test/asan/TestCases/Windows/dll_thread_stack_array_left_oob.cc @@ -9,7 +9,7 @@ DWORD WINAPI thread_proc(void *context) { int subscript = -1; char stack_buffer[42]; stack_buffer[subscript] = 42; -// CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: AddressSanitizer: stack-buffer-underflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 1 at [[ADDR]] thread T1 // CHECK-NEXT: thread_proc {{.*}}dll_thread_stack_array_left_oob.cc:[[@LINE-3]] // diff --git a/test/asan/TestCases/Windows/free_hook_realloc.cc b/test/asan/TestCases/Windows/free_hook_realloc.cc new file mode 100644 index 000000000000..297218bf8e99 --- /dev/null +++ b/test/asan/TestCases/Windows/free_hook_realloc.cc @@ -0,0 +1,37 @@ +// Check that free hook doesn't conflict with Realloc. +// RUN: %clangxx_asan -O2 %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s + +// FIXME: merge this with the common free_hook_realloc test when we can run +// common tests on Windows. + +#include <stdlib.h> +#include <io.h> +#include <sanitizer/allocator_interface.h> + +static void *glob_ptr; + +extern "C" { +void __sanitizer_free_hook(const volatile void *ptr) { + if (ptr == glob_ptr) { + *(int*)ptr = 0; + write(1, "FreeHook\n", sizeof("FreeHook\n")); + } +} +} + +int main() { + int *x = (int*)malloc(100); + x[0] = 42; + glob_ptr = x; + int *y = (int*)realloc(x, 200); + // Verify that free hook was called and didn't spoil the memory. + if (y[0] != 42) { + _exit(1); + } + write(1, "Passed\n", sizeof("Passed\n")); + free(y); + // CHECK: FreeHook + // CHECK: Passed + return 0; +} diff --git a/test/asan/TestCases/Windows/on_error_callback.cc b/test/asan/TestCases/Windows/on_error_callback.cc new file mode 100644 index 000000000000..9e690a342b56 --- /dev/null +++ b/test/asan/TestCases/Windows/on_error_callback.cc @@ -0,0 +1,20 @@ +// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s + +// FIXME: merge this with the common on_error_callback test when we can run +// common tests on Windows. + +#include <stdio.h> +#include <stdlib.h> + +extern "C" +void __asan_on_error() { + fprintf(stderr, "__asan_on_error called"); + fflush(0); +} + +int main() { + char *x = (char*)malloc(10 * sizeof(char)); + free(x); + return x[5]; + // CHECK: __asan_on_error called +} diff --git a/test/asan/TestCases/Windows/queue_user_work_item.cc b/test/asan/TestCases/Windows/queue_user_work_item.cc new file mode 100644 index 000000000000..d99ea6fc2e45 --- /dev/null +++ b/test/asan/TestCases/Windows/queue_user_work_item.cc @@ -0,0 +1,55 @@ +// Make sure we can throw exceptions from work items executed via +// QueueUserWorkItem. +// +// Clang doesn't support exceptions on Windows yet, so for the time being we +// build this program in two parts: the code with exceptions is built with CL, +// the rest is built with Clang. This represents the typical scenario when we +// build a large project using "clang-cl -fallback -fsanitize=address". +// +// RUN: cl -c %s -Fo%t.obj +// RUN: %clangxx_asan -o %t.exe %s %t.obj +// RUN: %run %t.exe 2>&1 | FileCheck %s + +#include <windows.h> +#include <stdio.h> + +void ThrowAndCatch(); + +#if !defined(__clang__) +__declspec(noinline) +void Throw() { + fprintf(stderr, "Throw\n"); +// CHECK: Throw + throw 1; +} + +void ThrowAndCatch() { + int local; + try { + Throw(); + } catch(...) { + fprintf(stderr, "Catch\n"); +// CHECK: Catch + } +} +#else + +HANDLE done; + +DWORD CALLBACK work_item(LPVOID) { + ThrowAndCatch(); + SetEvent(done); + return 0; +} + +int main(int argc, char **argv) { + done = CreateEvent(0, false, false, "job is done"); + if (!done) + return 1; + QueueUserWorkItem(&work_item, nullptr, 0); + if (WAIT_OBJECT_0 != WaitForSingleObject(done, INFINITE)) + return 2; + fprintf(stderr, "Done!\n"); +// CHECK: Done! +} +#endif diff --git a/test/asan/TestCases/Windows/queue_user_work_item_report.cc b/test/asan/TestCases/Windows/queue_user_work_item_report.cc new file mode 100644 index 000000000000..a57e1e767dc7 --- /dev/null +++ b/test/asan/TestCases/Windows/queue_user_work_item_report.cc @@ -0,0 +1,29 @@ +// RUN: %clang_cl_asan -O0 %s -Fe%t +// RUN: not %run %t 2>&1 | FileCheck %s + +#include <windows.h> + +HANDLE done; + +DWORD CALLBACK work_item(LPVOID) { + int subscript = -1; + volatile char stack_buffer[42]; + stack_buffer[subscript] = 42; +// CHECK: AddressSanitizer: stack-buffer-underflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: WRITE of size 1 at [[ADDR]] thread T1 +// CHECK: {{#0 .* work_item .*queue_user_work_item_report.cc}}:[[@LINE-3]] +// CHECK: Address [[ADDR]] is located in stack of thread T1 at offset {{.*}} in frame +// CHECK: work_item + SetEvent(done); + return 0; +} + +int main(int argc, char **argv) { + done = CreateEvent(0, false, false, "job is done"); + if (!done) + return 1; +// CHECK-NOT: Thread T1 created + QueueUserWorkItem(&work_item, nullptr, 0); + if (WAIT_OBJECT_0 != WaitForSingleObject(done, INFINITE)) + return 2; +} diff --git a/test/asan/TestCases/Windows/report_globals_reload_dll.cc b/test/asan/TestCases/Windows/report_globals_reload_dll.cc new file mode 100644 index 000000000000..8b050975aac1 --- /dev/null +++ b/test/asan/TestCases/Windows/report_globals_reload_dll.cc @@ -0,0 +1,51 @@ +// Make sure we can handle reloading the same DLL multiple times. +// RUN: %clang_cl_asan -LD -O0 -DDLL %s -Fe%t.dll +// RUN: %clang_cl_asan -O0 -DEXE %s -Fe%te.exe +// RUN: env ASAN_OPTIONS=report_globals=1 %run %te.exe %t.dll 2>&1 | FileCheck %s + +#include <windows.h> +#include <stdio.h> +#include <string.h> + +extern "C" { +#if defined(EXE) +int main(int argc, char **argv) { + if (argc != 2) { + printf("Usage: %s [client].dll\n", argv[0]); + return 101; + } + const char *dll_name = argv[1]; + +// CHECK: time to load DLL + printf("time to load DLL\n"); + fflush(0); + +// CHECK: in DLL(reason=1) +// CHECK: in DLL(reason=0) +// CHECK: in DLL(reason=1) +// CHECK: in DLL(reason=0) +// CHECK: in DLL(reason=1) +// CHECK: in DLL(reason=0) + for (int i = 0; i < 30; ++i) { + HMODULE dll = LoadLibrary(dll_name); + if (dll == NULL) + return 3; + + if (!FreeLibrary(dll)) + return 4; + } + +// CHECK: All OK! + printf("All OK!\n"); + fflush(0); +} +#elif defined(DLL) +BOOL WINAPI DllMain(HMODULE, DWORD reason, LPVOID) { + printf("in DLL(reason=%d)\n", (int)reason); + fflush(0); + return TRUE; +} +#else +# error oops! +#endif +} diff --git a/test/asan/TestCases/Windows/globals_multiple_dlls.cc b/test/asan/TestCases/Windows/report_globals_vs_freelibrary.cc index 634e5782796c..72bf36ad0be7 100644 --- a/test/asan/TestCases/Windows/globals_multiple_dlls.cc +++ b/test/asan/TestCases/Windows/report_globals_vs_freelibrary.cc @@ -1,7 +1,3 @@ -// Make sure everything works even if the main module doesn't have any stack -// variables, thus doesn't explicitly reference any symbol exported by the -// runtime thunk. -// // RUN: %clang_cl_asan -LD -O0 -DDLL %s -Fe%t.dll // RUN: %clang_cl_asan -O0 -DEXE %s -Fe%te.exe // RUN: env ASAN_OPTIONS=report_globals=2 %run %te.exe %t.dll 2>&1 | FileCheck %s diff --git a/test/asan/TestCases/Windows/stack_array_left_oob.cc b/test/asan/TestCases/Windows/stack_array_left_oob.cc index 040d855b48e2..845a1f33261f 100644 --- a/test/asan/TestCases/Windows/stack_array_left_oob.cc +++ b/test/asan/TestCases/Windows/stack_array_left_oob.cc @@ -7,7 +7,7 @@ int main() { int subscript = -1; char buffer[42]; buffer[subscript] = 42; -// CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: AddressSanitizer: stack-buffer-underflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 1 at [[ADDR]] thread T0 // CHECK-NEXT: {{#0 .* main .*stack_array_left_oob.cc}}:[[@LINE-3]] // CHECK: Address [[ADDR]] is located in stack of thread T0 at offset [[OFFSET:.*]] in frame diff --git a/test/asan/TestCases/Windows/thread_stack_array_left_oob.cc b/test/asan/TestCases/Windows/thread_stack_array_left_oob.cc index 17b9b1bf8ecb..63cb8ae1f43c 100644 --- a/test/asan/TestCases/Windows/thread_stack_array_left_oob.cc +++ b/test/asan/TestCases/Windows/thread_stack_array_left_oob.cc @@ -7,7 +7,7 @@ DWORD WINAPI thread_proc(void *) { int subscript = -1; volatile char stack_buffer[42]; stack_buffer[subscript] = 42; -// CHECK: AddressSanitizer: stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: AddressSanitizer: stack-buffer-underflow on address [[ADDR:0x[0-9a-f]+]] // CHECK: WRITE of size 1 at [[ADDR]] thread T1 // CHECK: {{#0 .* thread_proc .*thread_stack_array_left_oob.cc}}:[[@LINE-3]] // CHECK: Address [[ADDR]] is located in stack of thread T1 at offset {{.*}} in frame diff --git a/test/asan/TestCases/alloca_instruments_all_paddings.cc b/test/asan/TestCases/alloca_instruments_all_paddings.cc index d60a3b22dcb9..e2c7fafb193e 100644 --- a/test/asan/TestCases/alloca_instruments_all_paddings.cc +++ b/test/asan/TestCases/alloca_instruments_all_paddings.cc @@ -1,4 +1,5 @@ // RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t +// RUN: %clangxx_asan -O3 -mllvm -asan-instrument-allocas %s -o %t // RUN: %run %t 2>&1 // diff --git a/test/asan/TestCases/alloca_loop_unpoisoning.cc b/test/asan/TestCases/alloca_loop_unpoisoning.cc new file mode 100644 index 000000000000..3621a09aa720 --- /dev/null +++ b/test/asan/TestCases/alloca_loop_unpoisoning.cc @@ -0,0 +1,33 @@ +// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t +// RUN: %run %t 2>&1 +// +// REQUIRES: stable-runtime + +// This testcase checks that allocas and VLAs inside loop are correctly unpoisoned. + +#include <assert.h> +#include <alloca.h> +#include <stdint.h> +#include "sanitizer/asan_interface.h" + +void *top, *bot; + +__attribute__((noinline)) void foo(int len) { + char x; + top = &x; + char array[len]; // NOLINT + assert(!(reinterpret_cast<uintptr_t>(array) & 31L)); + alloca(len); + for (int i = 0; i < 32; ++i) { + char array[i]; // NOLINT + bot = alloca(i); + assert(!(reinterpret_cast<uintptr_t>(bot) & 31L)); + } +} + +int main(int argc, char **argv) { + foo(32); + void *q = __asan_region_is_poisoned(bot, (char *)top - (char *)bot); + assert(!q); + return 0; +} diff --git a/test/asan/TestCases/alloca_vla_interact.cc b/test/asan/TestCases/alloca_vla_interact.cc new file mode 100644 index 000000000000..531cc243055d --- /dev/null +++ b/test/asan/TestCases/alloca_vla_interact.cc @@ -0,0 +1,41 @@ +// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t +// RUN: %run %t 2>&1 +// +// REQUIRES: stable-runtime +// XFAIL: powerpc64 + +// This testcase checks correct interaction between VLAs and allocas. + +#include <assert.h> +#include <alloca.h> +#include <stdint.h> +#include "sanitizer/asan_interface.h" + +#define RZ 32 + +__attribute__((noinline)) void foo(int len) { + char *top, *bot; + // This alloca call should live until the end of foo. + char *alloca1 = (char *)alloca(len); + assert(!(reinterpret_cast<uintptr_t>(alloca1) & 31L)); + // This should be first poisoned address after loop. + top = alloca1 - RZ; + for (int i = 0; i < 32; ++i) { + // Check that previous alloca was unpoisoned at the end of iteration. + if (i) assert(!__asan_region_is_poisoned(bot, 96)); + // VLA is unpoisoned at the end of iteration. + volatile char array[i]; + assert(!(reinterpret_cast<uintptr_t>(array) & 31L)); + // Alloca is unpoisoned at the end of iteration, + // because dominated by VLA. + bot = (char *)alloca(i) - RZ; + } + // Check that all allocas from loop were unpoisoned correctly. + void *q = __asan_region_is_poisoned(bot, (char *)top - (char *)bot + 1); + assert(q == top); +} + +int main(int argc, char **argv) { + foo(32); + return 0; +} diff --git a/test/asan/TestCases/allocator_returns_null.cc b/test/asan/TestCases/allocator_returns_null.cc index da6fbd43099e..bc6cd2035163 100644 --- a/test/asan/TestCases/allocator_returns_null.cc +++ b/test/asan/TestCases/allocator_returns_null.cc @@ -4,16 +4,16 @@ // // RUN: %clangxx_asan -O0 %s -o %t // RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH -// RUN: env ASAN_OPTIONS=allocator_may_return_null=1 %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mNULL -// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH -// RUN: env ASAN_OPTIONS=allocator_may_return_null=1 %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cNULL -// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH -// RUN: env ASAN_OPTIONS=allocator_may_return_null=1 %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coNULL -// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH -// RUN: env ASAN_OPTIONS=allocator_may_return_null=1 %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rNULL -// RUN: env ASAN_OPTIONS=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH -// RUN: env ASAN_OPTIONS=allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrNULL +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1 %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mNULL +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cCRASH +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1 %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-cNULL +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coCRASH +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1 %run %t calloc-overflow 2>&1 | FileCheck %s --check-prefix=CHECK-coNULL +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rCRASH +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1 %run %t realloc 2>&1 | FileCheck %s --check-prefix=CHECK-rNULL +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrCRASH +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allocator_may_return_null=1 %run %t realloc-after-malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mrNULL #include <limits.h> #include <stdlib.h> diff --git a/test/asan/TestCases/asan_and_llvm_coverage_test.cc b/test/asan/TestCases/asan_and_llvm_coverage_test.cc index 35bdfcb353c2..05de12b66bba 100644 --- a/test/asan/TestCases/asan_and_llvm_coverage_test.cc +++ b/test/asan/TestCases/asan_and_llvm_coverage_test.cc @@ -1,5 +1,5 @@ // RUN: %clangxx_asan -coverage -O0 %s -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=1 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=1 %run %t 2>&1 | FileCheck %s // XFAIL: android #include <stdio.h> int foo() { return 1; } diff --git a/test/asan/TestCases/asan_options-help.cc b/test/asan/TestCases/asan_options-help.cc index f10830f16085..a5e19e0c2003 100644 --- a/test/asan/TestCases/asan_options-help.cc +++ b/test/asan/TestCases/asan_options-help.cc @@ -1,5 +1,5 @@ // RUN: %clangxx_asan -O0 %s -o %t -// RUN: ASAN_OPTIONS=help=1 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:help=1 %run %t 2>&1 | FileCheck %s int main() { } diff --git a/test/asan/TestCases/atexit_stats.cc b/test/asan/TestCases/atexit_stats.cc index be6534475245..596bfdaa0d53 100644 --- a/test/asan/TestCases/atexit_stats.cc +++ b/test/asan/TestCases/atexit_stats.cc @@ -1,6 +1,6 @@ // Make sure we report atexit stats. // RUN: %clangxx_asan -O3 %s -o %t -// RUN: env ASAN_OPTIONS=atexit=1:print_stats=1 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:atexit=1:print_stats=1 %run %t 2>&1 | FileCheck %s // // No atexit output on Android due to // https://code.google.com/p/address-sanitizer/issues/detail?id=263 diff --git a/test/asan/TestCases/atoi_strict.c b/test/asan/TestCases/atoi_strict.c new file mode 100644 index 000000000000..f3739506fb3a --- /dev/null +++ b/test/asan/TestCases/atoi_strict.c @@ -0,0 +1,55 @@ +// Test strict_string_checks option in atoi function +// RUN: %clang_asan %s -o %t +// RUN: %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +void test1(char *array) { + // Last symbol is non-digit + memset(array, '1', 10); + array[9] = 'a'; + int r = atoi(array); + assert(r == 111111111); +} + +void test2(char *array) { + // Single non-digit symbol + array[9] = 'a'; + int r = atoi(array + 9); + assert(r == 0); +} + +void test3(char *array) { + // Incorrect number format + memset(array, ' ', 10); + array[9] = '-'; + array[8] = '-'; + int r = atoi(array); + assert(r == 0); +} + +int main(int argc, char **argv) { + char *array = (char*)malloc(10); + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(array); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1: READ of size 11 + if (!strcmp(argv[1], "test2")) test2(array); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2: READ of size 2 + if (!strcmp(argv[1], "test3")) test3(array); + // CHECK3: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK3: READ of size 11 + free(array); + return 0; +} diff --git a/test/asan/TestCases/atol_strict.c b/test/asan/TestCases/atol_strict.c new file mode 100644 index 000000000000..f106150f3eaa --- /dev/null +++ b/test/asan/TestCases/atol_strict.c @@ -0,0 +1,55 @@ +// Test strict_string_checks option in atol function +// RUN: %clang_asan %s -o %t +// RUN: %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +void test1(char *array) { + // Last symbol is non-digit + memset(array, '1', 10); + array[9] = 'a'; + long r = atol(array); + assert(r == 111111111); +} + +void test2(char *array) { + // Single non-digit symbol + array[9] = 'a'; + long r = atol(array + 9); + assert(r == 0); +} + +void test3(char *array) { + // Incorrect number format + memset(array, ' ', 10); + array[9] = '-'; + array[8] = '-'; + long r = atol(array); + assert(r == 0); +} + +int main(int argc, char **argv) { + char *array = (char*)malloc(10); + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(array); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1: READ of size 11 + if (!strcmp(argv[1], "test2")) test2(array); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2: READ of size 2 + if (!strcmp(argv[1], "test3")) test3(array); + // CHECK3: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK3: READ of size 11 + free(array); + return 0; +} diff --git a/test/asan/TestCases/atoll_strict.c b/test/asan/TestCases/atoll_strict.c new file mode 100644 index 000000000000..23405d2d220d --- /dev/null +++ b/test/asan/TestCases/atoll_strict.c @@ -0,0 +1,55 @@ +// Test strict_string_checks option in atoll function +// RUN: %clang_asan %s -o %t +// RUN: %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +void test1(char *array) { + // Last symbol is non-digit + memset(array, '1', 10); + array[9] = 'a'; + long long r = atoll(array); + assert(r == 111111111); +} + +void test2(char *array) { + // Single non-digit symbol + array[9] = 'a'; + long long r = atoll(array + 9); + assert(r == 0); +} + +void test3(char *array) { + // Incorrect number format + memset(array, ' ', 10); + array[9] = '-'; + array[8] = '-'; + long long r = atoll(array); + assert(r == 0); +} + +int main(int argc, char **argv) { + char *array = (char*)malloc(10); + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(array); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1: READ of size 11 + if (!strcmp(argv[1], "test2")) test2(array); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2: READ of size 2 + if (!strcmp(argv[1], "test3")) test3(array); + // CHECK3: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK3: READ of size 11 + free(array); + return 0; +} diff --git a/test/asan/TestCases/closed-fds.cc b/test/asan/TestCases/closed-fds.cc new file mode 100644 index 000000000000..af0ac26743ca --- /dev/null +++ b/test/asan/TestCases/closed-fds.cc @@ -0,0 +1,33 @@ +// Check that when the program closed its std(in|out|err), running the external +// symbolizer still works. + +// RUN: rm -f %t.log.* +// RUN: %clangxx_asan -O0 %s -o %t 2>&1 && ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%t.log:verbosity=2 not %run %t 2>&1 +// RUN: FileCheck %s --check-prefix=CHECK-FILE < %t.log.* + +// FIXME: copy %t.log back from the device and re-enable on Android. +// UNSUPPORTED: android + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +int main(int argc, char **argv) { + int result = fprintf(stderr, "Closing streams.\n"); + assert(result > 0); + close(STDIN_FILENO); + close(STDOUT_FILENO); + close(STDERR_FILENO); + result = fprintf(stderr, "Can you hear me now?\n"); + assert(result < 0); + char *x = (char *)malloc(10 * sizeof(char)); + free(x); + x[argc] = 'X'; // BOOM + // CHECK-FILE: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}} + // CHECK-FILE: {{0x.* at pc 0x.* bp 0x.* sp 0x.*}} + // CHECK-FILE: {{WRITE of size 1 at 0x.* thread T0}} + // CHECK-FILE: {{ #0 0x.* in main .*closed-fds.cc:}}[[@LINE-4]] + return 0; +} diff --git a/test/asan/TestCases/contiguous_container_crash.cc b/test/asan/TestCases/contiguous_container_crash.cc index 143ae9d8edee..1ae1ff164302 100644 --- a/test/asan/TestCases/contiguous_container_crash.cc +++ b/test/asan/TestCases/contiguous_container_crash.cc @@ -1,7 +1,8 @@ // RUN: %clangxx_asan -O %s -o %t // RUN: not %run %t crash 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s -// RUN: not %run %t bad-bounds 2>&1 | FileCheck --check-prefix=CHECK-BAD %s -// RUN: env ASAN_OPTIONS=detect_container_overflow=0 %run %t crash +// RUN: not %run %t bad-bounds 2>&1 | FileCheck --check-prefix=CHECK-BAD-BOUNDS %s +// RUN: not %run %t bad-alignment 2>&1 | FileCheck --check-prefix=CHECK-BAD-ALIGNMENT %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_container_overflow=0 %run %t crash // // Test crash due to __sanitizer_annotate_contiguous_container. @@ -21,21 +22,31 @@ int TestCrash() { t[60] = 0; __sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 100, &t[0] + 50); +// CHECK-CRASH: AddressSanitizer: container-overflow return (int)t[60 * one]; // Touches the poisoned memory. } void BadBounds() { long t[100]; +// CHECK-BAD-BOUNDS: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container __sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 101, &t[0] + 50); } +void BadAlignment() { + int t[100]; +// CHECK-BAD-ALIGNMENT: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container +// CHECK-BAD-ALIGNMENT: ERROR: beg is not aligned by 8 + __sanitizer_annotate_contiguous_container(&t[1], &t[0] + 100, &t[1] + 10, + &t[0] + 50); +} + int main(int argc, char **argv) { assert(argc == 2); if (!strcmp(argv[1], "crash")) return TestCrash(); else if (!strcmp(argv[1], "bad-bounds")) BadBounds(); + else if (!strcmp(argv[1], "bad-alignment")) + BadAlignment(); } -// CHECK-CRASH: AddressSanitizer: container-overflow -// CHECK-BAD: ERROR: AddressSanitizer: bad parameters to __sanitizer_annotate_contiguous_container diff --git a/test/asan/TestCases/Linux/coverage-and-lsan.cc b/test/asan/TestCases/coverage-and-lsan.cc index 4cb8e2af3084..f65889c0a1bf 100644 --- a/test/asan/TestCases/Linux/coverage-and-lsan.cc +++ b/test/asan/TestCases/coverage-and-lsan.cc @@ -1,11 +1,11 @@ // Make sure coverage is dumped even if there are reported leaks. // -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t // // RUN: rm -rf %T/coverage-and-lsan // // RUN: mkdir -p %T/coverage-and-lsan/normal -// RUN: ASAN_OPTIONS=coverage=1:coverage_dir=%T/coverage-and-lsan:verbosity=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_dir=%T/coverage-and-lsan:verbosity=1 not %run %t 2>&1 | FileCheck %s // RUN: %sancov print %T/coverage-and-lsan/*.sancov 2>&1 // // REQUIRES: leak-detection diff --git a/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc b/test/asan/TestCases/coverage-caller-callee-total-count.cc index 7598f6bc7bc5..ac6d2486e462 100644 --- a/test/asan/TestCases/Linux/coverage-caller-callee-total-count.cc +++ b/test/asan/TestCases/coverage-caller-callee-total-count.cc @@ -1,7 +1,7 @@ // Test __sanitizer_get_total_unique_coverage for caller-callee coverage -// RUN: %clangxx_asan -fsanitize-coverage=4 %s -o %t -// RUN: ASAN_OPTIONS=coverage=1 %run %t +// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1 %run %t // RUN: rm -f caller-callee*.sancov // // REQUIRES: asan-64-bits diff --git a/test/asan/TestCases/Linux/coverage-caller-callee.cc b/test/asan/TestCases/coverage-caller-callee.cc index cd318962b8e0..9c42817776f9 100644 --- a/test/asan/TestCases/Linux/coverage-caller-callee.cc +++ b/test/asan/TestCases/coverage-caller-callee.cc @@ -1,13 +1,13 @@ // Test caller-callee coverage with large number of threads // and various numbers of callers and callees. -// RUN: %clangxx_asan -fsanitize-coverage=4 %s -o %t -// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 10 1 2>&1 | FileCheck %s --check-prefix=CHECK-10-1 -// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 9 2 2>&1 | FileCheck %s --check-prefix=CHECK-9-2 -// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 7 3 2>&1 | FileCheck %s --check-prefix=CHECK-7-3 -// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 17 1 2>&1 | FileCheck %s --check-prefix=CHECK-17-1 -// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 15 2 2>&1 | FileCheck %s --check-prefix=CHECK-15-2 -// RUN: ASAN_OPTIONS=coverage=1:verbosity=1 %run %t 18 3 2>&1 | FileCheck %s --check-prefix=CHECK-18-3 +// RUN: %clangxx_asan -fsanitize-coverage=edge,indirect-calls %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 10 1 2>&1 | FileCheck %s --check-prefix=CHECK-10-1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 9 2 2>&1 | FileCheck %s --check-prefix=CHECK-9-2 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 7 3 2>&1 | FileCheck %s --check-prefix=CHECK-7-3 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 17 1 2>&1 | FileCheck %s --check-prefix=CHECK-17-1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 15 2 2>&1 | FileCheck %s --check-prefix=CHECK-15-2 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 18 3 2>&1 | FileCheck %s --check-prefix=CHECK-18-3 // RUN: rm -f caller-callee*.sancov // // REQUIRES: asan-64-bits diff --git a/test/asan/TestCases/Linux/coverage-disabled.cc b/test/asan/TestCases/coverage-disabled.cc index cb33542a5701..dd28485a6bcf 100644 --- a/test/asan/TestCases/Linux/coverage-disabled.cc +++ b/test/asan/TestCases/coverage-disabled.cc @@ -1,19 +1,19 @@ // Test that no data is collected without a runtime flag. // -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t // // RUN: rm -rf %T/coverage-disabled // // RUN: mkdir -p %T/coverage-disabled/normal -// RUN: ASAN_OPTIONS=coverage_direct=0:coverage_dir=%T/coverage-disabled/normal:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_direct=0:coverage_dir=%T/coverage-disabled/normal:verbosity=1 %run %t // RUN: not %sancov print %T/coverage-disabled/normal/*.sancov 2>&1 // // RUN: mkdir -p %T/coverage-disabled/direct -// RUN: ASAN_OPTIONS=coverage_direct=1:coverage_dir=%T/coverage-disabled/direct:verbosity=1 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_direct=1:coverage_dir=%T/coverage-disabled/direct:verbosity=1 %run %t // RUN: cd %T/coverage-disabled/direct // RUN: not %sancov rawunpack *.sancov // -// XFAIL: android +// UNSUPPORTED: android int main(int argc, char **argv) { return 0; diff --git a/test/asan/TestCases/coverage-levels.cc b/test/asan/TestCases/coverage-levels.cc new file mode 100644 index 000000000000..aa3641927cf2 --- /dev/null +++ b/test/asan/TestCases/coverage-levels.cc @@ -0,0 +1,34 @@ +// Test various levels of coverage +// +// RUN: %clangxx_asan -O1 -fsanitize-coverage=func %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %clangxx_asan -O1 -fsanitize-coverage=bb %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %clangxx_asan -O1 -fsanitize-coverage=edge %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 +// RUN: %clangxx_asan -O1 -fsanitize-coverage=edge -mllvm -sanitizer-coverage-block-threshold=0 %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 +// RUN: %clangxx_asan -O1 -fsanitize-coverage=edge,8bit-counters %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_counters=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK_COUNTERS + +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_bitset=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOBITSET +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:coverage_pcs=0:verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3_NOPCS +// +// REQUIRES: asan-64-bits + +volatile int sink; +int main(int argc, char **argv) { + if (argc == 0) + sink = 0; +} + +// CHECK1: CovDump: bitset of 1 bits written for '{{.*}}', 1 bits are set +// CHECK1: 1 PCs written +// CHECK2: CovDump: bitset of 3 bits written for '{{.*}}', 2 bits are set +// CHECK2: 2 PCs written +// CHECK3: CovDump: bitset of 4 bits written for '{{.*}}', 3 bits are set +// CHECK3: 3 PCs written +// CHECK3_NOBITSET-NOT: bitset of +// CHECK3_NOPCS-NOT: PCs written +// CHECK_COUNTERS: CovDump: 4 counters written for diff --git a/test/asan/TestCases/Linux/coverage-maybe-open-file.cc b/test/asan/TestCases/coverage-maybe-open-file.cc index 4580de411799..b261fb0fc775 100644 --- a/test/asan/TestCases/Linux/coverage-maybe-open-file.cc +++ b/test/asan/TestCases/coverage-maybe-open-file.cc @@ -1,11 +1,11 @@ // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 // XFAIL: android // -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t // RUN: rm -rf %T/coverage-maybe-open-file // RUN: mkdir -p %T/coverage-maybe-open-file && cd %T/coverage-maybe-open-file -// RUN: ASAN_OPTIONS=coverage=1 %run %t | FileCheck %s --check-prefix=CHECK-success -// RUN: ASAN_OPTIONS=coverage=0 %run %t | FileCheck %s --check-prefix=CHECK-fail +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1 %run %t | FileCheck %s --check-prefix=CHECK-success +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=0 %run %t | FileCheck %s --check-prefix=CHECK-fail // RUN: [ "$(cat test.sancov.packed)" == "test" ] // RUN: cd .. && rm -rf %T/coverage-maybe-open-file @@ -15,6 +15,7 @@ #include <sanitizer/coverage_interface.h> +// FIXME: the code below might not work on Windows. int main(int argc, char **argv) { int fd = __sanitizer_maybe_open_cov_file("test"); if (fd > 0) { diff --git a/test/asan/TestCases/coverage-order-pcs.cc b/test/asan/TestCases/coverage-order-pcs.cc new file mode 100644 index 000000000000..3f56354e44a7 --- /dev/null +++ b/test/asan/TestCases/coverage-order-pcs.cc @@ -0,0 +1,56 @@ +// Test coverage_order_pcs=1 flag which orders the PCs by their appearance. +// RUN: DIR=%T/coverage-order-pcs +// RUN: rm -rf $DIR +// RUN: mkdir $DIR +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=0 %run %t +// RUN: mv $DIR/*sancov $DIR/A + +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=0 %run %t 1 +// RUN: mv $DIR/*sancov $DIR/B + +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=1 %run %t +// RUN: mv $DIR/*sancov $DIR/C + +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage_dir=$DIR:coverage=1:coverage_order_pcs=1 %run %t 1 +// RUN: mv $DIR/*sancov $DIR/D +// +// RUN: (%sancov print $DIR/A; %sancov print $DIR/B; %sancov print $DIR/C; %sancov print $DIR/D) | FileCheck %s +// +// RUN: rm -rf $DIR +// Ordering works only in 64-bit mode for now. +// REQUIRES: asan-64-bits +#include <stdio.h> + +void foo() { fprintf(stderr, "FOO\n"); } +void bar() { fprintf(stderr, "BAR\n"); } + +int main(int argc, char **argv) { + if (argc == 2) { + foo(); + bar(); + } else { + bar(); + foo(); + } +} + +// Run A: no ordering +// CHECK: [[FOO:0x[0-9a-f]*]] +// CHECK-NEXT: [[BAR:0x[0-9a-f]*]] +// CHECK-NEXT: [[MAIN:0x[0-9a-f]*]] +// +// Run B: still no ordering +// CHECK-NEXT: [[FOO]] +// CHECK-NEXT: [[BAR]] +// CHECK-NEXT: [[MAIN]] +// +// Run C: MAIN, BAR, FOO +// CHECK-NEXT: [[MAIN]] +// CHECK-NEXT: [[BAR]] +// CHECK-NEXT: [[FOO]] +// +// Run D: MAIN, FOO, BAR +// CHECK-NEXT: [[MAIN]] +// CHECK-NEXT: [[FOO]] +// CHECK-NEXT: [[BAR]] diff --git a/test/asan/TestCases/Linux/coverage-reset.cc b/test/asan/TestCases/coverage-reset.cc index d3d35e21b5a7..8e025600fda7 100644 --- a/test/asan/TestCases/Linux/coverage-reset.cc +++ b/test/asan/TestCases/coverage-reset.cc @@ -1,7 +1,7 @@ // Test __sanitizer_reset_coverage(). -// RUN: %clangxx_asan -fsanitize-coverage=1 %s -o %t -// RUN: ASAN_OPTIONS=coverage=1 %run %t +// RUN: %clangxx_asan -fsanitize-coverage=func %s -o %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1 %run %t #include <sanitizer/coverage_interface.h> #include <stdio.h> diff --git a/test/asan/TestCases/coverage-tracing.cc b/test/asan/TestCases/coverage-tracing.cc new file mode 100644 index 000000000000..21a98515f648 --- /dev/null +++ b/test/asan/TestCases/coverage-tracing.cc @@ -0,0 +1,50 @@ +// Test -fsanitize-coverage=trace-bb +// +// RUN: %clangxx_asan -O1 -fsanitize-coverage=func,trace-bb %s -o %t +// RUN: rm -rf %T/coverage-tracing +// RUN: mkdir %T/coverage-tracing +// RUN: cd %T/coverage-tracing +// RUN: A=x; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK1; mv trace-points.*.sancov $A.points +// RUN: A=f; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points +// RUN: A=b; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK2; mv trace-points.*.sancov $A.points +// RUN: A=bf; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points +// RUN: A=fb; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK3; mv trace-points.*.sancov $A.points +// RUN: A=ffb; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points +// RUN: A=fff; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK4; mv trace-points.*.sancov $A.points +// RUN: A=bbf; ASAN_OPTIONS=$ASAN_OPTIONS:coverage=1:verbosity=1 %run %t $A 100 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK301; mv trace-points.*.sancov $A.points +// RUN: diff f.points fff.points +// RUN: diff bf.points fb.points +// RUN: diff bf.points ffb.points +// RUN: diff bf.points bbf.points +// RUN: not diff x.points f.points +// RUN: not diff x.points b.points +// RUN: not diff x.points bf.points +// RUN: not diff f.points b.points +// RUN: not diff f.points bf.points +// RUN: not diff b.points bf.points +// RUN: rm -rf %T/coverage-tracing +// +// REQUIRES: asan-64-bits + +#include <stdlib.h> +volatile int sink; +__attribute__((noinline)) void foo() { sink++; } +__attribute__((noinline)) void bar() { sink++; } + +int main(int argc, char **argv) { + if (argc != 3) return 0; + int n = strtol(argv[2], 0, 10); + while (n-- > 0) { + for (int i = 0; argv[1][i]; i++) { + if (argv[1][i] == 'f') foo(); + else if (argv[1][i] == 'b') bar(); + } + } +} + +// CHECK: CovDump: Trace: 3 PCs written +// CHECK1: CovDump: Trace: 1 Events written +// CHECK2: CovDump: Trace: 2 Events written +// CHECK3: CovDump: Trace: 3 Events written +// CHECK4: CovDump: Trace: 4 Events written +// CHECK301: CovDump: Trace: 301 Events written diff --git a/test/asan/TestCases/debug_mapping.cc b/test/asan/TestCases/debug_mapping.cc index f96abf6d11cf..04de97548012 100644 --- a/test/asan/TestCases/debug_mapping.cc +++ b/test/asan/TestCases/debug_mapping.cc @@ -1,6 +1,6 @@ // Checks that the debugging API returns correct shadow scale and offset. // RUN: %clangxx_asan -O %s -o %t -// RUN: env ASAN_OPTIONS=verbosity=1 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1 %run %t 2>&1 | FileCheck %s #include <sanitizer/asan_interface.h> #include <stdio.h> @@ -8,14 +8,14 @@ // printed because of verbosity=1 // CHECK: SHADOW_SCALE: [[SCALE:[0-9]+]] -// CHECK: SHADOW_OFFSET: [[OFFSET:[0-9]+]] +// CHECK: SHADOW_OFFSET: [[OFFSET:0x[0-9a-f]+]] int main() { size_t scale, offset; __asan_get_shadow_mapping(&scale, &offset); - fprintf(stderr, "scale: %lx\n", scale); - fprintf(stderr, "offset: %lx\n", offset); + fprintf(stderr, "scale: %d\n", (int)scale); + fprintf(stderr, "offset: 0x%lx\n", offset); // CHECK: scale: [[SCALE]] // CHECK: offset: [[OFFSET]] diff --git a/test/asan/TestCases/debug_ppc64_mapping.cc b/test/asan/TestCases/debug_ppc64_mapping.cc index 3ddd3e1404ce..ad7e25ce3bd0 100644 --- a/test/asan/TestCases/debug_ppc64_mapping.cc +++ b/test/asan/TestCases/debug_ppc64_mapping.cc @@ -1,6 +1,6 @@ // RUN: %clang_asan -O0 %s -o %t -// RUN: env ASAN_OPTIONS=verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0 -// RUN: env ASAN_OPTIONS=verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64 // REQUIRES: powerpc64-supported-target #include <stdio.h> diff --git a/test/asan/TestCases/debug_stacks.cc b/test/asan/TestCases/debug_stacks.cc index 57bb5465035a..15af76dc438a 100644 --- a/test/asan/TestCases/debug_stacks.cc +++ b/test/asan/TestCases/debug_stacks.cc @@ -2,6 +2,9 @@ // malloc and free stacks. // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// FIXME: Figure out why allocation/free stack traces may be too short on ARM. +// REQUIRES: stable-runtime + #include <sanitizer/asan_interface.h> #include <stdio.h> #include <stdlib.h> diff --git a/test/asan/TestCases/deep_call_stack.cc b/test/asan/TestCases/deep_call_stack.cc index a5b846e3eb75..0a26a80758c6 100644 --- a/test/asan/TestCases/deep_call_stack.cc +++ b/test/asan/TestCases/deep_call_stack.cc @@ -1,10 +1,10 @@ // Check that UAR mode can handle very deep recusrion. -// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 // RUN: %clangxx_asan -O2 %s -o %t && \ // RUN: (ulimit -s 4096; %run %t) 2>&1 | FileCheck %s // Also check that use_sigaltstack+verbosity doesn't crash. -// RUN: env ASAN_OPTIONS=verbosity=1:use_sigaltstack=1 %run %t | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:verbosity=1:use_sigaltstack=1 %run %t | FileCheck %s #include <stdio.h> __attribute__((noinline)) diff --git a/test/asan/TestCases/deep_stack_uaf.cc b/test/asan/TestCases/deep_stack_uaf.cc index 3e88d697fcef..7b0f56ef3c66 100644 --- a/test/asan/TestCases/deep_stack_uaf.cc +++ b/test/asan/TestCases/deep_stack_uaf.cc @@ -1,7 +1,7 @@ // Check that we can store lots of stack frames if asked to. // RUN: %clangxx_asan -O0 %s -o %t 2>&1 -// RUN: env ASAN_OPTIONS=malloc_context_size=120:redzone=512 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=120:redzone=512 not %run %t 2>&1 | FileCheck %s // XFAIL: arm-linux-gnueabi // XFAIL: armv7l-unknown-linux-gnueabihf #include <stdlib.h> diff --git a/test/asan/TestCases/default_options.cc b/test/asan/TestCases/default_options.cc index 1614fbe71b4b..a3aa6637e8ac 100644 --- a/test/asan/TestCases/default_options.cc +++ b/test/asan/TestCases/default_options.cc @@ -1,9 +1,6 @@ // RUN: %clangxx_asan -O2 %s -o %t // RUN: %run %t 2>&1 | FileCheck %s -// __asan_default_options() are not supported on Windows. -// XFAIL: win32 - const char *kAsanDefaultOptions="verbosity=1 help=1"; extern "C" diff --git a/test/asan/TestCases/double-free.cc b/test/asan/TestCases/double-free.cc index f0dd29174849..2966aadff706 100644 --- a/test/asan/TestCases/double-free.cc +++ b/test/asan/TestCases/double-free.cc @@ -2,8 +2,8 @@ // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX // Also works if no malloc context is available. -// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s // XFAIL: arm-linux-gnueabi // XFAIL: armv7l-unknown-linux-gnueabihf diff --git a/test/asan/TestCases/dump_instruction_bytes.cc b/test/asan/TestCases/dump_instruction_bytes.cc index 981e3c31327f..33f382cb12be 100644 --- a/test/asan/TestCases/dump_instruction_bytes.cc +++ b/test/asan/TestCases/dump_instruction_bytes.cc @@ -1,7 +1,7 @@ // Check that ASan prints the faulting instruction bytes on // dump_instruction_bytes=1 // RUN: %clangxx_asan %s -o %t -// RUN: env ASAN_OPTIONS=dump_instruction_bytes=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:dump_instruction_bytes=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP // // REQUIRES: x86_64-supported-target,i386-supported-target diff --git a/test/asan/TestCases/free_hook_realloc.cc b/test/asan/TestCases/free_hook_realloc.cc index 4b2753252a8d..cbc5d6fed56e 100644 --- a/test/asan/TestCases/free_hook_realloc.cc +++ b/test/asan/TestCases/free_hook_realloc.cc @@ -2,9 +2,6 @@ // RUN: %clangxx_asan -O2 %s -o %t // RUN: %run %t 2>&1 | FileCheck %s -// Malloc/free hooks are not supported on Windows. -// XFAIL: win32 - #include <stdlib.h> #include <unistd.h> #include <sanitizer/allocator_interface.h> diff --git a/test/asan/TestCases/gc-test.cc b/test/asan/TestCases/gc-test.cc index 4ffa51dd22d3..3fedd6a68d38 100644 --- a/test/asan/TestCases/gc-test.cc +++ b/test/asan/TestCases/gc-test.cc @@ -1,9 +1,9 @@ // RUN: %clangxx_asan %s -pthread -o %t -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 // RUN: %clangxx_asan -O3 %s -pthread -o %t -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 // REQUIRES: stable-runtime #include <assert.h> diff --git a/test/asan/TestCases/heap-overflow-large.cc b/test/asan/TestCases/heap-overflow-large.cc index eb2fcc3220e7..566b1158a5da 100644 --- a/test/asan/TestCases/heap-overflow-large.cc +++ b/test/asan/TestCases/heap-overflow-large.cc @@ -15,9 +15,9 @@ int main(int argc, char *argv[]) { int *x = new int[5]; memset(x, 0, sizeof(x[0]) * 5); int index = atoi(argv[1]); - int res = x[index]; + unsigned res = x[index]; // CHECK: main // CHECK-NOT: CHECK failed delete[] x; - return res ? res : 1; + return (res % 10) + 1; } diff --git a/test/asan/TestCases/heap-overflow.cc b/test/asan/TestCases/heap-overflow.cc index 70a1203562be..caecea704966 100644 --- a/test/asan/TestCases/heap-overflow.cc +++ b/test/asan/TestCases/heap-overflow.cc @@ -2,7 +2,7 @@ // RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=print_stats=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:print_stats=1 not %run %t 2>&1 | FileCheck %s // FIXME: Fix this test under GCC. // REQUIRES: Clang diff --git a/test/asan/TestCases/heavy_uar_test.cc b/test/asan/TestCases/heavy_uar_test.cc index 1f8caea21690..a70dcef14345 100644 --- a/test/asan/TestCases/heavy_uar_test.cc +++ b/test/asan/TestCases/heavy_uar_test.cc @@ -1,4 +1,4 @@ -// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s // XFAIL: arm-linux-gnueabi diff --git a/test/asan/TestCases/init-order-atexit.cc b/test/asan/TestCases/init-order-atexit.cc index e0dac325ce58..1bbc655b17f1 100644 --- a/test/asan/TestCases/init-order-atexit.cc +++ b/test/asan/TestCases/init-order-atexit.cc @@ -1,6 +1,3 @@ -// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 -// XFAIL: android -// // Test for the following situation: // (1) global A is constructed. // (2) exit() is called during construction of global B. @@ -8,7 +5,7 @@ // We do *not* want to report init-order bug in this case. // RUN: %clangxx_asan -O0 %s %p/Helpers/init-order-atexit-extra.cc -o %t -// RUN: env ASAN_OPTIONS=strict_init_order=true not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true not %run %t 2>&1 | FileCheck %s #include <stdio.h> #include <stdlib.h> diff --git a/test/asan/TestCases/init-order-pthread-create.cc b/test/asan/TestCases/init-order-pthread-create.cc index eeff308a4cd5..12362fc440dc 100644 --- a/test/asan/TestCases/init-order-pthread-create.cc +++ b/test/asan/TestCases/init-order-pthread-create.cc @@ -2,29 +2,40 @@ // called. // RUN: %clangxx_asan %s %p/Helpers/init-order-pthread-create-extra.cc -pthread -o %t -// RUN: env ASAN_OPTIONS=strict_init_order=true %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_init_order=true %run %t #include <stdio.h> #include <pthread.h> +#include <unistd.h> -void *run(void *arg) { - return arg; +void *bar(void *input, bool sleep_before_init) { + if (sleep_before_init) + usleep(500000); + return input; } -void *foo(void *input) { - pthread_t t; - pthread_create(&t, 0, run, input); - void *res; - pthread_join(t, &res); - return res; -} +void *glob = bar((void*)0x1234, false); +extern void *glob2; -void *bar(void *input) { - return input; +void *poll(void *arg) { + void **glob = (void**)arg; + while (true) { + usleep(100000); + printf("glob is now: %p\n", *glob); + } } -void *glob = foo((void*)0x1234); -extern void *glob2; +struct GlobalPollerStarter { + GlobalPollerStarter() { + pthread_t p; + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_create(&p, 0, poll, &glob); + pthread_attr_destroy(&attr); + printf("glob poller is started"); + } +} global_poller; int main() { printf("%p %p\n", glob, glob2); diff --git a/test/asan/TestCases/initialization-blacklist.cc b/test/asan/TestCases/initialization-blacklist.cc index 8ea6b46c1833..bcdb111b8bfb 100644 --- a/test/asan/TestCases/initialization-blacklist.cc +++ b/test/asan/TestCases/initialization-blacklist.cc @@ -3,15 +3,15 @@ // RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-blacklist-extra.cc\ // RUN: %p/Helpers/initialization-blacklist-extra2.cc \ // RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-blacklist-extra.cc\ // RUN: %p/Helpers/initialization-blacklist-extra2.cc \ // RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-blacklist-extra.cc\ // RUN: %p/Helpers/initialization-blacklist-extra2.cc \ // RUN: -fsanitize-blacklist=%p/Helpers/initialization-blacklist.txt -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // Function is defined in another TU. int readBadGlobal(); diff --git a/test/asan/TestCases/initialization-bug.cc b/test/asan/TestCases/initialization-bug.cc index badc6d1d1165..6257d67c308d 100644 --- a/test/asan/TestCases/initialization-bug.cc +++ b/test/asan/TestCases/initialization-bug.cc @@ -1,7 +1,7 @@ // Test to make sure basic initialization order errors are caught. -// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t-INIT-ORDER-EXE +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true not %run %t-INIT-ORDER-EXE 2>&1 | FileCheck %s // Do not test with optimization -- the error may be optimized away. @@ -32,6 +32,8 @@ int __attribute__((noinline)) initX() { // CHECK: {{AddressSanitizer: initialization-order-fiasco}} // CHECK: {{READ of size .* at 0x.* thread T0}} // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}} + // CHECK: registered at: + // CHECK: 0x{{.*}} in __asan_register_globals } // This initializer begins our initialization order problems. diff --git a/test/asan/TestCases/initialization-constexpr.cc b/test/asan/TestCases/initialization-constexpr.cc index 644246186e02..1188766b6020 100644 --- a/test/asan/TestCases/initialization-constexpr.cc +++ b/test/asan/TestCases/initialization-constexpr.cc @@ -5,13 +5,13 @@ // not dynamic initialization). // RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-constexpr-extra.cc --std=c++11 -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 class Integer { private: diff --git a/test/asan/TestCases/initialization-nobug.cc b/test/asan/TestCases/initialization-nobug.cc index 1249deb425aa..3890edf07202 100644 --- a/test/asan/TestCases/initialization-nobug.cc +++ b/test/asan/TestCases/initialization-nobug.cc @@ -2,13 +2,13 @@ // order checking. If successful, this will just return 0. // RUN: %clangxx_asan -O0 %s %p/Helpers/initialization-nobug-extra.cc -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O1 %s %p/Helpers/initialization-nobug-extra.cc -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O2 %s %p/Helpers/initialization-nobug-extra.cc -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // RUN: %clangxx_asan -O3 %s %p/Helpers/initialization-nobug-extra.cc -o %t -// RUN: env ASAN_OPTIONS=check_initialization_order=true %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_initialization_order=true %run %t 2>&1 // Simple access: // Make sure that accessing a global in the same TU is safe diff --git a/test/asan/TestCases/interface_test.cc b/test/asan/TestCases/interface_test.cc index dc9d0652c8c3..9419f07e91ea 100644 --- a/test/asan/TestCases/interface_test.cc +++ b/test/asan/TestCases/interface_test.cc @@ -1,8 +1,8 @@ // Check that user may include ASan interface header. // RUN: %clang_asan %s -o %t && %run %t // RUN: %clang_asan -x c %s -o %t && %run %t -// RUN: %clang %s -o %t && %run %t -// RUN: %clang -x c %s -o %t && %run %t +// RUN: %clang %s -pie -o %t && %run %t +// RUN: %clang -x c %s -pie -o %t && %run %t #include <sanitizer/asan_interface.h> int main() { diff --git a/test/asan/TestCases/invalid-free.cc b/test/asan/TestCases/invalid-free.cc index cb545ccc215e..c6f7b842a91d 100644 --- a/test/asan/TestCases/invalid-free.cc +++ b/test/asan/TestCases/invalid-free.cc @@ -2,8 +2,8 @@ // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=MALLOC-CTX // Also works if no malloc context is available. -// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s // XFAIL: arm-linux-gnueabi // XFAIL: armv7l-unknown-linux-gnueabihf diff --git a/test/asan/TestCases/log-path_test.cc b/test/asan/TestCases/log-path_test.cc index 7dd1fadda86d..d253a6f50cf3 100644 --- a/test/asan/TestCases/log-path_test.cc +++ b/test/asan/TestCases/log-path_test.cc @@ -9,21 +9,21 @@ // Good log_path. // RUN: rm -f %t.log.* -// RUN: env ASAN_OPTIONS=log_path=%t.log not %run %t 2> %t.out +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%t.log not %run %t 2> %t.out // RUN: FileCheck %s --check-prefix=CHECK-ERROR < %t.log.* // Invalid log_path. -// RUN: env ASAN_OPTIONS=log_path=/dev/null/INVALID not %run %t 2> %t.out +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=/dev/null/INVALID not %run %t 2> %t.out // RUN: FileCheck %s --check-prefix=CHECK-INVALID < %t.out // Too long log_path. -// RUN: env ASAN_OPTIONS=log_path=`for((i=0;i<10000;i++)); do echo -n $i; done` \ +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=`for((i=0;i<10000;i++)); do echo -n $i; done` \ // RUN: not %run %t 2> %t.out // RUN: FileCheck %s --check-prefix=CHECK-LONG < %t.out // Run w/o errors should not produce any log. // RUN: rm -f %t.log.* -// RUN: env ASAN_OPTIONS=log_path=%t.log %run %t ARG ARG ARG +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%t.log %run %t ARG ARG ARG // RUN: not cat %t.log.* // FIXME: log_path is not supported on Windows yet. diff --git a/test/asan/TestCases/malloc_context_size.cc b/test/asan/TestCases/malloc_context_size.cc index 0d9f31598545..91e1bdc5613e 100644 --- a/test/asan/TestCases/malloc_context_size.cc +++ b/test/asan/TestCases/malloc_context_size.cc @@ -1,9 +1,9 @@ // RUN: %clangxx_asan -O0 %s -o %t -// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=malloc_context_size=1:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=malloc_context_size=1:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=malloc_context_size=2 not %run %t 2>&1 | FileCheck %s --check-prefix=TWO +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=1:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=1:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:malloc_context_size=2 not %run %t 2>&1 | FileCheck %s --check-prefix=TWO int main() { char *x = new char[20]; diff --git a/test/asan/TestCases/malloc_fill.cc b/test/asan/TestCases/malloc_fill.cc index 5c926803708d..13a73a719ddd 100644 --- a/test/asan/TestCases/malloc_fill.cc +++ b/test/asan/TestCases/malloc_fill.cc @@ -1,8 +1,8 @@ // Check that we fill malloc-ed memory correctly. // RUN: %clangxx_asan %s -o %t // RUN: %run %t | FileCheck %s -// RUN: env ASAN_OPTIONS=max_malloc_fill_size=10:malloc_fill_byte=8 %run %t | FileCheck %s --check-prefix=CHECK-10-8 -// RUN: env ASAN_OPTIONS=max_malloc_fill_size=20:malloc_fill_byte=171 %run %t | FileCheck %s --check-prefix=CHECK-20-ab +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:max_malloc_fill_size=10:malloc_fill_byte=8 %run %t | FileCheck %s --check-prefix=CHECK-10-8 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:max_malloc_fill_size=20:malloc_fill_byte=171 %run %t | FileCheck %s --check-prefix=CHECK-20-ab #include <stdio.h> int main(int argc, char **argv) { diff --git a/test/asan/TestCases/max_redzone.cc b/test/asan/TestCases/max_redzone.cc index 01c25a9f3efc..c5539bcfb16f 100644 --- a/test/asan/TestCases/max_redzone.cc +++ b/test/asan/TestCases/max_redzone.cc @@ -1,8 +1,8 @@ // Test max_redzone runtime option. -// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=max_redzone=16 %run %t 0 2>&1 +// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:max_redzone=16 %run %t 0 2>&1 // RUN: %clangxx_asan -O0 %s -o %t && %run %t 1 2>&1 -// RUN: %clangxx_asan -O3 %s -o %t && env ASAN_OPTIONS=max_redzone=16 %run %t 0 2>&1 +// RUN: %clangxx_asan -O3 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:max_redzone=16 %run %t 0 2>&1 // RUN: %clangxx_asan -O3 %s -o %t && %run %t 1 2>&1 #include <stdio.h> diff --git a/test/asan/TestCases/memcmp_strict_test.cc b/test/asan/TestCases/memcmp_strict_test.cc index 16b7673dd547..a15d0a35e5ec 100644 --- a/test/asan/TestCases/memcmp_strict_test.cc +++ b/test/asan/TestCases/memcmp_strict_test.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=strict_memcmp=0 %run %t -// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=strict_memcmp=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_memcmp=0 %run %t +// RUN: %clangxx_asan -O0 %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_memcmp=1 not %run %t 2>&1 | FileCheck %s // Default to strict_memcmp=1. // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s diff --git a/test/asan/TestCases/mmap_limit_mb.cc b/test/asan/TestCases/mmap_limit_mb.cc index d4ffb2eac246..02410525b2d6 100644 --- a/test/asan/TestCases/mmap_limit_mb.cc +++ b/test/asan/TestCases/mmap_limit_mb.cc @@ -3,10 +3,10 @@ // RUN: %clangxx_asan -O2 %s -o %t // RUN: %run %t 20 16 // RUN: %run %t 30 1000000 -// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 %run %t 20 16 -// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 %run %t 20 1000000 -// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 not %run %t 500 16 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=mmap_limit_mb=300 not %run %t 500 1000000 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 %run %t 20 16 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 %run %t 20 1000000 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 not %run %t 500 16 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:mmap_limit_mb=300 not %run %t 500 1000000 2>&1 | FileCheck %s // XFAIL: arm-linux-gnueabi #include <assert.h> diff --git a/test/asan/TestCases/no_asan_gen_globals.c b/test/asan/TestCases/no_asan_gen_globals.c index 0a383da1384d..2b13deace4b5 100644 --- a/test/asan/TestCases/no_asan_gen_globals.c +++ b/test/asan/TestCases/no_asan_gen_globals.c @@ -1,5 +1,7 @@ // FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 // XFAIL: android +// FIXME: http://llvm.org/bugs/show_bug.cgi?id=22682 +// REQUIRES: asan-64-bits // // Make sure __asan_gen_* strings do not end up in the symbol table. diff --git a/test/asan/TestCases/on_error_callback.cc b/test/asan/TestCases/on_error_callback.cc index c378c8b2de1b..0ad83d549af2 100644 --- a/test/asan/TestCases/on_error_callback.cc +++ b/test/asan/TestCases/on_error_callback.cc @@ -1,8 +1,5 @@ // RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s -// FIXME: __asan_on_error() is not supported on Windows yet. -// XFAIL: win32 - #include <stdio.h> #include <stdlib.h> diff --git a/test/asan/TestCases/poison_partial.cc b/test/asan/TestCases/poison_partial.cc index ce9c98b7859a..8a8921566dbc 100644 --- a/test/asan/TestCases/poison_partial.cc +++ b/test/asan/TestCases/poison_partial.cc @@ -1,8 +1,8 @@ // RUN: %clangxx_asan -O0 %s -o %t // RUN: not %run %t 2>&1 | FileCheck %s // RUN: not %run %t heap 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=poison_partial=0 %run %t -// RUN: env ASAN_OPTIONS=poison_partial=0 %run %t heap +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_partial=0 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:poison_partial=0 %run %t heap #include <string.h> char g[21]; char *x; diff --git a/test/asan/TestCases/print_summary.cc b/test/asan/TestCases/print_summary.cc index 79411c529469..675934071252 100644 --- a/test/asan/TestCases/print_summary.cc +++ b/test/asan/TestCases/print_summary.cc @@ -1,14 +1,16 @@ // RUN: %clangxx_asan -O0 %s -o %t -// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=YES -// RUN: env ASAN_OPTIONS=print_summary=false not %run %t 2>&1 | FileCheck %s --check-prefix=NO +// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=SOURCE +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:symbolize=false not %run %t 2>&1 | FileCheck %s --check-prefix=MODULE +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:print_summary=false not %run %t 2>&1 | FileCheck %s --check-prefix=MISSING int main() { char *x = new char[20]; delete[] x; return x[0]; - // YES: ERROR: AddressSanitizer: heap-use-after-free - // YES: SUMMARY: AddressSanitizer: heap-use-after-free - // NO: ERROR: AddressSanitizer: heap-use-after-free - // NO-NOT: SUMMARY: AddressSanitizer: heap-use-after-free + // SOURCE: ERROR: AddressSanitizer: heap-use-after-free + // SOURCE: SUMMARY: AddressSanitizer: heap-use-after-free {{.*}}print_summary.cc:[[@LINE-2]]{{.*}} main + // MODULE: ERROR: AddressSanitizer: heap-use-after-free + // MODULE: SUMMARY: AddressSanitizer: heap-use-after-free ({{.*}}+0x{{.*}}) + // MISSING: ERROR: AddressSanitizer: heap-use-after-free + // MISSING-NOT: SUMMARY } - diff --git a/test/asan/TestCases/printf-1.c b/test/asan/TestCases/printf-1.c index 5657083c5865..2df74b67a31a 100644 --- a/test/asan/TestCases/printf-1.c +++ b/test/asan/TestCases/printf-1.c @@ -1,6 +1,6 @@ // RUN: %clang_asan -O2 %s -o %t -// RUN: env ASAN_OPTIONS=check_printf=1 %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=check_printf=0 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=1 %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=0 %run %t 2>&1 | FileCheck %s // RUN: %run %t 2>&1 | FileCheck %s #include <stdio.h> diff --git a/test/asan/TestCases/printf-2.c b/test/asan/TestCases/printf-2.c index e9cb47e24c15..b3ab96111142 100644 --- a/test/asan/TestCases/printf-2.c +++ b/test/asan/TestCases/printf-2.c @@ -1,9 +1,9 @@ // RUN: %clang_asan -O2 %s -o %t // We need replace_str=0 and replace_intrin=0 to avoid reporting errors in // strlen() and memcpy() called by printf(). -// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s -// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s -// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s // FIXME: printf is not intercepted on Windows yet. // XFAIL: win32 diff --git a/test/asan/TestCases/printf-3.c b/test/asan/TestCases/printf-3.c index d16833d83c6e..bc9fece5dd96 100644 --- a/test/asan/TestCases/printf-3.c +++ b/test/asan/TestCases/printf-3.c @@ -1,6 +1,6 @@ // RUN: %clang_asan -O2 %s -o %t -// RUN: env ASAN_OPTIONS=check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s -// RUN: env ASAN_OPTIONS=check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s // FIXME: printf is not intercepted on Windows yet. diff --git a/test/asan/TestCases/printf-4.c b/test/asan/TestCases/printf-4.c index e269211d4871..b2a14ff4f25a 100644 --- a/test/asan/TestCases/printf-4.c +++ b/test/asan/TestCases/printf-4.c @@ -1,8 +1,8 @@ // RUN: %clang_asan -O2 %s -o %t // We need replace_str=0 and replace_intrin=0 to avoid reporting errors in // strlen() and memcpy() called by puts(). -// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s -// RUN: env ASAN_OPTIONS=replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s // FIXME: printf is not intercepted on Windows yet. // XFAIL: win32 diff --git a/test/asan/TestCases/printf-5.c b/test/asan/TestCases/printf-5.c index ac2c1c4b2997..d4e2a0ab9cce 100644 --- a/test/asan/TestCases/printf-5.c +++ b/test/asan/TestCases/printf-5.c @@ -1,8 +1,8 @@ // RUN: %clang_asan -O2 %s -o %t // We need replace_intrin=0 to avoid reporting errors in memcpy. -// RUN: env ASAN_OPTIONS=replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s -// RUN: env ASAN_OPTIONS=replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s -// RUN: env ASAN_OPTIONS=replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s // FIXME: printf is not intercepted on Windows yet. // XFAIL: win32 diff --git a/test/asan/TestCases/sleep_before_dying.c b/test/asan/TestCases/sleep_before_dying.c index 28ae0bf66d47..2029f572a9eb 100644 --- a/test/asan/TestCases/sleep_before_dying.c +++ b/test/asan/TestCases/sleep_before_dying.c @@ -1,5 +1,5 @@ // RUN: %clang_asan -O2 %s -o %t -// RUN: env ASAN_OPTIONS="sleep_before_dying=1" not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:sleep_before_dying=1" not %run %t 2>&1 | FileCheck %s #include <stdlib.h> int main() { diff --git a/test/asan/TestCases/stack-overflow.cc b/test/asan/TestCases/stack-overflow.cc index d4bb74730f12..d792c466f977 100644 --- a/test/asan/TestCases/stack-overflow.cc +++ b/test/asan/TestCases/stack-overflow.cc @@ -1,18 +1,18 @@ // Test ASan detection of stack-overflow condition. -// RUN: %clangxx_asan -O0 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O0 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O0 %s -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O0 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O0 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O0 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -O3 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DTHREAD -DSMALL_FRAME -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DTHREAD -DSAVE_ALL_THE_REGISTERS -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O0 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_asan -O3 %s -DTHREAD -pthread -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:use_sigaltstack=1 not %run %t 2>&1 | FileCheck %s // RUN: not %run %t 2>&1 | FileCheck %s // REQUIRES: stable-runtime diff --git a/test/asan/TestCases/stack-use-after-return.cc b/test/asan/TestCases/stack-use-after-return.cc index 437c457748c4..669e8703b82f 100644 --- a/test/asan/TestCases/stack-use-after-return.cc +++ b/test/asan/TestCases/stack-use-after-return.cc @@ -1,9 +1,9 @@ -// RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 +// RUN: export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 // RUN: %clangxx_asan -O0 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O1 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s // RUN: %clangxx_asan -O3 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=0 %run %t // Regression test for a CHECK failure with small stack size and large frame. // RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=65536 && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s // diff --git a/test/asan/TestCases/strcasestr-1.c b/test/asan/TestCases/strcasestr-1.c new file mode 100644 index 000000000000..c6f9d193e503 --- /dev/null +++ b/test/asan/TestCases/strcasestr-1.c @@ -0,0 +1,24 @@ +// Test haystack overflow in strcasestr function +// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strstr asan option +// Disable other interceptors because strlen may be called inside strcasestr +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1 + +// There's no interceptor for strcasestr on Windows +// XFAIL: win32 + +#define _GNU_SOURCE +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + char *r = 0; + char s2[] = "c"; + char s1[] = {'a', 'C'}; + char s3 = 0; + r = strcasestr(s1, s2); + // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == s1 + 1); + return 0; +} diff --git a/test/asan/TestCases/strcasestr-2.c b/test/asan/TestCases/strcasestr-2.c new file mode 100644 index 000000000000..a4bc6362636e --- /dev/null +++ b/test/asan/TestCases/strcasestr-2.c @@ -0,0 +1,24 @@ +// Test needle overflow in strcasestr function +// RUN: %clang_asan %s -o %t && ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strstr asan option +// Disable other interceptors because strlen may be called inside strcasestr +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1 + +// There's no interceptor for strcasestr on Windows +// XFAIL: win32 + +#define _GNU_SOURCE +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + char *r = 0; + char s1[] = "ab"; + char s2[] = {'c'}; + char s3 = 0; + r = strcasestr(s1, s2); + assert(r == 0); + // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + return 0; +} diff --git a/test/asan/TestCases/strcasestr_strict.c b/test/asan/TestCases/strcasestr_strict.c new file mode 100644 index 000000000000..03c066bb1b9d --- /dev/null +++ b/test/asan/TestCases/strcasestr_strict.c @@ -0,0 +1,28 @@ +// Test strict_string_checks option in strcasestr function +// RUN: %clang_asan %s -o %t && %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// There's no interceptor for strcasestr on Windows +// XFAIL: win32 + +#define _GNU_SOURCE +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t size = 100; + char *s1 = (char*)malloc(size); + char *s2 = (char*)malloc(size); + memset(s1, 'o', size); + memset(s2, 'O', size); + s2[size - 1]='\0'; + char* r = strcasestr(s1, s2); + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: READ of size 101 + assert(r == s1); + free(s1); + free(s2); + return 0; +} diff --git a/test/asan/TestCases/strcat_strict.c b/test/asan/TestCases/strcat_strict.c new file mode 100644 index 000000000000..8321f5b620f9 --- /dev/null +++ b/test/asan/TestCases/strcat_strict.c @@ -0,0 +1,44 @@ +// Test strict_string_checks option in strcat function +// RUN: %clang_asan %s -o %t +// RUN: not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-STRICT --check-prefix=CHECK1 +// RUN: not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +void test1(char *to, int to_size, char *from) { + // One of arguments points to not allocated memory. + char* r = strcat(to + to_size, from); +} + +void test2(char *to, int to_size, char *from) { + // "to" is not zero-terminated. + memset(to, 'z', to_size); + char* r = strcat(to, from); +} + +int main(int argc, char **argv) { + size_t to_size = 100; + char *to = (char*)malloc(to_size); + size_t from_size = 20; + char *from = (char*)malloc(from_size); + memset(from, 'z', from_size); + from[from_size - 1] = '\0'; + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(to, to_size, from); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1-STRICT: READ of size 1 + // CHECK1-NONSTRICT: WRITE of size 20 + if (!strcmp(argv[1], "test2")) test2(to, to_size, from); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2-STRICT: READ of size 101 + // CHECK2-NONSTRICT: WRITE of size 20 + free(to); + free(from); + return 0; +} diff --git a/test/asan/TestCases/strchr_strict.c b/test/asan/TestCases/strchr_strict.c new file mode 100644 index 000000000000..48c1f139583e --- /dev/null +++ b/test/asan/TestCases/strchr_strict.c @@ -0,0 +1,22 @@ +// Test strict_string_checks option in strchr function +// RUN: %clang_asan %s -o %t && %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t size = 100; + char fill = 'o'; + char *s = (char*)malloc(size); + memset(s, fill, size); + char c = 'o'; + char* r = strchr(s, c); + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: READ of size 101 + assert(r == s); + free(s); + return 0; +} diff --git a/test/asan/TestCases/strcmp_strict.c b/test/asan/TestCases/strcmp_strict.c new file mode 100644 index 000000000000..316765e18371 --- /dev/null +++ b/test/asan/TestCases/strcmp_strict.c @@ -0,0 +1,26 @@ +// Test strict_string_checks option in strcmp function +// RUN: %clang_asan %s -o %t && %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t size = 100; + char fill = 'o'; + char *s1 = (char*)malloc(size); + memset(s1, fill, size); + char *s2 = (char*)malloc(size); + memset(s2, fill, size); + s1[size - 1] = 'z'; + s2[size - 1] = 'x'; + int r = strcmp(s1, s2); + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: READ of size 101 + assert(r == 1); + free(s1); + free(s2); + return 0; +} diff --git a/test/asan/TestCases/strcspn-1.c b/test/asan/TestCases/strcspn-1.c new file mode 100644 index 000000000000..ef02a049530a --- /dev/null +++ b/test/asan/TestCases/strcspn-1.c @@ -0,0 +1,19 @@ +// Test string s1 overflow in strcspn function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strspn asan option +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t r; + char s2[] = "ab"; + char s1[] = {'c', 'a'}; + char s3 = 0; + r = strcspn(s1, s2); + // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == 1); + return 0; +} diff --git a/test/asan/TestCases/strcspn-2.c b/test/asan/TestCases/strcspn-2.c new file mode 100644 index 000000000000..aa82aa60abfe --- /dev/null +++ b/test/asan/TestCases/strcspn-2.c @@ -0,0 +1,19 @@ +// Test stopset overflow in strcspn function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strcspn asan option +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t r; + char s1[] = "ab"; + char s2[] = {'a'}; + char s3 = 0; + r = strcspn(s1, s2); + // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == 0); + return 0; +} diff --git a/test/asan/TestCases/strcspn_strict.c b/test/asan/TestCases/strcspn_strict.c new file mode 100644 index 000000000000..7198f9a08723 --- /dev/null +++ b/test/asan/TestCases/strcspn_strict.c @@ -0,0 +1,26 @@ +// Test strict_string_checks option in strcspn function +// RUN: %clang_asan %s -o %t && %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t size = 100; + char fill = 'o'; + char *s1 = (char*)malloc(size); + char *s2 = (char*)malloc(size); + memset(s1, fill, size); + s1[0] = 'z'; + memset(s2, fill, size); + s2[size-1] = '\0'; + size_t r = strcspn(s1, s2); + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: READ of size 101 + assert(r == 1); + free(s1); + free(s2); + return 0; +} diff --git a/test/asan/TestCases/strip_path_prefix.c b/test/asan/TestCases/strip_path_prefix.c index 4556e9031e2d..fc9ebd1691cc 100644 --- a/test/asan/TestCases/strip_path_prefix.c +++ b/test/asan/TestCases/strip_path_prefix.c @@ -1,5 +1,5 @@ // RUN: %clang_asan -O2 %s -o %t -// RUN: env ASAN_OPTIONS="strip_path_prefix='/'" not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:strip_path_prefix='%S/'" not %run %t 2>&1 | FileCheck %s #include <stdlib.h> int main() { @@ -8,5 +8,5 @@ int main() { return x[5]; // Check that paths in error report don't start with slash. // CHECK: heap-use-after-free - // CHECK-NOT: #0 0x{{.*}} ({{[/].*}}) + // CHECK: #0 0x{{.*}} in main strip_path_prefix.c:[[@LINE-3]] } diff --git a/test/asan/TestCases/strncat_strict.c b/test/asan/TestCases/strncat_strict.c new file mode 100644 index 000000000000..16de17689d0c --- /dev/null +++ b/test/asan/TestCases/strncat_strict.c @@ -0,0 +1,44 @@ +// Test strict_string_checks option in strncat function +// RUN: %clang_asan %s -o %t +// RUN: not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-NONSTRICT --check-prefix=CHECK1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1-STRICT --check-prefix=CHECK1 +// RUN: not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-NONSTRICT --check-prefix=CHECK2 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2-STRICT --check-prefix=CHECK2 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +void test1(char *to, int to_size, char *from) { + // One of arguments points to not allocated memory. + char* r = strncat(to + to_size, from, 2); +} + +void test2(char *to, int to_size, char *from) { + // "to" is not zero-terminated. + memset(to, 'z', to_size); + char* r = strncat(to, from, 1); +} + +int main(int argc, char **argv) { + size_t to_size = 100; + char *to = (char*)malloc(to_size); + size_t from_size = 20; + char *from = (char*)malloc(from_size); + memset(from, 'z', from_size); + from[from_size - 1] = '\0'; + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(to, to_size, from); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1-STRICT: READ of size 1 + // CHECK1-NONSTRICT: WRITE of size 3 + if (!strcmp(argv[1], "test2")) test2(to, to_size, from); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2-STRICT: READ of size 101 + // CHECK2-NONSTRICT: WRITE of size 2 + free(to); + free(from); + return 0; +} diff --git a/test/asan/TestCases/strpbrk-1.c b/test/asan/TestCases/strpbrk-1.c new file mode 100644 index 000000000000..7cd45bd0979a --- /dev/null +++ b/test/asan/TestCases/strpbrk-1.c @@ -0,0 +1,19 @@ +// Test string s1 overflow in strpbrk function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strpbrk asan option +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strpbrk=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + char *r; + char s2[] = "ab"; + char s1[] = {'c', 'a'}; + char s3 = 0; + r = strpbrk(s1, s2); + // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == s1 + 1); + return 0; +} diff --git a/test/asan/TestCases/strpbrk-2.c b/test/asan/TestCases/strpbrk-2.c new file mode 100644 index 000000000000..0d50c002a21a --- /dev/null +++ b/test/asan/TestCases/strpbrk-2.c @@ -0,0 +1,19 @@ +// Test stopset overflow in strpbrk function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strpbrk asan option +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strpbrk=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + char *r; + char s1[] = "c"; + char s2[] = {'b', 'c'}; + char s3 = 0; + r = strpbrk(s1, s2); + // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == s1); + return 0; +} diff --git a/test/asan/TestCases/strpbrk_strict.c b/test/asan/TestCases/strpbrk_strict.c new file mode 100644 index 000000000000..2521e96ba5f0 --- /dev/null +++ b/test/asan/TestCases/strpbrk_strict.c @@ -0,0 +1,25 @@ +// Test strict_string_checks option in strpbrk function +// RUN: %clang_asan %s -o %t && %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t size = 100; + char fill = 'o'; + char *s1 = (char*)malloc(size); + char *s2 = (char*)malloc(2); + memset(s1, fill, size); + s2[0] = fill; + s2[1]='\0'; + char* r = strpbrk(s1, s2); + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: READ of size 101 + assert(r == s1); + free(s1); + free(s2); + return 0; +} diff --git a/test/asan/TestCases/strspn-1.c b/test/asan/TestCases/strspn-1.c new file mode 100644 index 000000000000..24d0d2daac1e --- /dev/null +++ b/test/asan/TestCases/strspn-1.c @@ -0,0 +1,19 @@ +// Test string s1 overflow in strspn function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strspn asan option +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t r; + char s2[] = "ab"; + char s1[] = {'a', 'c'}; + char s3 = 0; + r = strspn(s1, s2); + // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == 1); + return 0; +} diff --git a/test/asan/TestCases/strspn-2.c b/test/asan/TestCases/strspn-2.c new file mode 100644 index 000000000000..e4621e5bfede --- /dev/null +++ b/test/asan/TestCases/strspn-2.c @@ -0,0 +1,19 @@ +// Test stopset overflow in strspn function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strspn asan option +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strspn=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t r; + char s1[] = "bbc"; + char s2[] = {'a', 'b'}; + char s3 = 0; + r = strspn(s1, s2); + // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r >= 2); + return 0; +} diff --git a/test/asan/TestCases/strspn_strict.c b/test/asan/TestCases/strspn_strict.c new file mode 100644 index 000000000000..7df6c0da9ab0 --- /dev/null +++ b/test/asan/TestCases/strspn_strict.c @@ -0,0 +1,25 @@ +// Test strict_str`ing_checks option in strspn function +// RUN: %clang_asan %s -o %t && %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t size = 100; + char fill = 'o'; + char *s1 = (char*)malloc(size); + char *s2 = (char*)malloc(2); + memset(s1, fill, size); + s1[0] = s2[0] = 'z'; + s2[1] = '\0'; + size_t r = strspn(s1, s2); + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: READ of size 101 + assert(r == 1); + free(s1); + free(s2); + return 0; +} diff --git a/test/asan/TestCases/strstr-1.c b/test/asan/TestCases/strstr-1.c new file mode 100644 index 000000000000..193334e9bb34 --- /dev/null +++ b/test/asan/TestCases/strstr-1.c @@ -0,0 +1,20 @@ +// Test haystack overflow in strstr function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strstr asan option +// Disable other interceptors because strlen may be called inside strstr +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + char *r = 0; + char s2[] = "c"; + char s1[] = {'a', 'c'}; + char s3 = 0; + r = strstr(s1, s2); + // CHECK:'s{{[1|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == s1 + 1); + return 0; +} diff --git a/test/asan/TestCases/strstr-2.c b/test/asan/TestCases/strstr-2.c new file mode 100644 index 000000000000..cd116212fa95 --- /dev/null +++ b/test/asan/TestCases/strstr-2.c @@ -0,0 +1,20 @@ +// Test needle overflow in strstr function +// RUN: %clang_asan %s -o %t && env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +// Test intercept_strstr asan option +// Disable other interceptors because strlen may be called inside strstr +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:intercept_strstr=false:replace_str=false %run %t 2>&1 + +#include <assert.h> +#include <string.h> + +int main(int argc, char **argv) { + char *r = 0; + char s1[] = "ab"; + char s2[] = {'c'}; + char s3 = 0; + r = strstr(s1, s2); + // CHECK:'s{{[2|3]}}' <== Memory access at offset {{[0-9]+ .*}}flows this variable + assert(r == 0); + return 0; +} diff --git a/test/asan/TestCases/strstr_strict.c b/test/asan/TestCases/strstr_strict.c new file mode 100644 index 000000000000..f7eca6aeb900 --- /dev/null +++ b/test/asan/TestCases/strstr_strict.c @@ -0,0 +1,25 @@ +// Test strict_string_checks option in strstr function +// RUN: %clang_asan %s -o %t && %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdlib.h> +#include <string.h> + +int main(int argc, char **argv) { + size_t size = 100; + char fill = 'o'; + char *s1 = (char*)malloc(size); + char *s2 = (char*)malloc(size); + memset(s1, fill, size); + memset(s2, fill, size); + s2[size - 1]='\0'; + char* r = strstr(s1, s2); + // CHECK: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK: READ of size 101 + assert(r == s1); + free(s1); + free(s2); + return 0; +} diff --git a/test/asan/TestCases/strtol_strict.c b/test/asan/TestCases/strtol_strict.c new file mode 100644 index 000000000000..fac3b3a5439d --- /dev/null +++ b/test/asan/TestCases/strtol_strict.c @@ -0,0 +1,116 @@ +// Test strict_string_checks option in strtol function +// RUN: %clang_asan -DTEST1 %s -o %t +// RUN: %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3 +// RUN: %run %t test4 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test4 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4 +// RUN: %run %t test5 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test5 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5 +// RUN: %run %t test6 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test6 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6 +// RUN: %run %t test7 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test7 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <sanitizer/asan_interface.h> + +void test1(char *array, char *endptr) { + // Buffer overflow if there is no terminating null (depends on base) + long r = strtol(array, &endptr, 3); + assert(array + 2 == endptr); + assert(r == 5); +} + +void test2(char *array, char *endptr) { + // Buffer overflow if there is no terminating null (depends on base) + array[2] = 'z'; + long r = strtol(array, &endptr, 35); + assert(array + 2 == endptr); + assert(r == 37); +} + +void test3(char *array, char *endptr) { + // Buffer overflow if base is invalid. + memset(array, 0, 8); + ASAN_POISON_MEMORY_REGION(array, 8); + long r = strtol(array + 1, NULL, -1); + assert(r == 0); + ASAN_UNPOISON_MEMORY_REGION(array, 8); +} + +void test4(char *array, char *endptr) { + // Buffer overflow if base is invalid. + long r = strtol(array + 3, NULL, 1); + assert(r == 0); +} + +void test5(char *array, char *endptr) { + // Overflow if no digits are found. + array[0] = ' '; + array[1] = '+'; + array[2] = '-'; + long r = strtol(array, NULL, 0); + assert(r == 0); +} + +void test6(char *array, char *endptr) { + // Overflow if no digits are found. + array[0] = ' '; + array[1] = array[2] = 'z'; + long r = strtol(array, &endptr, 0); + assert(array == endptr); + assert(r == 0); +} + +void test7(char *array, char *endptr) { + // Overflow if no digits are found. + array[2] = 'z'; + long r = strtol(array + 2, NULL, 0); + assert(r == 0); +} + +int main(int argc, char **argv) { + char *array0 = (char*)malloc(11); + char* array = array0 + 8; + char *endptr = NULL; + array[0] = '1'; + array[1] = '2'; + array[2] = '3'; + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(array, endptr); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1: READ of size 4 + if (!strcmp(argv[1], "test2")) test2(array, endptr); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2: READ of size 4 + if (!strcmp(argv[1], "test3")) test3(array0, endptr); + // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}} + // CHECK3: READ of size 1 + if (!strcmp(argv[1], "test4")) test4(array, endptr); + // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK4: READ of size 1 + if (!strcmp(argv[1], "test5")) test5(array, endptr); + // CHECK5: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK5: READ of size 4 + if (!strcmp(argv[1], "test6")) test6(array, endptr); + // CHECK6: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK6: READ of size 4 + if (!strcmp(argv[1], "test7")) test7(array, endptr); + // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK7: READ of size 2 + free(array0); + return 0; +} diff --git a/test/asan/TestCases/strtoll_strict.c b/test/asan/TestCases/strtoll_strict.c new file mode 100644 index 000000000000..983da9f7ed30 --- /dev/null +++ b/test/asan/TestCases/strtoll_strict.c @@ -0,0 +1,116 @@ +// Test strict_string_checks option in strtoll function +// RUN: %clang_asan -DTEST1 %s -o %t +// RUN: %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test1 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test2 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test3 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3 +// RUN: %run %t test4 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test4 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4 +// RUN: %run %t test5 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test5 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5 +// RUN: %run %t test6 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test6 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6 +// RUN: %run %t test7 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=false %run %t test7 2>&1 +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <sanitizer/asan_interface.h> + +void test1(char *array, char *endptr) { + // Buffer overflow if there is no terminating null (depends on base) + long long r = strtoll(array, &endptr, 3); + assert(array + 2 == endptr); + assert(r == 5); +} + +void test2(char *array, char *endptr) { + // Buffer overflow if there is no terminating null (depends on base) + array[2] = 'z'; + long long r = strtoll(array, &endptr, 35); + assert(array + 2 == endptr); + assert(r == 37); +} + +void test3(char *array, char *endptr) { + // Buffer overflow if base is invalid. + memset(array, 0, 8); + ASAN_POISON_MEMORY_REGION(array, 8); + long long r = strtoll(array + 1, NULL, -1); + assert(r == 0); + ASAN_UNPOISON_MEMORY_REGION(array, 8); +} + +void test4(char *array, char *endptr) { + // Buffer overflow if base is invalid. + long long r = strtoll(array + 3, NULL, 1); + assert(r == 0); +} + +void test5(char *array, char *endptr) { + // Overflow if no digits are found. + array[0] = ' '; + array[1] = '+'; + array[2] = '-'; + long long r = strtoll(array, NULL, 0); + assert(r == 0); +} + +void test6(char *array, char *endptr) { + // Overflow if no digits are found. + array[0] = ' '; + array[1] = array[2] = 'z'; + long long r = strtoll(array, &endptr, 0); + assert(array == endptr); + assert(r == 0); +} + +void test7(char *array, char *endptr) { + // Overflow if no digits are found. + array[2] = 'z'; + long long r = strtoll(array + 2, NULL, 0); + assert(r == 0); +} + +int main(int argc, char **argv) { + char *array0 = (char*)malloc(11); + char* array = array0 + 8; + char *endptr = NULL; + array[0] = '1'; + array[1] = '2'; + array[2] = '3'; + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(array, endptr); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1: READ of size 4 + if (!strcmp(argv[1], "test2")) test2(array, endptr); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2: READ of size 4 + if (!strcmp(argv[1], "test3")) test3(array0, endptr); + // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}} + // CHECK3: READ of size 1 + if (!strcmp(argv[1], "test4")) test4(array, endptr); + // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK4: READ of size 1 + if (!strcmp(argv[1], "test5")) test5(array, endptr); + // CHECK5: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK5: READ of size 4 + if (!strcmp(argv[1], "test6")) test6(array, endptr); + // CHECK6: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK6: READ of size 4 + if (!strcmp(argv[1], "test7")) test7(array, endptr); + // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK7: READ of size 2 + free(array0); + return 0; +} diff --git a/test/asan/TestCases/suppressions-exec-relative-location.cc b/test/asan/TestCases/suppressions-exec-relative-location.cc new file mode 100644 index 000000000000..84f0262dc0bc --- /dev/null +++ b/test/asan/TestCases/suppressions-exec-relative-location.cc @@ -0,0 +1,47 @@ +// Check that without suppressions, we catch the issue. +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s + +// If the executable is started from a different location, we should still +// find the suppression file located relative to the location of the executable. +// RUN: rm -rf %T/suppressions-exec-relative-location +// RUN: mkdir -p %T/suppressions-exec-relative-location +// RUN: %clangxx_asan -O0 %s -o %T/suppressions-exec-relative-location/exec +// RUN: echo "interceptor_via_fun:crash_function" > \ +// RUN: %T/suppressions-exec-relative-location/supp.txt +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions=supp.txt" \ +// RUN: %run %T/suppressions-exec-relative-location/exec 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: rm -rf %T/suppressions-exec-relative-location + +// If the wrong absolute path is given, we don't try to construct +// a relative path with it. +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='/absolute/path'" not %run %t 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-WRONG-FILE-NAME %s + +// Test that we reject directory as filename. +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='folder/only/'" not %run %t 2>&1 | \ +// RUN: FileCheck --check-prefix=CHECK-WRONG-FILE-NAME %s + +// XFAIL: android +// XFAIL: win32 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +void crash_function() { + char *a = (char *)malloc(6); + free(a); + size_t len = strlen(a); // BOOM + fprintf(stderr, "strlen ignored, len = %zu\n", len); +} + +int main() { + crash_function(); +} + +// CHECK-CRASH: AddressSanitizer: heap-use-after-free +// CHECK-IGNORE-NOT: AddressSanitizer: heap-buffer-overflow +// CHECK-IGNORE: ignored +// CHECK-WRONG-FILE-NAME: failed to read suppressions file diff --git a/test/asan/TestCases/suppressions-function.cc b/test/asan/TestCases/suppressions-function.cc index 0a6c9995827e..fe5419f17938 100644 --- a/test/asan/TestCases/suppressions-function.cc +++ b/test/asan/TestCases/suppressions-function.cc @@ -3,8 +3,8 @@ // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s // RUN: echo "interceptor_via_fun:crash_function" > %t.supp -// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s -// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: %clangxx_asan -O0 %s -o %t && ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: %clangxx_asan -O3 %s -o %t && ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s // XFAIL: android diff --git a/test/asan/TestCases/suppressions-interceptor.cc b/test/asan/TestCases/suppressions-interceptor.cc index 45a14d1a422a..8bb1f1a92d3b 100644 --- a/test/asan/TestCases/suppressions-interceptor.cc +++ b/test/asan/TestCases/suppressions-interceptor.cc @@ -3,7 +3,7 @@ // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s // RUN: echo "interceptor_name:strlen" > %t.supp -// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s // XFAIL: android diff --git a/test/asan/TestCases/suppressions-library.cc b/test/asan/TestCases/suppressions-library.cc index 28f19f54efc1..52fd60910539 100644 --- a/test/asan/TestCases/suppressions-library.cc +++ b/test/asan/TestCases/suppressions-library.cc @@ -1,11 +1,11 @@ -// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so -install_name @rpath/suppressions-library.cc.tmp-so.so -// RUN: %clangxx_asan -O0 %s %t-so.so -o %t -rpath @executable_path +// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %dynamiclib %ld_flags_rpath_so +// RUN: %clangxx_asan -O0 %s -o %t %ld_flags_rpath_exe // Check that without suppressions, we catch the issue. // RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-CRASH %s -// RUN: echo "interceptor_via_lib:suppressions-library.cc.tmp-so.so" > %t.supp -// RUN: ASAN_OPTIONS="suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s +// RUN: echo "interceptor_via_lib:"`basename %dynamiclib` > %t.supp +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:suppressions='%t.supp'" %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s // XFAIL: android diff --git a/test/asan/TestCases/uar_and_exceptions.cc b/test/asan/TestCases/uar_and_exceptions.cc index 0bfe29729555..bdeca434e6c2 100644 --- a/test/asan/TestCases/uar_and_exceptions.cc +++ b/test/asan/TestCases/uar_and_exceptions.cc @@ -1,5 +1,5 @@ // Test that use-after-return works with exceptions. -// export ASAN_OPTIONS=detect_stack_use_after_return=1 +// export ASAN_OPTIONS=$ASAN_OPTIONS:detect_stack_use_after_return=1 // RUN: %clangxx_asan -O0 %s -o %t && %run %t // Clang doesn't support exceptions on Windows yet. diff --git a/test/asan/TestCases/use-after-poison.cc b/test/asan/TestCases/use-after-poison.cc index 3b247ff531b9..ecca2c85028f 100644 --- a/test/asan/TestCases/use-after-poison.cc +++ b/test/asan/TestCases/use-after-poison.cc @@ -2,7 +2,7 @@ // RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s // // Check that we can disable it -// RUN: env ASAN_OPTIONS=allow_user_poisoning=0 %run %t +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:allow_user_poisoning=0 %run %t #include <stdlib.h> diff --git a/test/asan/TestCases/use-after-scope.cc b/test/asan/TestCases/use-after-scope.cc index f98a8e6b62e1..e244ee34b101 100644 --- a/test/asan/TestCases/use-after-scope.cc +++ b/test/asan/TestCases/use-after-scope.cc @@ -1,6 +1,6 @@ // RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \ // RUN: not %run %t 2>&1 | FileCheck %s -// RUN: env ASAN_OPTIONS="detect_stack_use_after_return=1" not %run %t 2>&1 | FileCheck %s +// RUN: env ASAN_OPTIONS="$ASAN_OPTIONS:detect_stack_use_after_return=1" not %run %t 2>&1 | FileCheck %s // XFAIL: * int main() { diff --git a/test/asan/TestCases/verbose-log-path_test.cc b/test/asan/TestCases/verbose-log-path_test.cc new file mode 100644 index 000000000000..12372ec68078 --- /dev/null +++ b/test/asan/TestCases/verbose-log-path_test.cc @@ -0,0 +1,21 @@ +// RUN: %clangxx_asan %s -o %T/verbose-log-path_test-binary + +// Good log_path. +// RUN: rm -f %T/asan.log.* +// RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:log_path=%T/asan.log:log_exe_name=1 not %run %T/verbose-log-path_test-binary 2> %t.out +// RUN: FileCheck %s --check-prefix=CHECK-ERROR < %T/asan.log.verbose-log-path_test-binary.* + +// FIXME: only FreeBSD and Linux have verbose log paths now. +// XFAIL: win32,android + +#include <stdlib.h> +#include <string.h> +int main(int argc, char **argv) { + if (argc > 2) return 0; + char *x = (char*)malloc(10); + memset(x, 0, 10); + int res = x[argc * 10]; // BOOOM + free(x); + return res; +} +// CHECK-ERROR: ERROR: AddressSanitizer diff --git a/test/asan/TestCases/vla_chrome_testcase.cc b/test/asan/TestCases/vla_chrome_testcase.cc new file mode 100644 index 000000000000..8ee040120c48 --- /dev/null +++ b/test/asan/TestCases/vla_chrome_testcase.cc @@ -0,0 +1,30 @@ +// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// + +// This is reduced testcase based on Chromium code. +// See http://reviews.llvm.org/D6055?vs=on&id=15616&whitespace=ignore-all#toc. + +#include <stdint.h> +#include <assert.h> + +int a = 7; +int b; +int c; +int *p; + +__attribute__((noinline)) void fn3(int *first, int second) { +} + +int main() { + int d = b && c; + int e[a]; // NOLINT + assert(!(reinterpret_cast<uintptr_t>(e) & 31L)); + int f; + if (d) + fn3(&f, sizeof 0 * (&c - e)); + e[a] = 0; +// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: WRITE of size 4 at [[ADDR]] thread T0 + return 0; +} diff --git a/test/asan/TestCases/vla_condition_overflow.cc b/test/asan/TestCases/vla_condition_overflow.cc new file mode 100644 index 000000000000..17f28d823252 --- /dev/null +++ b/test/asan/TestCases/vla_condition_overflow.cc @@ -0,0 +1,22 @@ +// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// +// REQUIRES: stable-runtime + +#include <assert.h> +#include <stdint.h> + +__attribute__((noinline)) void foo(int index, int len) { + if (index > len) { + char str[len]; //NOLINT + assert(!(reinterpret_cast<uintptr_t>(str) & 31L)); + str[index] = '1'; // BOOM +// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: WRITE of size 1 at [[ADDR]] thread T0 + } +} + +int main(int argc, char **argv) { + foo(33, 10); + return 0; +} diff --git a/test/asan/TestCases/vla_loop_overfow.cc b/test/asan/TestCases/vla_loop_overfow.cc new file mode 100644 index 000000000000..4f20c8d19d14 --- /dev/null +++ b/test/asan/TestCases/vla_loop_overfow.cc @@ -0,0 +1,22 @@ +// RUN: %clangxx_asan -O0 -mllvm -asan-instrument-allocas %s -o %t +// RUN: not %run %t 2>&1 | FileCheck %s +// +// REQUIRES: stable-runtime + +#include <assert.h> +#include <stdint.h> + +void foo(int index, int len) { + for (int i = 1; i < len; ++i) { + char array[len]; // NOLINT + assert(!(reinterpret_cast<uintptr_t>(array) & 31L)); + array[index + i] = 0; +// CHECK: ERROR: AddressSanitizer: dynamic-stack-buffer-overflow on address [[ADDR:0x[0-9a-f]+]] +// CHECK: WRITE of size 1 at [[ADDR]] thread T0 + } +} + +int main(int argc, char **argv) { + foo(9, 21); + return 0; +} diff --git a/test/asan/lit.cfg b/test/asan/lit.cfg index a6f443cfb6a5..c5164713dbe4 100644 --- a/test/asan/lit.cfg +++ b/test/asan/lit.cfg @@ -29,6 +29,9 @@ def push_dynamic_library_lookup_path(config, new_path): # Setup config name. config.name = 'AddressSanitizer' + config.name_suffix +# Setup default ASAN_OPTIONS +config.environment['ASAN_OPTIONS'] = 'symbolize_vs_style=false' + # testFormat: The test format to use to interpret tests. external_bash = (not sys.platform in ['win32']) config.test_format = lit.formats.ShTest(external_bash) @@ -135,6 +138,20 @@ config.substitutions.append( ("%libdl", libdl_flag) ) config.available_features.add("asan-" + config.bits + "-bits") +if config.host_os == 'Darwin': + config.substitutions.append( ("%ld_flags_rpath_exe", '-Wl,-rpath,@executable_path/ %dynamiclib') ) + config.substitutions.append( ("%ld_flags_rpath_so", '-install_name @rpath/`basename %dynamiclib`') ) +elif config.host_os == 'FreeBSD': + config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-z,origin -Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") ) + config.substitutions.append( ("%ld_flags_rpath_so", '') ) +elif config.host_os == 'Linux': + config.substitutions.append( ("%ld_flags_rpath_exe", "-Wl,-rpath,\$ORIGIN -L%T -l%xdynamiclib_namespec") ) + config.substitutions.append( ("%ld_flags_rpath_so", '') ) + +# Must be defined after the substitutions that use %dynamiclib. +config.substitutions.append( ("%dynamiclib", '%T/lib%xdynamiclib_namespec.so') ) +config.substitutions.append( ("%xdynamiclib_namespec", '$(basename %t).dynamic') ) + # Allow tests to use REQUIRES=stable-runtime. For use when you cannot use XFAIL # because the test hangs. if config.target_arch != 'arm': diff --git a/test/builtins/Unit/absvdi2_test.c b/test/builtins/Unit/absvdi2_test.c index f0bf560681e7..f69ae4151072 100644 --- a/test/builtins/Unit/absvdi2_test.c +++ b/test/builtins/Unit/absvdi2_test.c @@ -19,7 +19,7 @@ // Effects: aborts if abs(x) < 0 -di_int __absvdi2(di_int a); +COMPILER_RT_ABI di_int __absvdi2(di_int a); int test__absvdi2(di_int a) { diff --git a/test/builtins/Unit/absvsi2_test.c b/test/builtins/Unit/absvsi2_test.c index 3b88078dfb4a..c395cca7adc8 100644 --- a/test/builtins/Unit/absvsi2_test.c +++ b/test/builtins/Unit/absvsi2_test.c @@ -19,7 +19,7 @@ // Effects: aborts if abs(x) < 0 -si_int __absvsi2(si_int a); +COMPILER_RT_ABI si_int __absvsi2(si_int a); int test__absvsi2(si_int a) { diff --git a/test/builtins/Unit/absvti2_test.c b/test/builtins/Unit/absvti2_test.c index 9b71f200ac7b..6c626e97d930 100644 --- a/test/builtins/Unit/absvti2_test.c +++ b/test/builtins/Unit/absvti2_test.c @@ -21,7 +21,7 @@ // Effects: aborts if abs(x) < 0 -ti_int __absvti2(ti_int a); +COMPILER_RT_ABI ti_int __absvti2(ti_int a); int test__absvti2(ti_int a) { diff --git a/test/builtins/Unit/adddf3vfp_test.c b/test/builtins/Unit/adddf3vfp_test.c index 5ad42f7b3a6e..739515291fe8 100644 --- a/test/builtins/Unit/adddf3vfp_test.c +++ b/test/builtins/Unit/adddf3vfp_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> #if __arm__ -extern double __adddf3vfp(double a, double b); +extern COMPILER_RT_ABI double __adddf3vfp(double a, double b); int test__adddf3vfp(double a, double b) { diff --git a/test/builtins/Unit/addsf3vfp_test.c b/test/builtins/Unit/addsf3vfp_test.c index 95e057c36305..4b3dcccac4d3 100644 --- a/test/builtins/Unit/addsf3vfp_test.c +++ b/test/builtins/Unit/addsf3vfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern float __addsf3vfp(float a, float b); +extern COMPILER_RT_ABI float __addsf3vfp(float a, float b); #if __arm__ int test__addsf3vfp(float a, float b) diff --git a/test/builtins/Unit/addtf3_test.c b/test/builtins/Unit/addtf3_test.c index 4a3aacd96e6d..7b92ccee1af0 100644 --- a/test/builtins/Unit/addtf3_test.c +++ b/test/builtins/Unit/addtf3_test.c @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 @@ -18,7 +19,7 @@ #include "fp_test.h" // Returns: a + b -long double __addtf3(long double a, long double b); +COMPILER_RT_ABI long double __addtf3(long double a, long double b); int test__addtf3(long double a, long double b, uint64_t expectedHi, uint64_t expectedLo) diff --git a/test/builtins/Unit/addvdi3_test.c b/test/builtins/Unit/addvdi3_test.c index 0d7271d5a4ae..5f8729a61266 100644 --- a/test/builtins/Unit/addvdi3_test.c +++ b/test/builtins/Unit/addvdi3_test.c @@ -18,7 +18,7 @@ // Effects: aborts if a + b overflows -di_int __addvdi3(di_int a, di_int b); +COMPILER_RT_ABI di_int __addvdi3(di_int a, di_int b); int test__addvdi3(di_int a, di_int b) { diff --git a/test/builtins/Unit/addvsi3_test.c b/test/builtins/Unit/addvsi3_test.c index 59fd9d2ae15f..b5358d0f5d47 100644 --- a/test/builtins/Unit/addvsi3_test.c +++ b/test/builtins/Unit/addvsi3_test.c @@ -18,7 +18,7 @@ // Effects: aborts if a + b overflows -si_int __addvsi3(si_int a, si_int b); +COMPILER_RT_ABI si_int __addvsi3(si_int a, si_int b); int test__addvsi3(si_int a, si_int b) { diff --git a/test/builtins/Unit/addvti3_test.c b/test/builtins/Unit/addvti3_test.c index fe093e3b26a2..e2f75cf86148 100644 --- a/test/builtins/Unit/addvti3_test.c +++ b/test/builtins/Unit/addvti3_test.c @@ -20,7 +20,7 @@ // Effects: aborts if a + b overflows -ti_int __addvti3(ti_int a, ti_int b); +COMPILER_RT_ABI ti_int __addvti3(ti_int a, ti_int b); int test__addvti3(ti_int a, ti_int b) { diff --git a/test/builtins/Unit/ashldi3_test.c b/test/builtins/Unit/ashldi3_test.c index fb80c6f77e40..398fb69beb78 100644 --- a/test/builtins/Unit/ashldi3_test.c +++ b/test/builtins/Unit/ashldi3_test.c @@ -18,7 +18,7 @@ // Precondition: 0 <= b < bits_in_dword -di_int __ashldi3(di_int a, si_int b); +COMPILER_RT_ABI di_int __ashldi3(di_int a, si_int b); int test__ashldi3(di_int a, si_int b, di_int expected) { diff --git a/test/builtins/Unit/ashlti3_test.c b/test/builtins/Unit/ashlti3_test.c index 2361d16b3699..595e353065a9 100644 --- a/test/builtins/Unit/ashlti3_test.c +++ b/test/builtins/Unit/ashlti3_test.c @@ -20,7 +20,7 @@ // Precondition: 0 <= b < bits_in_tword -ti_int __ashlti3(ti_int a, si_int b); +COMPILER_RT_ABI ti_int __ashlti3(ti_int a, si_int b); int test__ashlti3(ti_int a, si_int b, ti_int expected) { diff --git a/test/builtins/Unit/ashrdi3_test.c b/test/builtins/Unit/ashrdi3_test.c index ac517e191880..ee6409c870be 100644 --- a/test/builtins/Unit/ashrdi3_test.c +++ b/test/builtins/Unit/ashrdi3_test.c @@ -18,7 +18,7 @@ // Precondition: 0 <= b < bits_in_dword -di_int __ashrdi3(di_int a, si_int b); +COMPILER_RT_ABI di_int __ashrdi3(di_int a, si_int b); int test__ashrdi3(di_int a, si_int b, di_int expected) { diff --git a/test/builtins/Unit/ashrti3_test.c b/test/builtins/Unit/ashrti3_test.c index 62ba1017ecd9..201582d4eac4 100644 --- a/test/builtins/Unit/ashrti3_test.c +++ b/test/builtins/Unit/ashrti3_test.c @@ -20,7 +20,7 @@ // Precondition: 0 <= b < bits_in_tword -ti_int __ashrti3(ti_int a, si_int b); +COMPILER_RT_ABI ti_int __ashrti3(ti_int a, si_int b); int test__ashrti3(ti_int a, si_int b, ti_int expected) { diff --git a/test/builtins/Unit/clzdi2_test.c b/test/builtins/Unit/clzdi2_test.c index 58403f091f48..41e120932dfd 100644 --- a/test/builtins/Unit/clzdi2_test.c +++ b/test/builtins/Unit/clzdi2_test.c @@ -18,7 +18,7 @@ // Precondition: a != 0 -si_int __clzdi2(di_int a); +COMPILER_RT_ABI si_int __clzdi2(di_int a); int test__clzdi2(di_int a, si_int expected) { diff --git a/test/builtins/Unit/clzsi2_test.c b/test/builtins/Unit/clzsi2_test.c index cc1da64b03ef..80b300feea86 100644 --- a/test/builtins/Unit/clzsi2_test.c +++ b/test/builtins/Unit/clzsi2_test.c @@ -18,7 +18,7 @@ // Precondition: a != 0 -si_int __clzsi2(si_int a); +COMPILER_RT_ABI si_int __clzsi2(si_int a); int test__clzsi2(si_int a, si_int expected) { diff --git a/test/builtins/Unit/clzti2_test.c b/test/builtins/Unit/clzti2_test.c index 5a0e3e8b1e98..3a2c6fabb82e 100644 --- a/test/builtins/Unit/clzti2_test.c +++ b/test/builtins/Unit/clzti2_test.c @@ -20,7 +20,7 @@ // Precondition: a != 0 -si_int __clzti2(ti_int a); +COMPILER_RT_ABI si_int __clzti2(ti_int a); int test__clzti2(ti_int a, si_int expected) { diff --git a/test/builtins/Unit/cmpdi2_test.c b/test/builtins/Unit/cmpdi2_test.c index 609ab1a63a61..33a12a042400 100644 --- a/test/builtins/Unit/cmpdi2_test.c +++ b/test/builtins/Unit/cmpdi2_test.c @@ -18,7 +18,7 @@ // if (a == b) returns 1 // if (a > b) returns 2 -si_int __cmpdi2(di_int a, di_int b); +COMPILER_RT_ABI si_int __cmpdi2(di_int a, di_int b); int test__cmpdi2(di_int a, di_int b, si_int expected) { diff --git a/test/builtins/Unit/cmpti2_test.c b/test/builtins/Unit/cmpti2_test.c index 15ee4fc68d53..d951923b2da3 100644 --- a/test/builtins/Unit/cmpti2_test.c +++ b/test/builtins/Unit/cmpti2_test.c @@ -20,7 +20,7 @@ // if (a == b) returns 1 // if (a > b) returns 2 -si_int __cmpti2(ti_int a, ti_int b); +COMPILER_RT_ABI si_int __cmpti2(ti_int a, ti_int b); int test__cmpti2(ti_int a, ti_int b, si_int expected) { diff --git a/test/builtins/Unit/ctzdi2_test.c b/test/builtins/Unit/ctzdi2_test.c index 1f2d101a1943..bde66b1e5450 100644 --- a/test/builtins/Unit/ctzdi2_test.c +++ b/test/builtins/Unit/ctzdi2_test.c @@ -18,7 +18,7 @@ // Precondition: a != 0 -si_int __ctzdi2(di_int a); +COMPILER_RT_ABI si_int __ctzdi2(di_int a); int test__ctzdi2(di_int a, si_int expected) { diff --git a/test/builtins/Unit/ctzsi2_test.c b/test/builtins/Unit/ctzsi2_test.c index 36f221595b68..cbc101fca04d 100644 --- a/test/builtins/Unit/ctzsi2_test.c +++ b/test/builtins/Unit/ctzsi2_test.c @@ -18,7 +18,7 @@ // Precondition: a != 0 -si_int __ctzsi2(si_int a); +COMPILER_RT_ABI si_int __ctzsi2(si_int a); int test__ctzsi2(si_int a, si_int expected) { diff --git a/test/builtins/Unit/ctzti2_test.c b/test/builtins/Unit/ctzti2_test.c index 9a972f9e2f94..0ca1920bd74b 100644 --- a/test/builtins/Unit/ctzti2_test.c +++ b/test/builtins/Unit/ctzti2_test.c @@ -20,7 +20,7 @@ // Precondition: a != 0 -si_int __ctzti2(ti_int a); +COMPILER_RT_ABI si_int __ctzti2(ti_int a); int test__ctzti2(ti_int a, si_int expected) { diff --git a/test/builtins/Unit/divdc3_test.c b/test/builtins/Unit/divdc3_test.c index 9224cddceeb8..80b9e86e1e2d 100644 --- a/test/builtins/Unit/divdc3_test.c +++ b/test/builtins/Unit/divdc3_test.c @@ -18,7 +18,8 @@ // Returns: the quotient of (a + ib) / (c + id) -double _Complex __divdc3(double __a, double __b, double __c, double __d); +COMPILER_RT_ABI double _Complex +__divdc3(double __a, double __b, double __c, double __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/divdf3vfp_test.c b/test/builtins/Unit/divdf3vfp_test.c index e13822ffcaa0..6f0808abc931 100644 --- a/test/builtins/Unit/divdf3vfp_test.c +++ b/test/builtins/Unit/divdf3vfp_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> #if __arm__ -extern double __divdf3vfp(double a, double b); +extern COMPILER_RT_ABI double __divdf3vfp(double a, double b); int test__divdf3vfp(double a, double b) { diff --git a/test/builtins/Unit/divdi3_test.c b/test/builtins/Unit/divdi3_test.c index c25f917a419e..1d459803e1ee 100644 --- a/test/builtins/Unit/divdi3_test.c +++ b/test/builtins/Unit/divdi3_test.c @@ -16,7 +16,7 @@ // Returns: a / b -di_int __divdi3(di_int a, di_int b); +COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b); int test__divdi3(di_int a, di_int b, di_int expected) { diff --git a/test/builtins/Unit/divmodsi4_test.c b/test/builtins/Unit/divmodsi4_test.c index bea31ea9a445..6fb1c985ab5c 100644 --- a/test/builtins/Unit/divmodsi4_test.c +++ b/test/builtins/Unit/divmodsi4_test.c @@ -16,7 +16,7 @@ // Returns: a / b -extern si_int __divmodsi4(si_int a, si_int b, si_int* rem); +extern COMPILER_RT_ABI si_int __divmodsi4(si_int a, si_int b, si_int* rem); int test__divmodsi4(si_int a, si_int b, diff --git a/test/builtins/Unit/divsc3_test.c b/test/builtins/Unit/divsc3_test.c index 9d060a2d1489..2d7c6593796f 100644 --- a/test/builtins/Unit/divsc3_test.c +++ b/test/builtins/Unit/divsc3_test.c @@ -18,7 +18,8 @@ // Returns: the quotient of (a + ib) / (c + id) -float _Complex __divsc3(float __a, float __b, float __c, float __d); +COMPILER_RT_ABI float _Complex +__divsc3(float __a, float __b, float __c, float __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/divsf3vfp_test.c b/test/builtins/Unit/divsf3vfp_test.c index 8382558412cf..f742441991f8 100644 --- a/test/builtins/Unit/divsf3vfp_test.c +++ b/test/builtins/Unit/divsf3vfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern float __divsf3vfp(float a, float b); +extern COMPILER_RT_ABI float __divsf3vfp(float a, float b); #if __arm__ int test__divsf3vfp(float a, float b) diff --git a/test/builtins/Unit/divsi3_test.c b/test/builtins/Unit/divsi3_test.c index 6fda54ff37ec..c523367455a9 100644 --- a/test/builtins/Unit/divsi3_test.c +++ b/test/builtins/Unit/divsi3_test.c @@ -16,7 +16,7 @@ // Returns: a / b -si_int __divsi3(si_int a, si_int b); +COMPILER_RT_ABI si_int __divsi3(si_int a, si_int b); int test__divsi3(si_int a, si_int b, si_int expected) { diff --git a/test/builtins/Unit/divtc3_test.c b/test/builtins/Unit/divtc3_test.c index 7bb74d755146..ad2c96dc0409 100644 --- a/test/builtins/Unit/divtc3_test.c +++ b/test/builtins/Unit/divtc3_test.c @@ -11,16 +11,17 @@ // //===----------------------------------------------------------------------===// +#include <stdio.h> + #if _ARCH_PPC #include "int_lib.h" #include <math.h> #include <complex.h> -#include <stdio.h> // Returns: the quotient of (a + ib) / (c + id) -long double _Complex +COMPILER_RT_ABI long double _Complex __divtc3(long double __a, long double __b, long double __c, long double __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/divtf3_test.c b/test/builtins/Unit/divtf3_test.c index dad631cc4f17..e0def45ffd58 100644 --- a/test/builtins/Unit/divtf3_test.c +++ b/test/builtins/Unit/divtf3_test.c @@ -11,6 +11,7 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 @@ -18,7 +19,7 @@ #include "fp_test.h" // Returns: a / b -long double __divtf3(long double a, long double b); +COMPILER_RT_ABI long double __divtf3(long double a, long double b); int test__divtf3(long double a, long double b, uint64_t expectedHi, uint64_t expectedLo) diff --git a/test/builtins/Unit/divti3_test.c b/test/builtins/Unit/divti3_test.c index bc81c2a5418d..3a94dab8c7a6 100644 --- a/test/builtins/Unit/divti3_test.c +++ b/test/builtins/Unit/divti3_test.c @@ -18,7 +18,7 @@ // Returns: a / b -ti_int __divti3(ti_int a, ti_int b); +COMPILER_RT_ABI ti_int __divti3(ti_int a, ti_int b); int test__divti3(ti_int a, ti_int b, ti_int expected) { diff --git a/test/builtins/Unit/divxc3_test.c b/test/builtins/Unit/divxc3_test.c index aa8a7625d139..509b4b18e978 100644 --- a/test/builtins/Unit/divxc3_test.c +++ b/test/builtins/Unit/divxc3_test.c @@ -20,7 +20,7 @@ // Returns: the quotient of (a + ib) / (c + id) -long double _Complex +COMPILER_RT_ABI long double _Complex __divxc3(long double __a, long double __b, long double __c, long double __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/extebdsfdf2vfp_test.c b/test/builtins/Unit/extebdsfdf2vfp_test.c index 3a009cf2d7f8..53c72828f741 100644 --- a/test/builtins/Unit/extebdsfdf2vfp_test.c +++ b/test/builtins/Unit/extebdsfdf2vfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern double __extendsfdf2vfp(float a); +extern COMPILER_RT_ABI double __extendsfdf2vfp(float a); #if __arm__ int test__extendsfdf2vfp(float a) diff --git a/test/builtins/Unit/extenddftf2_test.c b/test/builtins/Unit/extenddftf2_test.c index 05acc08c0951..2cfb32b2604a 100644 --- a/test/builtins/Unit/extenddftf2_test.c +++ b/test/builtins/Unit/extenddftf2_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 #include "fp_test.h" -long double __extenddftf2(double a); +COMPILER_RT_ABI long double __extenddftf2(double a); int test__extenddftf2(double a, uint64_t expectedHi, uint64_t expectedLo) { diff --git a/test/builtins/Unit/extendhfsf2_test.c b/test/builtins/Unit/extendhfsf2_test.c new file mode 100644 index 000000000000..5dd994cae1c6 --- /dev/null +++ b/test/builtins/Unit/extendhfsf2_test.c @@ -0,0 +1,113 @@ +//===--------------- extendhfsf2_test.c - Test __extendhfsf2 --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __extendhfsf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +#include "fp_test.h" + +float __extendhfsf2(uint16_t a); + +int test__extendhfsf2(uint16_t a, float expected) +{ + float x = __extendhfsf2(a); + int ret = compareResultH(x, expected); + + if (ret){ + printf("error in test__extendhfsf2(%#.4x) = %f, " + "expected %f\n", a, x, expected); + } + return ret; +} + +char assumption_1[sizeof(__fp16) * CHAR_BIT == 16] = {0}; + +int main() +{ + // qNaN + if (test__extendhfsf2(UINT16_C(0x7e00), + makeQNaN32())) + return 1; + // NaN + if (test__extendhfsf2(UINT16_C(0x7e00), + makeNaN32(UINT32_C(0x8000)))) + return 1; + // inf + if (test__extendhfsf2(UINT16_C(0x7c00), + makeInf32())) + return 1; + if (test__extendhfsf2(UINT16_C(0xfc00), + -makeInf32())) + return 1; + // zero + if (test__extendhfsf2(UINT16_C(0x0), + 0.0f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x8000), + -0.0f)) + return 1; + + if (test__extendhfsf2(UINT16_C(0x4248), + 3.1415926535f)) + return 1; + if (test__extendhfsf2(UINT16_C(0xc248), + -3.1415926535f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x7c00), + 0x1.987124876876324p+100f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x6e62), + 0x1.988p+12f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x3c00), + 0x1.0p+0f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x0400), + 0x1.0p-14f)) + return 1; + // denormal + if (test__extendhfsf2(UINT16_C(0x0010), + 0x1.0p-20f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x0001), + 0x1.0p-24f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x8001), + -0x1.0p-24f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x0001), + 0x1.5p-25f)) + return 1; + // and back to zero + if (test__extendhfsf2(UINT16_C(0x0000), + 0x1.0p-25f)) + return 1; + if (test__extendhfsf2(UINT16_C(0x8000), + -0x1.0p-25f)) + return 1; + // max (precise) + if (test__extendhfsf2(UINT16_C(0x7bff), + 65504.0f)) + return 1; + // max (rounded) + if (test__extendhfsf2(UINT16_C(0x7bff), + 65504.0f)) + return 1; + // max (to +inf) + if (test__extendhfsf2(UINT16_C(0x7c00), + makeInf32())) + return 1; + if (test__extendhfsf2(UINT16_C(0xfc00), + -makeInf32())) + return 1; + return 0; +} diff --git a/test/builtins/Unit/extendsftf2_test.c b/test/builtins/Unit/extendsftf2_test.c index 5f41928b862f..7dff5b6be3d9 100644 --- a/test/builtins/Unit/extendsftf2_test.c +++ b/test/builtins/Unit/extendsftf2_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 #include "fp_test.h" -long double __extendsftf2(float a); +COMPILER_RT_ABI long double __extendsftf2(float a); int test__extendsftf2(float a, uint64_t expectedHi, uint64_t expectedLo) { diff --git a/test/builtins/Unit/ffsdi2_test.c b/test/builtins/Unit/ffsdi2_test.c index 9041127d1a62..a27d154fd351 100644 --- a/test/builtins/Unit/ffsdi2_test.c +++ b/test/builtins/Unit/ffsdi2_test.c @@ -17,7 +17,7 @@ // Returns: the index of the least significant 1-bit in a, or // the value zero if a is zero. The least significant bit is index one. -si_int __ffsdi2(di_int a); +COMPILER_RT_ABI si_int __ffsdi2(di_int a); int test__ffsdi2(di_int a, si_int expected) { diff --git a/test/builtins/Unit/ffsti2_test.c b/test/builtins/Unit/ffsti2_test.c index f944ed0a1e45..396269d51369 100644 --- a/test/builtins/Unit/ffsti2_test.c +++ b/test/builtins/Unit/ffsti2_test.c @@ -19,7 +19,7 @@ // Returns: the index of the least significant 1-bit in a, or // the value zero if a is zero. The least significant bit is index one. -si_int __ffsti2(ti_int a); +COMPILER_RT_ABI si_int __ffsti2(ti_int a); int test__ffsti2(ti_int a, si_int expected) { diff --git a/test/builtins/Unit/fixdfdi_test.c b/test/builtins/Unit/fixdfdi_test.c index d08afe3a5336..4a7cfa31c7f0 100644 --- a/test/builtins/Unit/fixdfdi_test.c +++ b/test/builtins/Unit/fixdfdi_test.c @@ -22,7 +22,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -di_int __fixdfdi(double a); +COMPILER_RT_ABI di_int __fixdfdi(double a); int test__fixdfdi(double a, di_int expected) { diff --git a/test/builtins/Unit/fixdfti_test.c b/test/builtins/Unit/fixdfti_test.c index bfa88fd70e14..b5da456fc6b3 100644 --- a/test/builtins/Unit/fixdfti_test.c +++ b/test/builtins/Unit/fixdfti_test.c @@ -24,7 +24,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -ti_int __fixdfti(double a); +COMPILER_RT_ABI ti_int __fixdfti(double a); int test__fixdfti(double a, ti_int expected) { diff --git a/test/builtins/Unit/fixsfdi_test.c b/test/builtins/Unit/fixsfdi_test.c index d3e934a5c02a..f37ecef047aa 100644 --- a/test/builtins/Unit/fixsfdi_test.c +++ b/test/builtins/Unit/fixsfdi_test.c @@ -22,7 +22,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -di_int __fixsfdi(float a); +COMPILER_RT_ABI di_int __fixsfdi(float a); int test__fixsfdi(float a, di_int expected) { diff --git a/test/builtins/Unit/fixsfti_test.c b/test/builtins/Unit/fixsfti_test.c index 2b0b99774819..38748aabc91b 100644 --- a/test/builtins/Unit/fixsfti_test.c +++ b/test/builtins/Unit/fixsfti_test.c @@ -24,7 +24,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -ti_int __fixsfti(float a); +COMPILER_RT_ABI ti_int __fixsfti(float a); int test__fixsfti(float a, ti_int expected) { diff --git a/test/builtins/Unit/fixtfsi_test.c b/test/builtins/Unit/fixtfsi_test.c new file mode 100644 index 000000000000..45ad0d243785 --- /dev/null +++ b/test/builtins/Unit/fixtfsi_test.c @@ -0,0 +1,65 @@ +//===--------------- fixtfsi_test.c - Test __fixtfsi ----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __fixtfsi for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +#if __LDBL_MANT_DIG__ == 113 + +#include "fp_test.h" + +int __fixtfsi(long double a); + +int test__fixtfsi(long double a, int expected) +{ + int x = __fixtfsi(a); + int ret = (x != expected); + + if (ret){ + printf("error in test__fixtfsi(%.20Lf) = %d, " + "expected %d\n", a, x, expected); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LDBL_MANT_DIG__ == 113 + if (test__fixtfsi(makeInf128(), 0x7fffffff)) + return 1; + if (test__fixtfsi(0, 0x0)) + return 1; + if (test__fixtfsi(0x1.23456789abcdefp+5, 0x24)) + return 1; + if (test__fixtfsi(0x1.23456789abcdefp-3, 0x0)) + return 1; + if (test__fixtfsi(0x1.23456789abcdefp+20, 0x123456)) + return 1; + if (test__fixtfsi(0x1.23456789abcdefp+40, 0x7fffffff)) + return 1; + if (test__fixtfsi(0x1.23456789abcdefp+256, 0x7fffffff)) + return 1; + if (test__fixtfsi(-0x1.23456789abcdefp+20, 0xffedcbaa)) + return 1; + if (test__fixtfsi(-0x1.23456789abcdefp+40, 0x80000001)) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} diff --git a/test/builtins/Unit/fixunsdfdi_test.c b/test/builtins/Unit/fixunsdfdi_test.c index 0803fd28f5bb..3998482876f3 100644 --- a/test/builtins/Unit/fixunsdfdi_test.c +++ b/test/builtins/Unit/fixunsdfdi_test.c @@ -24,7 +24,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -du_int __fixunsdfdi(double a); +COMPILER_RT_ABI du_int __fixunsdfdi(double a); int test__fixunsdfdi(double a, du_int expected) { diff --git a/test/builtins/Unit/fixunsdfsi_test.c b/test/builtins/Unit/fixunsdfsi_test.c index 54fe35b5c35a..551fc88a5241 100644 --- a/test/builtins/Unit/fixunsdfsi_test.c +++ b/test/builtins/Unit/fixunsdfsi_test.c @@ -24,7 +24,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -su_int __fixunsdfsi(double a); +COMPILER_RT_ABI su_int __fixunsdfsi(double a); int test__fixunsdfsi(double a, su_int expected) { diff --git a/test/builtins/Unit/fixunsdfsivfp_test.c b/test/builtins/Unit/fixunsdfsivfp_test.c index 3727cf7b02fb..ebd0be274f62 100644 --- a/test/builtins/Unit/fixunsdfsivfp_test.c +++ b/test/builtins/Unit/fixunsdfsivfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern unsigned int __fixunsdfsivfp(double a); +extern COMPILER_RT_ABI unsigned int __fixunsdfsivfp(double a); #if __arm__ int test__fixunsdfsivfp(double a) diff --git a/test/builtins/Unit/fixunsdfti_test.c b/test/builtins/Unit/fixunsdfti_test.c index 9f89de493680..e1aa56d7631e 100644 --- a/test/builtins/Unit/fixunsdfti_test.c +++ b/test/builtins/Unit/fixunsdfti_test.c @@ -26,7 +26,7 @@ #ifdef CRT_HAS_128BIT -tu_int __fixunsdfti(double a); +COMPILER_RT_ABI tu_int __fixunsdfti(double a); int test__fixunsdfti(double a, tu_int expected) { diff --git a/test/builtins/Unit/fixunssfdi_test.c b/test/builtins/Unit/fixunssfdi_test.c index ac89be7bbb27..812457a002de 100644 --- a/test/builtins/Unit/fixunssfdi_test.c +++ b/test/builtins/Unit/fixunssfdi_test.c @@ -24,7 +24,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -du_int __fixunssfdi(float a); +COMPILER_RT_ABI du_int __fixunssfdi(float a); int test__fixunssfdi(float a, du_int expected) { diff --git a/test/builtins/Unit/fixunssfsi_test.c b/test/builtins/Unit/fixunssfsi_test.c index ce6a9287515f..94a8b0867eca 100644 --- a/test/builtins/Unit/fixunssfsi_test.c +++ b/test/builtins/Unit/fixunssfsi_test.c @@ -24,7 +24,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -su_int __fixunssfsi(float a); +COMPILER_RT_ABI su_int __fixunssfsi(float a); int test__fixunssfsi(float a, su_int expected) { diff --git a/test/builtins/Unit/fixunssfti_test.c b/test/builtins/Unit/fixunssfti_test.c index 7965b9500d05..979d661910f0 100644 --- a/test/builtins/Unit/fixunssfti_test.c +++ b/test/builtins/Unit/fixunssfti_test.c @@ -26,7 +26,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -tu_int __fixunssfti(float a); +COMPILER_RT_ABI tu_int __fixunssfti(float a); int test__fixunssfti(float a, tu_int expected) { diff --git a/test/builtins/Unit/fixunstfdi_test.c b/test/builtins/Unit/fixunstfdi_test.c index d0a5db7a9c97..60ea503d2778 100644 --- a/test/builtins/Unit/fixunstfdi_test.c +++ b/test/builtins/Unit/fixunstfdi_test.c @@ -11,10 +11,11 @@ // //===----------------------------------------------------------------------===// +#include <stdio.h> + #if _ARCH_PPC #include "int_lib.h" -#include <stdio.h> // Returns: convert a to a unsigned long long, rounding toward zero. // Negative values all become zero. @@ -24,7 +25,7 @@ // value in long double is representable in du_int or is negative // (no range checking performed) -du_int __fixunstfdi(long double a); +COMPILER_RT_ABI du_int __fixunstfdi(long double a); int test__fixunstfdi(long double a, du_int expected) { diff --git a/test/builtins/Unit/fixunstfsi_test.c b/test/builtins/Unit/fixunstfsi_test.c new file mode 100644 index 000000000000..4bf8fdec607c --- /dev/null +++ b/test/builtins/Unit/fixunstfsi_test.c @@ -0,0 +1,64 @@ +//===--------------- fixunstfsi_test.c - Test __fixunstfsi ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __fixunstfsi for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +#if __LDBL_MANT_DIG__ == 113 + +#include "fp_test.h" + +unsigned int __fixunstfsi(long double a); + +int test__fixunstfsi(long double a, unsigned int expected) +{ + unsigned int x = __fixunstfsi(a); + int ret = (x != expected); + + if (ret) + { + printf("error in test__fixunstfsi(%.20Lf) = %u, " + "expected %u\n", a, x, expected); + } + return ret; +} + +char assumption_1[sizeof(long double) * CHAR_BIT == 128] = {0}; + +#endif + +int main() +{ +#if __LDBL_MANT_DIG__ == 113 + if (test__fixunstfsi(makeInf128(), UINT32_C(0xffffffff))) + return 1; + if (test__fixunstfsi(0, UINT32_C(0x0))) + return 1; + if (test__fixunstfsi(0x1.23456789abcdefp+5, UINT32_C(0x24))) + return 1; + if (test__fixunstfsi(0x1.23456789abcdefp-3, UINT32_C(0x0))) + return 1; + if (test__fixunstfsi(0x1.23456789abcdefp+20, UINT32_C(0x123456))) + return 1; + if (test__fixunstfsi(0x1.23456789abcdefp+40, UINT32_C(0xffffffff))) + return 1; + if (test__fixunstfsi(0x1.23456789abcdefp+256, UINT32_C(0xffffffff))) + return 1; + if (test__fixunstfsi(-0x1.23456789abcdefp+3, UINT32_C(0x0))) + return 1; + +#else + printf("skipped\n"); + +#endif + return 0; +} diff --git a/test/builtins/Unit/fixunsxfdi_test.c b/test/builtins/Unit/fixunsxfdi_test.c index 4308f6f4ef1f..6f42079695f2 100644 --- a/test/builtins/Unit/fixunsxfdi_test.c +++ b/test/builtins/Unit/fixunsxfdi_test.c @@ -28,7 +28,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -du_int __fixunsxfdi(long double a); +COMPILER_RT_ABI du_int __fixunsxfdi(long double a); int test__fixunsxfdi(long double a, du_int expected) { diff --git a/test/builtins/Unit/fixunsxfsi_test.c b/test/builtins/Unit/fixunsxfsi_test.c index cb2a7f487210..0d78dcb53c0f 100644 --- a/test/builtins/Unit/fixunsxfsi_test.c +++ b/test/builtins/Unit/fixunsxfsi_test.c @@ -26,7 +26,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -su_int __fixunsxfsi(long double a); +COMPILER_RT_ABI su_int __fixunsxfsi(long double a); int test__fixunsxfsi(long double a, su_int expected) { diff --git a/test/builtins/Unit/fixunsxfti_test.c b/test/builtins/Unit/fixunsxfti_test.c index 7d18b1267b3a..94b5aebe4d16 100644 --- a/test/builtins/Unit/fixunsxfti_test.c +++ b/test/builtins/Unit/fixunsxfti_test.c @@ -27,7 +27,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -tu_int __fixunsxfti(long double a); +COMPILER_RT_ABI tu_int __fixunsxfti(long double a); int test__fixunsxfti(long double a, tu_int expected) { diff --git a/test/builtins/Unit/fixxfdi_test.c b/test/builtins/Unit/fixxfdi_test.c index 43ac0f8aaa3c..0a90a56e6101 100644 --- a/test/builtins/Unit/fixxfdi_test.c +++ b/test/builtins/Unit/fixxfdi_test.c @@ -25,7 +25,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -di_int __fixxfdi(long double a); +COMPILER_RT_ABI di_int __sfixxfdi(long double a); int test__fixxfdi(long double a, di_int expected) { diff --git a/test/builtins/Unit/fixxfti_test.c b/test/builtins/Unit/fixxfti_test.c index 87914c5341bd..b8573cc14173 100644 --- a/test/builtins/Unit/fixxfti_test.c +++ b/test/builtins/Unit/fixxfti_test.c @@ -25,7 +25,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -ti_int __fixxfti(long double a); +COMPILER_RT_ABI ti_int __fixxfti(long double a); int test__fixxfti(long double a, ti_int expected) { diff --git a/test/builtins/Unit/floatdidf_test.c b/test/builtins/Unit/floatdidf_test.c index af3dacd4f38b..9bf2be97c7a4 100644 --- a/test/builtins/Unit/floatdidf_test.c +++ b/test/builtins/Unit/floatdidf_test.c @@ -22,7 +22,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -double __floatdidf(di_int a); +COMPILER_RT_ABI double __floatdidf(di_int a); int test__floatdidf(di_int a, double expected) { diff --git a/test/builtins/Unit/floatdisf_test.c b/test/builtins/Unit/floatdisf_test.c index 3e71df7b2228..a55c6a9617e9 100644 --- a/test/builtins/Unit/floatdisf_test.c +++ b/test/builtins/Unit/floatdisf_test.c @@ -22,7 +22,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -float __floatdisf(di_int a); +COMPILER_RT_ABI float __floatdisf(di_int a); int test__floatdisf(di_int a, float expected) { diff --git a/test/builtins/Unit/floatdixf_test.c b/test/builtins/Unit/floatdixf_test.c index 337666426318..f6ab5a4665c1 100644 --- a/test/builtins/Unit/floatdixf_test.c +++ b/test/builtins/Unit/floatdixf_test.c @@ -23,7 +23,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -long double __floatdixf(di_int a); +long COMPILER_RT_ABI double __floatdixf(di_int a); int test__floatdixf(di_int a, long double expected) { diff --git a/test/builtins/Unit/floatsidfvfp_test.c b/test/builtins/Unit/floatsidfvfp_test.c index e21ecda59945..e5ea3a4d4dc9 100644 --- a/test/builtins/Unit/floatsidfvfp_test.c +++ b/test/builtins/Unit/floatsidfvfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern double __floatsidfvfp(int a); +extern COMPILER_RT_ABI double __floatsidfvfp(int a); #if __arm__ int test__floatsidfvfp(int a) diff --git a/test/builtins/Unit/floatsisfvfp_test.c b/test/builtins/Unit/floatsisfvfp_test.c index d20905bd91e3..ab21e2e7ff4d 100644 --- a/test/builtins/Unit/floatsisfvfp_test.c +++ b/test/builtins/Unit/floatsisfvfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern float __floatsisfvfp(int a); +extern COMPILER_RT_ABI float __floatsisfvfp(int a); #if __arm__ int test__floatsisfvfp(int a) diff --git a/test/builtins/Unit/floatsitf_test.c b/test/builtins/Unit/floatsitf_test.c index db4d020af2a9..8373c7d96e26 100644 --- a/test/builtins/Unit/floatsitf_test.c +++ b/test/builtins/Unit/floatsitf_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 #include "fp_test.h" -long double __floatsitf(int a); +long COMPILER_RT_ABI double __floatsitf(int a); int test__floatsitf(int a, uint64_t expectedHi, uint64_t expectedLo) { diff --git a/test/builtins/Unit/floattidf_test.c b/test/builtins/Unit/floattidf_test.c index 476304f96f10..3af382ac001a 100644 --- a/test/builtins/Unit/floattidf_test.c +++ b/test/builtins/Unit/floattidf_test.c @@ -24,7 +24,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -double __floattidf(ti_int a); +COMPILER_RT_ABI double __floattidf(ti_int a); int test__floattidf(ti_int a, double expected) { diff --git a/test/builtins/Unit/floattisf_test.c b/test/builtins/Unit/floattisf_test.c index 75b8e917f76d..0f5dc544da68 100644 --- a/test/builtins/Unit/floattisf_test.c +++ b/test/builtins/Unit/floattisf_test.c @@ -24,7 +24,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -float __floattisf(ti_int a); +COMPILER_RT_ABI float __floattisf(ti_int a); int test__floattisf(ti_int a, float expected) { diff --git a/test/builtins/Unit/floattixf_test.c b/test/builtins/Unit/floattixf_test.c index ce3566867a47..d281debdcf55 100644 --- a/test/builtins/Unit/floattixf_test.c +++ b/test/builtins/Unit/floattixf_test.c @@ -25,7 +25,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -long double __floattixf(ti_int a); +COMPILER_RT_ABI long double __floattixf(ti_int a); int test__floattixf(ti_int a, long double expected) { diff --git a/test/builtins/Unit/floatundidf_test.c b/test/builtins/Unit/floatundidf_test.c index ae91ac374eb0..97fb1e5ec098 100644 --- a/test/builtins/Unit/floatundidf_test.c +++ b/test/builtins/Unit/floatundidf_test.c @@ -22,7 +22,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -double __floatundidf(du_int a); +COMPILER_RT_ABI double __floatundidf(du_int a); int test__floatundidf(di_int a, double expected) { diff --git a/test/builtins/Unit/floatundisf_test.c b/test/builtins/Unit/floatundisf_test.c index 394c945a3919..40b6bcc459af 100644 --- a/test/builtins/Unit/floatundisf_test.c +++ b/test/builtins/Unit/floatundisf_test.c @@ -22,7 +22,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -float __floatundisf(du_int a); +COMPILER_RT_ABI float __floatundisf(du_int a); int test__floatundisf(du_int a, float expected) { diff --git a/test/builtins/Unit/floatundixf_test.c b/test/builtins/Unit/floatundixf_test.c index 1974fa01012a..690dce19957a 100644 --- a/test/builtins/Unit/floatundixf_test.c +++ b/test/builtins/Unit/floatundixf_test.c @@ -24,7 +24,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -long double __floatundixf(du_int a); +COMPILER_RT_ABI long double __floatundixf(du_int a); int test__floatundixf(du_int a, long double expected) { diff --git a/test/builtins/Unit/floatunsitf_test.c b/test/builtins/Unit/floatunsitf_test.c index 1af72d246ab2..c3d3fe949c4e 100644 --- a/test/builtins/Unit/floatunsitf_test.c +++ b/test/builtins/Unit/floatunsitf_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 #include "fp_test.h" -long double __floatunsitf(unsigned int a); +COMPILER_RT_ABI long double __floatunsitf(unsigned int a); int test__floatunsitf(unsigned int a, uint64_t expectedHi, uint64_t expectedLo) { diff --git a/test/builtins/Unit/floatunssidfvfp_test.c b/test/builtins/Unit/floatunssidfvfp_test.c index 4883af1cf5fa..75e4bbd6c21f 100644 --- a/test/builtins/Unit/floatunssidfvfp_test.c +++ b/test/builtins/Unit/floatunssidfvfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern double __floatunssidfvfp(unsigned int a); +extern COMPILER_RT_ABI double __floatunssidfvfp(unsigned int a); #if __arm__ int test__floatunssidfvfp(unsigned int a) diff --git a/test/builtins/Unit/floatunssisfvfp_test.c b/test/builtins/Unit/floatunssisfvfp_test.c index 917061a91b18..47f837cc89a8 100644 --- a/test/builtins/Unit/floatunssisfvfp_test.c +++ b/test/builtins/Unit/floatunssisfvfp_test.c @@ -14,9 +14,9 @@ #include <stdio.h> #include <stdlib.h> #include <math.h> +#include "int_lib.h" - -extern float __floatunssisfvfp(unsigned int a); +extern COMPILER_RT_ABI float __floatunssisfvfp(unsigned int a); #if __arm__ int test__floatunssisfvfp(unsigned int a) diff --git a/test/builtins/Unit/floatuntidf_test.c b/test/builtins/Unit/floatuntidf_test.c index 3cab027051c7..9855ff79703e 100644 --- a/test/builtins/Unit/floatuntidf_test.c +++ b/test/builtins/Unit/floatuntidf_test.c @@ -24,7 +24,7 @@ // seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -double __floatuntidf(tu_int a); +COMPILER_RT_ABI double __floatuntidf(tu_int a); int test__floatuntidf(tu_int a, double expected) { diff --git a/test/builtins/Unit/floatuntisf_test.c b/test/builtins/Unit/floatuntisf_test.c index aeac3ee41e54..9b5ff790a64f 100644 --- a/test/builtins/Unit/floatuntisf_test.c +++ b/test/builtins/Unit/floatuntisf_test.c @@ -24,7 +24,7 @@ // seee eeee emmm mmmm mmmm mmmm mmmm mmmm -float __floatuntisf(tu_int a); +COMPILER_RT_ABI float __floatuntisf(tu_int a); int test__floatuntisf(tu_int a, float expected) { diff --git a/test/builtins/Unit/floatuntixf_test.c b/test/builtins/Unit/floatuntixf_test.c index 9c3434fdde0c..c58b55d3e4c1 100644 --- a/test/builtins/Unit/floatuntixf_test.c +++ b/test/builtins/Unit/floatuntixf_test.c @@ -25,7 +25,7 @@ // gggg gggg gggg gggg gggg gggg gggg gggg | gggg gggg gggg gggg seee eeee eeee eeee | // 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm -long double __floatuntixf(tu_int a); +COMPILER_RT_ABI long double __floatuntixf(tu_int a); int test__floatuntixf(tu_int a, long double expected) { diff --git a/test/builtins/Unit/fp_test.h b/test/builtins/Unit/fp_test.h index da58ca989cda..1f0e7be6d6a4 100644 --- a/test/builtins/Unit/fp_test.h +++ b/test/builtins/Unit/fp_test.h @@ -14,11 +14,17 @@ #include <stdlib.h> #include <limits.h> #include <string.h> +#include <stdint.h> enum EXPECTED_RESULT { LESS_0, LESS_EQUAL_0, EQUAL_0, GREATER_0, GREATER_EQUAL_0, NEQUAL_0 }; +static inline uint16_t fromRep16(uint16_t x) +{ + return x; +} + static inline float fromRep32(uint32_t x) { float ret; @@ -33,6 +39,7 @@ static inline double fromRep64(uint64_t x) return ret; } +#if __LDBL_MANT_DIG__ == 113 static inline long double fromRep128(uint64_t hi, uint64_t lo) { __uint128_t x = ((__uint128_t)hi << 64) + lo; @@ -40,6 +47,12 @@ static inline long double fromRep128(uint64_t hi, uint64_t lo) memcpy(&ret, &x, 16); return ret; } +#endif + +static inline uint16_t toRep16(uint16_t x) +{ + return x; +} static inline uint32_t toRep32(float x) { @@ -55,12 +68,32 @@ static inline uint64_t toRep64(double x) return ret; } +#if __LDBL_MANT_DIG__ == 113 static inline __uint128_t toRep128(long double x) { __uint128_t ret; memcpy(&ret, &x, 16); return ret; } +#endif + +static inline int compareResultH(uint16_t result, + uint16_t expected) +{ + uint16_t rep = toRep16(result); + + if (rep == expected){ + return 0; + } + // test other posible NaN representation(signal NaN) + else if (expected == 0x7e00U){ + if ((rep & 0x7c00U) == 0x7c00U && + (rep & 0x3ffU) > 0){ + return 0; + } + } + return 1; +} static inline int compareResultF(float result, uint32_t expected) @@ -98,6 +131,7 @@ static inline int compareResultD(double result, return 1; } +#if __LDBL_MANT_DIG__ == 113 // return 0 if equal // use two 64-bit integers intead of one 128-bit integer // because 128-bit integer constant can't be assigned directly @@ -121,6 +155,7 @@ static inline int compareResultLD(long double result, } return 1; } +#endif static inline int compareResultCMP(int result, enum EXPECTED_RESULT expected) @@ -177,6 +212,11 @@ static inline char *expectedStr(enum EXPECTED_RESULT expected) return ""; } +static inline uint16_t makeQNaN16() +{ + return fromRep16(0x7e00U); +} + static inline float makeQNaN32() { return fromRep32(0x7fc00000U); @@ -187,10 +227,17 @@ static inline double makeQNaN64() return fromRep64(0x7ff8000000000000UL); } +#if __LDBL_MANT_DIG__ == 113 static inline long double makeQNaN128() { return fromRep128(0x7fff800000000000UL, 0x0UL); } +#endif + +static inline uint16_t makeNaN16(uint16_t rand) +{ + return fromRep16(0x7c00U | (rand & 0x7fffU)); +} static inline float makeNaN32(uint32_t rand) { @@ -202,10 +249,17 @@ static inline double makeNaN64(uint64_t rand) return fromRep64(0x7ff0000000000000UL | (rand & 0xfffffffffffffUL)); } +#if __LDBL_MANT_DIG__ == 113 static inline long double makeNaN128(uint64_t rand) { return fromRep128(0x7fff000000000000UL | (rand & 0xffffffffffffUL), 0x0UL); } +#endif + +static inline uint16_t makeInf16() +{ + return fromRep16(0x7c00U); +} static inline float makeInf32() { @@ -217,7 +271,9 @@ static inline double makeInf64() return fromRep64(0x7ff0000000000000UL); } +#if __LDBL_MANT_DIG__ == 113 static inline long double makeInf128() { return fromRep128(0x7fff000000000000UL, 0x0UL); } +#endif diff --git a/test/builtins/Unit/lshrdi3_test.c b/test/builtins/Unit/lshrdi3_test.c index ffc6a69d0e9f..d48ae4dd79fa 100644 --- a/test/builtins/Unit/lshrdi3_test.c +++ b/test/builtins/Unit/lshrdi3_test.c @@ -18,7 +18,7 @@ // Precondition: 0 <= b < bits_in_dword -di_int __lshrdi3(di_int a, si_int b); +COMPILER_RT_ABI di_int __lshrdi3(di_int a, si_int b); int test__lshrdi3(di_int a, si_int b, di_int expected) { diff --git a/test/builtins/Unit/lshrti3_test.c b/test/builtins/Unit/lshrti3_test.c index 3f33c089cd62..f5a0dd616cb5 100644 --- a/test/builtins/Unit/lshrti3_test.c +++ b/test/builtins/Unit/lshrti3_test.c @@ -20,7 +20,7 @@ // Precondition: 0 <= b < bits_in_dword -ti_int __lshrti3(ti_int a, si_int b); +COMPILER_RT_ABI ti_int __lshrti3(ti_int a, si_int b); int test__lshrti3(ti_int a, si_int b, ti_int expected) { diff --git a/test/builtins/Unit/moddi3_test.c b/test/builtins/Unit/moddi3_test.c index 9f6801d6f41b..62e8f227b34b 100644 --- a/test/builtins/Unit/moddi3_test.c +++ b/test/builtins/Unit/moddi3_test.c @@ -16,7 +16,7 @@ // Returns: a % b -di_int __moddi3(di_int a, di_int b); +COMPILER_RT_ABI di_int __moddi3(di_int a, di_int b); int test__moddi3(di_int a, di_int b, di_int expected) { diff --git a/test/builtins/Unit/modsi3_test.c b/test/builtins/Unit/modsi3_test.c index 52ec9a0ae36b..8c9f58832b9c 100644 --- a/test/builtins/Unit/modsi3_test.c +++ b/test/builtins/Unit/modsi3_test.c @@ -17,7 +17,7 @@ /* Returns: a % b */ -si_int __modsi3(si_int a, si_int b); +COMPILER_RT_ABI si_int __modsi3(si_int a, si_int b); int test__modsi3(si_int a, si_int b, si_int expected) { si_int x = __modsi3(a, b); diff --git a/test/builtins/Unit/modti3_test.c b/test/builtins/Unit/modti3_test.c index ba9f9804dfca..99413aaa2f6a 100644 --- a/test/builtins/Unit/modti3_test.c +++ b/test/builtins/Unit/modti3_test.c @@ -18,7 +18,7 @@ // Returns: a % b -ti_int __modti3(ti_int a, ti_int b); +COMPILER_RT_ABI ti_int __modti3(ti_int a, ti_int b); int test__modti3(ti_int a, ti_int b, ti_int expected) { diff --git a/test/builtins/Unit/muldc3_test.c b/test/builtins/Unit/muldc3_test.c index 112b6120358a..6902ef3222a9 100644 --- a/test/builtins/Unit/muldc3_test.c +++ b/test/builtins/Unit/muldc3_test.c @@ -18,7 +18,8 @@ // Returns: the product of a + ib and c + id -double _Complex __muldc3(double __a, double __b, double __c, double __d); +COMPILER_RT_ABI double _Complex +__muldc3(double __a, double __b, double __c, double __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/muldf3vfp_test.c b/test/builtins/Unit/muldf3vfp_test.c index 73454bf290aa..766972d7d1d7 100644 --- a/test/builtins/Unit/muldf3vfp_test.c +++ b/test/builtins/Unit/muldf3vfp_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> #if __arm__ -extern double __muldf3vfp(double a, double b); +extern COMPILER_RT_ABI double __muldf3vfp(double a, double b); int test__muldf3vfp(double a, double b) { diff --git a/test/builtins/Unit/muldi3_test.c b/test/builtins/Unit/muldi3_test.c index 83b525592645..651dd0177347 100644 --- a/test/builtins/Unit/muldi3_test.c +++ b/test/builtins/Unit/muldi3_test.c @@ -14,7 +14,7 @@ #include "int_lib.h" #include <stdio.h> -di_int __muldi3(di_int a, di_int b); +COMPILER_RT_ABI di_int __muldi3(di_int a, di_int b); int test__muldi3(di_int a, di_int b, di_int expected) { diff --git a/test/builtins/Unit/mulodi4_test.c b/test/builtins/Unit/mulodi4_test.c index 10a0eaac61f9..4546609fb8ec 100644 --- a/test/builtins/Unit/mulodi4_test.c +++ b/test/builtins/Unit/mulodi4_test.c @@ -14,7 +14,7 @@ #include "int_lib.h" #include <stdio.h> -extern di_int __mulodi4(di_int a, di_int b, int* overflow); +extern COMPILER_RT_ABI di_int __mulodi4(di_int a, di_int b, int* overflow); int test__mulodi4(di_int a, di_int b, di_int expected, int expected_overflow) { diff --git a/test/builtins/Unit/mulosi4_test.c b/test/builtins/Unit/mulosi4_test.c index fc509db2c178..6a27d69bd6b7 100644 --- a/test/builtins/Unit/mulosi4_test.c +++ b/test/builtins/Unit/mulosi4_test.c @@ -18,7 +18,7 @@ // Effects: aborts if a * b overflows -si_int __mulosi4(si_int a, si_int b, int *overflow); +COMPILER_RT_ABI si_int __mulosi4(si_int a, si_int b, int *overflow); int test__mulosi4(si_int a, si_int b, si_int expected, int expected_overflow) { diff --git a/test/builtins/Unit/muloti4_test.c b/test/builtins/Unit/muloti4_test.c index 95439a4197a3..d00e7bb6b68b 100644 --- a/test/builtins/Unit/muloti4_test.c +++ b/test/builtins/Unit/muloti4_test.c @@ -20,7 +20,7 @@ // Effects: sets overflow if a * b overflows -ti_int __muloti4(ti_int a, ti_int b, int *overflow); +COMPILER_RT_ABI ti_int __muloti4(ti_int a, ti_int b, int *overflow); int test__muloti4(ti_int a, ti_int b, ti_int expected, int expected_overflow) { diff --git a/test/builtins/Unit/mulsc3_test.c b/test/builtins/Unit/mulsc3_test.c index 7a1b3ae0092d..eeb537ac135d 100644 --- a/test/builtins/Unit/mulsc3_test.c +++ b/test/builtins/Unit/mulsc3_test.c @@ -18,7 +18,8 @@ // Returns: the product of a + ib and c + id -float _Complex __mulsc3(float __a, float __b, float __c, float __d); +COMPILER_RT_ABI float _Complex +__mulsc3(float __a, float __b, float __c, float __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/mulsf3vfp_test.c b/test/builtins/Unit/mulsf3vfp_test.c index 92cf1f128497..5b0f6c14384d 100644 --- a/test/builtins/Unit/mulsf3vfp_test.c +++ b/test/builtins/Unit/mulsf3vfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern float __mulsf3vfp(float a, float b); +extern COMPILER_RT_ABI float __mulsf3vfp(float a, float b); #if __arm__ int test__mulsf3vfp(float a, float b) diff --git a/test/builtins/Unit/multc3_test.c b/test/builtins/Unit/multc3_test.c index f8c66c0e426f..b1482638a913 100644 --- a/test/builtins/Unit/multc3_test.c +++ b/test/builtins/Unit/multc3_test.c @@ -11,16 +11,17 @@ // //===----------------------------------------------------------------------===// +#include <stdio.h> + #if _ARCH_PPC #include "int_lib.h" #include <math.h> #include <complex.h> -#include <stdio.h> // Returns: the product of a + ib and c + id -long double _Complex +COMPILER_RT_ABI long double _Complex __multc3(long double __a, long double __b, long double __c, long double __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/multf3_test.c b/test/builtins/Unit/multf3_test.c index 89610056b27e..98a8f7a3231e 100644 --- a/test/builtins/Unit/multf3_test.c +++ b/test/builtins/Unit/multf3_test.c @@ -18,7 +18,7 @@ #include "fp_test.h" // Returns: a * b -long double __multf3(long double a, long double b); +COMPILER_RT_ABI long double __multf3(long double a, long double b); int test__multf3(long double a, long double b, uint64_t expectedHi, uint64_t expectedLo) diff --git a/test/builtins/Unit/multi3_test.c b/test/builtins/Unit/multi3_test.c index 2ccbd06c3e7d..04b1b8aa851e 100644 --- a/test/builtins/Unit/multi3_test.c +++ b/test/builtins/Unit/multi3_test.c @@ -16,7 +16,7 @@ #ifdef CRT_HAS_128BIT -ti_int __multi3(ti_int a, ti_int b); +COMPILER_RT_ABI ti_int __multi3(ti_int a, ti_int b); int test__multi3(ti_int a, ti_int b, ti_int expected) { diff --git a/test/builtins/Unit/mulvdi3_test.c b/test/builtins/Unit/mulvdi3_test.c index a023bf611279..7f16c4c4f612 100644 --- a/test/builtins/Unit/mulvdi3_test.c +++ b/test/builtins/Unit/mulvdi3_test.c @@ -18,7 +18,7 @@ // Effects: aborts if a * b overflows -di_int __mulvdi3(di_int a, di_int b); +COMPILER_RT_ABI di_int __mulvdi3(di_int a, di_int b); int test__mulvdi3(di_int a, di_int b, di_int expected) { diff --git a/test/builtins/Unit/mulvsi3_test.c b/test/builtins/Unit/mulvsi3_test.c index 1eb53a5d5daa..64df4fe24daf 100644 --- a/test/builtins/Unit/mulvsi3_test.c +++ b/test/builtins/Unit/mulvsi3_test.c @@ -18,7 +18,7 @@ // Effects: aborts if a * b overflows -si_int __mulvsi3(si_int a, si_int b); +COMPILER_RT_ABI si_int __mulvsi3(si_int a, si_int b); int test__mulvsi3(si_int a, si_int b, si_int expected) { diff --git a/test/builtins/Unit/mulvti3_test.c b/test/builtins/Unit/mulvti3_test.c index 6336f4550e0d..bf2f7316ba19 100644 --- a/test/builtins/Unit/mulvti3_test.c +++ b/test/builtins/Unit/mulvti3_test.c @@ -20,7 +20,7 @@ // Effects: aborts if a * b overflows -ti_int __mulvti3(ti_int a, ti_int b); +COMPILER_RT_ABI ti_int __mulvti3(ti_int a, ti_int b); int test__mulvti3(ti_int a, ti_int b, ti_int expected) { diff --git a/test/builtins/Unit/mulxc3_test.c b/test/builtins/Unit/mulxc3_test.c index 4297c162bd8e..e77e94fa9cf9 100644 --- a/test/builtins/Unit/mulxc3_test.c +++ b/test/builtins/Unit/mulxc3_test.c @@ -20,7 +20,7 @@ // Returns: the product of a + ib and c + id -long double _Complex +COMPILER_RT_ABI long double _Complex __mulxc3(long double __a, long double __b, long double __c, long double __d); enum {zero, non_zero, inf, NaN, non_zero_nan}; diff --git a/test/builtins/Unit/negdf2vfp_test.c b/test/builtins/Unit/negdf2vfp_test.c index dc55428d6780..f0e66777e3a1 100644 --- a/test/builtins/Unit/negdf2vfp_test.c +++ b/test/builtins/Unit/negdf2vfp_test.c @@ -16,7 +16,7 @@ #include <math.h> -extern double __negdf2vfp(double a); +extern COMPILER_RT_ABI double __negdf2vfp(double a); #if __arm__ int test__negdf2vfp(double a) diff --git a/test/builtins/Unit/negdi2_test.c b/test/builtins/Unit/negdi2_test.c index 510b3b046b56..beccd71ee796 100644 --- a/test/builtins/Unit/negdi2_test.c +++ b/test/builtins/Unit/negdi2_test.c @@ -16,7 +16,7 @@ // Returns: -a -di_int __negdi2(di_int a); +COMPILER_RT_ABI di_int __negdi2(di_int a); int test__negdi2(di_int a, di_int expected) { diff --git a/test/builtins/Unit/negsf2vfp_test.c b/test/builtins/Unit/negsf2vfp_test.c index ef54cee1dbee..9e47d89094ce 100644 --- a/test/builtins/Unit/negsf2vfp_test.c +++ b/test/builtins/Unit/negsf2vfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern float __negsf2vfp(float a); +extern COMPILER_RT_ABI float __negsf2vfp(float a); #if __arm__ int test__negsf2vfp(float a) diff --git a/test/builtins/Unit/negti2_test.c b/test/builtins/Unit/negti2_test.c index a40c0c324bb2..b07597868ced 100644 --- a/test/builtins/Unit/negti2_test.c +++ b/test/builtins/Unit/negti2_test.c @@ -18,7 +18,7 @@ // Returns: -a -ti_int __negti2(ti_int a); +COMPILER_RT_ABI ti_int __negti2(ti_int a); int test__negti2(ti_int a, ti_int expected) { diff --git a/test/builtins/Unit/negvdi2_test.c b/test/builtins/Unit/negvdi2_test.c index 9617b95ff105..5c202e55cfb7 100644 --- a/test/builtins/Unit/negvdi2_test.c +++ b/test/builtins/Unit/negvdi2_test.c @@ -18,7 +18,7 @@ // Effects: aborts if -a overflows -di_int __negvdi2(di_int a); +COMPILER_RT_ABI di_int __negvdi2(di_int a); int test__negvdi2(di_int a) { diff --git a/test/builtins/Unit/negvsi2_test.c b/test/builtins/Unit/negvsi2_test.c index 5ea0e2e86c2a..6330803d5fcf 100644 --- a/test/builtins/Unit/negvsi2_test.c +++ b/test/builtins/Unit/negvsi2_test.c @@ -18,7 +18,7 @@ // Effects: aborts if -a overflows -si_int __negvsi2(si_int a); +COMPILER_RT_ABI si_int __negvsi2(si_int a); int test__negvsi2(si_int a) { diff --git a/test/builtins/Unit/negvti2_test.c b/test/builtins/Unit/negvti2_test.c index 8126cdb5b668..005f8a8acadf 100644 --- a/test/builtins/Unit/negvti2_test.c +++ b/test/builtins/Unit/negvti2_test.c @@ -20,8 +20,8 @@ // Effects: aborts if -a overflows -ti_int __negvti2(ti_int a); -ti_int __negti2(ti_int a); +COMPILER_RT_ABI ti_int __negvti2(ti_int a); +COMPILER_RT_ABI ti_int __negti2(ti_int a); int test__negvti2(ti_int a) { diff --git a/test/builtins/Unit/paritydi2_test.c b/test/builtins/Unit/paritydi2_test.c index 5360e374d439..98220bd8cb61 100644 --- a/test/builtins/Unit/paritydi2_test.c +++ b/test/builtins/Unit/paritydi2_test.c @@ -17,7 +17,7 @@ // Returns: 1 if number of bits is odd else returns 0 -si_int __paritydi2(di_int a); +COMPILER_RT_ABI si_int __paritydi2(di_int a); int naive_parity(di_int a) { diff --git a/test/builtins/Unit/paritysi2_test.c b/test/builtins/Unit/paritysi2_test.c index 3ea8473aad5c..175aeb2c9c00 100644 --- a/test/builtins/Unit/paritysi2_test.c +++ b/test/builtins/Unit/paritysi2_test.c @@ -17,7 +17,7 @@ // Returns: 1 if number of bits is odd else returns 0 -si_int __paritysi2(si_int a); +COMPILER_RT_ABI si_int __paritysi2(si_int a); int naive_parity(si_int a) { diff --git a/test/builtins/Unit/parityti2_test.c b/test/builtins/Unit/parityti2_test.c index 8f065b953d22..cc1e999f29eb 100644 --- a/test/builtins/Unit/parityti2_test.c +++ b/test/builtins/Unit/parityti2_test.c @@ -19,7 +19,7 @@ // Returns: 1 if number of bits is odd else returns 0 -si_int __parityti2(ti_int a); +COMPILER_RT_ABI si_int __parityti2(ti_int a); int naive_parity(ti_int a) { diff --git a/test/builtins/Unit/popcountdi2_test.c b/test/builtins/Unit/popcountdi2_test.c index 4c5611796434..bfd4977b416c 100644 --- a/test/builtins/Unit/popcountdi2_test.c +++ b/test/builtins/Unit/popcountdi2_test.c @@ -17,7 +17,7 @@ // Returns: count of 1 bits -si_int __popcountdi2(di_int a); +COMPILER_RT_ABI si_int __popcountdi2(di_int a); int naive_popcount(di_int a) { diff --git a/test/builtins/Unit/popcountsi2_test.c b/test/builtins/Unit/popcountsi2_test.c index d0a05c45e544..10b757d814e4 100644 --- a/test/builtins/Unit/popcountsi2_test.c +++ b/test/builtins/Unit/popcountsi2_test.c @@ -17,7 +17,7 @@ // Returns: count of 1 bits -si_int __popcountsi2(si_int a); +COMPILER_RT_ABI si_int __popcountsi2(si_int a); int naive_popcount(si_int a) { diff --git a/test/builtins/Unit/popcountti2_test.c b/test/builtins/Unit/popcountti2_test.c index d17e03afd665..3a3c3cb4fa2c 100644 --- a/test/builtins/Unit/popcountti2_test.c +++ b/test/builtins/Unit/popcountti2_test.c @@ -19,7 +19,7 @@ // Returns: count of 1 bits -si_int __popcountti2(ti_int a); +COMPILER_RT_ABI si_int __popcountti2(ti_int a); int naive_popcount(ti_int a) { diff --git a/test/builtins/Unit/powidf2_test.c b/test/builtins/Unit/powidf2_test.c index 2abc84de7676..c499d9abaeb2 100644 --- a/test/builtins/Unit/powidf2_test.c +++ b/test/builtins/Unit/powidf2_test.c @@ -17,7 +17,7 @@ // Returns: a ^ b -double __powidf2(double a, si_int b); +COMPILER_RT_ABI double __powidf2(double a, si_int b); int test__powidf2(double a, si_int b, double expected) { diff --git a/test/builtins/Unit/powisf2_test.c b/test/builtins/Unit/powisf2_test.c index 98409f432e66..1186ef4af5b0 100644 --- a/test/builtins/Unit/powisf2_test.c +++ b/test/builtins/Unit/powisf2_test.c @@ -17,7 +17,7 @@ // Returns: a ^ b -float __powisf2(float a, si_int b); +COMPILER_RT_ABI float __powisf2(float a, si_int b); int test__powisf2(float a, si_int b, float expected) { diff --git a/test/builtins/Unit/powitf2_test.c b/test/builtins/Unit/powitf2_test.c index 817cb1130dee..13c890a0dcaf 100644 --- a/test/builtins/Unit/powitf2_test.c +++ b/test/builtins/Unit/powitf2_test.c @@ -11,15 +11,16 @@ // //===----------------------------------------------------------------------===// +#include <stdio.h> + #if _ARCH_PPC #include "int_lib.h" -#include <stdio.h> #include <math.h> // Returns: a ^ b -long double __powitf2(long double a, si_int b); +COMPILER_RT_ABI long double __powitf2(long double a, si_int b); int test__powitf2(long double a, si_int b, long double expected) { diff --git a/test/builtins/Unit/powixf2_test.c b/test/builtins/Unit/powixf2_test.c index 201870b37f15..a28f1f9696f7 100644 --- a/test/builtins/Unit/powixf2_test.c +++ b/test/builtins/Unit/powixf2_test.c @@ -19,7 +19,7 @@ // Returns: a ^ b -long double __powixf2(long double a, si_int b); +COMPILER_RT_ABI long double __powixf2(long double a, si_int b); int test__powixf2(long double a, si_int b, long double expected) { diff --git a/test/builtins/Unit/ppc/floatditf_test.c b/test/builtins/Unit/ppc/floatditf_test.c index 578260aeddc4..71ecf7c4b5dd 100644 --- a/test/builtins/Unit/ppc/floatditf_test.c +++ b/test/builtins/Unit/ppc/floatditf_test.c @@ -1,7 +1,7 @@ #include <stdint.h> #include <stdio.h> -long double __floatditf(int64_t); +COMPILER_RT_ABI long double __floatditf(int64_t); #include "floatunditf_test.h" #include "DD.h" diff --git a/test/builtins/Unit/ppc/floatunditf_test.c b/test/builtins/Unit/ppc/floatunditf_test.c index 68390d197229..4d1ce088476b 100644 --- a/test/builtins/Unit/ppc/floatunditf_test.c +++ b/test/builtins/Unit/ppc/floatunditf_test.c @@ -1,7 +1,7 @@ #include <stdint.h> #include <stdio.h> -long double __floatunditf(uint64_t); +COMPILER_RT_ABI long double __floatunditf(uint64_t); #include "floatunditf_test.h" #include "DD.h" diff --git a/test/builtins/Unit/subdf3vfp_test.c b/test/builtins/Unit/subdf3vfp_test.c index 86d6f2fef22b..5d5d7117088f 100644 --- a/test/builtins/Unit/subdf3vfp_test.c +++ b/test/builtins/Unit/subdf3vfp_test.c @@ -17,7 +17,7 @@ #if __arm__ -extern double __subdf3vfp(double a, double b); +extern COMPILER_RT_ABI double __subdf3vfp(double a, double b); int test__subdf3vfp(double a, double b) { diff --git a/test/builtins/Unit/subsf3vfp_test.c b/test/builtins/Unit/subsf3vfp_test.c index 223e7f8f3936..fe60058de6f7 100644 --- a/test/builtins/Unit/subsf3vfp_test.c +++ b/test/builtins/Unit/subsf3vfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern float __subsf3vfp(float a, float b); +extern COMPILER_RT_ABI float __subsf3vfp(float a, float b); #if __arm__ int test__subsf3vfp(float a, float b) diff --git a/test/builtins/Unit/subtf3_test.c b/test/builtins/Unit/subtf3_test.c index 2ab249a994c3..ad115a40ca39 100644 --- a/test/builtins/Unit/subtf3_test.c +++ b/test/builtins/Unit/subtf3_test.c @@ -18,7 +18,7 @@ #include "fp_test.h" // Returns: a - b -long double __subtf3(long double a, long double b); +COMPILER_RT_ABI long double __subtf3(long double a, long double b); int test__subtf3(long double a, long double b, uint64_t expectedHi, uint64_t expectedLo) diff --git a/test/builtins/Unit/subvdi3_test.c b/test/builtins/Unit/subvdi3_test.c index 0fb8f5156896..96e825cafb1f 100644 --- a/test/builtins/Unit/subvdi3_test.c +++ b/test/builtins/Unit/subvdi3_test.c @@ -19,7 +19,7 @@ // Effects: aborts if a - b overflows -di_int __subvdi3(di_int a, di_int b); +COMPILER_RT_ABI di_int __subvdi3(di_int a, di_int b); int test__subvdi3(di_int a, di_int b) { diff --git a/test/builtins/Unit/subvsi3_test.c b/test/builtins/Unit/subvsi3_test.c index 14e6ce193904..03ef5045d257 100644 --- a/test/builtins/Unit/subvsi3_test.c +++ b/test/builtins/Unit/subvsi3_test.c @@ -19,7 +19,7 @@ // Effects: aborts if a - b overflows -si_int __subvsi3(si_int a, si_int b); +COMPILER_RT_ABI si_int __subvsi3(si_int a, si_int b); int test__subvsi3(si_int a, si_int b) { diff --git a/test/builtins/Unit/subvti3_test.c b/test/builtins/Unit/subvti3_test.c index b2c225c3a7f4..40eb5186917a 100644 --- a/test/builtins/Unit/subvti3_test.c +++ b/test/builtins/Unit/subvti3_test.c @@ -21,7 +21,7 @@ // Effects: aborts if a - b overflows -ti_int __subvti3(ti_int a, ti_int b); +COMPILER_RT_ABI ti_int __subvti3(ti_int a, ti_int b); int test__subvti3(ti_int a, ti_int b) { diff --git a/test/builtins/Unit/truncdfhf2_test.c b/test/builtins/Unit/truncdfhf2_test.c new file mode 100644 index 000000000000..6627a001eab8 --- /dev/null +++ b/test/builtins/Unit/truncdfhf2_test.c @@ -0,0 +1,114 @@ +//===--------------- truncdfhf2_test.c - Test __truncdfhf2 ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __truncdfhf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +#include "fp_test.h" + +uint16_t __truncdfhf2(double a); + +int test__truncdfhf2(double a, uint16_t expected) +{ + uint16_t x = __truncdfhf2(a); + int ret = compareResultH(x, expected); + + if (ret){ + printf("error in test__truncdfhf2(%f) = %#.4x, " + "expected %#.4x\n", a, x, fromRep16(expected)); + } + return ret; +} + +char assumption_1[sizeof(__fp16) * CHAR_BIT == 16] = {0}; + +int main() +{ + // qNaN + if (test__truncdfhf2(makeQNaN64(), + UINT16_C(0x7e00))) + return 1; + // NaN + if (test__truncdfhf2(makeNaN64(UINT64_C(0x8000)), + UINT16_C(0x7e00))) + return 1; + // inf + if (test__truncdfhf2(makeInf64(), + UINT16_C(0x7c00))) + return 1; + if (test__truncdfhf2(-makeInf64(), + UINT16_C(0xfc00))) + return 1; + // zero + if (test__truncdfhf2(0.0, UINT16_C(0x0))) + return 1; + if (test__truncdfhf2(-0.0, UINT16_C(0x8000))) + return 1; + + if (test__truncdfhf2(3.1415926535, + UINT16_C(0x4248))) + return 1; + if (test__truncdfhf2(-3.1415926535, + UINT16_C(0xc248))) + return 1; + if (test__truncdfhf2(0x1.987124876876324p+1000, + UINT16_C(0x7c00))) + return 1; + if (test__truncdfhf2(0x1.987124876876324p+12, + UINT16_C(0x6e62))) + return 1; + if (test__truncdfhf2(0x1.0p+0, + UINT16_C(0x3c00))) + return 1; + if (test__truncdfhf2(0x1.0p-14, + UINT16_C(0x0400))) + return 1; + // denormal + if (test__truncdfhf2(0x1.0p-20, + UINT16_C(0x0010))) + return 1; + if (test__truncdfhf2(0x1.0p-24, + UINT16_C(0x0001))) + return 1; + if (test__truncdfhf2(-0x1.0p-24, + UINT16_C(0x8001))) + return 1; + if (test__truncdfhf2(0x1.5p-25, + UINT16_C(0x0001))) + return 1; + // and back to zero + if (test__truncdfhf2(0x1.0p-25, + UINT16_C(0x0000))) + return 1; + if (test__truncdfhf2(-0x1.0p-25, + UINT16_C(0x8000))) + return 1; + // max (precise) + if (test__truncdfhf2(65504.0, + UINT16_C(0x7bff))) + return 1; + // max (rounded) + if (test__truncdfhf2(65519.0, + UINT16_C(0x7bff))) + return 1; + // max (to +inf) + if (test__truncdfhf2(65520.0, + UINT16_C(0x7c00))) + return 1; + if (test__truncdfhf2(-65520.0, + UINT16_C(0xfc00))) + return 1; + if (test__truncdfhf2(65536.0, + UINT16_C(0x7c00))) + return 1; + return 0; +} diff --git a/test/builtins/Unit/truncdfsf2_test.c b/test/builtins/Unit/truncdfsf2_test.c new file mode 100644 index 000000000000..a208a3a56bed --- /dev/null +++ b/test/builtins/Unit/truncdfsf2_test.c @@ -0,0 +1,38 @@ +//===--------------- truncdfsf2_test.c - Test __truncdfsf2 ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __truncdfsf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +#include "fp_test.h" + +float __truncdfsf2(double a); + +int test__truncdfsf2(double a) +{ + float actual = __truncdfsf2(a); + float expected = a; + + if (actual != expected) { + printf("error in test__truncdfsf2(%lf) = %f, " + "expected %f\n", a, actual, expected); + return 1; + } + return 0; +} + +int main() +{ + if (test__truncdfsf2(340282366920938463463374607431768211456.0)) + return 1; + return 0; +} diff --git a/test/builtins/Unit/truncdfsf2vfp_test.c b/test/builtins/Unit/truncdfsf2vfp_test.c index afc7868b0de0..eaeda658259e 100644 --- a/test/builtins/Unit/truncdfsf2vfp_test.c +++ b/test/builtins/Unit/truncdfsf2vfp_test.c @@ -11,12 +11,13 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #include <stdlib.h> #include <math.h> -extern float __truncdfsf2vfp(double a); +extern COMPILER_RT_ABI float __truncdfsf2vfp(double a); #if __arm__ int test__truncdfsf2vfp(double a) diff --git a/test/builtins/Unit/truncsfhf2_test.c b/test/builtins/Unit/truncsfhf2_test.c new file mode 100644 index 000000000000..5bc3c8e22d59 --- /dev/null +++ b/test/builtins/Unit/truncsfhf2_test.c @@ -0,0 +1,114 @@ +//===--------------- truncsfhf2_test.c - Test __truncsfhf2 ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file tests __truncsfhf2 for the compiler_rt library. +// +//===----------------------------------------------------------------------===// + +#include <stdio.h> + +#include "fp_test.h" + +uint16_t __truncsfhf2(float a); + +int test__truncsfhf2(float a, uint16_t expected) +{ + uint16_t x = __truncsfhf2(a); + int ret = compareResultH(x, expected); + + if (ret){ + printf("error in test__truncsfhf2(%f) = %#.4x, " + "expected %#.4x\n", a, x, fromRep16(expected)); + } + return ret; +} + +char assumption_1[sizeof(__fp16) * CHAR_BIT == 16] = {0}; + +int main() +{ + // qNaN + if (test__truncsfhf2(makeQNaN32(), + UINT16_C(0x7e00))) + return 1; + // NaN + if (test__truncsfhf2(makeNaN32(UINT32_C(0x8000)), + UINT16_C(0x7e00))) + return 1; + // inf + if (test__truncsfhf2(makeInf32(), + UINT16_C(0x7c00))) + return 1; + if (test__truncsfhf2(-makeInf32(), + UINT16_C(0xfc00))) + return 1; + // zero + if (test__truncsfhf2(0.0f, UINT16_C(0x0))) + return 1; + if (test__truncsfhf2(-0.0f, UINT16_C(0x8000))) + return 1; + + if (test__truncsfhf2(3.1415926535f, + UINT16_C(0x4248))) + return 1; + if (test__truncsfhf2(-3.1415926535f, + UINT16_C(0xc248))) + return 1; + if (test__truncsfhf2(0x1.987124876876324p+100f, + UINT16_C(0x7c00))) + return 1; + if (test__truncsfhf2(0x1.987124876876324p+12f, + UINT16_C(0x6e62))) + return 1; + if (test__truncsfhf2(0x1.0p+0f, + UINT16_C(0x3c00))) + return 1; + if (test__truncsfhf2(0x1.0p-14f, + UINT16_C(0x0400))) + return 1; + // denormal + if (test__truncsfhf2(0x1.0p-20f, + UINT16_C(0x0010))) + return 1; + if (test__truncsfhf2(0x1.0p-24f, + UINT16_C(0x0001))) + return 1; + if (test__truncsfhf2(-0x1.0p-24f, + UINT16_C(0x8001))) + return 1; + if (test__truncsfhf2(0x1.5p-25f, + UINT16_C(0x0001))) + return 1; + // and back to zero + if (test__truncsfhf2(0x1.0p-25f, + UINT16_C(0x0000))) + return 1; + if (test__truncsfhf2(-0x1.0p-25f, + UINT16_C(0x8000))) + return 1; + // max (precise) + if (test__truncsfhf2(65504.0f, + UINT16_C(0x7bff))) + return 1; + // max (rounded) + if (test__truncsfhf2(65519.0f, + UINT16_C(0x7bff))) + return 1; + // max (to +inf) + if (test__truncsfhf2(65520.0f, + UINT16_C(0x7c00))) + return 1; + if (test__truncsfhf2(65536.0f, + UINT16_C(0x7c00))) + return 1; + if (test__truncsfhf2(-65520.0f, + UINT16_C(0xfc00))) + return 1; + return 0; +} diff --git a/test/builtins/Unit/trunctfdf2_test.c b/test/builtins/Unit/trunctfdf2_test.c index 46855e31bb5e..0366a8ce99f2 100644 --- a/test/builtins/Unit/trunctfdf2_test.c +++ b/test/builtins/Unit/trunctfdf2_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 #include "fp_test.h" -double __trunctfdf2(long double a); +COMPILER_RT_ABI double __trunctfdf2(long double a); int test__trunctfdf2(long double a, uint64_t expected) { diff --git a/test/builtins/Unit/trunctfsf2_test.c b/test/builtins/Unit/trunctfsf2_test.c index 44e7fd1827fe..a6b922ce122d 100644 --- a/test/builtins/Unit/trunctfsf2_test.c +++ b/test/builtins/Unit/trunctfsf2_test.c @@ -11,13 +11,14 @@ // //===----------------------------------------------------------------------===// +#include "int_lib.h" #include <stdio.h> #if __LDBL_MANT_DIG__ == 113 #include "fp_test.h" -float __trunctfsf2(long double a); +COMPILER_RT_ABI float __trunctfsf2(long double a); int test__trunctfsf2(long double a, uint32_t expected) { diff --git a/test/builtins/Unit/ucmpdi2_test.c b/test/builtins/Unit/ucmpdi2_test.c index 22059077c795..65ae4fce0e79 100644 --- a/test/builtins/Unit/ucmpdi2_test.c +++ b/test/builtins/Unit/ucmpdi2_test.c @@ -18,7 +18,7 @@ // if (a == b) returns 1 // if (a > b) returns 2 -si_int __ucmpdi2(du_int a, du_int b); +COMPILER_RT_ABI si_int __ucmpdi2(du_int a, du_int b); int test__ucmpdi2(du_int a, du_int b, si_int expected) { diff --git a/test/builtins/Unit/ucmpti2_test.c b/test/builtins/Unit/ucmpti2_test.c index 0713da8971af..826cd6439dd3 100644 --- a/test/builtins/Unit/ucmpti2_test.c +++ b/test/builtins/Unit/ucmpti2_test.c @@ -20,7 +20,7 @@ // if (a == b) returns 1 // if (a > b) returns 2 -si_int __ucmpti2(tu_int a, tu_int b); +COMPILER_RT_ABI si_int __ucmpti2(tu_int a, tu_int b); int test__ucmpti2(tu_int a, tu_int b, si_int expected) { diff --git a/test/builtins/Unit/udivdi3_test.c b/test/builtins/Unit/udivdi3_test.c index 24843f8bde6a..48c99e30973a 100644 --- a/test/builtins/Unit/udivdi3_test.c +++ b/test/builtins/Unit/udivdi3_test.c @@ -16,7 +16,7 @@ // Returns: a / b -du_int __udivdi3(du_int a, du_int b); +COMPILER_RT_ABI du_int __udivdi3(du_int a, du_int b); int test__udivdi3(du_int a, du_int b, du_int expected_q) { diff --git a/test/builtins/Unit/udivmoddi4_test.c b/test/builtins/Unit/udivmoddi4_test.c index 43bf1a11f348..79af1eeff613 100644 --- a/test/builtins/Unit/udivmoddi4_test.c +++ b/test/builtins/Unit/udivmoddi4_test.c @@ -17,7 +17,7 @@ // Effects: if rem != 0, *rem = a % b // Returns: a / b -du_int __udivmoddi4(du_int a, du_int b, du_int* rem); +COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int* rem); int test__udivmoddi4(du_int a, du_int b, du_int expected_q, du_int expected_r) { diff --git a/test/builtins/Unit/udivmodsi4_test.c b/test/builtins/Unit/udivmodsi4_test.c index d734cd1fdf71..4c14e297d567 100644 --- a/test/builtins/Unit/udivmodsi4_test.c +++ b/test/builtins/Unit/udivmodsi4_test.c @@ -16,7 +16,7 @@ // Returns: a / b -extern su_int __udivmodsi4(su_int a, su_int b, su_int* rem); +extern COMPILER_RT_ABI su_int __udivmodsi4(su_int a, su_int b, su_int* rem); int test__udivmodsi4(su_int a, su_int b, su_int expected_result, su_int expected_rem) diff --git a/test/builtins/Unit/udivmodti4_test.c b/test/builtins/Unit/udivmodti4_test.c index 751aa868325f..c4246613d2e6 100644 --- a/test/builtins/Unit/udivmodti4_test.c +++ b/test/builtins/Unit/udivmodti4_test.c @@ -19,7 +19,7 @@ // Effects: if rem != 0, *rem = a % b // Returns: a / b -tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); +COMPILER_RT_ABI tu_int __udivmodti4(tu_int a, tu_int b, tu_int* rem); int test__udivmodti4(tu_int a, tu_int b, tu_int expected_q, tu_int expected_r) { diff --git a/test/builtins/Unit/udivsi3_test.c b/test/builtins/Unit/udivsi3_test.c index 325e4e6e8859..49053865bf49 100644 --- a/test/builtins/Unit/udivsi3_test.c +++ b/test/builtins/Unit/udivsi3_test.c @@ -16,7 +16,7 @@ // Returns: a / b -su_int __udivsi3(su_int a, su_int b); +COMPILER_RT_ABI su_int __udivsi3(su_int a, su_int b); int test__udivsi3(su_int a, su_int b, su_int expected_q) { diff --git a/test/builtins/Unit/udivti3_test.c b/test/builtins/Unit/udivti3_test.c index af5aad9a391d..f24ff03b2424 100644 --- a/test/builtins/Unit/udivti3_test.c +++ b/test/builtins/Unit/udivti3_test.c @@ -18,7 +18,7 @@ // Returns: a / b -tu_int __udivti3(tu_int a, tu_int b); +COMPILER_RT_ABI tu_int __udivti3(tu_int a, tu_int b); int test__udivti3(tu_int a, tu_int b, tu_int expected_q) { diff --git a/test/builtins/Unit/umoddi3_test.c b/test/builtins/Unit/umoddi3_test.c index a8f39b41550d..b46fb4022817 100644 --- a/test/builtins/Unit/umoddi3_test.c +++ b/test/builtins/Unit/umoddi3_test.c @@ -16,7 +16,7 @@ // Returns: a % b -du_int __umoddi3(du_int a, du_int b); +COMPILER_RT_ABI du_int __umoddi3(du_int a, du_int b); int test__umoddi3(du_int a, du_int b, du_int expected_r) { diff --git a/test/builtins/Unit/umodsi3_test.c b/test/builtins/Unit/umodsi3_test.c index 66da695ffd96..3655da1395f7 100644 --- a/test/builtins/Unit/umodsi3_test.c +++ b/test/builtins/Unit/umodsi3_test.c @@ -16,7 +16,7 @@ // Returns: a % b -su_int __umodsi3(su_int a, su_int b); +COMPILER_RT_ABI su_int __umodsi3(su_int a, su_int b); int test__umodsi3(su_int a, su_int b, su_int expected_r) { diff --git a/test/builtins/Unit/umodti3_test.c b/test/builtins/Unit/umodti3_test.c index 93b556ccaa21..21e82a4a21e0 100644 --- a/test/builtins/Unit/umodti3_test.c +++ b/test/builtins/Unit/umodti3_test.c @@ -18,7 +18,7 @@ // Returns: a % b -tu_int __umodti3(tu_int a, tu_int b); +COMPILER_RT_ABI tu_int __umodti3(tu_int a, tu_int b); int test__umodti3(tu_int a, tu_int b, tu_int expected_r) { diff --git a/test/cfi/CMakeLists.txt b/test/cfi/CMakeLists.txt index f519fb089505..21463ac408de 100644 --- a/test/cfi/CMakeLists.txt +++ b/test/cfi/CMakeLists.txt @@ -9,15 +9,32 @@ if(NOT COMPILER_RT_STANDALONE_BUILD) FileCheck clang not + ubsan ) if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR) list(APPEND CFI_TEST_DEPS LLVMgold ) endif() + if(APPLE) + list(APPEND CFI_TEST_DEPS + LTO + ) + endif() + if(WIN32 AND EXISTS ${CMAKE_SOURCE_DIR}/tools/lld) + list(APPEND CFI_TEST_DEPS + lld + ) + endif() endif() add_lit_testsuite(check-cfi "Running the cfi regression tests" ${CMAKE_CURRENT_BINARY_DIR} DEPENDS ${CFI_TEST_DEPS}) + +add_lit_target(check-cfi-and-supported "Running the cfi regression tests" + ${CMAKE_CURRENT_BINARY_DIR} + PARAMS check_supported=1 + DEPENDS ${CFI_TEST_DEPS}) + set_target_properties(check-cfi PROPERTIES FOLDER "Tests") diff --git a/test/cfi/README.txt b/test/cfi/README.txt new file mode 100644 index 000000000000..6b82f5edc235 --- /dev/null +++ b/test/cfi/README.txt @@ -0,0 +1,8 @@ +The tests in this directory use a common convention for exercising the +functionality associated with bit sets of different sizes. When certain +macros are defined the tests instantiate classes that force the bit sets +to be of certain sizes. + +- B32 forces 32-bit bit sets. +- B64 forces 64-bit bit sets. +- BM forces memory bit sets. diff --git a/test/cfi/anon-namespace.cpp b/test/cfi/anon-namespace.cpp index 0c2c689966f1..f25f3405516e 100644 --- a/test/cfi/anon-namespace.cpp +++ b/test/cfi/anon-namespace.cpp @@ -1,27 +1,32 @@ // RUN: %clangxx_cfi -c -DTU1 -o %t1.o %s // RUN: %clangxx_cfi -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp -// RUN: %clangxx_cfi -o %t %t1.o %t2.o -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t1 %t1.o %t2.o +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s // RUN: %clangxx_cfi -c -DTU1 -DB32 -o %t1.o %s // RUN: %clangxx_cfi -c -DTU2 -DB32 -o %t2.o %S/../cfi/anon-namespace.cpp -// RUN: %clangxx_cfi -o %t %t1.o %t2.o -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t2 %t1.o %t2.o +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s // RUN: %clangxx_cfi -c -DTU1 -DB64 -o %t1.o %s // RUN: %clangxx_cfi -c -DTU2 -DB64 -o %t2.o %S/../cfi/anon-namespace.cpp -// RUN: %clangxx_cfi -o %t %t1.o %t2.o -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t3 %t1.o %t2.o +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s // RUN: %clangxx_cfi -c -DTU1 -DBM -o %t1.o %s // RUN: %clangxx_cfi -c -DTU2 -DBM -o %t2.o %S/../cfi/anon-namespace.cpp -// RUN: %clangxx_cfi -o %t %t1.o %t2.o -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t4 %t1.o %t2.o +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s // RUN: %clangxx -c -DTU1 -o %t1.o %s // RUN: %clangxx -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp -// RUN: %clangxx -o %t %t1.o %t2.o -// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s +// RUN: %clangxx -o %t5 %t1.o %t2.o +// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s + +// RUN: %clangxx_cfi_diag -c -DTU1 -o %t1.o %s +// RUN: %clangxx_cfi_diag -c -DTU2 -o %t2.o %S/../cfi/anon-namespace.cpp +// RUN: %clangxx_cfi_diag -o %t6 %t1.o %t2.o +// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s // Tests that the CFI mechanism treats classes in the anonymous namespace in // different translation units as having distinct identities. This is done by @@ -33,6 +38,8 @@ // are different. It currently does so because bitset names have global scope // so we have to mangle the file path into the bitset name. +// REQUIRES: cxxabi + #include <stdio.h> #include "utils.h" @@ -83,10 +90,14 @@ int main() { // NCFI: 1 fprintf(stderr, "1\n"); + // CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during base-to-derived cast + // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B' + // CFI-DIAG: runtime error: control flow integrity check for type '(anonymous namespace)::B' failed during virtual call + // CFI-DIAG-NEXT: note: vtable is of type '{{.*}}anonymous namespace{{.*}}::B' ((B *)a)->f(); // UB here - // CFI-NOT: 2 - // NCFI: 2 + // CFI-NOT: {{^2$}} + // NCFI: {{^2$}} fprintf(stderr, "2\n"); } diff --git a/test/cfi/bad-cast.cpp b/test/cfi/bad-cast.cpp new file mode 100644 index 000000000000..9ba6f6dbacec --- /dev/null +++ b/test/cfi/bad-cast.cpp @@ -0,0 +1,150 @@ +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 a 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t1 b 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t1 c 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t1 d 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t1 e 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t1 f 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %expect_crash %t1 g 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t1 h 2>&1 | FileCheck --check-prefix=PASS %s + +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 a 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t2 b 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t2 c 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t2 d 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t2 e 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t2 f 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %expect_crash %t2 g 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t2 h 2>&1 | FileCheck --check-prefix=PASS %s + +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 a 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t3 b 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t3 c 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t3 d 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t3 e 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t3 f 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %expect_crash %t3 g 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t3 h 2>&1 | FileCheck --check-prefix=PASS %s + +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 a 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t4 b 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t4 c 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t4 d 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t4 e 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t4 f 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %expect_crash %t4 g 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %t4 h 2>&1 | FileCheck --check-prefix=PASS %s + +// RUN: %clangxx_cfi -fsanitize=cfi-cast-strict -o %t5 %s +// RUN: %expect_crash %t5 a 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t5 b 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t5 c 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t5 d 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t5 e 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t5 f 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t5 g 2>&1 | FileCheck --check-prefix=FAIL %s +// RUN: %expect_crash %t5 h 2>&1 | FileCheck --check-prefix=FAIL %s + +// RUN: %clangxx -o %t6 %s +// RUN: %t6 a 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t6 b 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t6 c 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t6 d 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t6 e 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t6 f 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t6 g 2>&1 | FileCheck --check-prefix=PASS %s +// RUN: %t6 h 2>&1 | FileCheck --check-prefix=PASS %s + +// RUN: %clangxx_cfi_diag -o %t7 %s +// RUN: %t7 a 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s +// RUN: %t7 b 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s +// RUN: %t7 c 2>&1 | FileCheck --check-prefix=CFI-DIAG-D %s +// RUN: %t7 g 2>&1 | FileCheck --check-prefix=CFI-DIAG-U %s + +// Tests that the CFI enforcement detects bad casts. + +// REQUIRES: cxxabi + +#include <stdio.h> +#include "utils.h" + +struct A { + virtual void f(); +}; + +void A::f() {} + +struct B : A { + virtual void f(); +}; + +void B::f() {} + +struct C : A { +}; + +int main(int argc, char **argv) { +#ifdef B32 + break_optimization(new Deriver<B, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); + break_optimization(new Deriver<B, 2>); +#endif + + B *b = new B; + break_optimization(b); + + // FAIL: 1 + // PASS: 1 + fprintf(stderr, "1\n"); + + A a; + + // CFI-DIAG-D: runtime error: control flow integrity check for type 'B' failed during base-to-derived cast + // CFI-DIAG-D-NEXT: note: vtable is of type '{{(struct )?}}A' + + // CFI-DIAG-U: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type + // CFI-DIAG-U-NEXT: note: vtable is of type '{{(struct )?}}A' + + switch (argv[1][0]) { + case 'a': + static_cast<B *>(&a); // UB + break; + case 'b': + static_cast<B &>(a); // UB + break; + case 'c': + static_cast<B &&>(a); // UB + break; + case 'd': + static_cast<C *>(&a); // UB, strict only + break; + case 'e': + static_cast<C &>(a); // UB, strict only + break; + case 'f': + static_cast<C &&>(a); // UB, strict only + break; + case 'g': + static_cast<B *>(static_cast<void *>(&a)); // Non-UB bad cast + break; + case 'h': + static_cast<C *>(static_cast<void *>(&a)); // Non-UB bad cast, strict only + break; + } + + // FAIL-NOT: {{^2$}} + // PASS: {{^2$}} + fprintf(stderr, "2\n"); +} diff --git a/test/cfi/lit.cfg b/test/cfi/lit.cfg index d78820daa055..1fa5a1e25137 100644 --- a/test/cfi/lit.cfg +++ b/test/cfi/lit.cfg @@ -1,35 +1,19 @@ import lit.formats import os -import subprocess -import sys config.name = 'cfi' config.suffixes = ['.cpp'] config.test_source_root = os.path.dirname(__file__) -def is_darwin_lto_supported(): - return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib')) - -def is_linux_lto_supported(): - if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')): - return False - - ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE) - ld_out = ld_cmd.stdout.read().decode() - ld_cmd.wait() - - if not '-plugin' in ld_out: - return False - - return True - clangxx = ' '.join([config.clang] + config.cxx_mode_flags) config.substitutions.append((r"%clangxx ", clangxx + ' ')) - -if sys.platform == 'darwin' and is_darwin_lto_supported(): - config.substitutions.append((r"%clangxx_cfi ", 'env DYLD_LIBRARY_PATH=' + config.llvm_shlib_dir + ' ' + clangxx + ' -fsanitize=cfi ')) -elif sys.platform.startswith('linux') and is_linux_lto_supported(): - config.substitutions.append((r"%clangxx_cfi ", clangxx + ' -fuse-ld=gold -fsanitize=cfi ')) +if config.lto_supported: + clangxx_cfi = ' '.join(config.lto_launch + [clangxx] + config.lto_flags + ['-flto -fsanitize=cfi ']) + config.substitutions.append((r"%clangxx_cfi ", clangxx_cfi)) + config.substitutions.append((r"%clangxx_cfi_diag ", clangxx_cfi + '-fno-sanitize-trap=cfi -fsanitize-recover=cfi ')) else: config.unsupported = True + +if lit_config.params.get('check_supported', None) and config.unsupported: + raise BaseException("Tests unsupported") diff --git a/test/cfi/multiple-inheritance.cpp b/test/cfi/multiple-inheritance.cpp index 523af6f72f2f..e2a9abebb955 100644 --- a/test/cfi/multiple-inheritance.cpp +++ b/test/cfi/multiple-inheritance.cpp @@ -1,26 +1,32 @@ -// RUN: %clangxx_cfi -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %expect_crash %t1 x 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB32 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %expect_crash %t2 x 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB64 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %expect_crash %t3 x 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DBM -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: not --crash %t x 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %expect_crash %t4 x 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx -o %t %s -// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s -// RUN: %t x 2>&1 | FileCheck --check-prefix=NCFI %s +// RUN: %clangxx -o %t5 %s +// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s +// RUN: %t5 x 2>&1 | FileCheck --check-prefix=NCFI %s + +// RUN: %clangxx_cfi_diag -o %t6 %s +// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG2 %s +// RUN: %t6 x 2>&1 | FileCheck --check-prefix=CFI-DIAG1 %s // Tests that the CFI mechanism is sensitive to multiple inheritance and only // permits calls via virtual tables for the correct base class. +// REQUIRES: cxxabi + #include <stdio.h> #include "utils.h" @@ -70,13 +76,17 @@ int main(int argc, char **argv) { if (argc > 1) { A *a = c; + // CFI-DIAG1: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type + // CFI-DIAG1-NEXT: note: vtable is of type '{{(struct )?}}C' ((B *)a)->g(); // UB here } else { + // CFI-DIAG2: runtime error: control flow integrity check for type 'A' failed during cast to unrelated type + // CFI-DIAG2-NEXT: note: vtable is of type '{{(struct )?}}C' B *b = c; ((A *)b)->f(); // UB here } - // CFI-NOT: 2 - // NCFI: 2 + // CFI-NOT: {{^2$}} + // NCFI: {{^2$}} fprintf(stderr, "2\n"); } diff --git a/test/cfi/nvcall.cpp b/test/cfi/nvcall.cpp new file mode 100644 index 000000000000..04419bd9d855 --- /dev/null +++ b/test/cfi/nvcall.cpp @@ -0,0 +1,72 @@ +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx -o %t5 %s +// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s + +// RUN: %clangxx_cfi_diag -o %t6 %s +// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s + +// Tests that the CFI mechanism crashes the program when making a non-virtual +// call to an object of the wrong class, by casting a pointer to such an object +// and attempting to make a call through it. + +// REQUIRES: cxxabi + +#include <stdio.h> +#include "utils.h" + +struct A { + virtual void v(); +}; + +void A::v() {} + +struct B { + void f(); + virtual void g(); +}; + +void B::f() {} +void B::g() {} + +int main() { +#ifdef B32 + break_optimization(new Deriver<B, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); + break_optimization(new Deriver<B, 2>); +#endif + + A *a = new A; + break_optimization(a); + + // CFI: 1 + // NCFI: 1 + fprintf(stderr, "1\n"); + + // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during non-virtual call + // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' + ((B *)a)->f(); // UB here + + // CFI-NOT: {{^2$}} + // NCFI: {{^2$}} + fprintf(stderr, "2\n"); +} diff --git a/test/cfi/overwrite.cpp b/test/cfi/overwrite.cpp index d7e58d9277e9..a24e628326f3 100644 --- a/test/cfi/overwrite.cpp +++ b/test/cfi/overwrite.cpp @@ -1,23 +1,28 @@ -// RUN: %clangxx_cfi -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB32 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB64 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DBM -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx -o %t %s -// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s +// RUN: %clangxx -o %t5 %s +// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s + +// RUN: %clangxx_cfi_diag -o %t6 %s +// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s // Tests that the CFI mechanism crashes the program when a virtual table is // replaced with a compatible table of function pointers that does not belong to // any class, by manually overwriting the virtual table of an object and // attempting to make a call through it. +// REQUIRES: cxxabi + #include <stdio.h> #include "utils.h" @@ -31,7 +36,7 @@ void foo() { fprintf(stderr, "foo\n"); } -void *fake_vtable[] = { (void *)&foo }; +void *fake_vtable[] = { 0, 0, (void *)&foo }; int main() { #ifdef B32 @@ -50,7 +55,7 @@ int main() { #endif A *a = new A; - *((void **)a) = fake_vtable; // UB here + *((void **)a) = fake_vtable + 2; // UB here break_optimization(a); // CFI: 1 @@ -59,9 +64,11 @@ int main() { // CFI-NOT: foo // NCFI: foo + // CFI-DIAG: runtime error: control flow integrity check for type 'A' failed during virtual call + // CFI-DIAG-NEXT: note: invalid vtable a->f(); - // CFI-NOT: 2 - // NCFI: 2 + // CFI-NOT: {{^2$}} + // NCFI: {{^2$}} fprintf(stderr, "2\n"); } diff --git a/test/cfi/sibling.cpp b/test/cfi/sibling.cpp new file mode 100644 index 000000000000..a865cbc0cf6b --- /dev/null +++ b/test/cfi/sibling.cpp @@ -0,0 +1,67 @@ +// XFAIL: * + +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s + +// RUN: %clangxx -o %t5 %s +// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s + +// Tests that the CFI enforcement distinguishes betwen non-overriding siblings. +// XFAILed as not implemented yet. + +#include <stdio.h> +#include "utils.h" + +struct A { + virtual void f(); +}; + +void A::f() {} + +struct B : A { + virtual void f(); +}; + +void B::f() {} + +struct C : A { +}; + +int main() { +#ifdef B32 + break_optimization(new Deriver<B, 0>); +#endif + +#ifdef B64 + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); +#endif + +#ifdef BM + break_optimization(new Deriver<B, 0>); + break_optimization(new Deriver<B, 1>); + break_optimization(new Deriver<B, 2>); +#endif + + B *b = new B; + break_optimization(b); + + // CFI: 1 + // NCFI: 1 + fprintf(stderr, "1\n"); + + ((C *)b)->f(); // UB here + + // CFI-NOT: 2 + // NCFI: 2 + fprintf(stderr, "2\n"); +} diff --git a/test/cfi/simple-fail.cpp b/test/cfi/simple-fail.cpp index cf24f86e0064..c7bebb0deccc 100644 --- a/test/cfi/simple-fail.cpp +++ b/test/cfi/simple-fail.cpp @@ -1,58 +1,63 @@ -// RUN: %clangxx_cfi -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB32 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB64 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DBM -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O1 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O1 -o %t5 %s +// RUN: %expect_crash %t5 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O1 -DB32 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O1 -DB32 -o %t6 %s +// RUN: %expect_crash %t6 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O1 -DB64 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O1 -DB64 -o %t7 %s +// RUN: %expect_crash %t7 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O1 -DBM -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O1 -DBM -o %t8 %s +// RUN: %expect_crash %t8 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O2 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O2 -o %t9 %s +// RUN: %expect_crash %t9 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O2 -DB32 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O2 -DB32 -o %t10 %s +// RUN: %expect_crash %t10 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O2 -DB64 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O2 -DB64 -o %t11 %s +// RUN: %expect_crash %t11 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O2 -DBM -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O2 -DBM -o %t12 %s +// RUN: %expect_crash %t12 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O3 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O3 -o %t13 %s +// RUN: %expect_crash %t13 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O3 -DB32 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O3 -DB32 -o %t14 %s +// RUN: %expect_crash %t14 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O3 -DB64 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O3 -DB64 -o %t15 %s +// RUN: %expect_crash %t15 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -O3 -DBM -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -O3 -DBM -o %t16 %s +// RUN: %expect_crash %t16 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx -o %t %s -// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s +// RUN: %clangxx_cfi_diag -o %t17 %s +// RUN: %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s + +// RUN: %clangxx -o %t18 %s +// RUN: %t18 2>&1 | FileCheck --check-prefix=NCFI %s // Tests that the CFI mechanism crashes the program when making a virtual call // to an object of the wrong class but with a compatible vtable, by casting a // pointer to such an object and attempting to make a call through it. +// REQUIRES: cxxabi + #include <stdio.h> #include "utils.h" @@ -91,9 +96,13 @@ int main() { // NCFI: 1 fprintf(stderr, "1\n"); + // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during cast to unrelated type + // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' + // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call + // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' ((B *)a)->f(); // UB here - // CFI-NOT: 2 - // NCFI: 2 + // CFI-NOT: {{^2$}} + // NCFI: {{^2$}} fprintf(stderr, "2\n"); } diff --git a/test/cfi/simple-pass.cpp b/test/cfi/simple-pass.cpp index 50e7d9256084..4d856eb48ce7 100644 --- a/test/cfi/simple-pass.cpp +++ b/test/cfi/simple-pass.cpp @@ -3,95 +3,119 @@ // Tests that the CFI mechanism does not crash the program when making various // kinds of valid calls involving classes with various different linkages and -// types of inheritance. +// types of inheritance, and both virtual and non-virtual member functions. #include "utils.h" struct A { virtual void f(); + void g(); }; void A::f() {} +void A::g() {} struct A2 : A { virtual void f(); + void g(); }; void A2::f() {} +void A2::g() {} struct B { virtual void f() {} + void g() {} }; struct B2 : B { virtual void f() {} + void g() {} }; namespace { struct C { virtual void f(); + void g(); }; void C::f() {} +void C::g() {} struct C2 : C { virtual void f(); + void g(); }; void C2::f() {} +void C2::g() {} struct D { virtual void f() {} + void g() {} }; struct D2 : D { virtual void f() {} + void g() {} }; } struct E { virtual void f() {} + void g() {} }; struct E2 : virtual E { virtual void f() {} + void g() {} }; int main() { A *a = new A; break_optimization(a); a->f(); + a->g(); a = new A2; break_optimization(a); a->f(); + a->g(); B *b = new B; break_optimization(b); b->f(); + b->g(); b = new B2; break_optimization(b); b->f(); + b->g(); C *c = new C; break_optimization(c); c->f(); + c->g(); c = new C2; break_optimization(c); c->f(); + c->g(); D *d = new D; break_optimization(d); d->f(); + d->g(); d = new D2; break_optimization(d); d->f(); + d->g(); E *e = new E; break_optimization(e); e->f(); + e->g(); e = new E2; break_optimization(e); e->f(); + e->g(); } diff --git a/test/cfi/vdtor.cpp b/test/cfi/vdtor.cpp index e21883c380dd..fb484ea73308 100644 --- a/test/cfi/vdtor.cpp +++ b/test/cfi/vdtor.cpp @@ -1,21 +1,26 @@ -// RUN: %clangxx_cfi -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -o %t1 %s +// RUN: %expect_crash %t1 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB32 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB32 -o %t2 %s +// RUN: %expect_crash %t2 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DB64 -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DB64 -o %t3 %s +// RUN: %expect_crash %t3 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx_cfi -DBM -o %t %s -// RUN: not --crash %t 2>&1 | FileCheck --check-prefix=CFI %s +// RUN: %clangxx_cfi -DBM -o %t4 %s +// RUN: %expect_crash %t4 2>&1 | FileCheck --check-prefix=CFI %s -// RUN: %clangxx -o %t %s -// RUN: %t 2>&1 | FileCheck --check-prefix=NCFI %s +// RUN: %clangxx -o %t5 %s +// RUN: %t5 2>&1 | FileCheck --check-prefix=NCFI %s + +// RUN: %clangxx_cfi_diag -o %t6 %s +// RUN: %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s // Tests that the CFI enforcement also applies to virtual destructor calls made // via 'delete'. +// REQUIRES: cxxabi + #include <stdio.h> #include "utils.h" @@ -54,9 +59,11 @@ int main() { // NCFI: 1 fprintf(stderr, "1\n"); + // CFI-DIAG: runtime error: control flow integrity check for type 'B' failed during virtual call + // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A' delete (B *)a; // UB here - // CFI-NOT: 2 - // NCFI: 2 + // CFI-NOT: {{^2$}} + // NCFI: {{^2$}} fprintf(stderr, "2\n"); } diff --git a/test/dfsan/basic.c b/test/dfsan/basic.c index 6582727e5e61..990fd1161069 100644 --- a/test/dfsan/basic.c +++ b/test/dfsan/basic.c @@ -1,5 +1,5 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %run %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %run %t +// RUN: %clang_dfsan %s -o %t && %run %t +// RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t && %run %t // Tests that labels are propagated through loads and stores. diff --git a/test/dfsan/custom.cc b/test/dfsan/custom.cc index d7bb3e3073fb..057b0608e038 100644 --- a/test/dfsan/custom.cc +++ b/test/dfsan/custom.cc @@ -1,7 +1,7 @@ -// RUN: %clang_dfsan -m64 %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t -// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -m64 %s -o %t && %run %t -// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi -m64 %s -o %t && %run %t +// RUN: %clang_dfsan %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t +// RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t && DFSAN_OPTIONS="strict_data_dependencies=0" %run %t +// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES %s -o %t && %run %t +// RUN: %clang_dfsan -DSTRICT_DATA_DEPENDENCIES -mllvm -dfsan-args-abi %s -o %t && %run %t // Tests custom implementations of various glibc functions. @@ -870,6 +870,11 @@ void test_sprintf() { test_sprintf_chunk("z", "%c", 'z'); // %n, %s, %d, %f, and %% already tested + + // Test formatting with width passed as an argument. + r = sprintf(buf, "hi %*d my %*s friend %.*f", 3, 1, 6, "dear", 4, 3.14159265359); + assert(r == 30); + assert(strcmp(buf, "hi 1 my dear friend 3.1416") == 0); } void test_snprintf() { diff --git a/test/dfsan/dump_labels.c b/test/dfsan/dump_labels.c index 67801af1838f..3bbc1e2c0b90 100644 --- a/test/dfsan/dump_labels.c +++ b/test/dfsan/dump_labels.c @@ -1,4 +1,4 @@ -// RUN: %clang_dfsan -m64 %s -o %t +// RUN: %clang_dfsan %s -o %t // RUN: DFSAN_OPTIONS=dump_labels_at_exit=/dev/stdout %run %t 2>&1 | FileCheck %s // RUN: DFSAN_OPTIONS=dump_labels_at_exit=/dev/stdout not %run %t c 2>&1 | FileCheck %s --check-prefix=CHECK-OOL // RUN: DFSAN_OPTIONS=dump_labels_at_exit=/dev/stdout not %run %t u 2>&1 | FileCheck %s --check-prefix=CHECK-OOL diff --git a/test/dfsan/flags.c b/test/dfsan/flags.c index 79069b96f83a..914f54f42b6c 100644 --- a/test/dfsan/flags.c +++ b/test/dfsan/flags.c @@ -1,6 +1,6 @@ -// RUN: %clang_dfsan -m64 %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && %run %t 2>&1 | FileCheck %s -// RUN: %clang_dfsan -m64 %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && DFSAN_OPTIONS=warn_unimplemented=0 %run %t 2>&1 | count 0 -// RUN: %clang_dfsan -m64 %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && DFSAN_OPTIONS=warn_nonzero_labels=1 %run %t 2>&1 | FileCheck --check-prefix=CHECK-NONZERO %s +// RUN: %clang_dfsan %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && %run %t 2>&1 | FileCheck %s +// RUN: %clang_dfsan %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && DFSAN_OPTIONS=warn_unimplemented=0 %run %t 2>&1 | count 0 +// RUN: %clang_dfsan %s -fsanitize-blacklist=%S/Inputs/flags_abilist.txt -mllvm -dfsan-debug-nonzero-labels -o %t && DFSAN_OPTIONS=warn_nonzero_labels=1 %run %t 2>&1 | FileCheck --check-prefix=CHECK-NONZERO %s // Tests that flags work correctly. diff --git a/test/dfsan/fncall.c b/test/dfsan/fncall.c index e780f3145e87..458fba66dbbe 100644 --- a/test/dfsan/fncall.c +++ b/test/dfsan/fncall.c @@ -1,5 +1,5 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %run %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %run %t +// RUN: %clang_dfsan %s -o %t && %run %t +// RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t && %run %t // Tests that labels are propagated through function calls. diff --git a/test/dfsan/label_count.c b/test/dfsan/label_count.c index a4b608701811..b42ce5824256 100644 --- a/test/dfsan/label_count.c +++ b/test/dfsan/label_count.c @@ -1,11 +1,11 @@ -// RUN: %clang_dfsan -DLIB -m64 -c %s -o %t.lib.o && \ -// RUN: %clang_dfsan -m64 -c %s -o %t.o && \ -// RUN: %clang_dfsan -m64 %t.lib.o %t.o -o %t.bin && \ +// RUN: %clang_dfsan -DLIB -c %s -o %t.lib.o && \ +// RUN: %clang_dfsan -c %s -o %t.o && \ +// RUN: %clang_dfsan %t.lib.o %t.o -o %t.bin && \ // RUN: %run %t.bin -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 -DLIB -c %s -o %t.lib.o && \ -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 -c %s -o %t.o && \ -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %t.o %t.lib.o -o %t.bin && \ +// RUN: %clang_dfsan -mllvm -dfsan-args-abi -DLIB -c %s -o %t.lib.o && \ +// RUN: %clang_dfsan -mllvm -dfsan-args-abi -c %s -o %t.o && \ +// RUN: %clang_dfsan -mllvm -dfsan-args-abi %t.o %t.lib.o -o %t.bin && \ // RUN: %run %t.bin #include <sanitizer/dfsan_interface.h> diff --git a/test/dfsan/lit.cfg b/test/dfsan/lit.cfg index d4adb9a5110a..e4d4e8f57af9 100644 --- a/test/dfsan/lit.cfg +++ b/test/dfsan/lit.cfg @@ -9,7 +9,7 @@ config.name = 'DataFlowSanitizer' config.test_source_root = os.path.dirname(__file__) # Setup default compiler flags used with -fsanitize=dataflow option. -clang_dfsan_cflags = ["-fsanitize=dataflow"] +clang_dfsan_cflags = ["-fsanitize=dataflow", "-m64"] clang_dfsan_cxxflags = config.cxx_mode_flags + clang_dfsan_cflags def build_invocation(compile_flags): diff --git a/test/dfsan/propagate.c b/test/dfsan/propagate.c index 733538cb109a..c30a087d6636 100644 --- a/test/dfsan/propagate.c +++ b/test/dfsan/propagate.c @@ -1,5 +1,5 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %run %t -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %run %t +// RUN: %clang_dfsan %s -o %t && %run %t +// RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t && %run %t // Tests that labels are propagated through computation and that union labels // are properly created. diff --git a/test/dfsan/vararg.c b/test/dfsan/vararg.c index 2227ba715639..f51e39c71899 100644 --- a/test/dfsan/vararg.c +++ b/test/dfsan/vararg.c @@ -1,7 +1,7 @@ -// RUN: %clang_dfsan -m64 %s -o %t +// RUN: %clang_dfsan %s -o %t // RUN: not %run %t 2>&1 | FileCheck %s // RUN: %run %t foo -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t +// RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t // RUN: not %run %t 2>&1 | FileCheck %s // RUN: %run %t foo diff --git a/test/dfsan/write_callback.c b/test/dfsan/write_callback.c index bb35f3250740..3ba027a0a46a 100644 --- a/test/dfsan/write_callback.c +++ b/test/dfsan/write_callback.c @@ -1,5 +1,5 @@ -// RUN: %clang_dfsan -m64 %s -o %t && %run %t | FileCheck %s -// RUN: %clang_dfsan -mllvm -dfsan-args-abi -m64 %s -o %t && %run %t | FileCheck %s +// RUN: %clang_dfsan %s -o %t && %run %t | FileCheck %s +// RUN: %clang_dfsan -mllvm -dfsan-args-abi %s -o %t && %run %t | FileCheck %s // Tests that the custom implementation of write() does writes with or without // a callback set using dfsan_set_write_callback(). diff --git a/test/lit.common.cfg b/test/lit.common.cfg index 0a551862c32b..02a3cd613029 100644 --- a/test/lit.common.cfg +++ b/test/lit.common.cfg @@ -5,6 +5,7 @@ # It is mostly copied from lit.cfg used by Clang. import os import platform +import subprocess import lit.formats import lit.util @@ -37,7 +38,9 @@ else: config.available_features.add(compiler_id) # Clear some environment variables that might affect Clang. -possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS', +possibly_dangerous_env_vars = ['ASAN_OPTIONS', 'DFSAN_OPTIONS', 'LSAN_OPTIONS', + 'MSAN_OPTIONS', 'UBSAN_OPTIONS', + 'COMPILER_PATH', 'RC_DEBUG_OPTIONS', 'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH', 'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH', 'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH', @@ -77,6 +80,15 @@ config.substitutions.append( ('%run', config.emulator) ) # Define CHECK-%os to check for OS-dependent output. config.substitutions.append( ('CHECK-%os', ("CHECK-" + config.host_os))) +if config.host_os == 'Windows': + # FIXME: This isn't quite right. Specifically, it will succeed if the program + # does not crash but exits with a non-zero exit code. We ought to merge + # KillTheDoctor and not --crash to make the latter more useful and remove the + # need for this substitution. + config.substitutions.append( ("%expect_crash ", "not KillTheDoctor ") ) +else: + config.substitutions.append( ("%expect_crash ", "not --crash ") ) + # Add supported compiler_rt architectures to a list of available features. compiler_rt_arch = getattr(config, 'compiler_rt_arch', None) if compiler_rt_arch: @@ -87,4 +99,42 @@ compiler_rt_debug = getattr(config, 'compiler_rt_debug', False) if not compiler_rt_debug: config.available_features.add('compiler-rt-optimized') +sanitizer_can_use_cxxabi = getattr(config, 'sanitizer_can_use_cxxabi', True) +if sanitizer_can_use_cxxabi: + config.available_features.add('cxxabi') + lit.util.usePlatformSdkOnDarwin(config, lit_config) + +def is_darwin_lto_supported(): + return os.path.exists(os.path.join(config.llvm_shlib_dir, 'libLTO.dylib')) + +def is_linux_lto_supported(): + if not os.path.exists(os.path.join(config.llvm_shlib_dir, 'LLVMgold.so')): + return False + + ld_cmd = subprocess.Popen([config.gold_executable, '--help'], stdout = subprocess.PIPE) + ld_out = ld_cmd.stdout.read().decode() + ld_cmd.wait() + + if not '-plugin' in ld_out: + return False + + return True + +def is_windows_lto_supported(): + return os.path.exists(os.path.join(config.llvm_tools_dir, 'lld-link2.exe')) + +if config.host_os == 'Darwin' and is_darwin_lto_supported(): + config.lto_supported = True + config.lto_launch = ["env", "DYLD_LIBRARY_PATH=" + config.llvm_shlib_dir] + config.lto_flags = [] +elif config.host_os == 'Linux' and is_linux_lto_supported(): + config.lto_supported = True + config.lto_launch = [] + config.lto_flags = ["-fuse-ld=gold"] +elif config.host_os == 'Windows' and is_windows_lto_supported(): + config.lto_supported = True + config.lto_launch = [] + config.lto_flags = ["-fuse-ld=lld-link2"] +else: + config.lto_supported = False diff --git a/test/lit.common.configured.in b/test/lit.common.configured.in index 4a5966e44f32..f250e8275a29 100644 --- a/test/lit.common.configured.in +++ b/test/lit.common.configured.in @@ -27,6 +27,7 @@ set_default("python_executable", "@PYTHON_EXECUTABLE@") set_default("compiler_rt_debug", @COMPILER_RT_DEBUG_PYBOOL@) set_default("compiler_rt_libdir", "@COMPILER_RT_LIBRARY_OUTPUT_DIR@") set_default("emulator", "@COMPILER_RT_EMULATOR@") +set_default("sanitizer_can_use_cxxabi", @SANITIZER_CAN_USE_CXXABI_PYBOOL@) # LLVM tools dir can be passed in lit parameters, so try to # apply substitution. diff --git a/test/lsan/CMakeLists.txt b/test/lsan/CMakeLists.txt index 7f49b0d3983d..6cca00a90b6b 100644 --- a/test/lsan/CMakeLists.txt +++ b/test/lsan/CMakeLists.txt @@ -10,14 +10,12 @@ configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/AsanConfig/lit.site.cfg) -if(NOT APPLE AND NOT ANDROID) - set(LSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) - if(NOT COMPILER_RT_STANDALONE_BUILD) - list(APPEND LSAN_TEST_DEPS lsan asan) - endif() - add_lit_testsuite(check-lsan "Running the LeakSanitizer tests" - ${CMAKE_CURRENT_BINARY_DIR}/LsanConfig - ${CMAKE_CURRENT_BINARY_DIR}/AsanConfig - DEPENDS ${LSAN_TEST_DEPS}) - set_target_properties(check-lsan PROPERTIES FOLDER "LSan tests") +set(LSAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +if(NOT COMPILER_RT_STANDALONE_BUILD) + list(APPEND LSAN_TEST_DEPS lsan asan) endif() +add_lit_testsuite(check-lsan "Running the LeakSanitizer tests" + ${CMAKE_CURRENT_BINARY_DIR}/LsanConfig + ${CMAKE_CURRENT_BINARY_DIR}/AsanConfig + DEPENDS ${LSAN_TEST_DEPS}) +set_target_properties(check-lsan PROPERTIES FOLDER "LSan tests") diff --git a/test/lsan/TestCases/recoverable_leak_check.cc b/test/lsan/TestCases/recoverable_leak_check.cc new file mode 100644 index 000000000000..0fe377f65af1 --- /dev/null +++ b/test/lsan/TestCases/recoverable_leak_check.cc @@ -0,0 +1,32 @@ +// Test for on-demand leak checking. +// RUN: LSAN_BASE="use_stacks=0:use_registers=0" +// RUN: %clangxx_lsan %s -o %t +// RUN: LSAN_OPTIONS=$LSAN_BASE %run %t foo 2>&1 | FileCheck %s +// RUN: LSAN_OPTIONS=$LSAN_BASE %run %t 2>&1 | FileCheck %s + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sanitizer/lsan_interface.h> + +void *p; + +int main(int argc, char *argv[]) { + p = malloc(23); + + assert(__lsan_do_recoverable_leak_check() == 0); + + fprintf(stderr, "Test alloc: %p.\n", malloc(1337)); +// CHECK: Test alloc: + + assert(__lsan_do_recoverable_leak_check() == 1); +// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 1337 byte + + // Test that we correctly reset chunk tags. + p = 0; + assert(__lsan_do_recoverable_leak_check() == 1); +// CHECK: SUMMARY: {{(Leak|Address)}}Sanitizer: 1360 byte + + _exit(0); +} diff --git a/test/msan/Linux/fopencookie.cc b/test/msan/Linux/fopencookie.cc new file mode 100644 index 000000000000..e5b8f936e0d2 --- /dev/null +++ b/test/msan/Linux/fopencookie.cc @@ -0,0 +1,65 @@ +// Test fopencookie interceptor. +// RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -std=c++11 -fsanitize-memory-track-origins -O0 %s -o %t && %run %t + +#include <assert.h> +#include <pthread.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <sanitizer/msan_interface.h> + +constexpr uintptr_t kMagicCookie = 0x12345678; + +static ssize_t cookie_read(void *cookie, char *buf, size_t size) { + assert((uintptr_t)cookie == kMagicCookie); + memset(buf, 0, size); + return 0; +} + +static ssize_t cookie_write(void *cookie, const char *buf, size_t size) { + assert((uintptr_t)cookie == kMagicCookie); + __msan_check_mem_is_initialized(buf, size); + return 0; +} + +static int cookie_seek(void *cookie, off64_t *offset, int whence) { + assert((uintptr_t)cookie == kMagicCookie); + __msan_check_mem_is_initialized(offset, sizeof(*offset)); + return 0; +} + +static int cookie_close(void *cookie) { + assert((uintptr_t)cookie == kMagicCookie); + return 0; +} + +void PoisonStack() { char a[8192]; } + +void TestPoisonStack() { + // Verify that PoisonStack has poisoned the stack - otherwise this test is not + // testing anything. + char a; + assert(__msan_test_shadow(&a - 1000, 1) == 0); +} + +int main() { + void *cookie = (void *)kMagicCookie; + FILE *f = fopencookie(cookie, "rw", + {cookie_read, cookie_write, cookie_seek, cookie_close}); + PoisonStack(); + TestPoisonStack(); + fseek(f, 100, SEEK_SET); + char buf[50]; + fread(buf, 50, 1, f); + fwrite(buf, 50, 1, f); + fclose(f); + + f = fopencookie(cookie, "rw", {nullptr, nullptr, nullptr, nullptr}); + fseek(f, 100, SEEK_SET); + fread(buf, 50, 1, f); + fwrite(buf, 50, 1, f); + fclose(f); +} diff --git a/test/msan/Linux/getresid.cc b/test/msan/Linux/getresid.cc index 385351dfdcde..f3c0914b52f5 100644 --- a/test/msan/Linux/getresid.cc +++ b/test/msan/Linux/getresid.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p 2>&1 -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p 2>&1 #include <assert.h> #include <unistd.h> diff --git a/test/msan/Linux/glob.cc b/test/msan/Linux/glob.cc index 8604e4d76265..1481861a08e0 100644 --- a/test/msan/Linux/glob.cc +++ b/test/msan/Linux/glob.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p 2>&1 | FileCheck %s #include <assert.h> #include <glob.h> diff --git a/test/msan/Linux/glob_altdirfunc.cc b/test/msan/Linux/glob_altdirfunc.cc index 2c02e735e05e..cb7fe09cbc3d 100644 --- a/test/msan/Linux/glob_altdirfunc.cc +++ b/test/msan/Linux/glob_altdirfunc.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 | FileCheck %s -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p 2>&1 | FileCheck %s #include <assert.h> #include <glob.h> diff --git a/test/msan/Linux/glob_nomatch.cc b/test/msan/Linux/glob_nomatch.cc index bc35c30d6d07..fa132c813727 100644 --- a/test/msan/Linux/glob_nomatch.cc +++ b/test/msan/Linux/glob_nomatch.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p #include <assert.h> #include <glob.h> diff --git a/test/msan/ioctl_sound.cc b/test/msan/Linux/ioctl_sound.cc index ed896f761181..fb36c52f2e7e 100644 --- a/test/msan/ioctl_sound.cc +++ b/test/msan/Linux/ioctl_sound.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O3 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O3 -g %s -o %t && %run %t #include <assert.h> #include <fcntl.h> diff --git a/test/msan/mallinfo.cc b/test/msan/Linux/mallinfo.cc index 3f308683077e..3c3692969852 100644 --- a/test/msan/mallinfo.cc +++ b/test/msan/Linux/mallinfo.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t #include <assert.h> #include <malloc.h> diff --git a/test/msan/obstack.cc b/test/msan/Linux/obstack.cc index 222f43b839dc..f1f53be4c9b2 100644 --- a/test/msan/obstack.cc +++ b/test/msan/Linux/obstack.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -g -DPOSITIVE %s -o %t && not %run %t |& FileCheck %s +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g -DPOSITIVE %s -o %t && not %run %t |& FileCheck %s #include <obstack.h> #include <sanitizer/msan_interface.h> diff --git a/test/msan/Linux/sunrpc.cc b/test/msan/Linux/sunrpc.cc index 78645a7dcbf2..c92ad632c095 100644 --- a/test/msan/Linux/sunrpc.cc +++ b/test/msan/Linux/sunrpc.cc @@ -1,14 +1,14 @@ -// RUN: %clangxx_msan -m64 -g -O0 -DTYPE=int -DFN=xdr_int %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DTYPE=int -DFN=xdr_int %s -o %t && \ // RUN: %run %t 2>&1 -// RUN: %clangxx_msan -m64 -g -O0 -DTYPE=int -DFN=xdr_int -DUNINIT=1 %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DTYPE=int -DFN=xdr_int -DUNINIT=1 %s -o %t && \ // RUN: not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_msan -m64 -g -O0 -DTYPE=double -DFN=xdr_double %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DTYPE=double -DFN=xdr_double %s -o %t && \ // RUN: %run %t 2>&1 -// RUN: %clangxx_msan -m64 -g -O0 -DTYPE=double -DFN=xdr_double -DUNINIT=1 %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DTYPE=double -DFN=xdr_double -DUNINIT=1 %s -o %t && \ // RUN: not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_msan -m64 -g -O0 -DTYPE=u_quad_t -DFN=xdr_u_longlong_t %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DTYPE=u_quad_t -DFN=xdr_u_longlong_t %s -o %t && \ // RUN: %run %t 2>&1 -// RUN: %clangxx_msan -m64 -g -O0 -DTYPE=u_quad_t -DFN=xdr_u_longlong_t -DUNINIT=1 %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DTYPE=u_quad_t -DFN=xdr_u_longlong_t -DUNINIT=1 %s -o %t && \ // RUN: not %run %t 2>&1 | FileCheck %s #include <assert.h> diff --git a/test/msan/Linux/sunrpc_bytes.cc b/test/msan/Linux/sunrpc_bytes.cc index f0c35746f34d..477637af2b63 100644 --- a/test/msan/Linux/sunrpc_bytes.cc +++ b/test/msan/Linux/sunrpc_bytes.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -g -O0 %s -o %t && \ +// RUN: %clangxx_msan -g -O0 %s -o %t && \ // RUN: %run %t 2>&1 -// RUN: %clangxx_msan -m64 -g -O0 -DUNINIT=1 %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DUNINIT=1 %s -o %t && \ // RUN: not %run %t 2>&1 | FileCheck %s #include <assert.h> diff --git a/test/msan/Linux/sunrpc_string.cc b/test/msan/Linux/sunrpc_string.cc index 3f44a96d114c..350222f5cc1e 100644 --- a/test/msan/Linux/sunrpc_string.cc +++ b/test/msan/Linux/sunrpc_string.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -g -O0 %s -o %t && \ +// RUN: %clangxx_msan -g -O0 %s -o %t && \ // RUN: %run %t 2>&1 -// RUN: %clangxx_msan -m64 -g -O0 -DUNINIT=1 %s -o %t && \ +// RUN: %clangxx_msan -g -O0 -DUNINIT=1 %s -o %t && \ // RUN: not %run %t 2>&1 | FileCheck %s #include <assert.h> diff --git a/test/msan/Linux/syscalls.cc b/test/msan/Linux/syscalls.cc index 4dd97e745148..78dba36638a6 100644 --- a/test/msan/Linux/syscalls.cc +++ b/test/msan/Linux/syscalls.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && %run %t 2>&1 #include <assert.h> #include <errno.h> diff --git a/test/msan/Linux/tcgetattr.cc b/test/msan/Linux/tcgetattr.cc index e1425b84f550..454b7fd1537e 100644 --- a/test/msan/Linux/tcgetattr.cc +++ b/test/msan/Linux/tcgetattr.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p #include <assert.h> #include <glob.h> diff --git a/test/msan/Linux/xattr.cc b/test/msan/Linux/xattr.cc index 1beba117d574..86cc2cd474d5 100644 --- a/test/msan/Linux/xattr.cc +++ b/test/msan/Linux/xattr.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p 2>&1 -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p 2>&1 #include <argz.h> #include <assert.h> diff --git a/test/msan/backtrace.cc b/test/msan/backtrace.cc index 473e0ae8f88b..9cb883c5cf7d 100644 --- a/test/msan/backtrace.cc +++ b/test/msan/backtrace.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t #include <assert.h> #include <execinfo.h> @@ -17,7 +17,7 @@ void f() { char **s = backtrace_symbols(buf, sz); assert(s > 0); for (int i = 0; i < sz; ++i) - printf("%d\n", strlen(s[i])); + printf("%d\n", (int)strlen(s[i])); } int main(void) { diff --git a/test/msan/c-strdup.c b/test/msan/c-strdup.c index 059300e4205a..b1e02b914fcd 100644 --- a/test/msan/c-strdup.c +++ b/test/msan/c-strdup.c @@ -1,7 +1,7 @@ -// RUN: %clang_msan -m64 -O0 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clang_msan -m64 -O1 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clang_msan -m64 -O2 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clang_msan -m64 -O3 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clang_msan -O0 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clang_msan -O1 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clang_msan -O2 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clang_msan -O3 %s -o %t && %run %t >%t.out 2>&1 // Test that strdup in C programs is intercepted. // GLibC headers translate strdup to __strdup at -O1 and higher. diff --git a/test/msan/chained_origin.cc b/test/msan/chained_origin.cc index 336bbd852cb3..ae72c10b6ac8 100644 --- a/test/msan/chained_origin.cc +++ b/test/msan/chained_origin.cc @@ -1,17 +1,17 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-STACK < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DHEAP=1 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DHEAP=1 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-HEAP < %t.out -// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-STACK < %t.out -// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -DHEAP=1 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -DHEAP=1 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-HEAP < %t.out diff --git a/test/msan/chained_origin_empty_stack.cc b/test/msan/chained_origin_empty_stack.cc index 36727e3d7aa7..f1ed66b75e42 100644 --- a/test/msan/chained_origin_empty_stack.cc +++ b/test/msan/chained_origin_empty_stack.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O3 %s -o %t && \ // RUN: MSAN_OPTIONS=store_context_size=1 not %run %t 2>&1 | FileCheck %s // Test that stack trace for the intermediate store is not empty. diff --git a/test/msan/chained_origin_limits.cc b/test/msan/chained_origin_limits.cc index 0cc57f32a6ac..90fd09a86b29 100644 --- a/test/msan/chained_origin_limits.cc +++ b/test/msan/chained_origin_limits.cc @@ -1,7 +1,7 @@ // This test program creates a very large number of unique histories. // Heap origin. -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O3 %s -o %t // RUN: MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out @@ -16,7 +16,7 @@ // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out // Stack origin. -// RUN: %clangxx_msan -DSTACK -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t +// RUN: %clangxx_msan -DSTACK -fsanitize-memory-track-origins=2 -O3 %s -o %t // RUN: MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out @@ -32,7 +32,7 @@ // Heap origin, with calls. -// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t +// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t // RUN: MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out @@ -48,7 +48,7 @@ // Stack origin, with calls. -// RUN: %clangxx_msan -DSTACK -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t +// RUN: %clangxx_msan -DSTACK -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t // RUN: MSAN_OPTIONS=origin_history_size=7 not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK7 < %t.out diff --git a/test/msan/chained_origin_memcpy.cc b/test/msan/chained_origin_memcpy.cc index f4c2f7fcac87..3fe0b77a0614 100644 --- a/test/msan/chained_origin_memcpy.cc +++ b/test/msan/chained_origin_memcpy.cc @@ -1,17 +1,17 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -DOFFSET=0 -O3 %s -o %t && \ +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DOFFSET=0 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z1 < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DOFFSET=10 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -DOFFSET=10 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z2 < %t.out -// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -m64 -DOFFSET=0 -O3 %s -o %t && \ +// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -DOFFSET=0 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z1 < %t.out -// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -DOFFSET=10 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -DOFFSET=10 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-Z2 < %t.out diff --git a/test/msan/chained_origin_with_signals.cc b/test/msan/chained_origin_with_signals.cc index 2841e34a1f1d..43dbdcca76a9 100644 --- a/test/msan/chained_origin_with_signals.cc +++ b/test/msan/chained_origin_with_signals.cc @@ -2,11 +2,11 @@ // This is, in fact, undesired behavior caused by our chained origins // implementation being not async-signal-safe. -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -m64 -O3 %s -o %t && \ +// RUN: %clangxx_msan -mllvm -msan-instrumentation-with-call-threshold=0 -fsanitize-memory-track-origins=2 -O3 %s -o %t && \ // RUN: not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out diff --git a/test/msan/check_mem_is_initialized.cc b/test/msan/check_mem_is_initialized.cc index 7d2328810d90..e1d3b117e42f 100644 --- a/test/msan/check_mem_is_initialized.cc +++ b/test/msan/check_mem_is_initialized.cc @@ -1,19 +1,19 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out #include <sanitizer/msan_interface.h> diff --git a/test/msan/coverage-levels.cc b/test/msan/coverage-levels.cc index 7c2e143d3ab8..d71bfecb2ebb 100644 --- a/test/msan/coverage-levels.cc +++ b/test/msan/coverage-levels.cc @@ -1,13 +1,13 @@ // Test various levels of coverage // -// RUN: %clangxx_msan -DINIT_VAR=1 -O1 -fsanitize-coverage=1 %s -o %t +// RUN: %clangxx_msan -DINIT_VAR=1 -O1 -fsanitize-coverage=func %s -o %t // RUN: mkdir -p %T/coverage-levels // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_NOWARN -// RUN: %clangxx_msan -O1 -fsanitize-coverage=1 %s -o %t +// RUN: %clangxx_msan -O1 -fsanitize-coverage=func %s -o %t // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 --check-prefix=CHECK_WARN -// RUN: %clangxx_msan -O1 -fsanitize-coverage=2 %s -o %t +// RUN: %clangxx_msan -O1 -fsanitize-coverage=bb %s -o %t // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK2 --check-prefix=CHECK_WARN -// RUN: %clangxx_msan -O1 -fsanitize-coverage=3 %s -o %t +// RUN: %clangxx_msan -O1 -fsanitize-coverage=edge %s -o %t // RUN: MSAN_OPTIONS=coverage=1:verbosity=1:coverage_dir=%T/coverage-levels not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK3 --check-prefix=CHECK_WARN // volatile int sink; diff --git a/test/msan/cxa_atexit.cc b/test/msan/cxa_atexit.cc index 0aa36ecee011..70384b9c93f8 100644 --- a/test/msan/cxa_atexit.cc +++ b/test/msan/cxa_atexit.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p // PR17377: C++ module destructors get stale argument shadow. diff --git a/test/msan/death-callback.cc b/test/msan/death-callback.cc index 6d0488339998..08cf2911b0f9 100644 --- a/test/msan/death-callback.cc +++ b/test/msan/death-callback.cc @@ -1,10 +1,10 @@ -// RUN: %clangxx_msan -m64 -DERROR %s -o %t && not %run %t 2>&1 | \ +// RUN: %clangxx_msan -DERROR %s -o %t && not %run %t 2>&1 | \ // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOCB -// RUN: %clangxx_msan -m64 -DERROR -DMSANCB_SET %s -o %t && not %run %t 2>&1 | \ +// RUN: %clangxx_msan -DERROR -DMSANCB_SET %s -o %t && not %run %t 2>&1 | \ // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-CB -// RUN: %clangxx_msan -m64 -DERROR -DMSANCB_SET -DMSANCB_CLEAR %s -o %t && not %run %t 2>&1 | \ +// RUN: %clangxx_msan -DERROR -DMSANCB_SET -DMSANCB_CLEAR %s -o %t && not %run %t 2>&1 | \ // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOCB -// RUN: %clangxx_msan -m64 -DMSANCB_SET %s -o %t && %run %t 2>&1 | \ +// RUN: %clangxx_msan -DMSANCB_SET %s -o %t && %run %t 2>&1 | \ // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOCB #include <sanitizer/msan_interface.h> diff --git a/test/msan/dlerror.cc b/test/msan/dlerror.cc index 2c726d36041e..d5510b65c4a5 100644 --- a/test/msan/dlerror.cc +++ b/test/msan/dlerror.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t #include <assert.h> #include <dlfcn.h> diff --git a/test/msan/dso-origin.cc b/test/msan/dso-origin.cc index ba008c00718d..7f62449842ce 100644 --- a/test/msan/dso-origin.cc +++ b/test/msan/dso-origin.cc @@ -1,7 +1,7 @@ // Build a library with origin tracking and an executable w/o origin tracking. // Test that origin tracking is enabled at runtime. -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -DBUILD_SO -fPIC -shared -o %t-so.so -// RUN: %clangxx_msan -m64 -O0 %s %t-so.so -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -DBUILD_SO -fPIC -shared -o %t-so.so +// RUN: %clangxx_msan -O0 %s %t-so.so -o %t && not %run %t 2>&1 | FileCheck %s #ifdef BUILD_SO diff --git a/test/msan/dtls_test.c b/test/msan/dtls_test.c index cb88ede2f0a6..4036f71a7f8e 100644 --- a/test/msan/dtls_test.c +++ b/test/msan/dtls_test.c @@ -1,5 +1,5 @@ -/* RUN: %clang_msan -g -m64 %s -o %t - RUN: %clang_msan -g -m64 %s -DBUILD_SO -fPIC -o %t-so.so -shared +/* RUN: %clang_msan -g %s -o %t + RUN: %clang_msan -g %s -DBUILD_SO -fPIC -o %t-so.so -shared RUN: %run %t 2>&1 Regression test for a bug in msan/glibc integration, diff --git a/test/msan/errno.cc b/test/msan/errno.cc index 8af8eb5ee6f9..6ed0fd4108e6 100644 --- a/test/msan/errno.cc +++ b/test/msan/errno.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t #include <assert.h> #include <errno.h> diff --git a/test/msan/fork.cc b/test/msan/fork.cc index 10de8a9379d8..78a62d549ec3 100644 --- a/test/msan/fork.cc +++ b/test/msan/fork.cc @@ -2,7 +2,7 @@ // Run a number of threads that create new chained origins, then fork // and verify that origin reads do not deadlock in the child process. -// RUN: %clangxx_msan -std=c++11 -fsanitize-memory-track-origins=2 -g -m64 -O3 %s -o %t +// RUN: %clangxx_msan -std=c++11 -fsanitize-memory-track-origins=2 -g -O3 %s -o %t // RUN: MSAN_OPTIONS=store_context_size=1000,origin_history_size=0,origin_history_per_stack_limit=0 %run %t |& FileCheck %s // Fun fact: if test output is redirected to a file (as opposed to diff --git a/test/msan/ftime.cc b/test/msan/ftime.cc index 2d0935d18037..7a5a2fbf7dce 100644 --- a/test/msan/ftime.cc +++ b/test/msan/ftime.cc @@ -1,4 +1,7 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t + +// ftime() is deprecated on FreeBSD. +// XFAIL: freebsd #include <assert.h> #include <sys/timeb.h> diff --git a/test/msan/getaddrinfo-positive.cc b/test/msan/getaddrinfo-positive.cc index 7658cd504dba..45c1b604d1e3 100644 --- a/test/msan/getaddrinfo-positive.cc +++ b/test/msan/getaddrinfo-positive.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out #include <sys/types.h> diff --git a/test/msan/getaddrinfo.cc b/test/msan/getaddrinfo.cc index abab8bd78f75..c9dcf3ecbae5 100644 --- a/test/msan/getaddrinfo.cc +++ b/test/msan/getaddrinfo.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t #include <sys/types.h> #include <sys/socket.h> diff --git a/test/msan/getc_unlocked.c b/test/msan/getc_unlocked.c index 7df958ad657a..8468fed5ccfa 100644 --- a/test/msan/getc_unlocked.c +++ b/test/msan/getc_unlocked.c @@ -1,12 +1,12 @@ -// RUN: %clangxx_msan -DGETC -m64 -O0 -g -xc++ %s -o %t && %run %t -// RUN: %clangxx_msan -DGETC -m64 -O3 -g -xc++ %s -o %t && %run %t -// RUN: %clang_msan -DGETC -m64 -O0 -g %s -o %t && %run %t -// RUN: %clang_msan -DGETC -m64 -O3 -g %s -o %t && %run %t +// RUN: %clangxx_msan -DGETC -O0 -g -xc++ %s -o %t && %run %t +// RUN: %clangxx_msan -DGETC -O3 -g -xc++ %s -o %t && %run %t +// RUN: %clang_msan -DGETC -O0 -g %s -o %t && %run %t +// RUN: %clang_msan -DGETC -O3 -g %s -o %t && %run %t -// RUN: %clangxx_msan -DGETCHAR -m64 -O0 -g -xc++ %s -o %t && %run %t -// RUN: %clangxx_msan -DGETCHAR -m64 -O3 -g -xc++ %s -o %t && %run %t -// RUN: %clang_msan -DGETCHAR -m64 -O0 -g %s -o %t && %run %t -// RUN: %clang_msan -DGETCHAR -m64 -O3 -g %s -o %t && %run %t +// RUN: %clangxx_msan -DGETCHAR -O0 -g -xc++ %s -o %t && %run %t +// RUN: %clangxx_msan -DGETCHAR -O3 -g -xc++ %s -o %t && %run %t +// RUN: %clang_msan -DGETCHAR -O0 -g %s -o %t && %run %t +// RUN: %clang_msan -DGETCHAR -O3 -g %s -o %t && %run %t #include <assert.h> #include <stdio.h> diff --git a/test/msan/getline.cc b/test/msan/getline.cc index 51e105e0be5c..ee12d4ddc529 100644 --- a/test/msan/getline.cc +++ b/test/msan/getline.cc @@ -7,6 +7,10 @@ // RUN: %clang_msan -O0 -xc -D_GNU_SOURCE=1 %s -o %t && %run %t %t-testdata // RUN: %clang_msan -O2 -xc -D_GNU_SOURCE=1 %s -o %t && %run %t %t-testdata +#if defined(__FreeBSD__) +#define _WITH_GETLINE // To declare getline(). +#endif + #include <assert.h> #include <stdio.h> #include <stdlib.h> diff --git a/test/msan/heap-origin.cc b/test/msan/heap-origin.cc index 0920001beed7..4f170f0d7377 100644 --- a/test/msan/heap-origin.cc +++ b/test/msan/heap-origin.cc @@ -1,19 +1,19 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out #include <stdlib.h> diff --git a/test/msan/iconv.cc b/test/msan/iconv.cc index ea6958b79b96..c2da938169b3 100644 --- a/test/msan/iconv.cc +++ b/test/msan/iconv.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -g -DPOSITIVE %s -o %t && not %run %t |& FileCheck %s +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g -DPOSITIVE %s -o %t && not %run %t |& FileCheck %s #include <assert.h> #include <iconv.h> @@ -15,7 +15,12 @@ int main(void) { char inbuf_[100]; strcpy(inbuf_, "sample text"); char outbuf_[100]; +#if defined(__FreeBSD__) + // FreeBSD's iconv() expects the 2nd argument be of type 'const char**'. + const char *inbuf = inbuf_; +#else char *inbuf = inbuf_; +#endif char *outbuf = outbuf_; size_t inbytesleft = strlen(inbuf_); size_t outbytesleft = sizeof(outbuf_); diff --git a/test/msan/if_indextoname.cc b/test/msan/if_indextoname.cc index b74aec16c98a..7b1b989e57d5 100644 --- a/test/msan/if_indextoname.cc +++ b/test/msan/if_indextoname.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t 2>&1 -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && %run %t 2>&1 #include <assert.h> #include <errno.h> @@ -18,6 +18,6 @@ int main(int argc, char *argv[]) { printf("No network interfaces found.\n"); return 0; } - assert(strlen(ifname) + 1 == __msan_test_shadow(ifname, sizeof(ifname))); + assert(strlen(ifname) + 1 <= __msan_test_shadow(ifname, sizeof(ifname))); return 0; } diff --git a/test/msan/ifaddrs.cc b/test/msan/ifaddrs.cc index 6a0db3a5b71f..6f5eb935ab52 100644 --- a/test/msan/ifaddrs.cc +++ b/test/msan/ifaddrs.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p 2>&1 -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p 2>&1 #include <assert.h> #include <errno.h> @@ -10,6 +10,10 @@ #include <vector> +#if defined(__FreeBSD__) +#include <sys/socket.h> // To define 'struct sockaddr'. +#endif + #include <sanitizer/msan_interface.h> #define CHECK_AND_PUSH(addr, size) \ diff --git a/test/msan/initgroups.cc b/test/msan/initgroups.cc index 94f6cd8252f3..974b1cbaa666 100644 --- a/test/msan/initgroups.cc +++ b/test/msan/initgroups.cc @@ -1,7 +1,8 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t #include <sys/types.h> #include <grp.h> +#include <unistd.h> // FreeBSD declares initgroups() here. int main(void) { initgroups("root", 0); diff --git a/test/msan/insertvalue_origin.cc b/test/msan/insertvalue_origin.cc index 545debffaad5..a0c70023f2f6 100644 --- a/test/msan/insertvalue_origin.cc +++ b/test/msan/insertvalue_origin.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out // Test origin propagation through insertvalue IR instruction. diff --git a/test/msan/ioctl.cc b/test/msan/ioctl.cc index caa5c274f5eb..e21ef636c604 100644 --- a/test/msan/ioctl.cc +++ b/test/msan/ioctl.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O3 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O3 -g %s -o %t && %run %t #include <assert.h> #include <stdlib.h> diff --git a/test/msan/ioctl_custom.cc b/test/msan/ioctl_custom.cc index 7c7fde4bd5d0..6df22d75e95e 100644 --- a/test/msan/ioctl_custom.cc +++ b/test/msan/ioctl_custom.cc @@ -1,8 +1,8 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O3 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O3 -g %s -o %t && %run %t -// RUN: %clangxx_msan -DPOSITIVE -m64 -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s -// RUN: %clangxx_msan -DPOSITIVE -m64 -O3 -g %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_msan -DPOSITIVE -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_msan -DPOSITIVE -O3 -g %s -o %t && not %run %t 2>&1 | FileCheck %s #include <assert.h> #include <stdlib.h> diff --git a/test/msan/keep-going-dso.cc b/test/msan/keep-going-dso.cc index 7975306c557f..f32a513ea9e7 100644 --- a/test/msan/keep-going-dso.cc +++ b/test/msan/keep-going-dso.cc @@ -1,15 +1,15 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out -// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 // FileCheck %s <%t.out -// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 // FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && not %run %t >%t.out 2>&1 // FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 // FileCheck %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 // FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out // Test how -mllvm -msan-keep-going and MSAN_OPTIONS=keep_going affect reports diff --git a/test/msan/keep-going.cc b/test/msan/keep-going.cc index 6426574a9e50..57729756357d 100644 --- a/test/msan/keep-going.cc +++ b/test/msan/keep-going.cc @@ -1,19 +1,19 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // FileCheck %s <%t.out -// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 // FileCheck %s <%t.out -// RUN: %clangxx_msan -m64 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 // FileCheck %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && not %run %t >%t.out 2>&1 // FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=0 not %run %t >%t.out 2>&1 // FileCheck %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=keep_going=1 not %run %t >%t.out 2>&1 // FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=halt_on_error=1 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=halt_on_error=1 not %run %t >%t.out 2>&1 // FileCheck %s <%t.out -// RUN: %clangxx_msan -m64 -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=halt_on_error=0 not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -mllvm -msan-keep-going=1 -O0 %s -o %t && MSAN_OPTIONS=halt_on_error=0 not %run %t >%t.out 2>&1 // FileCheck --check-prefix=CHECK-KEEP-GOING %s <%t.out // Test behaviour of -mllvm -msan-keep-going and MSAN_OPTIONS=keep_going. diff --git a/test/msan/lit.cfg b/test/msan/lit.cfg index f425e25957ac..011ccd2fae74 100644 --- a/test/msan/lit.cfg +++ b/test/msan/lit.cfg @@ -14,6 +14,9 @@ clang_msan_cflags = ["-fsanitize=memory", "-fno-omit-frame-pointer", "-fno-optimize-sibling-calls", "-m64"] + config.debug_info_flags +# Some Msan tests leverage backtrace() which requires libexecinfo on FreeBSD. +if config.host_os == 'FreeBSD': + clang_msan_cflags += ["-lexecinfo"] clang_msan_cxxflags = config.cxx_mode_flags + clang_msan_cflags def build_invocation(compile_flags): diff --git a/test/msan/mktime.cc b/test/msan/mktime.cc index c419057c3907..997fb0ddbbab 100644 --- a/test/msan/mktime.cc +++ b/test/msan/mktime.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -g -DUNINIT %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g -DUNINIT %s -o %t && not %run %t 2>&1 | FileCheck %s #include <assert.h> #include <time.h> diff --git a/test/msan/mmap.cc b/test/msan/mmap.cc new file mode 100644 index 000000000000..c09fcb76a827 --- /dev/null +++ b/test/msan/mmap.cc @@ -0,0 +1,45 @@ +// Test that mmap (without MAP_FIXED) always returns valid application addresses. +// RUN: %clangxx_msan -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -fsanitize-memory-track-origins %s -o %t && %run %t + +#include <assert.h> +#include <errno.h> +#include <stdint.h> +#include <sys/mman.h> +#include <stdio.h> + +bool AddrIsApp(void *p) { + uintptr_t addr = (uintptr_t)p; +#if defined(__FreeBSD__) && defined(__x86_64__) + return addr < 0x010000000000ULL || addr >= 0x600000000000ULL; +#elif defined(__x86_64__) + return addr >= 0x600000000000ULL; +#elif defined(__mips64) + return addr >= 0x00e000000000ULL; +#elif defined(__powerpc64__) + return addr < 0x000100000000ULL || addr >= 0x300000000000ULL; +#endif +} + +int main() { + // Large enough to quickly exhaust the entire address space. +#if defined(__mips64) + const size_t kMapSize = 0x100000000ULL; +#else + const size_t kMapSize = 0x1000000000ULL; +#endif + int success_count = 0; + while (true) { + void *p = mmap(0, kMapSize, PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0); + printf("%p\n", p); + if (p == MAP_FAILED) { + assert(errno == ENOMEM); + break; + } + assert(AddrIsApp(p)); + success_count++; + } + printf("successful mappings: %d\n", success_count); + assert(success_count > 5); +} diff --git a/test/msan/mmap_below_shadow.cc b/test/msan/mmap_below_shadow.cc index 0b982d58930d..563d8774f525 100644 --- a/test/msan/mmap_below_shadow.cc +++ b/test/msan/mmap_below_shadow.cc @@ -3,10 +3,10 @@ // Without MAP_FIXED, we ignore the address hint and map somewhere in // application range. -// RUN: %clangxx_msan -m64 -O0 -DFIXED=0 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -DFIXED=1 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -DFIXED=0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -DFIXED=1 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -DFIXED=0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -DFIXED=1 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -DFIXED=0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -DFIXED=1 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t #include <assert.h> #include <errno.h> @@ -15,12 +15,18 @@ int main(void) { // Hint address just below shadow. -#if defined(__x86_64__) +#if defined(__FreeBSD__) && defined(__x86_64__) + uintptr_t hint = 0x0f0000000000ULL; + const uintptr_t app_start = 0x000000000000ULL; +#elif defined(__x86_64__) uintptr_t hint = 0x4f0000000000ULL; const uintptr_t app_start = 0x600000000000ULL; #elif defined (__mips64) uintptr_t hint = 0x4f00000000ULL; const uintptr_t app_start = 0x6000000000ULL; +#elif defined (__powerpc64__) + uintptr_t hint = 0x2f0000000000ULL; + const uintptr_t app_start = 0x300000000000ULL; #endif uintptr_t p = (uintptr_t)mmap( (void *)hint, 4096, PROT_WRITE, diff --git a/test/msan/msan_check_mem_is_initialized.cc b/test/msan/msan_check_mem_is_initialized.cc index 33558cd2feb2..599cf2d7dd46 100644 --- a/test/msan/msan_check_mem_is_initialized.cc +++ b/test/msan/msan_check_mem_is_initialized.cc @@ -1,9 +1,9 @@ -// RUN: %clangxx_msan -m64 -O0 -g -DPOSITIVE %s -o %t +// RUN: %clangxx_msan -O0 -g -DPOSITIVE %s -o %t // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK // RUN: MSAN_OPTIONS=verbosity=1 not %run %t 2>&1 | \ // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-VERBOSE -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t #include <sanitizer/msan_interface.h> diff --git a/test/msan/msan_dump_shadow.cc b/test/msan/msan_dump_shadow.cc index 08371e306f32..543fa7013223 100644 --- a/test/msan/msan_dump_shadow.cc +++ b/test/msan/msan_dump_shadow.cc @@ -1,10 +1,10 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out #include <sanitizer/msan_interface.h> diff --git a/test/msan/msan_print_shadow.cc b/test/msan/msan_print_shadow.cc index f4894596a0e2..9668be2c240f 100644 --- a/test/msan/msan_print_shadow.cc +++ b/test/msan/msan_print_shadow.cc @@ -1,10 +1,10 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ORIGINS --check-prefix=CHECK-ORIGINS-2 < %t.out #include <sanitizer/msan_interface.h> diff --git a/test/msan/msan_print_shadow2.cc b/test/msan/msan_print_shadow2.cc index 343ee9e5c3de..5095081c9655 100644 --- a/test/msan/msan_print_shadow2.cc +++ b/test/msan/msan_print_shadow2.cc @@ -1,10 +1,10 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NO-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-ORIGINS < %t.out #include <sanitizer/msan_interface.h> diff --git a/test/msan/msan_print_shadow3.cc b/test/msan/msan_print_shadow3.cc index c605ef18886d..b29f3222dc33 100644 --- a/test/msan/msan_print_shadow3.cc +++ b/test/msan/msan_print_shadow3.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out #include <stdint.h> diff --git a/test/msan/mul_by_const.cc b/test/msan/mul_by_const.cc index a975bb92167e..8240fdbedb5b 100644 --- a/test/msan/mul_by_const.cc +++ b/test/msan/mul_by_const.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O2 %s -o %t && %run %t +// RUN: %clangxx_msan -O2 %s -o %t && %run %t #include <sanitizer/msan_interface.h> diff --git a/test/msan/no_sanitize_memory.cc b/test/msan/no_sanitize_memory.cc index c5643816c281..5c53ee4f3482 100644 --- a/test/msan/no_sanitize_memory.cc +++ b/test/msan/no_sanitize_memory.cc @@ -1,12 +1,12 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O1 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O2 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O0 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O1 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O2 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t -DCHECK_IN_F && %run %t >%t.out 2>&1 // Test that (no_sanitize_memory) functions // * don't check shadow values (-DCHECK_IN_F) diff --git a/test/msan/no_sanitize_memory_prop.cc b/test/msan/no_sanitize_memory_prop.cc index 4275ebbf78e1..bfd4194dd266 100644 --- a/test/msan/no_sanitize_memory_prop.cc +++ b/test/msan/no_sanitize_memory_prop.cc @@ -1,7 +1,7 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O1 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O2 %s -o %t && %run %t >%t.out 2>&1 -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && %run %t >%t.out 2>&1 // Test that (no_sanitize_memory) functions DO NOT propagate shadow. diff --git a/test/msan/origin-store-long.cc b/test/msan/origin-store-long.cc index a7c2b7a7d578..5c9fe04b7203 100644 --- a/test/msan/origin-store-long.cc +++ b/test/msan/origin-store-long.cc @@ -1,7 +1,7 @@ // Check that 8-byte store updates origin for the full store range. -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out #include <sanitizer/msan_interface.h> diff --git a/test/msan/param_tls_limit.cc b/test/msan/param_tls_limit.cc index 869afc935773..982ae1ebdc2e 100644 --- a/test/msan/param_tls_limit.cc +++ b/test/msan/param_tls_limit.cc @@ -1,9 +1,9 @@ // ParamTLS has limited size. Everything that does not fit is considered fully // initialized. -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && %run %t -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && %run %t #include <sanitizer/msan_interface.h> #include <assert.h> diff --git a/test/msan/print_stats.cc b/test/msan/print_stats.cc index 74943835b367..39af504179d6 100644 --- a/test/msan/print_stats.cc +++ b/test/msan/print_stats.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -g %s -o %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -g %s -o %t // RUN: %run %t 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-NOSTATS %s // RUN: MSAN_OPTIONS=print_stats=1 %run %t 2>&1 | \ @@ -6,13 +6,13 @@ // RUN: MSAN_OPTIONS=print_stats=1,atexit=1 %run %t 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-STATS %s -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -g -DPOSITIVE=1 %s -o %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -g -DPOSITIVE=1 %s -o %t // RUN: not %run %t 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-NOSTATS %s // RUN: MSAN_OPTIONS=print_stats=1 not %run %t 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-STATS %s -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -g -DPOSITIVE=1 -mllvm -msan-keep-going=1 %s -o %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -g -DPOSITIVE=1 -mllvm -msan-keep-going=1 %s -o %t // RUN: not %run %t 2>&1 | \ // RUN: FileCheck --check-prefix=CHECK --check-prefix=CHECK-NOSTATS --check-prefix=CHECK-KEEPGOING %s // RUN: MSAN_OPTIONS=print_stats=1 not %run %t 2>&1 | \ diff --git a/test/msan/pthread_getattr_np_deadlock.cc b/test/msan/pthread_getattr_np_deadlock.cc index 07f19cb61b6c..0f52280856cc 100644 --- a/test/msan/pthread_getattr_np_deadlock.cc +++ b/test/msan/pthread_getattr_np_deadlock.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -fsanitize-memory-track-origins -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && %run %t // Regression test for a deadlock in pthread_getattr_np diff --git a/test/msan/rand_r.cc b/test/msan/rand_r.cc index d6bdb1deaa68..f40cf9f9632a 100644 --- a/test/msan/rand_r.cc +++ b/test/msan/rand_r.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -g -DUNINIT %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g -DUNINIT %s -o %t && not %run %t 2>&1 | FileCheck %s #include <assert.h> #include <stdio.h> diff --git a/test/msan/readdir64.cc b/test/msan/readdir64.cc index 4f00d1838794..e77ada6ac8f2 100644 --- a/test/msan/readdir64.cc +++ b/test/msan/readdir64.cc @@ -1,12 +1,12 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O1 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O2 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O1 %s -o %t && %run %t +// RUN: %clangxx_msan -O2 %s -o %t && %run %t +// RUN: %clangxx_msan -O3 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O1 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O2 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t -// RUN: %clangxx_msan -m64 -O3 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t +// RUN: %clangxx_msan -O1 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t +// RUN: %clangxx_msan -O2 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t +// RUN: %clangxx_msan -O3 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t // Test that readdir64 is intercepted as well as readdir. diff --git a/test/msan/realloc-large-origin.cc b/test/msan/realloc-large-origin.cc index de39394cbb79..ce25ad8c47fd 100644 --- a/test/msan/realloc-large-origin.cc +++ b/test/msan/realloc-large-origin.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins=2 -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out // This is a regression test: there used to be broken "stored to memory at" diff --git a/test/msan/realloc-origin.cc b/test/msan/realloc-origin.cc index 6707cc9049a4..e6893713ea46 100644 --- a/test/msan/realloc-origin.cc +++ b/test/msan/realloc-origin.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out // This test relies on realloc from 100 to 101 being done in-place. diff --git a/test/msan/report-demangling.cc b/test/msan/report-demangling.cc index e6d5c27ec85d..fbb6554470f2 100644 --- a/test/msan/report-demangling.cc +++ b/test/msan/report-demangling.cc @@ -1,7 +1,7 @@ // Test that function name is mangled in the "created by an allocation" line, // and demangled in the single-frame "stack trace" that follows. -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out __attribute__((noinline)) @@ -15,5 +15,5 @@ int main(int argc, char **argv) { return f(); // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value // CHECK: Uninitialized value was created by an allocation of 'x' in the stack frame of function '_Z1fv' - // CHECK: #0 {{.*}} in f() {{.*}}report-demangling.cc:[[@LINE-10]] + // CHECK: #0 {{.*}} in f{{.*}} {{.*}}report-demangling.cc:[[@LINE-10]] } diff --git a/test/msan/scandir.cc b/test/msan/scandir.cc index 571ba4f603d2..8adfe006602a 100644 --- a/test/msan/scandir.cc +++ b/test/msan/scandir.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p #include <assert.h> #include <glob.h> diff --git a/test/msan/scandir_null.cc b/test/msan/scandir_null.cc index e7663dc43a74..94ac31a4143b 100644 --- a/test/msan/scandir_null.cc +++ b/test/msan/scandir_null.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t %p -// RUN: %clangxx_msan -m64 -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p -// RUN: %clangxx_msan -m64 -O3 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O0 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O0 -D_FILE_OFFSET_BITS=64 %s -o %t && %run %t %p +// RUN: %clangxx_msan -O3 %s -o %t && %run %t %p #include <assert.h> #include <glob.h> diff --git a/test/msan/select.cc b/test/msan/select.cc index 89de75ebaaef..7b8c34785c23 100644 --- a/test/msan/select.cc +++ b/test/msan/select.cc @@ -1,10 +1,10 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out #include <stdlib.h> diff --git a/test/msan/setlocale.cc b/test/msan/setlocale.cc index b7007f78da7c..796f4454e6aa 100644 --- a/test/msan/setlocale.cc +++ b/test/msan/setlocale.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t #include <assert.h> #include <locale.h> diff --git a/test/msan/stack-origin.cc b/test/msan/stack-origin.cc index c39c3a8cf6d0..e69c072242c5 100644 --- a/test/msan/stack-origin.cc +++ b/test/msan/stack-origin.cc @@ -1,19 +1,19 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out #include <stdlib.h> diff --git a/test/msan/stack-origin2.cc b/test/msan/stack-origin2.cc index 0ba57607dadb..6c7428c2dec8 100644 --- a/test/msan/stack-origin2.cc +++ b/test/msan/stack-origin2.cc @@ -1,21 +1,21 @@ // Test that on the second entry to a function the origins are still right. -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out #include <stdlib.h> diff --git a/test/msan/strlen_of_shadow.cc b/test/msan/strlen_of_shadow.cc index 8f1b4e1fc6bb..763b3a1c73c0 100644 --- a/test/msan/strlen_of_shadow.cc +++ b/test/msan/strlen_of_shadow.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t // Check that strlen() and similar intercepted functions can be called on shadow // memory. @@ -13,6 +13,10 @@ const char *mem_to_shadow(const char *p) { return (char *)((uintptr_t)p & ~0x400000000000ULL); #elif defined (__mips64) return (char *)((uintptr_t)p & ~0x4000000000ULL); +#elif defined(__powerpc64__) +#define LINEARIZE_MEM(mem) \ + (((uintptr_t)(mem) & ~0x200000000000ULL) ^ 0x100000000000ULL) + return (char *)(LINEARIZE_MEM(p) + 0x080000000000ULL); #endif } diff --git a/test/msan/strxfrm.cc b/test/msan/strxfrm.cc index b930a6af69c4..9a30d03c33ae 100644 --- a/test/msan/strxfrm.cc +++ b/test/msan/strxfrm.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t #include <assert.h> #include <sanitizer/msan_interface.h> diff --git a/test/msan/sync_lock_set_and_test.cc b/test/msan/sync_lock_set_and_test.cc index b6d344a61340..11fd14fae0f1 100644 --- a/test/msan/sync_lock_set_and_test.cc +++ b/test/msan/sync_lock_set_and_test.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t int main(void) { int i; diff --git a/test/msan/textdomain.cc b/test/msan/textdomain.cc index 47e991e8c16b..760debd68c33 100644 --- a/test/msan/textdomain.cc +++ b/test/msan/textdomain.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t #include <libintl.h> #include <stdio.h> diff --git a/test/msan/times.cc b/test/msan/times.cc index a042f548dc0c..7c81884118bc 100644 --- a/test/msan/times.cc +++ b/test/msan/times.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -O0 -g %s -o %t && %run %t #include <assert.h> #include <stdlib.h> diff --git a/test/msan/tls_reuse.cc b/test/msan/tls_reuse.cc index e024a5a8d13f..78a328fa3ce0 100644 --- a/test/msan/tls_reuse.cc +++ b/test/msan/tls_reuse.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t // Check that when TLS block is reused between threads, its shadow is cleaned. diff --git a/test/msan/tzset.cc b/test/msan/tzset.cc index ed61d7bcc449..05915e047e15 100644 --- a/test/msan/tzset.cc +++ b/test/msan/tzset.cc @@ -1,4 +1,4 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -O0 %s -o %t && %run %t #include <stdlib.h> #include <string.h> diff --git a/test/msan/unaligned_read_origin.cc b/test/msan/unaligned_read_origin.cc index e5618efbde24..b04800a139f2 100644 --- a/test/msan/unaligned_read_origin.cc +++ b/test/msan/unaligned_read_origin.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s < %t.out #include <sanitizer/msan_interface.h> diff --git a/test/msan/unpoison_string.cc b/test/msan/unpoison_string.cc index ac947b9cf6fd..84d952833539 100644 --- a/test/msan/unpoison_string.cc +++ b/test/msan/unpoison_string.cc @@ -1,6 +1,6 @@ -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t // RUN: %run %t -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t // RUN: %run %t #include <assert.h> diff --git a/test/msan/use-after-free.cc b/test/msan/use-after-free.cc index 869bad98e455..c505124479b0 100644 --- a/test/msan/use-after-free.cc +++ b/test/msan/use-after-free.cc @@ -1,19 +1,19 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O0 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O1 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O2 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out -// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %run %t >%t.out 2>&1 +// RUN: %clangxx_msan -fsanitize-memory-track-origins -O3 %s -o %t && not %run %t >%t.out 2>&1 // RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out #include <stdlib.h> diff --git a/test/msan/vector_cvt.cc b/test/msan/vector_cvt.cc index bd9b6a8b8000..633a8b15c444 100644 --- a/test/msan/vector_cvt.cc +++ b/test/msan/vector_cvt.cc @@ -1,5 +1,6 @@ -// RUN: %clangxx_msan -m64 -O0 %s -o %t && %run %t -// RUN: %clangxx_msan -DPOSITIVE -m64 -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clangxx_msan -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -DPOSITIVE -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// REQUIRES: x86_64-supported-target #include <emmintrin.h> diff --git a/test/msan/vector_select.cc b/test/msan/vector_select.cc index afeb1ad50c8b..0cf116497801 100644 --- a/test/msan/vector_select.cc +++ b/test/msan/vector_select.cc @@ -1,5 +1,5 @@ -// RUN: %clangxx_msan -m64 -O0 %s -c -o %t -// RUN: %clangxx_msan -m64 -O3 %s -c -o %t +// RUN: %clangxx_msan -O0 %s -c -o %t +// RUN: %clangxx_msan -O3 %s -c -o %t // Regression test for MemorySanitizer instrumentation of a select instruction // with vector arguments. @@ -11,7 +11,7 @@ __m128d select(bool b, __m128d c, __m128d d) { return b ? c : d; } -#elif defined (__mips64) +#elif defined (__mips64) || defined (__powerpc64__) typedef double __w64d __attribute__ ((vector_size(16))); __w64d select(bool b, __w64d c, __w64d d) diff --git a/test/profile/Inputs/gcc-flag-compatibility.c b/test/profile/Inputs/gcc-flag-compatibility.c new file mode 100644 index 000000000000..1c07bb1d0f30 --- /dev/null +++ b/test/profile/Inputs/gcc-flag-compatibility.c @@ -0,0 +1,8 @@ +int X = 0; + +int main() { + int i; + for (i = 0; i < 100; i++) + X += i; + return 0; +} diff --git a/test/profile/Inputs/instrprof-dynamic-a.cpp b/test/profile/Inputs/instrprof-dynamic-a.cpp index 67de263c4d88..2ec484a5b381 100644 --- a/test/profile/Inputs/instrprof-dynamic-a.cpp +++ b/test/profile/Inputs/instrprof-dynamic-a.cpp @@ -1,7 +1,7 @@ #include "instrprof-dynamic-header.h" void a() { if (true) { - bar<void>(); - bar<char>(); + bar<void>(1); + bar<char>(1); } } diff --git a/test/profile/Inputs/instrprof-dynamic-b.cpp b/test/profile/Inputs/instrprof-dynamic-b.cpp index c8fb75ef52ed..5c2d9bae8dba 100644 --- a/test/profile/Inputs/instrprof-dynamic-b.cpp +++ b/test/profile/Inputs/instrprof-dynamic-b.cpp @@ -1,7 +1,7 @@ #include "instrprof-dynamic-header.h" void b() { if (true) { - bar<void>(); - bar<int>(); + bar<void>(1); + bar<int>(1); } } diff --git a/test/profile/Inputs/instrprof-dynamic-header.h b/test/profile/Inputs/instrprof-dynamic-header.h index 1dc2e37ef82c..7a57b13c67f9 100644 --- a/test/profile/Inputs/instrprof-dynamic-header.h +++ b/test/profile/Inputs/instrprof-dynamic-header.h @@ -1,5 +1,7 @@ -template <class T> void bar() { - if (true) {} +template <class T> void bar(int X) { + if (X) { + X *= 4; + } } void a(); void b(); diff --git a/test/profile/Inputs/instrprof-dynamic-main.cpp b/test/profile/Inputs/instrprof-dynamic-main.cpp index 0dd60213926e..2cf37c8b6d5e 100644 --- a/test/profile/Inputs/instrprof-dynamic-main.cpp +++ b/test/profile/Inputs/instrprof-dynamic-main.cpp @@ -2,7 +2,7 @@ void foo(int K) { if (K) {} } int main(int argc, char *argv[]) { foo(5); - bar<void>(); + bar<void>(1); a(); b(); return 0; diff --git a/test/profile/gcc-flag-compatibility.test b/test/profile/gcc-flag-compatibility.test new file mode 100644 index 000000000000..8e8b55dafe23 --- /dev/null +++ b/test/profile/gcc-flag-compatibility.test @@ -0,0 +1,17 @@ +RUN: mkdir -p %t.d +RUN: %clang_profgen_gcc=%t.d/d1/d2 -o %t.d/code %S/Inputs/gcc-flag-compatibility.c + +# Test that the instrumented code writes to %t.d/d1/d2/default.profraw +RUN: %run %t.d/code +RUN: llvm-profdata merge -o %t.profdata %t.d/d1/d2/default.profraw + +# Test that we can override the directory and file name with LLVM_PROFILE_FILE. +RUN: env LLVM_PROFILE_FILE=%t.d/x1/prof.raw %run %t.d/code +RUN: llvm-profdata merge -o %t.profdata %t.d/x1/prof.raw + +# Test that we can specify a directory with -fprofile-use. +RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/x1/prof.raw +RUN: %clang_profuse_gcc=%t.d -o %t.d/code %S/Inputs/gcc-flag-compatibility.c + +# Test that we can specify a file with -fprofile-use. +RUN: %clang_profuse_gcc=%t.profdata -o %t.d/code %S/Inputs/gcc-flag-compatibility.c diff --git a/test/profile/instrprof-override-filename-then-reset-default.c b/test/profile/instrprof-override-filename-then-reset-default.c new file mode 100644 index 000000000000..137a3b2f2291 --- /dev/null +++ b/test/profile/instrprof-override-filename-then-reset-default.c @@ -0,0 +1,19 @@ +// RUN: rm -rf %t.d +// RUN: mkdir -p %t.d +// RUN: cd %t.d +// RUN: %clang_profgen -O3 %s -o %t.out +// RUN: %run %t.out %t.d/bad.profraw +// RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/default.profraw +// RUN: %clang_profuse=%t.d/default.profdata -o - -S -emit-llvm %s | FileCheck %s + + +void __llvm_profile_override_default_filename(const char *); +int main(int argc, const char *argv[]) { + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + if (argc < 2) + return 1; + __llvm_profile_override_default_filename(argv[1]); + __llvm_profile_override_default_filename(0); + return 0; +} +// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2} diff --git a/test/profile/instrprof-override-filename-with-env.c b/test/profile/instrprof-override-filename-with-env.c new file mode 100644 index 000000000000..cce83891663a --- /dev/null +++ b/test/profile/instrprof-override-filename-with-env.c @@ -0,0 +1,14 @@ +// RUN: %clang_profgen -o %t -O3 %s +// RUN: env LLVM_PROFILE_FILE=%t.good.profraw %run %t %t.bad.profraw +// RUN: llvm-profdata merge -o %t.profdata %t.good.profraw +// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s + +void __llvm_profile_override_default_filename(const char *); +int main(int argc, const char *argv[]) { + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + if (argc < 2) + return 1; + __llvm_profile_override_default_filename(argv[1]); + return 0; +} +// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2} diff --git a/test/profile/instrprof-override-filename.c b/test/profile/instrprof-override-filename.c new file mode 100644 index 000000000000..59dea29e3b88 --- /dev/null +++ b/test/profile/instrprof-override-filename.c @@ -0,0 +1,14 @@ +// RUN: %clang_profgen -o %t -O3 %s +// RUN: %run %t %t.profraw +// RUN: llvm-profdata merge -o %t.profdata %t.profraw +// RUN: %clang_profuse=%t.profdata -o - -S -emit-llvm %s | FileCheck %s + +void __llvm_profile_override_default_filename(const char *); +int main(int argc, const char *argv[]) { + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + if (argc < 2) + return 1; + __llvm_profile_override_default_filename(argv[1]); + return 0; +} +// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2} diff --git a/test/profile/instrprof-set-filename-then-reset-default.c b/test/profile/instrprof-set-filename-then-reset-default.c new file mode 100644 index 000000000000..6c07994f08c6 --- /dev/null +++ b/test/profile/instrprof-set-filename-then-reset-default.c @@ -0,0 +1,18 @@ +// RUN: rm -rf %t.d +// RUN: mkdir -p %t.d +// RUN: cd %t.d +// RUN: %clang_profgen -O3 %s -o %t.out +// RUN: %run %t.out %t.d/bad.profraw +// RUN: llvm-profdata merge -o %t.d/default.profdata %t.d/default.profraw +// RUN: %clang_profuse=%t.d/default.profdata -o - -S -emit-llvm %s | FileCheck %s + +void __llvm_profile_set_filename(const char *); +int main(int argc, const char *argv[]) { + // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}}, !prof ![[PD1:[0-9]+]] + if (argc < 2) + return 1; + __llvm_profile_set_filename(argv[1]); + __llvm_profile_set_filename(0); + return 0; +} +// CHECK: ![[PD1]] = !{!"branch_weights", i32 1, i32 2} diff --git a/test/profile/lit.cfg b/test/profile/lit.cfg index e4910abbe7a4..b1b44a1a0665 100644 --- a/test/profile/lit.cfg +++ b/test/profile/lit.cfg @@ -45,6 +45,8 @@ def build_invocation(compile_flags): config.substitutions.append( ("%clang ", build_invocation(clang_cflags)) ) config.substitutions.append( ("%clang_profgen ", build_invocation(clang_cflags) + " -fprofile-instr-generate ") ) config.substitutions.append( ("%clang_profuse=", build_invocation(clang_cflags) + " -fprofile-instr-use=") ) +config.substitutions.append( ("%clang_profgen_gcc=", build_invocation(clang_cflags) + " -fprofile-generate=") ) +config.substitutions.append( ("%clang_profuse_gcc=", build_invocation(clang_cflags) + " -fprofile-use=") ) if config.host_os not in ['Darwin', 'FreeBSD', 'Linux']: config.unsupported = True diff --git a/test/safestack/CMakeLists.txt b/test/safestack/CMakeLists.txt new file mode 100644 index 000000000000..6f5c2f9b0af4 --- /dev/null +++ b/test/safestack/CMakeLists.txt @@ -0,0 +1,29 @@ +set(SAFESTACK_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(SAFESTACK_LIT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) + +set(SAFESTACK_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) +if(NOT COMPILER_RT_STANDALONE_BUILD) + list(APPEND SAFESTACK_TEST_DEPS safestack) + + # Some tests require LTO, so add a dependency on the relevant LTO plugin. + if(LLVM_ENABLE_PIC AND LLVM_BINUTILS_INCDIR) + list(APPEND SAFESTACK_TEST_DEPS + LLVMgold + ) + endif() + if(APPLE) + list(APPEND SAFESTACK_TEST_DEPS + LTO + ) + endif() +endif() + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ) + +add_lit_testsuite(check-safestack "Running the SafeStack tests" + ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${SAFESTACK_TEST_DEPS}) +set_target_properties(check-safestack PROPERTIES FOLDER "SafeStack tests") diff --git a/test/safestack/buffer-copy-vla.c b/test/safestack/buffer-copy-vla.c new file mode 100644 index 000000000000..356a1ac5c65c --- /dev/null +++ b/test/safestack/buffer-copy-vla.c @@ -0,0 +1,26 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +#include "utils.h" + +// Test that loads/stores work correctly for VLAs on the unsafe stack. + +int main(int argc, char **argv) +{ + int i = 128; + break_optimization(&i); + char buffer[i]; + + // check that we can write to a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + buffer[i] = argv[0][i]; + buffer[i] = '\0'; + + break_optimization(buffer); + + // check that we can read from a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + if (buffer[i] != argv[0][i]) + return 1; + return 0; +} diff --git a/test/safestack/buffer-copy.c b/test/safestack/buffer-copy.c new file mode 100644 index 000000000000..96b2302be1b1 --- /dev/null +++ b/test/safestack/buffer-copy.c @@ -0,0 +1,25 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +#include "utils.h" + +// Test that loads/stores work correctly for variables on the unsafe stack. + +int main(int argc, char **argv) +{ + int i; + char buffer[128]; + + // check that we can write to a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + buffer[i] = argv[0][i]; + buffer[i] = '\0'; + + break_optimization(buffer); + + // check that we can read from a buffer + for (i = 0; argv[0][i] && i < sizeof (buffer) - 1; ++i) + if (buffer[i] != argv[0][i]) + return 1; + return 0; +} diff --git a/test/safestack/init.c b/test/safestack/init.c new file mode 100644 index 000000000000..cff75f5f8939 --- /dev/null +++ b/test/safestack/init.c @@ -0,0 +1,9 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +// Basic smoke test for the runtime library. + +int main(int argc, char **argv) +{ + return 0; +} diff --git a/test/safestack/lit.cfg b/test/safestack/lit.cfg new file mode 100644 index 000000000000..13fc92fa4b2b --- /dev/null +++ b/test/safestack/lit.cfg @@ -0,0 +1,24 @@ +# -*- Python -*- + +import os + +# Setup config name. +config.name = 'SafeStack' + +# Setup source root. +config.test_source_root = os.path.dirname(__file__) + +# Test suffixes. +config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm', '.ll', '.test'] + +# Add clang substitutions. +config.substitutions.append( ("%clang_nosafestack ", config.clang + " -O0 -fno-sanitize=safe-stack ") ) +config.substitutions.append( ("%clang_safestack ", config.clang + " -O0 -fsanitize=safe-stack ") ) + +if config.lto_supported: + config.available_features.add('lto') + config.substitutions.append((r"%clang_lto_safestack ", ' '.join(config.lto_launch + [config.clang] + config.lto_flags + ['-flto -fsanitize=safe-stack ']))) + +# SafeStack tests are currently supported on Linux, FreeBSD and Darwin only. +if config.host_os not in ['Linux', 'FreeBSD', 'Darwin']: + config.unsupported = True diff --git a/test/safestack/lit.site.cfg.in b/test/safestack/lit.site.cfg.in new file mode 100644 index 000000000000..cb1e7292e5f2 --- /dev/null +++ b/test/safestack/lit.site.cfg.in @@ -0,0 +1,8 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! + +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") + +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@SAFESTACK_LIT_SOURCE_DIR@/lit.cfg") diff --git a/test/safestack/lto.c b/test/safestack/lto.c new file mode 100644 index 000000000000..6ee23a1c72f2 --- /dev/null +++ b/test/safestack/lto.c @@ -0,0 +1,12 @@ +// REQUIRES: lto + +// RUN: %clang_lto_safestack %s -o %t +// RUN: %run %t + +// Test that safe stack works with LTO. + +int main() { + char c[] = "hello world"; + puts(c); + return 0; +} diff --git a/test/safestack/overflow.c b/test/safestack/overflow.c new file mode 100644 index 000000000000..14e29823cd99 --- /dev/null +++ b/test/safestack/overflow.c @@ -0,0 +1,23 @@ +// RUN: %clang_safestack %s -o %t +// RUN: %run %t + +// RUN: %clang_nosafestack -fno-stack-protector %s -o %t +// RUN: not %run %t + +// Test that buffer overflows on the unsafe stack do not affect variables on the +// safe stack. + +__attribute__((noinline)) +void fct(volatile int *buffer) +{ + memset(buffer - 1, 0, 7 * sizeof(int)); +} + +int main(int argc, char **argv) +{ + int value1 = 42; + int buffer[5]; + int value2 = 42; + fct(buffer); + return value1 != 42 || value2 != 42; +} diff --git a/test/safestack/pthread-cleanup.c b/test/safestack/pthread-cleanup.c new file mode 100644 index 000000000000..805366c9f1eb --- /dev/null +++ b/test/safestack/pthread-cleanup.c @@ -0,0 +1,31 @@ +// RUN: %clang_safestack %s -pthread -o %t +// RUN: not --crash %run %t + +// Test that unsafe stacks are deallocated correctly on thread exit. + +#include <stdlib.h> +#include <string.h> +#include <pthread.h> + +enum { kBufferSize = (1 << 15) }; + +void *t1_start(void *ptr) +{ + char buffer[kBufferSize]; + return buffer; +} + +int main(int argc, char **argv) +{ + pthread_t t1; + char *buffer = NULL; + + if (pthread_create(&t1, NULL, t1_start, NULL)) + abort(); + if (pthread_join(t1, &buffer)) + abort(); + + // should segfault here + memset(buffer, 0, kBufferSize); + return 0; +} diff --git a/test/safestack/pthread.c b/test/safestack/pthread.c new file mode 100644 index 000000000000..416586ee13e7 --- /dev/null +++ b/test/safestack/pthread.c @@ -0,0 +1,42 @@ +// RUN: %clang_safestack %s -pthread -o %t +// RUN: %run %t + +// XFAIL: darwin + +// Test that pthreads receive their own unsafe stack. + +#include <stdlib.h> +#include <string.h> +#include <pthread.h> +#include "utils.h" + +static int ptr_test = 42; + +void *t1_start(void *ptr) +{ + if (ptr != &ptr_test) + abort(); + + // safe stack + int val = ptr_test * 5; + + // unsafe stack + char buffer[8096]; // two pages + memset(buffer, val, sizeof (buffer)); + break_optimization(buffer); + + return ptr; +} + +int main(int argc, char **argv) +{ + pthread_t t1; + void *ptr = NULL; + if (pthread_create(&t1, NULL, t1_start, &ptr_test)) + abort(); + if (pthread_join(t1, &ptr)) + abort(); + if (ptr != &ptr_test) + abort(); + return 0; +} diff --git a/test/safestack/utils.h b/test/safestack/utils.h new file mode 100644 index 000000000000..b04e3bdc127e --- /dev/null +++ b/test/safestack/utils.h @@ -0,0 +1,8 @@ +#ifndef UTILS_H +#define UTILS_H + +static inline void break_optimization(void *arg) { + __asm__ __volatile__("" : : "r" (arg) : "memory"); +} + +#endif diff --git a/test/sanitizer_common/CMakeLists.txt b/test/sanitizer_common/CMakeLists.txt index 13eecbdc1b2b..7eca7f7672d0 100644 --- a/test/sanitizer_common/CMakeLists.txt +++ b/test/sanitizer_common/CMakeLists.txt @@ -16,16 +16,27 @@ endif() # Create a separate config for each tool we support. foreach(tool ${SUPPORTE |