aboutsummaryrefslogtreecommitdiff
path: root/test/asan
diff options
context:
space:
mode:
Diffstat (limited to 'test/asan')
-rw-r--r--test/asan/CMakeLists.txt18
-rw-r--r--test/asan/TestCases/Android/coverage-android.cc4
-rw-r--r--test/asan/TestCases/Darwin/abort_on_error.cc2
-rw-r--r--test/asan/TestCases/Darwin/address-range-limit.mm4
-rw-r--r--test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc2
-rw-r--r--test/asan/TestCases/Darwin/atos-symbolizer.cc2
-rw-r--r--test/asan/TestCases/Darwin/dead-strip.c22
-rw-r--r--test/asan/TestCases/Darwin/dladdr-demangling.cc4
-rw-r--r--test/asan/TestCases/Darwin/malloc_size_crash.mm15
-rw-r--r--test/asan/TestCases/Darwin/objc-odr.mm2
-rw-r--r--test/asan/TestCases/Darwin/segv_read_write.c26
-rw-r--r--test/asan/TestCases/Darwin/suppressions-darwin.cc1
-rw-r--r--test/asan/TestCases/Linux/abort_on_error.cc2
-rw-r--r--test/asan/TestCases/Linux/asan-asm-stacktrace-test.cc2
-rw-r--r--test/asan/TestCases/Linux/asan_prelink_test.cc2
-rw-r--r--test/asan/TestCases/Linux/clang_gcc_abi.cc2
-rw-r--r--test/asan/TestCases/Linux/clone_test.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage-missing.cc2
-rw-r--r--test/asan/TestCases/Linux/coverage_html_report.cc24
-rw-r--r--test/asan/TestCases/Linux/interface_symbols_linux.c2
-rw-r--r--test/asan/TestCases/Linux/kernel-area.cc2
-rw-r--r--test/asan/TestCases/Linux/leak_check_segv.cc6
-rw-r--r--test/asan/TestCases/Linux/local_alias.cc40
-rw-r--r--test/asan/TestCases/Linux/malloc-in-qsort.cc2
-rw-r--r--test/asan/TestCases/Linux/memmem_test.cc21
-rw-r--r--test/asan/TestCases/Linux/new_delete_mismatch.cc16
-rw-r--r--test/asan/TestCases/Linux/nohugepage_test.cc2
-rw-r--r--test/asan/TestCases/Linux/odr-violation.cc8
-rw-r--r--test/asan/TestCases/Linux/odr_c_test.c28
-rw-r--r--test/asan/TestCases/Linux/overflow-in-qsort.cc2
-rw-r--r--test/asan/TestCases/Linux/print_memory_profile_test.cc29
-rw-r--r--test/asan/TestCases/Linux/ptrace.cc7
-rw-r--r--test/asan/TestCases/Linux/recvfrom.cc81
-rw-r--r--test/asan/TestCases/Linux/scariness_score_test.cc192
-rw-r--r--test/asan/TestCases/Linux/segv_read_write.c26
-rw-r--r--test/asan/TestCases/Linux/stack-overflow-recovery-mode.cc36
-rw-r--r--test/asan/TestCases/Linux/static_tls.cc2
-rw-r--r--test/asan/TestCases/Linux/swapcontext_annotation.cc178
-rw-r--r--test/asan/TestCases/Linux/swapcontext_test.cc2
-rw-r--r--test/asan/TestCases/Linux/unpoison_tls.cc2
-rw-r--r--test/asan/TestCases/Posix/closed-fds.cc2
-rw-r--r--test/asan/TestCases/Posix/coverage-sandboxing.cc4
-rw-r--r--test/asan/TestCases/Posix/dlclose-test.cc4
-rw-r--r--test/asan/TestCases/Posix/dump_instruction_bytes.cc (renamed from test/asan/TestCases/dump_instruction_bytes.cc)2
-rw-r--r--test/asan/TestCases/Posix/global-registration.c69
-rw-r--r--test/asan/TestCases/Posix/halt_on_error-torture.cc8
-rw-r--r--test/asan/TestCases/Posix/mmap_limit_mb.cc (renamed from test/asan/TestCases/mmap_limit_mb.cc)0
-rw-r--r--test/asan/TestCases/Posix/print_cmdline.cc18
-rw-r--r--test/asan/TestCases/Posix/start-deactivated.cc2
-rw-r--r--test/asan/TestCases/Windows/bind_io_completion_callback.cc8
-rw-r--r--test/asan/TestCases/Windows/coverage-basic.cc4
-rw-r--r--test/asan/TestCases/Windows/crash_read_write.cc29
-rw-r--r--test/asan/TestCases/Windows/dll_seh.cc14
-rw-r--r--test/asan/TestCases/Windows/intercept_strdup.cc12
-rw-r--r--test/asan/TestCases/Windows/oom.cc1
-rw-r--r--test/asan/TestCases/Windows/queue_user_work_item.cc13
-rw-r--r--test/asan/TestCases/Windows/queue_user_work_item_report.cc2
-rw-r--r--test/asan/TestCases/Windows/report_after_syminitialize.cc4
-rw-r--r--test/asan/TestCases/Windows/throw_catch.cc73
-rw-r--r--test/asan/TestCases/alloca_constant_size.cc51
-rw-r--r--test/asan/TestCases/asan_and_llvm_coverage_test.cc4
-rw-r--r--test/asan/TestCases/contiguous_container_crash.cc1
-rw-r--r--test/asan/TestCases/coverage-levels.cc10
-rw-r--r--test/asan/TestCases/coverage-pc-buffer.cc69
-rw-r--r--test/asan/TestCases/coverage-reset.cc7
-rw-r--r--test/asan/TestCases/coverage-trace-pc.cc31
-rw-r--r--test/asan/TestCases/debug_ppc64_mapping.cc2
-rw-r--r--test/asan/TestCases/double-free.cc6
-rw-r--r--test/asan/TestCases/initialization-bug.cc3
-rw-r--r--test/asan/TestCases/invalid-pointer-pairs.cc44
-rw-r--r--test/asan/TestCases/large_func_test.cc2
-rw-r--r--test/asan/TestCases/printf-2.c10
-rw-r--r--test/asan/TestCases/printf-4.c14
-rw-r--r--test/asan/TestCases/stack-oob-frames.cc3
-rw-r--r--test/asan/TestCases/strcasestr-2.c2
-rw-r--r--test/asan/TestCases/strdup_oob_test.cc9
-rw-r--r--test/asan/TestCases/strstr-2.c2
-rw-r--r--test/asan/TestCases/throw_call_test.cc3
-rw-r--r--test/asan/TestCases/throw_invoke_test.cc5
-rw-r--r--test/asan/TestCases/uar_and_exceptions.cc3
-rw-r--r--test/asan/TestCases/use-after-scope-capture.cc17
-rw-r--r--test/asan/TestCases/use-after-scope-chars.cc15
-rw-r--r--test/asan/TestCases/use-after-scope-dtor-order.cc6
-rw-r--r--test/asan/TestCases/use-after-scope-if.cc15
-rw-r--r--test/asan/TestCases/use-after-scope-inlined.cc4
-rw-r--r--test/asan/TestCases/use-after-scope-loop-bug.cc16
-rw-r--r--test/asan/TestCases/use-after-scope-loop-removed.cc19
-rw-r--r--test/asan/TestCases/use-after-scope-loop.cc14
-rw-r--r--test/asan/TestCases/use-after-scope-nobug.cc11
-rw-r--r--test/asan/TestCases/use-after-scope-temp.cc18
-rw-r--r--test/asan/TestCases/use-after-scope.cc9
-rw-r--r--test/asan/Unit/lit.site.cfg.in3
-rw-r--r--test/asan/android_commands/android_common.py27
-rw-r--r--test/asan/lit.cfg4
-rw-r--r--test/asan/lit.site.cfg.in4
95 files changed, 1306 insertions, 248 deletions
diff --git a/test/asan/CMakeLists.txt b/test/asan/CMakeLists.txt
index b2be9572002f..cb32cfba83b0 100644
--- a/test/asan/CMakeLists.txt
+++ b/test/asan/CMakeLists.txt
@@ -3,10 +3,16 @@ set(ASAN_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(ASAN_TESTSUITES)
set(ASAN_DYNAMIC_TESTSUITES)
+# TODO(wwchrome): Re-enable Win64 asan tests when ready.
+# Disable tests for asan Win64 temporarily.
+if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(EXCLUDE_FROM_ALL TRUE)
+endif()
+
macro(get_bits_for_arch arch bits)
if (${arch} MATCHES "i386|i686|arm|mips|mipsel")
set(${bits} 32)
- elseif (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|mips64|mips64el")
+ elseif (${arch} MATCHES "x86_64|powerpc64|powerpc64le|aarch64|mips64|mips64el|s390x")
set(${bits} 64)
else()
message(FATAL_ERROR "Unknown target architecture: ${arch}")
@@ -97,11 +103,12 @@ endif()
add_lit_testsuite(check-asan "Running the AddressSanitizer tests"
${ASAN_TESTSUITES}
DEPENDS ${ASAN_TEST_DEPS})
-set_target_properties(check-asan PROPERTIES FOLDER "ASan tests")
+set_target_properties(check-asan PROPERTIES FOLDER "Compiler-RT Misc")
if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
# Add check-dynamic-asan target. It is a part of check-all only on Windows,
# where we want to always test both dynamic and static runtime.
+
if(NOT OS_NAME MATCHES "Windows")
set(EXCLUDE_FROM_ALL TRUE)
endif()
@@ -110,8 +117,13 @@ if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
${ASAN_DYNAMIC_TESTSUITES}
DEPENDS ${ASAN_DYNAMIC_TEST_DEPS})
set_target_properties(check-asan-dynamic
- PROPERTIES FOLDER "ASan dynamic tests")
+ PROPERTIES FOLDER "Compiler-RT Misc")
if(NOT OS_NAME MATCHES "Windows")
set(EXCLUDE_FROM_ALL FALSE)
endif()
endif()
+
+# TODO(wwchrome): Re-enable the tests for asan Win64 when ready.
+if(OS_NAME MATCHES "Windows" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(EXCLUDE_FROM_ALL FALSE)
+endif()
diff --git a/test/asan/TestCases/Android/coverage-android.cc b/test/asan/TestCases/Android/coverage-android.cc
index 16a6e1f7e160..2a3359948691 100644
--- a/test/asan/TestCases/Android/coverage-android.cc
+++ b/test/asan/TestCases/Android/coverage-android.cc
@@ -139,5 +139,5 @@ int main(int argc, char **argv) {
#endif
// CHECK1: 2 PCs total
-// CHECK2: 7 PCs total
-// CHECK3: 8 PCs total
+// CHECK2: 4 PCs total
+// CHECK3: 5 PCs total
diff --git a/test/asan/TestCases/Darwin/abort_on_error.cc b/test/asan/TestCases/Darwin/abort_on_error.cc
index f09718bda06e..295afb8442a4 100644
--- a/test/asan/TestCases/Darwin/abort_on_error.cc
+++ b/test/asan/TestCases/Darwin/abort_on_error.cc
@@ -4,7 +4,7 @@
// RUN: %clangxx_asan %s -o %t
// Intentionally don't inherit the default ASAN_OPTIONS.
-// RUN: ASAN_OPTIONS="" not --crash %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS="" not --crash %run %t 2>&1 | FileCheck %s
// When we use lit's default ASAN_OPTIONS, we shouldn't crash.
// RUN: not %run %t 2>&1 | FileCheck %s
diff --git a/test/asan/TestCases/Darwin/address-range-limit.mm b/test/asan/TestCases/Darwin/address-range-limit.mm
index a6906766d7ee..ba9175a2ce20 100644
--- a/test/asan/TestCases/Darwin/address-range-limit.mm
+++ b/test/asan/TestCases/Darwin/address-range-limit.mm
@@ -1,7 +1,7 @@
// Regression test for https://code.google.com/p/address-sanitizer/issues/detail?id=368.
-// RUN: %clang_asan %s -Wno-deprecated-declarations -flat_namespace -bundle -undefined suppress -o %t.bundle
-// RUN: %clang_asan %s -Wno-deprecated-declarations -o %t -framework Foundation && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan %s -Wno-deprecated-declarations -flat_namespace -bundle -undefined suppress -o %t.bundle
+// RUN: %clangxx_asan %s -Wno-deprecated-declarations -o %t -framework Foundation && not %run %t 2>&1 | FileCheck %s
#import <Foundation/Foundation.h>
#import <mach-o/dyld.h>
diff --git a/test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc b/test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc
index 4595fb547f57..d2facd6d0c2e 100644
--- a/test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc
+++ b/test/asan/TestCases/Darwin/atos-symbolizer-dyld-root-path.cc
@@ -14,8 +14,8 @@ int main(int argc, char **argv) {
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: AddressSanitizer: attempting double-free{{.*}}in thread T0
// CHECK: #0 0x{{.*}} in {{.*}}free
// CHECK: #1 0x{{.*}} in main {{.*}}atos-symbolizer-dyld-root-path.cc:[[@LINE-4]]
// CHECK: freed by thread T0 here:
diff --git a/test/asan/TestCases/Darwin/atos-symbolizer.cc b/test/asan/TestCases/Darwin/atos-symbolizer.cc
index 2a9ffbc5b25c..b4a868e242ea 100644
--- a/test/asan/TestCases/Darwin/atos-symbolizer.cc
+++ b/test/asan/TestCases/Darwin/atos-symbolizer.cc
@@ -11,8 +11,8 @@ int main(int argc, char **argv) {
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: AddressSanitizer: attempting double-free{{.*}}in thread T0
// CHECK: #0 0x{{.*}} in {{.*}}free
// CHECK: #1 0x{{.*}} in main {{.*}}atos-symbolizer.cc:[[@LINE-4]]
// CHECK: freed by thread T0 here:
diff --git a/test/asan/TestCases/Darwin/dead-strip.c b/test/asan/TestCases/Darwin/dead-strip.c
new file mode 100644
index 000000000000..212dedd469c1
--- /dev/null
+++ b/test/asan/TestCases/Darwin/dead-strip.c
@@ -0,0 +1,22 @@
+// Test that AddressSanitizer does not re-animate dead globals when dead
+// stripping is turned on.
+//
+// This test verifies that an out-of-bounds access on a global variable is
+// detected after dead stripping has been performed. This proves that the
+// runtime is able to register globals in the __DATA,__asan_globals section.
+
+// REQUIRES: osx-ld64-live_support
+// RUN: %clang_asan -mllvm -asan-globals-live-support -Xlinker -dead_strip -o %t %s
+// RUN: llvm-nm -format=posix %t | FileCheck --check-prefix NM-CHECK %s
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix ASAN-CHECK %s
+
+int alive[1] = {};
+int dead[1] = {};
+// NM-CHECK: {{^_alive }}
+// NM-CHECK-NOT: {{^_dead }}
+
+int main(int argc, char *argv[]) {
+ alive[argc] = 0;
+ // ASAN-CHECK: {{0x.* is located 0 bytes to the right of global variable}}
+ return 0;
+}
diff --git a/test/asan/TestCases/Darwin/dladdr-demangling.cc b/test/asan/TestCases/Darwin/dladdr-demangling.cc
index d773659b74f8..6f52b93da04b 100644
--- a/test/asan/TestCases/Darwin/dladdr-demangling.cc
+++ b/test/asan/TestCases/Darwin/dladdr-demangling.cc
@@ -13,10 +13,10 @@ class MyClass {
char *x = (char*)malloc(n * sizeof(char));
free(x);
return x[5];
+ // CHECK-DLADDR: Using dladdr symbolizer
// 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-DLADDR: failed to fork
// CHECK: {{ #0 0x.* in MyClass::my_function\(int\)}}
// CHECK: {{freed by thread T0 here:}}
// CHECK: {{ #0 0x.* in wrap_free}}
diff --git a/test/asan/TestCases/Darwin/malloc_size_crash.mm b/test/asan/TestCases/Darwin/malloc_size_crash.mm
new file mode 100644
index 000000000000..04cb7637635c
--- /dev/null
+++ b/test/asan/TestCases/Darwin/malloc_size_crash.mm
@@ -0,0 +1,15 @@
+// RUN: %clang_asan %s -o %t -framework Foundation
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+#include <malloc/malloc.h>
+
+int main(int argc, char *argv[]) {
+ id obj = @0;
+ fprintf(stderr, "obj = %p\n", obj);
+ size_t size = malloc_size(obj);
+ fprintf(stderr, "size = 0x%zx\n", size);
+ fprintf(stderr, "Done.\n");
+ // CHECK: Done.
+ return 0;
+}
diff --git a/test/asan/TestCases/Darwin/objc-odr.mm b/test/asan/TestCases/Darwin/objc-odr.mm
index 72bc39c80dd4..c4c240ee419c 100644
--- a/test/asan/TestCases/Darwin/objc-odr.mm
+++ b/test/asan/TestCases/Darwin/objc-odr.mm
@@ -16,7 +16,7 @@ void f() {
}
int main() {
- NSLog(@"Hello world");
+ fprintf(stderr,"Hello world");
}
// CHECK-NOT: AddressSanitizer: odr-violation
diff --git a/test/asan/TestCases/Darwin/segv_read_write.c b/test/asan/TestCases/Darwin/segv_read_write.c
new file mode 100644
index 000000000000..d8e2d215f832
--- /dev/null
+++ b/test/asan/TestCases/Darwin/segv_read_write.c
@@ -0,0 +1,26 @@
+// RUN: %clangxx_asan -std=c++11 -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ
+// RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE
+// REQUIRES: x86-target-arch
+
+#include <sys/mman.h>
+
+static volatile int sink;
+__attribute__((noinline)) void Read(int *ptr) { sink = *ptr; }
+__attribute__((noinline)) void Write(int *ptr) { *ptr = 0; }
+int main(int argc, char **argv) {
+ // Writes to shadow are detected as reads from shadow gap (because of how the
+ // shadow mapping works). This is kinda hard to fix. Test a random address in
+ // the application part of the address space.
+ void *volatile p =
+ mmap(nullptr, 4096, PROT_READ, MAP_PRIVATE | MAP_ANON, 0, 0);
+ munmap(p, 4096);
+ if (argc == 1)
+ Read((int *)p);
+ else
+ Write((int *)p);
+}
+// READ: AddressSanitizer: SEGV on unknown address
+// READ: The signal is caused by a READ memory access.
+// WRITE: AddressSanitizer: SEGV on unknown address
+// WRITE: The signal is caused by a WRITE memory access.
diff --git a/test/asan/TestCases/Darwin/suppressions-darwin.cc b/test/asan/TestCases/Darwin/suppressions-darwin.cc
index 403d819706a9..a177c4e17ec4 100644
--- a/test/asan/TestCases/Darwin/suppressions-darwin.cc
+++ b/test/asan/TestCases/Darwin/suppressions-darwin.cc
@@ -4,6 +4,7 @@
// Check that suppressing the interceptor by name works.
// RUN: echo "interceptor_name:memmove" > %t.supp
+// RUN: echo "interceptor_name:memcpy" >> %t.supp
// RUN: %env_asan_opts=suppressions='"%t.supp"' %run %t 2>&1 | FileCheck --check-prefix=CHECK-IGNORE %s
// Check that suppressing by interceptor name works even without the symbolizer
diff --git a/test/asan/TestCases/Linux/abort_on_error.cc b/test/asan/TestCases/Linux/abort_on_error.cc
index 406d98b6764a..67fa9b83e65d 100644
--- a/test/asan/TestCases/Linux/abort_on_error.cc
+++ b/test/asan/TestCases/Linux/abort_on_error.cc
@@ -4,7 +4,7 @@
// RUN: %clangxx_asan %s -o %t
// Intentionally don't inherit the default ASAN_OPTIONS.
-// RUN: ASAN_OPTIONS="" not %run %t 2>&1 | FileCheck %s
+// RUN: env ASAN_OPTIONS="" not %run %t 2>&1 | FileCheck %s
// When we use lit's default ASAN_OPTIONS, we shouldn't crash either. On Linux
// lit doesn't set ASAN_OPTIONS anyway.
// RUN: not %run %t 2>&1 | FileCheck %s
diff --git a/test/asan/TestCases/Linux/asan-asm-stacktrace-test.cc b/test/asan/TestCases/Linux/asan-asm-stacktrace-test.cc
index 5332c992a0db..cbc900decea3 100644
--- a/test/asan/TestCases/Linux/asan-asm-stacktrace-test.cc
+++ b/test/asan/TestCases/Linux/asan-asm-stacktrace-test.cc
@@ -1,7 +1,7 @@
// Check that a stack unwinding algorithm works corretly even with the assembly
// instrumentation.
-// REQUIRES: x86_64-supported-target
+// REQUIRES: x86_64-target-arch
// RUN: %clangxx_asan -g -O1 %s -fno-inline-functions -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -mllvm -asan-instrument-assembly -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -g -O1 %s -fno-inline-functions -fomit-frame-pointer -momit-leaf-frame-pointer -mllvm -asan-instrument-assembly -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -g0 -O1 %s -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-exceptions -fno-inline-functions -fomit-frame-pointer -momit-leaf-frame-pointer -mllvm -asan-instrument-assembly -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-nounwind
diff --git a/test/asan/TestCases/Linux/asan_prelink_test.cc b/test/asan/TestCases/Linux/asan_prelink_test.cc
index d67d945851f9..a5808ba3a9a5 100644
--- a/test/asan/TestCases/Linux/asan_prelink_test.cc
+++ b/test/asan/TestCases/Linux/asan_prelink_test.cc
@@ -10,7 +10,7 @@
// RUN: %env_asan_opts=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
+// REQUIRES: x86_64-target-arch, Clang
#if BUILD_SO
int G;
int *getG() {
diff --git a/test/asan/TestCases/Linux/clang_gcc_abi.cc b/test/asan/TestCases/Linux/clang_gcc_abi.cc
index 669d1524077c..845f4121adcc 100644
--- a/test/asan/TestCases/Linux/clang_gcc_abi.cc
+++ b/test/asan/TestCases/Linux/clang_gcc_abi.cc
@@ -3,7 +3,7 @@
// RUN: %clangxx_asan -O2 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
// RUN: %clangxx_asan -O3 -x c %s -o %t && not %run %t 2>&1 | FileCheck %s
-// REQUIRES: arm-supported-target
+// REQUIRES: arm-target-arch
// XFAIL: armv7l-unknown-linux-gnueabihf
#include <stdlib.h>
diff --git a/test/asan/TestCases/Linux/clone_test.cc b/test/asan/TestCases/Linux/clone_test.cc
index e9c1f166eb45..f6eb26100f5e 100644
--- a/test/asan/TestCases/Linux/clone_test.cc
+++ b/test/asan/TestCases/Linux/clone_test.cc
@@ -22,7 +22,7 @@ int Child(void *arg) {
int main(int argc, char **argv) {
const int kStackSize = 1 << 20;
- char child_stack[kStackSize + 1];
+ char __attribute__((aligned(16))) child_stack[kStackSize + 1];
char *sp = child_stack + kStackSize; // Stack grows down.
printf("Parent: %p\n", sp);
pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL);
diff --git a/test/asan/TestCases/Linux/coverage-missing.cc b/test/asan/TestCases/Linux/coverage-missing.cc
index 6cd3201c48d1..49487d39a15b 100644
--- a/test/asan/TestCases/Linux/coverage-missing.cc
+++ b/test/asan/TestCases/Linux/coverage-missing.cc
@@ -43,7 +43,7 @@
// 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
+// REQUIRES: x86-target-arch
// XFAIL: android
#include <stdio.h>
diff --git a/test/asan/TestCases/Linux/coverage_html_report.cc b/test/asan/TestCases/Linux/coverage_html_report.cc
new file mode 100644
index 000000000000..78fbfb372403
--- /dev/null
+++ b/test/asan/TestCases/Linux/coverage_html_report.cc
@@ -0,0 +1,24 @@
+// REQUIRES: has_sancovcc, x86_64-linux, asan-dynamic-runtime
+// RUN: %clangxx_asan_static -fsanitize-coverage=func %s -o %t
+// RUN: rm -rf %T/coverage_html_report
+// RUN: mkdir -p %T/coverage_html_report
+// RUN: cd %T/coverage_html_report
+// RUN: %env_asan_opts=coverage=1:verbosity=1:html_cov_report=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-main
+// RUN: ls *.html | FileCheck %s --check-prefix=CHECK-ls
+// RUN: rm -r %T/coverage_html_report
+
+#include <stdio.h>
+#include <unistd.h>
+
+void bar() { printf("bar\n"); }
+
+int main(int argc, char **argv) {
+ fprintf(stderr, "PID: %d\n", getpid());
+ bar();
+ return 0;
+}
+
+// CHECK-main: PID: [[PID:[0-9]+]]
+// CHECK-main: [[PID]].sancov: 2 PCs written
+// CHECK-main: coverage report generated to ./coverage_html_report.cc.tmp.[[PID]].html
+// CHECK-ls: coverage_html_report.cc.tmp.{{[0-9]+}}.html
diff --git a/test/asan/TestCases/Linux/interface_symbols_linux.c b/test/asan/TestCases/Linux/interface_symbols_linux.c
index 971feb5dc09f..2e648575f28c 100644
--- a/test/asan/TestCases/Linux/interface_symbols_linux.c
+++ b/test/asan/TestCases/Linux/interface_symbols_linux.c
@@ -56,6 +56,6 @@
// FIXME: nm -D on powerpc somewhy shows ASan interface symbols residing
// in "initialized data section".
-// REQUIRES: x86_64-supported-target,i386-supported-target,asan-static-runtime
+// REQUIRES: x86-target-arch,asan-static-runtime
int main() { return 0; }
diff --git a/test/asan/TestCases/Linux/kernel-area.cc b/test/asan/TestCases/Linux/kernel-area.cc
index c0f17272ad27..d7a544fecaf9 100644
--- a/test/asan/TestCases/Linux/kernel-area.cc
+++ b/test/asan/TestCases/Linux/kernel-area.cc
@@ -16,7 +16,7 @@
// CHECK-kernel-64-bits: || `[0x28{{0+}}, 0x3{{f+}}]` || HighShadow ||
// CHECK-kernel-64-bits: || `[0x24{{0+}}, 0x27{{f+}}]` || ShadowGap ||
//
-// REQUIRES: asan-32-bits,i386-supported-target
+// REQUIRES: i386-target-arch
int main() {
return 0;
diff --git a/test/asan/TestCases/Linux/leak_check_segv.cc b/test/asan/TestCases/Linux/leak_check_segv.cc
index 8160d5fe56bb..2a2010f7ab0f 100644
--- a/test/asan/TestCases/Linux/leak_check_segv.cc
+++ b/test/asan/TestCases/Linux/leak_check_segv.cc
@@ -1,5 +1,5 @@
// 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
+// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
// REQUIRES: leak-detection
#include <stdlib.h>
#include <stdio.h>
@@ -11,7 +11,7 @@ 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)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");
@@ -19,5 +19,5 @@ int main() {
// CHECK: Tracer caught signal 11
// CHECK: LeakSanitizer has encountered a fatal error
+// CHECK: HINT: For debugging, try setting {{.*}} LSAN_OPTIONS
// CHECK-NOT: DONE
-
diff --git a/test/asan/TestCases/Linux/local_alias.cc b/test/asan/TestCases/Linux/local_alias.cc
new file mode 100644
index 000000000000..d941ff2f9171
--- /dev/null
+++ b/test/asan/TestCases/Linux/local_alias.cc
@@ -0,0 +1,40 @@
+// Test that mixing instrumented and non-instrumented code doesn't lead to crash.
+// Build two modules (one is instrumented, another is not) that have globals
+// with same names. Check, that ASan doesn't crash with CHECK failure or
+// false positive global-buffer-overflow due to sanitized library poisons
+// globals from non-sanitized one.
+//
+// FIXME: https://github.com/google/sanitizers/issues/316
+// XFAIL: android
+// XFAIL: mips64
+//
+// RUN: %clangxx_asan -DBUILD_INSTRUMENTED_DSO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %t-INSTRUMENTED-SO.so
+// RUN: %clangxx -DBUILD_UNINSTRUMENTED_DSO=1 -fPIC -shared %s -o %t-UNINSTRUMENTED-SO.so
+// RUN: %clangxx %s -c -mllvm -asan-use-private-alias -o %t.o
+// RUN: %clangxx_asan %t.o %t-UNINSTRUMENTED-SO.so %t-INSTRUMENTED-SO.so -o %t-EXE
+// RUN: %env_asan_opts=use_odr_indicator=true %run %t-EXE
+
+#if defined (BUILD_INSTRUMENTED_DSO)
+long h = 15;
+long f = 4;
+long foo(long *p) {
+ return *p;
+}
+#elif defined (BUILD_UNINSTRUMENTED_DSO)
+long foo(long *);
+long h = 12;
+long i = 13;
+long f = 5;
+
+int bar() {
+ if (foo(&f) != 5 || foo(&h) != 12 || foo(&i) != 13)
+ return 1;
+ return 0;
+}
+#else
+extern int bar();
+
+int main() {
+ return bar();
+}
+#endif
diff --git a/test/asan/TestCases/Linux/malloc-in-qsort.cc b/test/asan/TestCases/Linux/malloc-in-qsort.cc
index e8c9b7480b76..ea239244290f 100644
--- a/test/asan/TestCases/Linux/malloc-in-qsort.cc
+++ b/test/asan/TestCases/Linux/malloc-in-qsort.cc
@@ -7,7 +7,7 @@
// https://code.google.com/p/address-sanitizer/issues/detail?id=137
// Fast unwinder is only available on x86_64 and i386.
-// REQUIRES: x86_64-supported-target
+// REQUIRES: x86-target-arch
// REQUIRES: compiler-rt-optimized
diff --git a/test/asan/TestCases/Linux/memmem_test.cc b/test/asan/TestCases/Linux/memmem_test.cc
new file mode 100644
index 000000000000..54883004e0aa
--- /dev/null
+++ b/test/asan/TestCases/Linux/memmem_test.cc
@@ -0,0 +1,21 @@
+// RUN: %clangxx_asan %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=A1
+// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=A2
+// RUN: %env_asan_opts=intercept_memmem=0 %run %t
+
+#include <string.h>
+int main(int argc, char **argv) {
+ char a1[] = {1, 2, 3, 4, 5, 6, 7, 8};
+ char a2[] = {3, 4, 5};
+ void *res;
+ if (argc == 1)
+ res = memmem(a1, sizeof(a1) + 1, a2, sizeof(a2)); // BOOM
+ else
+ res = memmem(a1, sizeof(a1), a2, sizeof(a2) + 1); // BOOM
+ // CHECK: AddressSanitizer: stack-buffer-overflow
+ // CHECK: {{#0.*memmem}}
+ // CHECK: {{#1.*main}}
+ // A1: 'a1' <== Memory access at offset
+ // A2: 'a2' <== Memory access at offset
+ return res == NULL;
+}
diff --git a/test/asan/TestCases/Linux/new_delete_mismatch.cc b/test/asan/TestCases/Linux/new_delete_mismatch.cc
new file mode 100644
index 000000000000..1cfc0ef05312
--- /dev/null
+++ b/test/asan/TestCases/Linux/new_delete_mismatch.cc
@@ -0,0 +1,16 @@
+// Check that we report new[] vs delete as alloc-dealloc-mismatch and not as
+// new-delete-type-mismatch when -fsized-deallocation is enabled.
+
+// RUN: %clangxx_asan -g %s -o %t && not %run %t |& FileCheck %s
+// RUN: %clangxx_asan -fsized-deallocation -g %s -o %t && not %run %t |& FileCheck %s
+
+#include <stdlib.h>
+
+static volatile char *x;
+
+int main() {
+ x = new char[10];
+ delete x;
+}
+
+// CHECK: AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete) on 0x
diff --git a/test/asan/TestCases/Linux/nohugepage_test.cc b/test/asan/TestCases/Linux/nohugepage_test.cc
index 2758f0ad04f5..ce8f17e7899e 100644
--- a/test/asan/TestCases/Linux/nohugepage_test.cc
+++ b/test/asan/TestCases/Linux/nohugepage_test.cc
@@ -9,7 +9,7 @@
// 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...
//
-// REQUIRES: x86_64-supported-target, asan-64-bits
+// REQUIRES: x86_64-target-arch
//
// WARNING: this test is very subtle and may nto work on some systems.
// If this is the case we'll need to futher improve it or disable it.
diff --git a/test/asan/TestCases/Linux/odr-violation.cc b/test/asan/TestCases/Linux/odr-violation.cc
index bc76116632ec..143fb6e14344 100644
--- a/test/asan/TestCases/Linux/odr-violation.cc
+++ b/test/asan/TestCases/Linux/odr-violation.cc
@@ -1,5 +1,6 @@
// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
// XFAIL: android
+// XFAIL: mips64
//
// 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.
@@ -22,6 +23,13 @@
// RUN: echo "odr_violation:foo::G" > %t.supp
// RUN: %env_asan_opts=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
+//
+// Use private aliases for global variables: use indicator symbol to detect ODR violation.
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %t-ODR-SO.so -DSZ=100
+// RUN: %clangxx_asan -mllvm -asan-use-private-alias %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE
+// RUN: %env_asan_opts=fast_unwind_on_malloc=0 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %env_asan_opts=fast_unwind_on_malloc=0:use_odr_indicator=false %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
+// RUN: %env_asan_opts=fast_unwind_on_malloc=0:use_odr_indicator=true not %run %t-ODR-EXE 2>&1 | FileCheck %s
// GNU driver doesn't handle .so files properly.
// REQUIRES: Clang
diff --git a/test/asan/TestCases/Linux/odr_c_test.c b/test/asan/TestCases/Linux/odr_c_test.c
new file mode 100644
index 000000000000..b1d23493b570
--- /dev/null
+++ b/test/asan/TestCases/Linux/odr_c_test.c
@@ -0,0 +1,28 @@
+// Test that we can properly report an ODR violation
+// between an instrumented global and a non-instrumented global.
+
+// RUN: %clang_asan %s -fPIC -shared -o %t-1.so -DFILE1
+// RUN: %clang_asan %s -fPIC -shared -o %t-2.so -DFILE2
+// RUN: %clang_asan %s -fPIE %t-1.so %t-2.so -Wl,-R`pwd` -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s
+//
+// REQUIRES: x86_64-target-arch
+//
+// CHECK: The following global variable is not properly aligned.
+// CHECK: ERROR: AddressSanitizer: odr-violation
+#if defined(FILE1)
+__attribute__((aligned(8))) int x;
+__attribute__((aligned(1))) char y;
+// The gold linker puts ZZZ at the start of bss (where it is aligned)
+// unless we have a large alternative like Displace:
+__attribute__((aligned(1))) char Displace[105];
+__attribute__((aligned(1))) char ZZZ[100];
+#elif defined(FILE2)
+int ZZZ = 1;
+#else
+extern int ZZZ;
+int main() {
+ return ZZZ;
+}
+#endif
+
diff --git a/test/asan/TestCases/Linux/overflow-in-qsort.cc b/test/asan/TestCases/Linux/overflow-in-qsort.cc
index dc3918e876a6..6990518e43ac 100644
--- a/test/asan/TestCases/Linux/overflow-in-qsort.cc
+++ b/test/asan/TestCases/Linux/overflow-in-qsort.cc
@@ -7,7 +7,7 @@
// https://code.google.com/p/address-sanitizer/issues/detail?id=137
// Fast unwinder is only available on x86_64 and i386.
-// REQUIRES: x86_64-supported-target
+// REQUIRES: x86-target-arch
#include <stdlib.h>
#include <stdio.h>
diff --git a/test/asan/TestCases/Linux/print_memory_profile_test.cc b/test/asan/TestCases/Linux/print_memory_profile_test.cc
new file mode 100644
index 000000000000..d30dbea1cf6d
--- /dev/null
+++ b/test/asan/TestCases/Linux/print_memory_profile_test.cc
@@ -0,0 +1,29 @@
+// Printing memory profiling only works in the configuration where we can
+// detect leaks.
+// REQUIRES: leak-detection
+//
+// RUN: %clangxx_asan %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+#include <sanitizer/common_interface_defs.h>
+
+#include <stdio.h>
+
+char *sink[1000];
+
+int main() {
+ int idx = 0;
+ for (int i = 0; i < 17; i++)
+ sink[idx++] = new char[131000];
+ for (int i = 0; i < 28; i++)
+ sink[idx++] = new char[24000];
+
+ __sanitizer_print_memory_profile(100);
+ __sanitizer_print_memory_profile(50);
+}
+
+// CHECK: Live Heap Allocations: {{.*}}; showing top 100%
+// CHECK: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
+// CHECK: 672000 byte(s) ({{.*}}%) in 28 allocation(s)
+// CHECK: Live Heap Allocations: {{.*}}; showing top 50%
+// CHECK: 2227000 byte(s) ({{.*}}%) in 17 allocation(s)
+// CHECK-NOT: 1008 byte
diff --git a/test/asan/TestCases/Linux/ptrace.cc b/test/asan/TestCases/Linux/ptrace.cc
index d87d90be4753..bd3d2d27e1de 100644
--- a/test/asan/TestCases/Linux/ptrace.cc
+++ b/test/asan/TestCases/Linux/ptrace.cc
@@ -59,6 +59,13 @@ typedef char fpregs_struct[ARM_VFPREGS_SIZE];
#define PRINT_REG_PC(__regs) printf ("%x\n", (unsigned) (__regs.ARM_pc))
#define PRINT_REG_FP(__fpregs) printf ("%x\n", (unsigned) (__fpregs + 32 * 8))
#define __PTRACE_FPREQUEST PTRACE_GETVFPREGS
+
+#elif defined(__s390__)
+typedef _user_regs_struct regs_struct;
+typedef _user_fpregs_struct fpregs_struct;
+#define PRINT_REG_PC(__regs) printf ("%lx\n", (unsigned long) (__regs.psw.addr))
+#define PRINT_REG_FP(__fpregs) printf ("%lx\n", (unsigned long) (__fpregs.fpc))
+#define ARCH_IOVEC_FOR_GETREGSET
#endif
diff --git a/test/asan/TestCases/Linux/recvfrom.cc b/test/asan/TestCases/Linux/recvfrom.cc
new file mode 100644
index 000000000000..9c6eec35c957
--- /dev/null
+++ b/test/asan/TestCases/Linux/recvfrom.cc
@@ -0,0 +1,81 @@
+// Test that ASan detects buffer overflow on read from socket via recvfrom.
+//
+// RUN: %clangxx_asan %s -DRECVFROM -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RECVFROM
+// RUN: %clangxx_asan %s -DSENDTO -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SENDTO
+// RUN: %clangxx_asan %s -DSENDTO -o %t && %env_asan_opts=intercept_send=0 %run %t 2>&1
+//
+// UNSUPPORTED: android
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+#define CHECK_ERROR(p, m) \
+ do { \
+ if (p) { \
+ fprintf(stderr, "ERROR " m "\n"); \
+ exit(1); \
+ } \
+ } while (0)
+
+const int kBufSize = 10;
+int sockfd;
+
+static void *client_thread_udp(void *data) {
+#ifdef SENDTO
+ const char buf[kBufSize / 2] = {0, };
+#else
+ const char buf[kBufSize] = {0, };
+#endif
+ struct sockaddr_in serveraddr;
+ socklen_t addrlen = sizeof(serveraddr);
+
+ int succeeded = getsockname(sockfd, (struct sockaddr *)&serveraddr, &addrlen);
+ CHECK_ERROR(succeeded < 0, "in getsockname");
+
+ succeeded = sendto(sockfd, buf, kBufSize, 0, (struct sockaddr *)&serveraddr,
+ sizeof(serveraddr));
+ // CHECK-SENDTO: {{READ of size 10 at 0x.* thread T1}}
+ // CHECK-SENDTO: {{ #1 0x.* in client_thread_udp.*recvfrom.cc:}}[[@LINE-3]]
+ CHECK_ERROR(succeeded < 0, "in sending message");
+ return NULL;
+}
+
+int main() {
+#ifdef RECVFROM
+ char buf[kBufSize / 2];
+#else
+ char buf[kBufSize];
+#endif
+ pthread_t client_thread;
+ struct sockaddr_in serveraddr;
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ CHECK_ERROR(sockfd < 0, "opening socket");
+
+ memset(&serveraddr, 0, sizeof(serveraddr));
+ serveraddr.sin_family = AF_INET;
+ serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serveraddr.sin_port = 0;
+
+ int bound = bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
+ CHECK_ERROR(bound < 0, "on binding");
+
+ int succeeded =
+ pthread_create(&client_thread, NULL, client_thread_udp, &serveraddr);
+ CHECK_ERROR(succeeded, "creating thread");
+
+ recvfrom(sockfd, buf, kBufSize, 0, NULL, NULL); // BOOM
+ // CHECK-RECVFROM: {{WRITE of size 10 at 0x.* thread T0}}
+ // CHECK-RECVFROM: {{ #1 0x.* in main.*recvfrom.cc:}}[[@LINE-2]]
+ // CHECK-RECVFROM: {{Address 0x.* is located in stack of thread T0 at offset}}
+ // CHECK-RECVFROM-NEXT: in{{.*}}main{{.*}}recvfrom.cc
+ succeeded = pthread_join(client_thread, NULL);
+ CHECK_ERROR(succeeded, "joining thread");
+ return 0;
+}
diff --git a/test/asan/TestCases/Linux/scariness_score_test.cc b/test/asan/TestCases/Linux/scariness_score_test.cc
new file mode 100644
index 000000000000..24854132f539
--- /dev/null
+++ b/test/asan/TestCases/Linux/scariness_score_test.cc
@@ -0,0 +1,192 @@
+// Test how we produce the scariness score.
+
+// RUN: %clangxx_asan -O0 %s -o %t
+// RUN: export %env_asan_opts=detect_stack_use_after_return=1:handle_abort=1:print_scariness=1
+// Make sure the stack is limited (may not be the default under GNU make)
+// RUN: ulimit -s 4096
+// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK1
+// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK2
+// RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK3
+// RUN: not %run %t 4 2>&1 | FileCheck %s --check-prefix=CHECK4
+// RUN: not %run %t 5 2>&1 | FileCheck %s --check-prefix=CHECK5
+// RUN: not %run %t 6 2>&1 | FileCheck %s --check-prefix=CHECK6
+// RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=CHECK7
+// RUN: not %run %t 8 2>&1 | FileCheck %s --check-prefix=CHECK8
+// RUN: not %run %t 9 2>&1 | FileCheck %s --check-prefix=CHECK9
+// RUN: not %run %t 10 2>&1 | FileCheck %s --check-prefix=CHECK10
+// RUN: not %run %t 11 2>&1 | FileCheck %s --check-prefix=CHECK11
+// RUN: not %run %t 12 2>&1 | FileCheck %s --check-prefix=CHECK12
+// RUN: not %run %t 13 2>&1 | FileCheck %s --check-prefix=CHECK13
+// RUN: not %run %t 14 2>&1 | FileCheck %s --check-prefix=CHECK14
+// RUN: not %run %t 15 2>&1 | FileCheck %s --check-prefix=CHECK15
+// RUN: not %run %t 16 2>&1 | FileCheck %s --check-prefix=CHECK16
+// RUN: not %run %t 17 2>&1 | FileCheck %s --check-prefix=CHECK17
+// RUN: not %run %t 18 2>&1 | FileCheck %s --check-prefix=CHECK18
+// RUN: not %run %t 19 2>&1 | FileCheck %s --check-prefix=CHECK19
+// RUN: not %run %t 20 2>&1 | FileCheck %s --check-prefix=CHECK20
+// RUN: not %run %t 21 2>&1 | FileCheck %s --check-prefix=CHECK21
+// RUN: not %run %t 22 2>&1 | FileCheck %s --check-prefix=CHECK22
+// RUN: not %run %t 23 2>&1 | FileCheck %s --check-prefix=CHECK23
+// RUN: not %run %t 24 2>&1 | FileCheck %s --check-prefix=CHECK24
+// RUN: not %run %t 25 2>&1 | FileCheck %s --check-prefix=CHECK25
+// RUN: not %run %t 26 2>&1 | FileCheck %s --check-prefix=CHECK26
+// RUN: not %run %t 27 2>&1 | FileCheck %s --check-prefix=CHECK27
+// Parts of the test are too platform-specific:
+// REQUIRES: x86_64-target-arch
+// REQUIRES: shell
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <sanitizer/asan_interface.h>
+
+enum ReadOrWrite { Read = 0, Write = 1 };
+
+struct S32 {
+ char x[32];
+};
+
+template<class T>
+void HeapBuferOverflow(int Idx, ReadOrWrite w) {
+ T *t = new T[100];
+ static T sink;
+ if (w)
+ t[100 + Idx] = T();
+ else
+ sink = t[100 + Idx];
+ delete [] t;
+}
+
+template<class T>
+void HeapUseAfterFree(int Idx, ReadOrWrite w) {
+ T *t = new T[100];
+ static T sink;
+ sink = t[0];
+ delete [] t;
+ if (w)
+ t[Idx] = T();
+ else
+ sink = t[Idx];
+}
+
+template<class T>
+void StackBufferOverflow(int Idx, ReadOrWrite w) {
+ T t[100];
+ static T sink;
+ sink = t[Idx];
+ if (w)
+ t[100 + Idx] = T();
+ else
+ sink = t[100 + Idx];
+}
+
+template<class T>
+T *LeakStack() {
+ T t[100];
+ static volatile T *x;
+ x = &t[0];
+ return (T*)x;
+}
+
+template<class T>
+void StackUseAfterReturn(int Idx, ReadOrWrite w) {
+ static T sink;
+ T *t = LeakStack<T>();
+ if (w)
+ t[100 + Idx] = T();
+ else
+ sink = t[100 + Idx];
+}
+
+char g1[100];
+short g2[100];
+int g4[100];
+int64_t g8[100];
+S32 gm[100];
+
+void DoubleFree() {
+ int *x = new int;
+ static volatile int two = 2;
+ for (int i = 0; i < two; i++)
+ delete x;
+}
+
+void StackOverflow(int Idx) {
+ int some_stack[10000];
+ static volatile int *x;
+ x = &some_stack[0];
+ if (Idx > 0)
+ StackOverflow(Idx - 1);
+}
+
+void UseAfterPoison() {
+ int buf[100];
+ __asan_poison_memory_region(buf, sizeof(buf));
+ static volatile int sink;
+ sink = buf[42];
+}
+
+int main(int argc, char **argv) {
+ char arr[100];
+ static volatile int zero = 0;
+ static volatile int *zero_ptr = 0;
+ static volatile int *wild_addr = (int*)0x10000000; // System-dependent.
+ if (argc != 2) return 1;
+ int kind = atoi(argv[1]);
+ switch (kind) {
+ case 1: HeapBuferOverflow<char>(0, Read); break;
+ case 2: HeapBuferOverflow<int>(0, Read); break;
+ case 3: HeapBuferOverflow<short>(0, Write); break;
+ case 4: HeapBuferOverflow<int64_t>(2, Write); break;
+ case 5: HeapBuferOverflow<S32>(4, Write); break;
+ case 6: HeapUseAfterFree<char>(0, Read); break;
+ case 7: HeapUseAfterFree<int>(0, Write); break;
+ case 8: HeapUseAfterFree<int64_t>(0, Read); break;
+ case 9: HeapUseAfterFree<S32>(0, Write); break;
+ case 10: StackBufferOverflow<char>(0, Write); break;
+ case 11: StackBufferOverflow<int64_t>(0, Read); break;
+ case 12: StackBufferOverflow<int>(4, Write); break;
+ case 13: StackUseAfterReturn<char>(0, Read); break;
+ case 14: StackUseAfterReturn<S32>(0, Write); break;
+ case 15: g1[zero + 100] = 0; break;
+ case 16: gm[0] = gm[zero + 100 + 1]; break;
+ case 17: DoubleFree(); break;
+ case 18: StackOverflow(1000000); break;
+ case 19: *zero_ptr = 0; break;
+ case 20: *wild_addr = 0; break;
+ case 21: zero = *wild_addr; break;
+ case 22: abort(); break;
+ case 23: ((void (*)(void))wild_addr)(); break;
+ case 24: delete (new int[10]); break;
+ case 25: free((char*)malloc(100) + 10); break;
+ case 26: memcpy(arr, arr+10, 20); break;
+ case 27: UseAfterPoison(); break;
+ // CHECK1: SCARINESS: 12 (1-byte-read-heap-buffer-overflow)
+ // CHECK2: SCARINESS: 17 (4-byte-read-heap-buffer-overflow)
+ // CHECK3: SCARINESS: 33 (2-byte-write-heap-buffer-overflow)
+ // CHECK4: SCARINESS: 52 (8-byte-write-heap-buffer-overflow-far-from-bounds)
+ // CHECK5: SCARINESS: 55 (multi-byte-write-heap-buffer-overflow-far-from-bounds)
+ // CHECK6: SCARINESS: 40 (1-byte-read-heap-use-after-free)
+ // CHECK7: SCARINESS: 46 (4-byte-write-heap-use-after-free)
+ // CHECK8: SCARINESS: 51 (8-byte-read-heap-use-after-free)
+ // CHECK9: SCARINESS: 55 (multi-byte-write-heap-use-after-free)
+ // CHECK10: SCARINESS: 46 (1-byte-write-stack-buffer-overflow)
+ // CHECK11: SCARINESS: 38 (8-byte-read-stack-buffer-overflow)
+ // CHECK12: SCARINESS: 61 (4-byte-write-stack-buffer-overflow-far-from-bounds)
+ // CHECK13: SCARINESS: 50 (1-byte-read-stack-use-after-return)
+ // CHECK14: SCARINESS: 65 (multi-byte-write-stack-use-after-return)
+ // CHECK15: SCARINESS: 31 (1-byte-write-global-buffer-overflow)
+ // CHECK16: SCARINESS: 36 (multi-byte-read-global-buffer-overflow-far-from-bounds)
+ // CHECK17: SCARINESS: 42 (double-free)
+ // CHECK18: SCARINESS: 10 (stack-overflow)
+ // CHECK19: SCARINESS: 10 (null-deref)
+ // CHECK20: SCARINESS: 30 (wild-addr-write)
+ // CHECK21: SCARINESS: 20 (wild-addr-read)
+ // CHECK22: SCARINESS: 10 (signal)
+ // CHECK23: SCARINESS: 60 (wild-jump)
+ // CHECK24: SCARINESS: 10 (alloc-dealloc-mismatch)
+ // CHECK25: SCARINESS: 40 (bad-free)
+ // CHECK26: SCARINESS: 10 (memcpy-param-overlap)
+ // CHECK27: SCARINESS: 27 (4-byte-read-use-after-poison)
+ }
+}
diff --git a/test/asan/TestCases/Linux/segv_read_write.c b/test/asan/TestCases/Linux/segv_read_write.c
new file mode 100644
index 000000000000..b1379703ed86
--- /dev/null
+++ b/test/asan/TestCases/Linux/segv_read_write.c
@@ -0,0 +1,26 @@
+// RUN: %clangxx_asan -std=c++11 -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ
+// RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE
+// UNSUPPORTED: powerpc64,mips,s390
+
+#include <sys/mman.h>
+
+static volatile int sink;
+__attribute__((noinline)) void Read(int *ptr) { sink = *ptr; }
+__attribute__((noinline)) void Write(int *ptr) { *ptr = 0; }
+int main(int argc, char **argv) {
+ // Writes to shadow are detected as reads from shadow gap (because of how the
+ // shadow mapping works). This is kinda hard to fix. Test a random address in
+ // the application part of the address space.
+ void *volatile p =
+ mmap(nullptr, 4096, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ munmap(p, 4096);
+ if (argc == 1)
+ Read((int *)p);
+ else
+ Write((int *)p);
+}
+// READ: AddressSanitizer: SEGV on unknown address
+// READ: The signal is caused by a READ memory access.
+// WRITE: AddressSanitizer: SEGV on unknown address
+// WRITE: The signal is caused by a WRITE memory access.
diff --git a/test/asan/TestCases/Linux/stack-overflow-recovery-mode.cc b/test/asan/TestCases/Linux/stack-overflow-recovery-mode.cc
new file mode 100644
index 000000000000..e99665953784
--- /dev/null
+++ b/test/asan/TestCases/Linux/stack-overflow-recovery-mode.cc
@@ -0,0 +1,36 @@
+// Test that ASan doesn't hang on stack overflow in recovery mode.
+//
+// RUN: %clang_asan -O0 -fsanitize-recover=address %s -o %t
+// RUN: %env_asan_opts=halt_on_error=false not %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+
+static volatile int *recurse(volatile int n, volatile int *p) {
+ // CHECK: {{stack-overflow on address 0x.* \(pc 0x.* bp 0x.* sp 0x.* T.*\)}}
+ if (n >= 0) *recurse(n + 1, p) += n;
+ return p;
+}
+
+
+void LimitStackAndReexec(int argc, char **argv) {
+ struct rlimit rlim;
+ int res = getrlimit(RLIMIT_STACK, &rlim);
+ assert(res == 0);
+ if (rlim.rlim_cur == RLIM_INFINITY) {
+ rlim.rlim_cur = 256 * 1024;
+ res = setrlimit(RLIMIT_STACK, &rlim);
+ assert(res == 0);
+
+ execv(argv[0], argv);
+ assert(0 && "unreachable");
+ }
+}
+
+int main(int argc, char **argv) {
+ LimitStackAndReexec(argc, argv);
+ volatile int res;
+ return *recurse(argc + 1, &res);
+}
diff --git a/test/asan/TestCases/Linux/static_tls.cc b/test/asan/TestCases/Linux/static_tls.cc
index 11bb1a4f849c..5e569ddabd32 100644
--- a/test/asan/TestCases/Linux/static_tls.cc
+++ b/test/asan/TestCases/Linux/static_tls.cc
@@ -10,6 +10,8 @@
// CHECK: after
// XFAIL: aarch64
+// binutils 2.26 has a change that causes this test to fail on powerpc64.
+// UNSUPPORTED: powerpc64
#ifndef SHARED
#include <stdio.h>
diff --git a/test/asan/TestCases/Linux/swapcontext_annotation.cc b/test/asan/TestCases/Linux/swapcontext_annotation.cc
new file mode 100644
index 000000000000..90aabaee205b
--- /dev/null
+++ b/test/asan/TestCases/Linux/swapcontext_annotation.cc
@@ -0,0 +1,178 @@
+// Check that ASan plays well with annotated makecontext/swapcontext.
+
+// RUN: %clangxx_asan -lpthread -O0 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -lpthread -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -lpthread -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -lpthread -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// This test is too subtle to try on non-x86 arch for now.
+// REQUIRES: x86_64-supported-target,i386-supported-target
+
+#include <pthread.h>
+#include <setjmp.h>
+#include <stdio.h>
+#include <sys/time.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+#include <sanitizer/common_interface_defs.h>
+
+ucontext_t orig_context;
+ucontext_t child_context;
+ucontext_t next_child_context;
+
+char *next_child_stack;
+
+const int kStackSize = 1 << 20;
+
+void *main_thread_stack;
+size_t main_thread_stacksize;
+
+__attribute__((noinline, noreturn)) void LongJump(jmp_buf env) {
+ longjmp(env, 1);
+ _exit(1);
+}
+
+// Simulate __asan_handle_no_return().
+__attribute__((noinline)) void CallNoReturn() {
+ jmp_buf env;
+ if (setjmp(env) != 0) return;
+
+ LongJump(env);
+ _exit(1);
+}
+
+void NextChild() {
+ CallNoReturn();
+ __sanitizer_finish_switch_fiber();
+
+ char x[32] = {0}; // Stack gets poisoned.
+ printf("NextChild: %p\n", x);
+
+ CallNoReturn();
+
+ __sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+ CallNoReturn();
+ if (swapcontext(&next_child_context, &orig_context) < 0) {
+ perror("swapcontext");
+ _exit(1);
+ }
+}
+
+void Child(int mode) {
+ CallNoReturn();
+ __sanitizer_finish_switch_fiber();
+ char x[32] = {0}; // Stack gets poisoned.
+ printf("Child: %p\n", x);
+ CallNoReturn();
+ // (a) Do nothing, just return to parent function.
+ // (b) Jump into the original function. Stack remains poisoned unless we do
+ // something.
+ // (c) Jump to another function which will then jump back to the main function
+ if (mode == 0) {
+ __sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+ CallNoReturn();
+ } else if (mode == 1) {
+ __sanitizer_start_switch_fiber(main_thread_stack, main_thread_stacksize);
+ CallNoReturn();
+ if (swapcontext(&child_context, &orig_context) < 0) {
+ perror("swapcontext");
+ _exit(1);
+ }
+ } else if (mode == 2) {
+ getcontext(&next_child_context);
+ next_child_context.uc_stack.ss_sp = next_child_stack;
+ next_child_context.uc_stack.ss_size = kStackSize / 2;
+ makecontext(&next_child_context, (void (*)())NextChild, 0);
+ __sanitizer_start_switch_fiber(next_child_context.uc_stack.ss_sp,
+ next_child_context.uc_stack.ss_size);
+ CallNoReturn();
+ if (swapcontext(&child_context, &next_child_context) < 0) {
+ perror("swapcontext");
+ _exit(1);
+ }
+ }
+}
+
+int Run(int arg, int mode, char *child_stack) {
+ printf("Child stack: %p\n", child_stack);
+ // Setup child context.
+ getcontext(&child_context);
+ child_context.uc_stack.ss_sp = child_stack;
+ child_context.uc_stack.ss_size = kStackSize / 2;
+ if (mode == 0) {
+ child_context.uc_link = &orig_context;
+ }
+ makecontext(&child_context, (void (*)())Child, 1, mode);
+ CallNoReturn();
+ __sanitizer_start_switch_fiber(child_context.uc_stack.ss_sp,
+ child_context.uc_stack.ss_size);
+ CallNoReturn();
+ if (swapcontext(&orig_context, &child_context) < 0) {
+ perror("swapcontext");
+ _exit(1);
+ }
+ CallNoReturn();
+ __sanitizer_finish_switch_fiber();
+ CallNoReturn();
+
+ // Touch childs's stack to make sure it's unpoisoned.
+ for (int i = 0; i < kStackSize; i++) {
+ child_stack[i] = i;
+ }
+ return child_stack[arg];
+}
+
+void handler(int sig) { CallNoReturn(); }
+
+void InitStackBounds() {
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_getattr_np(pthread_self(), &attr);
+ pthread_attr_getstack(&attr, &main_thread_stack, &main_thread_stacksize);
+ pthread_attr_destroy(&attr);
+}
+
+int main(int argc, char **argv) {
+ InitStackBounds();
+
+ // set up a signal that will spam and trigger __asan_handle_no_return at
+ // tricky moments
+ struct sigaction act = {};
+ act.sa_handler = &handler;
+ if (sigaction(SIGPROF, &act, 0)) {
+ perror("sigaction");
+ _exit(1);
+ }
+
+ itimerval t;
+ t.it_interval.tv_sec = 0;
+ t.it_interval.tv_usec = 10;
+ t.it_value = t.it_interval;
+ if (setitimer(ITIMER_PROF, &t, 0)) {
+ perror("setitimer");
+ _exit(1);
+ }
+
+ char *heap = new char[kStackSize + 1];
+ next_child_stack = new char[kStackSize + 1];
+ char stack[kStackSize + 1];
+ // CHECK: WARNING: ASan doesn't fully support makecontext/swapcontext
+ int ret = 0;
+ // CHECK-NOT: ASan is ignoring requested __asan_handle_no_return
+ for (unsigned int i = 0; i < 30; ++i) {
+ ret += Run(argc - 1, 0, stack);
+ ret += Run(argc - 1, 1, stack);
+ ret += Run(argc - 1, 2, stack);
+ ret += Run(argc - 1, 0, heap);
+ ret += Run(argc - 1, 1, heap);
+ ret += Run(argc - 1, 2, heap);
+ }
+ // CHECK: Test passed
+ printf("Test passed\n");
+
+ delete[] heap;
+ delete[] next_child_stack;
+
+ return ret;
+}
diff --git a/test/asan/TestCases/Linux/swapcontext_test.cc b/test/asan/TestCases/Linux/swapcontext_test.cc
index 86ed5930bcf4..210a667d096a 100644
--- a/test/asan/TestCases/Linux/swapcontext_test.cc
+++ b/test/asan/TestCases/Linux/swapcontext_test.cc
@@ -6,7 +6,7 @@
// RUN: %clangxx_asan -O3 %s -o %t && %run %t 2>&1 | FileCheck %s
//
// This test is too sublte to try on non-x86 arch for now.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86-target-arch
#include <stdio.h>
#include <ucontext.h>
diff --git a/test/asan/TestCases/Linux/unpoison_tls.cc b/test/asan/TestCases/Linux/unpoison_tls.cc
index 9c1d74b28e5f..19ebec467c6c 100644
--- a/test/asan/TestCases/Linux/unpoison_tls.cc
+++ b/test/asan/TestCases/Linux/unpoison_tls.cc
@@ -1,5 +1,5 @@
// Test that TLS is unpoisoned on thread death.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86-target-arch
// RUN: %clangxx_asan -O1 %s -pthread -o %t && %run %t 2>&1
diff --git a/test/asan/TestCases/Posix/closed-fds.cc b/test/asan/TestCases/Posix/closed-fds.cc
index 3bbe3d8e68e1..b7bca26c305d 100644
--- a/test/asan/TestCases/Posix/closed-fds.cc
+++ b/test/asan/TestCases/Posix/closed-fds.cc
@@ -2,7 +2,7 @@
// symbolizer still works.
// RUN: rm -f %t.log.*
-// RUN: %clangxx_asan -O0 %s -o %t 2>&1 && %env_asan_opts=log_path=%t.log:verbosity=2 not %run %t 2>&1
+// RUN: %clangxx_asan -O0 %s -o %t 2>&1 && %env_asan_opts=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.
diff --git a/test/asan/TestCases/Posix/coverage-sandboxing.cc b/test/asan/TestCases/Posix/coverage-sandboxing.cc
index f6fc5266607c..c4e6bc7eef8a 100644
--- a/test/asan/TestCases/Posix/coverage-sandboxing.cc
+++ b/test/asan/TestCases/Posix/coverage-sandboxing.cc
@@ -79,8 +79,8 @@ int main(int argc, char **argv) {
#endif
// CHECK-vanilla: PID: [[PID:[0-9]+]]
-// CHECK-vanilla: .so.[[PID]].sancov: 258 PCs written
+// CHECK-vanilla: .so.[[PID]].sancov: 257 PCs written
// CHECK-vanilla: [[PID]].sancov: 1 PCs written
// CHECK-sandbox: PID: [[PID:[0-9]+]]
-// CHECK-sandbox: 258 PCs written to packed file
+// CHECK-sandbox: 257 PCs written to packed file
diff --git a/test/asan/TestCases/Posix/dlclose-test.cc b/test/asan/TestCases/Posix/dlclose-test.cc
index 369abd3127cc..0aafa3e79f6b 100644
--- a/test/asan/TestCases/Posix/dlclose-test.cc
+++ b/test/asan/TestCases/Posix/dlclose-test.cc
@@ -11,8 +11,8 @@
// This sublte test assumes that after a foo.so is dlclose-d
// we can mmap the region of memory that has been occupied by the library.
-// It works on i368/x86_64 Linux, but not necessary anywhere else.
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// It works on x86 Linux, but not necessary anywhere else.
+// REQUIRES: x86-target-arch
// RUN: %clangxx_asan -O0 -DSHARED_LIB %s -fPIC -shared -o %t-so.so
// RUN: %clangxx_asan -O0 %s %libdl -o %t && %run %t 2>&1 | FileCheck %s
diff --git a/test/asan/TestCases/dump_instruction_bytes.cc b/test/asan/TestCases/Posix/dump_instruction_bytes.cc
index da86a0f9aa48..b5b38ff08191 100644
--- a/test/asan/TestCases/dump_instruction_bytes.cc
+++ b/test/asan/TestCases/Posix/dump_instruction_bytes.cc
@@ -4,7 +4,7 @@
// RUN: %env_asan_opts=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
+// REQUIRES: x86-target-arch
int main() {
#if defined(__x86_64__)
diff --git a/test/asan/TestCases/Posix/global-registration.c b/test/asan/TestCases/Posix/global-registration.c
new file mode 100644
index 000000000000..62009b36cb7e
--- /dev/null
+++ b/test/asan/TestCases/Posix/global-registration.c
@@ -0,0 +1,69 @@
+// Test that globals from different shared objects all get registered.
+
+// This source file is compiled into three different source object files. Each
+// object file declares a global buffer. The first two are linked together, and
+// the third is loaded at runtime. We make sure that out-of-bounds accesses
+// are caught for all three buffers.
+
+// RUN: %clang_asan -c -o %t-one.o -DMAIN_FILE %s
+// RUN: %clang_asan -c -o %t-two.o -DSECONDARY_FILE %s
+// RUN: %clang_asan -o %t %t-one.o %t-two.o %libdl
+// RUN: %clang_asan -o %t-dynamic.so -shared -fPIC -DSHARED_LIBRARY_FILE %s
+// RUN: not %run %t 1 2>&1 | FileCheck --check-prefix ASAN-CHECK-1 %s
+// RUN: not %run %t 2 2>&1 | FileCheck --check-prefix ASAN-CHECK-2 %s
+// RUN: not %run %t 3 2>&1 | FileCheck --check-prefix ASAN-CHECK-3 %s
+
+#if MAIN_FILE
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern char buffer1[1];
+extern char buffer2[1];
+char buffer1[1] = { 0 };
+
+int main(int argc, char *argv[]) {
+ int n = atoi(argv[1]);
+ if (n == 1) {
+ buffer1[argc] = 0;
+ // ASAN-CHECK-1: {{0x.* is located 1 bytes .* 'buffer1'}}
+ } else if (n == 2) {
+ buffer2[argc] = 0;
+ // ASAN-CHECK-2: {{0x.* is located 1 bytes .* 'buffer2'}}
+ } else if (n == 3) {
+ char *libsuffix = "-dynamic.so";
+ char *libpath = malloc(strlen(argv[0]) + strlen(libsuffix) + 1);
+ sprintf(libpath, "%s%s", argv[0], libsuffix);
+
+ void *handle = dlopen(libpath, RTLD_NOW);
+ if (!handle) {
+ fprintf(stderr, "dlopen: %s\n", dlerror());
+ return 1;
+ }
+
+ char *buffer = (char *)dlsym(handle, "buffer3");
+ if (!buffer) {
+ fprintf(stderr, "dlsym: %s\n", dlerror());
+ return 1;
+ }
+
+ buffer[argc] = 0;
+ // ASAN-CHECK-3: {{0x.* is located 1 bytes .* 'buffer3'}}
+ }
+
+ return 0;
+}
+
+#elif SECONDARY_FILE
+
+extern char buffer2[1];
+char buffer2[1] = { 0 };
+
+#elif SHARED_LIBRARY_FILE
+
+extern char buffer3[1];
+char buffer3[1] = { 0 };
+
+#endif
diff --git a/test/asan/TestCases/Posix/halt_on_error-torture.cc b/test/asan/TestCases/Posix/halt_on_error-torture.cc
index 019f7d126a47..d3af1d027703 100644
--- a/test/asan/TestCases/Posix/halt_on_error-torture.cc
+++ b/test/asan/TestCases/Posix/halt_on_error-torture.cc
@@ -9,15 +9,11 @@
//
// Collisions are unlikely but still possible so we need the ||.
// RUN: %env_asan_opts=halt_on_error=false:suppress_equal_pcs=false %run %t 10 20 >10.txt 2>&1 || true
-// This one is racy although _very_ unlikely to fail:
-// RUN: FileCheck %s < 10.txt
-// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
+// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 10.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 10.txt
//
// Collisions are unlikely but still possible so we need the ||.
// RUN: %env_asan_opts=halt_on_error=false %run %t 10 20 >10.txt 2>&1 || true
-// This one is racy although _very_ unlikely to fail:
-// RUN: FileCheck %s < 10.txt
-// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
+// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 10.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 10.txt
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/asan/TestCases/mmap_limit_mb.cc b/test/asan/TestCases/Posix/mmap_limit_mb.cc
index 379524121a88..379524121a88 100644
--- a/test/asan/TestCases/mmap_limit_mb.cc
+++ b/test/asan/TestCases/Posix/mmap_limit_mb.cc
diff --git a/test/asan/TestCases/Posix/print_cmdline.cc b/test/asan/TestCases/Posix/print_cmdline.cc
new file mode 100644
index 000000000000..8c83bd97e0ce
--- /dev/null
+++ b/test/asan/TestCases/Posix/print_cmdline.cc
@@ -0,0 +1,18 @@
+// Check that ASan can print reproducer cmdline for failed binary if desired.
+//
+// RUN: %clang_asan %s -o %t-exe
+//
+// RUN: env not %run %t-exe 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=print_cmdline=false not %run %t-exe 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=print_cmdline=true not %run %t-exe first second/third [fourth] 2>&1 | FileCheck %s --check-prefix CHECK-PRINT
+
+volatile int ten = 10;
+
+int main() {
+ char x[10];
+ // CHECK-NOT: Command:
+ // CHECK-PRINT: {{Command: .*-exe first second/third \[fourth\]}}
+ x[ten] = 1; // BOOM
+ return 0;
+}
+
diff --git a/test/asan/TestCases/Posix/start-deactivated.cc b/test/asan/TestCases/Posix/start-deactivated.cc
index b30141549014..187ee5e549ef 100644
--- a/test/asan/TestCases/Posix/start-deactivated.cc
+++ b/test/asan/TestCases/Posix/start-deactivated.cc
@@ -6,7 +6,7 @@
// RUN: %clangxx -O0 %s -c -o %t.o
// RUN: %clangxx_asan -O0 %t.o %libdl -o %t
// RUN: %env_asan_opts=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_ACTIVATION_OPTIONS=allocator_may_return_null=1 not %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=start_deactivated=1 \
// RUN: ASAN_ACTIVATION_OPTIONS=help=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-HELP
// RUN: %env_asan_opts=start_deactivated=1,verbosity=1 \
diff --git a/test/asan/TestCases/Windows/bind_io_completion_callback.cc b/test/asan/TestCases/Windows/bind_io_completion_callback.cc
index c062a799fdcc..44b92ab91465 100644
--- a/test/asan/TestCases/Windows/bind_io_completion_callback.cc
+++ b/test/asan/TestCases/Windows/bind_io_completion_callback.cc
@@ -6,8 +6,7 @@
// 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: %clangxx_asan %s -o %t.exe
// RUN: %run %t.exe 2>&1 | FileCheck %s
#include <windows.h>
@@ -15,7 +14,6 @@
void ThrowAndCatch();
-#if !defined(__clang__)
__declspec(noinline)
void Throw() {
fprintf(stderr, "Throw\n");
@@ -32,7 +30,6 @@ void ThrowAndCatch() {
// CHECK: Catch
}
}
-#else
char buffer[65536];
HANDLE done;
@@ -62,9 +59,8 @@ int main(int argc, char **argv) {
GetLastError() != ERROR_IO_PENDING)
return 4;
- if (WAIT_OBJECT_0 != WaitForSingleObject(done, INFINITE))
+ if (WAIT_OBJECT_0 != WaitForSingleObject(done, 10 * 1000))
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
index 0ff105d1624e..918872f18f91 100644
--- a/test/asan/TestCases/Windows/coverage-basic.cc
+++ b/test/asan/TestCases/Windows/coverage-basic.cc
@@ -6,8 +6,8 @@
// RUN: %sancov print *.sancov | FileCheck %s
#include <stdio.h>
-void foo() { fprintf(stderr, "FOO\n"); }
-void bar() { fprintf(stderr, "BAR\n"); }
+void foo() { fputs("FOO", stderr); }
+void bar() { fputs("BAR", stderr); }
int main(int argc, char **argv) {
if (argc == 2) {
diff --git a/test/asan/TestCases/Windows/crash_read_write.cc b/test/asan/TestCases/Windows/crash_read_write.cc
new file mode 100644
index 000000000000..74200cca1521
--- /dev/null
+++ b/test/asan/TestCases/Windows/crash_read_write.cc
@@ -0,0 +1,29 @@
+// RUN: %clangxx_asan -std=c++11 -O0 %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=READ
+// RUN: not %run %t write 2>&1 | FileCheck %s --check-prefix=WRITE
+
+#include <windows.h>
+#include <stdio.h>
+
+static volatile int sink;
+__attribute__((noinline)) void Read(int *ptr) { sink = *ptr; }
+__attribute__((noinline)) void Write(int *ptr) { *ptr = 0; }
+int main(int argc, char **argv) {
+ // Writes to shadow are detected as reads from shadow gap (because of how the
+ // shadow mapping works). This is kinda hard to fix. Test a random address in
+ // the application part of the address space.
+ void *volatile p = VirtualAlloc(0, 4096, MEM_COMMIT, PAGE_READONLY);
+ bool ok = VirtualFree(p, 0, MEM_RELEASE);
+ if (!ok) {
+ printf("VirtualFree failed\n");
+ return 0;
+ }
+ if (argc == 1)
+ Read((int *)p);
+ else
+ Write((int *)p);
+}
+// READ: AddressSanitizer: access-violation on unknown address
+// READ: The signal is caused by a READ memory access.
+// WRITE: AddressSanitizer: access-violation on unknown address
+// WRITE: The signal is caused by a WRITE memory access.
diff --git a/test/asan/TestCases/Windows/dll_seh.cc b/test/asan/TestCases/Windows/dll_seh.cc
index 6e4c724e504d..0962138cb52f 100644
--- a/test/asan/TestCases/Windows/dll_seh.cc
+++ b/test/asan/TestCases/Windows/dll_seh.cc
@@ -1,17 +1,10 @@
-// Clang doesn't support SEH on Windows yet, so for the time being we
-// build this program in two parts: the code with SEH 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: %clang_cl_asan -O0 %p/dll_host.cc -Fe%t
//
// Check both -GS and -GS- builds:
-// RUN: cl -LD -c %s -Fo%t.obj
-// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll %t.obj
+// RUN: %clang_cl_asan -GS -LD -O0 %s -Fe%t.dll
// RUN: %run %t %t.dll
//
-// RUN: cl -LD -GS- -c %s -Fo%t.obj
-// RUN: %clang_cl_asan -LD -O0 %s -Fe%t.dll %t.obj
+// RUN: %clang_cl_asan -GS- -LD -O0 %s -Fe%t.dll
// RUN: %run %t %t.dll
#include <windows.h>
@@ -24,7 +17,6 @@ extern "C" bool __asan_address_is_poisoned(void *p);
void ThrowAndCatch();
-#if !defined(__clang__)
__declspec(noinline)
void Throw() {
int local, zero = 0;
@@ -41,7 +33,6 @@ void ThrowAndCatch() {
fprintf(stderr, "__except: %p\n", &local);
}
}
-#else
extern "C" __declspec(dllexport)
int test_function() {
@@ -57,4 +48,3 @@ int test_function() {
assert(!__asan_address_is_poisoned(x + 32));
return 0;
}
-#endif
diff --git a/test/asan/TestCases/Windows/intercept_strdup.cc b/test/asan/TestCases/Windows/intercept_strdup.cc
index 371053480d2c..95b659ffd336 100644
--- a/test/asan/TestCases/Windows/intercept_strdup.cc
+++ b/test/asan/TestCases/Windows/intercept_strdup.cc
@@ -20,9 +20,13 @@ int main() {
// CHECK: {{#0 .* main .*}}intercept_strdup.cc:[[@LINE-3]]
// CHECK: [[ADDR]] is located 1 bytes to the left of 6-byte region
// CHECK: allocated by thread T0 here:
-// CHECK: {{#0 .* malloc }}
-// FIXME: llvm-symbolizer can't find strdup in the CRT.
-// CHECKX: {{#1 .*strdup}}
-// CHECK: {{#2 .* main .*}}intercept_strdup.cc:[[@LINE-17]]
+//
+// The first frame is our wrapper normally but will be malloc in the dynamic
+// config.
+// CHECK: #0 {{.*}} in {{malloc|__asan_wrap_strdup}}
+//
+// The local call to _strdup above may be the second or third frame depending
+// on whether we're using the dynamic config.
+// CHECK: #{{[12]}} {{.*}} in main {{.*}}intercept_strdup.cc:[[@LINE-21]]
free(ptr);
}
diff --git a/test/asan/TestCases/Windows/oom.cc b/test/asan/TestCases/Windows/oom.cc
index b24cddf17a97..3475af79e6a4 100644
--- a/test/asan/TestCases/Windows/oom.cc
+++ b/test/asan/TestCases/Windows/oom.cc
@@ -6,7 +6,6 @@
int main() {
while (true) {
void *ptr = malloc(200 * 1024 * 1024); // 200MB
- free(ptr);
}
// CHECK: failed to allocate
}
diff --git a/test/asan/TestCases/Windows/queue_user_work_item.cc b/test/asan/TestCases/Windows/queue_user_work_item.cc
index d99ea6fc2e45..2a0b622f6218 100644
--- a/test/asan/TestCases/Windows/queue_user_work_item.cc
+++ b/test/asan/TestCases/Windows/queue_user_work_item.cc
@@ -6,8 +6,7 @@
// 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: %clangxx_asan %s -o %t.exe
// RUN: %run %t.exe 2>&1 | FileCheck %s
#include <windows.h>
@@ -15,7 +14,6 @@
void ThrowAndCatch();
-#if !defined(__clang__)
__declspec(noinline)
void Throw() {
fprintf(stderr, "Throw\n");
@@ -32,7 +30,6 @@ void ThrowAndCatch() {
// CHECK: Catch
}
}
-#else
HANDLE done;
@@ -47,9 +44,13 @@ int main(int argc, char **argv) {
if (!done)
return 1;
QueueUserWorkItem(&work_item, nullptr, 0);
- if (WAIT_OBJECT_0 != WaitForSingleObject(done, INFINITE))
+ unsigned wait_result = WaitForSingleObject(done, 10 * 1000);
+ if (wait_result == WAIT_ABANDONED)
+ fprintf(stderr, "Timed out\n");
+ if (wait_result != WAIT_OBJECT_0) {
+ fprintf(stderr, "Wait for work item failed\n");
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
index f0d3d3e7cbcc..e500a919fdae 100644
--- a/test/asan/TestCases/Windows/queue_user_work_item_report.cc
+++ b/test/asan/TestCases/Windows/queue_user_work_item_report.cc
@@ -24,6 +24,6 @@ int main(int argc, char **argv) {
return 1;
// CHECK-NOT: Thread T1 created
QueueUserWorkItem(&work_item, nullptr, 0);
- if (WAIT_OBJECT_0 != WaitForSingleObject(done, INFINITE))
+ if (WAIT_OBJECT_0 != WaitForSingleObject(done, 10 * 1000))
return 2;
}
diff --git a/test/asan/TestCases/Windows/report_after_syminitialize.cc b/test/asan/TestCases/Windows/report_after_syminitialize.cc
index d83d7dc264a7..20bf69514179 100644
--- a/test/asan/TestCases/Windows/report_after_syminitialize.cc
+++ b/test/asan/TestCases/Windows/report_after_syminitialize.cc
@@ -14,8 +14,10 @@ int main() {
*(volatile int*)0 = 42;
// CHECK: ERROR: AddressSanitizer: access-violation on unknown address
+ // CHECK: The signal is caused by a WRITE memory access.
+ // CHECK: Hint: address points to the zero page.
// CHECK-NEXT: {{WARNING: Failed to use and restart external symbolizer}}
// CHECK-NEXT: {{WARNING: .*DbgHelp}}
- // CHECK: {{#0 0x.* in main.*report_after_syminitialize.cc:}}[[@LINE-4]]
+ // CHECK: {{#0 0x.* in main.*report_after_syminitialize.cc:}}[[@LINE-6]]
// CHECK: AddressSanitizer can not provide additional info.
}
diff --git a/test/asan/TestCases/Windows/throw_catch.cc b/test/asan/TestCases/Windows/throw_catch.cc
deleted file mode 100644
index 5313d25b26d6..000000000000
--- a/test/asan/TestCases/Windows/throw_catch.cc
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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
-
-#include <assert.h>
-#include <stdio.h>
-
-// Should just "#include <sanitizer/asan_interface.h>" when C++ exceptions are
-// supported and we don't need to use CL.
-extern "C" bool __asan_address_is_poisoned(void *p);
-
-void ThrowAndCatch();
-void TestThrowInline();
-
-#if !defined(__clang__)
-__declspec(noinline)
-void Throw() {
- int local;
- fprintf(stderr, "Throw: %p\n", &local);
- throw 1;
-}
-
-__declspec(noinline)
-void ThrowAndCatch() {
- int local;
- try {
- Throw();
- } catch(...) {
- fprintf(stderr, "Catch: %p\n", &local);
- }
-}
-
-void TestThrowInline() {
- char x[32];
- fprintf(stderr, "Before: %p poisoned: %d\n", &x,
- __asan_address_is_poisoned(x + 32));
- try {
- Throw();
- } catch(...) {
- fprintf(stderr, "Catch\n");
- }
- fprintf(stderr, "After: %p poisoned: %d\n", &x,
- __asan_address_is_poisoned(x + 32));
- // FIXME: Invert this assertion once we fix
- // https://code.google.com/p/address-sanitizer/issues/detail?id=258
- assert(!__asan_address_is_poisoned(x + 32));
-}
-
-#else
-
-void TestThrow() {
- char x[32];
- fprintf(stderr, "Before: %p poisoned: %d\n", &x,
- __asan_address_is_poisoned(x + 32));
- assert(__asan_address_is_poisoned(x + 32));
- ThrowAndCatch();
- fprintf(stderr, "After: %p poisoned: %d\n", &x,
- __asan_address_is_poisoned(x + 32));
- // FIXME: Invert this assertion once we fix
- // https://code.google.com/p/address-sanitizer/issues/detail?id=258
- assert(!__asan_address_is_poisoned(x + 32));
-}
-
-int main(int argc, char **argv) {
- TestThrowInline();
- TestThrow();
-}
-#endif
diff --git a/test/asan/TestCases/alloca_constant_size.cc b/test/asan/TestCases/alloca_constant_size.cc
new file mode 100644
index 000000000000..61f6da710116
--- /dev/null
+++ b/test/asan/TestCases/alloca_constant_size.cc
@@ -0,0 +1,51 @@
+// Regression test for https://github.com/google/sanitizers/issues/691
+
+// RUN: %clangxx_asan -O0 %s -o %t -fstack-protector
+// RUN: %run %t 1 2>&1 | FileCheck %s
+// RUN: %run %t 2 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <string.h>
+
+// MSVC provides _alloca instead of alloca.
+#if defined(_MSC_VER) && !defined(alloca)
+# define alloca _alloca
+#else
+#include <alloca.h>
+#endif
+
+
+void f1_alloca() {
+ char *dynamic_buffer = (char *)alloca(200);
+ fprintf(stderr, "dynamic_buffer = %p\n", dynamic_buffer);
+ memset(dynamic_buffer, 'y', 200);
+ return;
+}
+
+static const int kDynamicArraySize = 200;
+
+void f1_vla() {
+ char dynamic_buffer[kDynamicArraySize];
+ fprintf(stderr, "dynamic_buffer = %p\n", dynamic_buffer);
+ memset(dynamic_buffer, 'y', kDynamicArraySize);
+ return;
+}
+
+void f2() {
+ char buf[1024];
+ memset(buf, 'x', 1024);
+}
+
+int main(int argc, const char *argv[]) {
+ if (!strcmp(argv[1], "1")) {
+ f1_alloca();
+ } else if (!strcmp(argv[1], "2")) {
+ f1_vla();
+ }
+ f2();
+ fprintf(stderr, "Done.\n");
+ return 0;
+}
+
+// CHECK-NOT: ERROR: AddressSanitizer
+// CHECK: Done.
diff --git a/test/asan/TestCases/asan_and_llvm_coverage_test.cc b/test/asan/TestCases/asan_and_llvm_coverage_test.cc
index 4748481fe548..d53deb4475de 100644
--- a/test/asan/TestCases/asan_and_llvm_coverage_test.cc
+++ b/test/asan/TestCases/asan_and_llvm_coverage_test.cc
@@ -1,6 +1,8 @@
// RUN: %clangxx_asan -coverage -O0 %s -o %t
// RUN: %env_asan_opts=check_initialization_order=1 %run %t 2>&1 | FileCheck %s
-// XFAIL: android,win32
+// XFAIL: android
+// We don't really support running tests using profile runtime on Windows.
+// UNSUPPORTED: win32
#include <stdio.h>
int foo() { return 1; }
int XXX = foo();
diff --git a/test/asan/TestCases/contiguous_container_crash.cc b/test/asan/TestCases/contiguous_container_crash.cc
index 5b999c04930c..af2102e6a12d 100644
--- a/test/asan/TestCases/contiguous_container_crash.cc
+++ b/test/asan/TestCases/contiguous_container_crash.cc
@@ -23,6 +23,7 @@ int TestCrash() {
__sanitizer_annotate_contiguous_container(&t[0], &t[0] + 100, &t[0] + 100,
&t[0] + 50);
// CHECK-CRASH: AddressSanitizer: container-overflow
+// CHECK-CRASH: if you don't care about these errors you may set ASAN_OPTIONS=detect_container_overflow=0
return (int)t[60 * one]; // Touches the poisoned memory.
}
diff --git a/test/asan/TestCases/coverage-levels.cc b/test/asan/TestCases/coverage-levels.cc
index 612bbd83777a..83f7cf6f779d 100644
--- a/test/asan/TestCases/coverage-levels.cc
+++ b/test/asan/TestCases/coverage-levels.cc
@@ -25,10 +25,10 @@ int main(int argc, char **argv) {
// 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
+// CHECK2: CovDump: bitset of 2 bits written for '{{.*}}', 1 bits are set
+// CHECK2: 1 PCs written
+// CHECK3: CovDump: bitset of 3 bits written for '{{.*}}', 2 bits are set
+// CHECK3: 2 PCs written
// CHECK3_NOBITSET-NOT: bitset of
// CHECK3_NOPCS-NOT: PCs written
-// CHECK_COUNTERS: CovDump: 4 counters written for
+// CHECK_COUNTERS: CovDump: 3 counters written for
diff --git a/test/asan/TestCases/coverage-pc-buffer.cc b/test/asan/TestCases/coverage-pc-buffer.cc
index 67b6935ec602..5895a5c45d15 100644
--- a/test/asan/TestCases/coverage-pc-buffer.cc
+++ b/test/asan/TestCases/coverage-pc-buffer.cc
@@ -19,30 +19,47 @@ void assertNotZeroPcs(uintptr_t *buf, uintptr_t size) {
}
int main() {
- uintptr_t *buf = NULL;
- uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
- assertNotZeroPcs(buf, sz);
- assert(sz);
-
- foo();
- bar();
- uintptr_t *buf1 = NULL;
- uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
- assertNotZeroPcs(buf1, sz1);
- assert(buf1 == buf);
- assert(sz1 > sz);
-
- bar();
- uintptr_t *buf2 = NULL;
- uintptr_t sz2 = __sanitizer_get_coverage_pc_buffer(&buf2);
- assertNotZeroPcs(buf2, sz2);
- assert(buf2 == buf);
- assert(sz2 > sz1);
-
- __sanitizer_reset_coverage();
- uintptr_t *buf3 = NULL;
- uintptr_t sz3 = __sanitizer_get_coverage_pc_buffer(&buf3);
- assertNotZeroPcs(buf3, sz3);
- assert(buf3 == buf);
- assert(sz3 < sz2);
+ {
+ uintptr_t *buf = NULL;
+ uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+ assertNotZeroPcs(buf, sz);
+ assert(sz);
+ }
+
+ {
+ uintptr_t *buf = NULL;
+ uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+ // call functions for the first time.
+ foo();
+ bar();
+ uintptr_t *buf1 = NULL;
+ uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
+ assertNotZeroPcs(buf1, sz1);
+ assert(buf1 == buf);
+ assert(sz1 > sz);
+ }
+
+ {
+ uintptr_t *buf = NULL;
+ uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+ // second call shouldn't increase coverage.
+ bar();
+ uintptr_t *buf1 = NULL;
+ uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
+ assertNotZeroPcs(buf1, sz1);
+ assert(buf1 == buf);
+ assert(sz1 == sz);
+ }
+
+ {
+ uintptr_t *buf = NULL;
+ uintptr_t sz = __sanitizer_get_coverage_pc_buffer(&buf);
+ // reset coverage to 0.
+ __sanitizer_reset_coverage();
+ uintptr_t *buf1 = NULL;
+ uintptr_t sz1 = __sanitizer_get_coverage_pc_buffer(&buf1);
+ assertNotZeroPcs(buf1, sz1);
+ assert(buf1 == buf);
+ assert(sz1 < sz);
+ }
}
diff --git a/test/asan/TestCases/coverage-reset.cc b/test/asan/TestCases/coverage-reset.cc
index eb8da8c1aa06..11c5ef66ecf6 100644
--- a/test/asan/TestCases/coverage-reset.cc
+++ b/test/asan/TestCases/coverage-reset.cc
@@ -13,6 +13,13 @@ static volatile int sink;
__attribute__((noinline)) void bar() { sink = 2; }
__attribute__((noinline)) void foo() { sink = 1; }
+// In MSVC 2015, printf is an inline function, which causes this test to fail as
+// it introduces an extra coverage point. Define away printf on that platform to
+// avoid the issue.
+#if _MSC_VER >= 1900
+# define printf(arg, ...)
+#endif
+
#define GET_AND_PRINT_COVERAGE() \
bitset = 0; \
for (size_t i = 0; i < n_guards; i++) \
diff --git a/test/asan/TestCases/coverage-trace-pc.cc b/test/asan/TestCases/coverage-trace-pc.cc
new file mode 100644
index 000000000000..c03a6f02f771
--- /dev/null
+++ b/test/asan/TestCases/coverage-trace-pc.cc
@@ -0,0 +1,31 @@
+// Test -fsanitize-coverage=edge,indirect-call,trace-pc
+// RUN: %clangxx_asan -O0 -DTRACE_RT %s -o %t-rt.o -c
+// RUN: %clangxx_asan -O0 -fsanitize-coverage=edge,trace-pc,indirect-calls %s -o %t %t-rt.o
+// RUN: %run %t
+#ifdef TRACE_RT
+int pc_count;
+void *last_callee;
+extern "C" void __sanitizer_cov_trace_pc() {
+ pc_count++;
+}
+extern "C" void __sanitizer_cov_trace_pc_indir(void *callee) {
+ last_callee = callee;
+}
+#else
+#include <stdio.h>
+#include <assert.h>
+extern int pc_count;
+extern void *last_callee;
+
+__attribute__((noinline)) void foo() { printf("foo\n"); }
+__attribute__((noinline)) void bar() { printf("bar\n"); }
+
+int main(int argc, char **argv) {
+ void (*f)(void) = argc ? foo : bar;
+ int c1 = pc_count;
+ f();
+ int c2 = pc_count;
+ assert(c1 < c2);
+ assert(last_callee == foo);
+}
+#endif
diff --git a/test/asan/TestCases/debug_ppc64_mapping.cc b/test/asan/TestCases/debug_ppc64_mapping.cc
index 753a6364f4ed..43e1183a2d03 100644
--- a/test/asan/TestCases/debug_ppc64_mapping.cc
+++ b/test/asan/TestCases/debug_ppc64_mapping.cc
@@ -1,7 +1,7 @@
// RUN: %clang_asan -O0 %s -o %t
// RUN: %env_asan_opts=verbosity=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64-V0
// RUN: %env_asan_opts=verbosity=2 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-PPC64
-// REQUIRES: powerpc64-supported-target
+// REQUIRES: powerpc64-target-arch
#include <stdio.h>
diff --git a/test/asan/TestCases/double-free.cc b/test/asan/TestCases/double-free.cc
index 3297b435e38e..9bd418fc6c80 100644
--- a/test/asan/TestCases/double-free.cc
+++ b/test/asan/TestCases/double-free.cc
@@ -4,6 +4,10 @@
// Also works if no malloc context is available.
// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
+
+// RUN: %clangxx_asan -O0 -fsanitize-recover=address %s -o %t 2>&1
+// RUN: %env_asan_opts=halt_on_error=false %run %t 2>&1 | FileCheck %s --check-prefix CHECK-RECOVER
+
// XFAIL: arm-linux-gnueabi
// XFAIL: armv7l-unknown-linux-gnueabihf
@@ -23,5 +27,7 @@ int main(int argc, char **argv) {
// MALLOC-CTX: #1 0x{{.*}} in main {{.*}}double-free.cc:[[@LINE-7]]
// CHECK: allocated by thread T0 here:
// MALLOC-CTX: double-free.cc:[[@LINE-12]]
+ // CHECK-RECOVER: AddressSanitizer: attempting double-free{{.*}}in thread T0
+ // CHECK-RECOVER-NOT: AddressSanitizer CHECK failed:
return res;
}
diff --git a/test/asan/TestCases/initialization-bug.cc b/test/asan/TestCases/initialization-bug.cc
index f5497256354c..6f361cb2bad8 100644
--- a/test/asan/TestCases/initialization-bug.cc
+++ b/test/asan/TestCases/initialization-bug.cc
@@ -8,6 +8,9 @@
// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=186
// XFAIL: darwin,win32
+// The test is expected to fail on OS X Yosemite and older
+// UNSUPPORTED: osx-no-ld64-live_support
+
#include <cstdio>
// The structure of the test is:
diff --git a/test/asan/TestCases/invalid-pointer-pairs.cc b/test/asan/TestCases/invalid-pointer-pairs.cc
new file mode 100644
index 000000000000..b36e6cd9c10a
--- /dev/null
+++ b/test/asan/TestCases/invalid-pointer-pairs.cc
@@ -0,0 +1,44 @@
+// RUN: %clangxx_asan -O0 %s -o %t -mllvm -asan-detect-invalid-pointer-pair
+
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 %run %t k 2>&1 | FileCheck %s -check-prefix=OK -allow-empty
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t g 2>&1 | FileCheck %s -check-prefix=CMP -check-prefix=ALL-ERRORS
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t s 2>&1 | FileCheck %s -check-prefix=SUB -check-prefix=ALL-ERRORS
+// RUN: %env_asan_opts=detect_invalid_pointer_pairs=1 not %run %t f 2>&1 | FileCheck %s -check-prefix=FREE -check-prefix=ALL-ERRORS
+
+#include <assert.h>
+#include <stdlib.h>
+
+int f(char c, char *p, char *q) {
+ // ALL-ERRORS: ERROR: AddressSanitizer: invalid-pointer-pair
+ // [[PTR1:0x[0-9a-f]+]] [[PTR2:0x[0-9a-f]+]]
+ switch (c) {
+ case 'g':
+ // CMP: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]:14
+ return p > q;
+ case 's':
+ // SUB: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+1]]:14
+ return p - q;
+ case 'k': {
+ // OK-NOT: ERROR
+ char *p2 = p + 20;
+ return p > p2;
+ }
+ case 'f': {
+ char *p3 = p + 20;
+ free(p);
+ // FREE: #{{[0-9]+ .*}} in f({{char, char\*, char\*|char,char \*,char \*}}) {{.*}}invalid-pointer-pairs.cc:[[@LINE+2]]:14
+ // FREE: freed by thread
+ return p < p3;
+ }
+ }
+ assert(0);
+}
+
+int main(int argc, char **argv) {
+ char *p = (char *)malloc(42);
+ char *q = (char *)malloc(42);
+ assert(argc >= 2);
+ f(argv[1][0], p, q);
+ free(p);
+ free(q);
+}
diff --git a/test/asan/TestCases/large_func_test.cc b/test/asan/TestCases/large_func_test.cc
index 6b592f8c4397..8d9afaeb4a75 100644
--- a/test/asan/TestCases/large_func_test.cc
+++ b/test/asan/TestCases/large_func_test.cc
@@ -49,5 +49,5 @@ int main(int argc, char **argv) {
// CHECK-Linux: {{ #0 0x.* in operator new.*}}
// CHECK-Darwin: {{ #0 0x.* in .*_Zna.*}}
// CHECK: {{ #1 0x.* in main .*large_func_test.cc:}}[[@LINE-7]]
- delete x;
+ delete[] x;
}
diff --git a/test/asan/TestCases/printf-2.c b/test/asan/TestCases/printf-2.c
index 4b5ae138dfff..0544847ff5bf 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_opts=replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// RUN: %env_asan_opts=replace_str=0:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
-// RUN: %env_asan_opts=replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// We need replace_str=0, intercept_strlen=0 and replace_intrin=0 to avoid
+// reporting errors in strlen() and memcpy() called by printf().
+// RUN: %env_asan_opts=replace_str=0:intercept_strlen=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: %env_asan_opts=replace_str=0:intercept_strlen=0:replace_intrin=0:check_printf=0 %run %t 2>&1 | FileCheck --check-prefix=CHECK-OFF %s
+// RUN: %env_asan_opts=replace_str=0:intercept_strlen=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-4.c b/test/asan/TestCases/printf-4.c
index 13bfc876c36c..5a883fe99efd 100644
--- a/test/asan/TestCases/printf-4.c
+++ b/test/asan/TestCases/printf-4.c
@@ -1,10 +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_opts=replace_str=0:replace_intrin=0:check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// RUN: %env_asan_opts=replace_str=0:replace_intrin=0 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: %env_asan_opts=check_printf=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK-ON %s
-// FIXME: printf is not intercepted on Windows yet.
+// FIXME: sprintf is not intercepted on Windows yet.
// XFAIL: win32
#include <stdio.h>
@@ -14,10 +12,14 @@ int main() {
volatile float f = 1.239;
volatile char s[] = "34";
volatile char buf[2];
+ fputs("before sprintf\n", stderr);
sprintf((char *)buf, "%c %d %.3f %s\n", c, x, f, s);
- puts((const char *)buf);
+ fputs("after sprintf", stderr);
+ fputs((const char *)buf, stderr);
return 0;
// Check that size of output buffer is sanitized.
+ // CHECK-ON: before sprintf
+ // CHECK-ON-NOT: after sprintf
// CHECK-ON: stack-buffer-overflow
// CHECK-ON-NOT: 0 12 1.239 34
}
diff --git a/test/asan/TestCases/stack-oob-frames.cc b/test/asan/TestCases/stack-oob-frames.cc
index 00db4b3e1875..3b5d511b2681 100644
--- a/test/asan/TestCases/stack-oob-frames.cc
+++ b/test/asan/TestCases/stack-oob-frames.cc
@@ -4,9 +4,6 @@
// RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK2
// RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK3
-// FIXME: Symbolization problems.
-// XFAIL: win32
-
#define NOINLINE __attribute__((noinline))
inline void break_optimization(void *arg) {
__asm__ __volatile__("" : : "r" (arg) : "memory");
diff --git a/test/asan/TestCases/strcasestr-2.c b/test/asan/TestCases/strcasestr-2.c
index cca6d208cd43..47fd69225de6 100644
--- a/test/asan/TestCases/strcasestr-2.c
+++ b/test/asan/TestCases/strcasestr-2.c
@@ -3,7 +3,7 @@
// Test intercept_strstr asan option
// Disable other interceptors because strlen may be called inside strcasestr
-// RUN: %env_asan_opts=intercept_strstr=false:replace_str=false %run %t 2>&1
+// RUN: %env_asan_opts=intercept_strstr=false:replace_str=false:intercept_strlen=false %run %t 2>&1
// There's no interceptor for strcasestr on Windows
// XFAIL: win32
diff --git a/test/asan/TestCases/strdup_oob_test.cc b/test/asan/TestCases/strdup_oob_test.cc
index a039568b2245..492555ad1019 100644
--- a/test/asan/TestCases/strdup_oob_test.cc
+++ b/test/asan/TestCases/strdup_oob_test.cc
@@ -3,6 +3,12 @@
// 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
+// When built as C on Linux, strdup is transformed to __strdup.
+// RUN: %clangxx_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// Unwind problem on arm: "main" is missing from the allocation stack trace.
+// UNSUPPORTED: armv7l-unknown-linux-gnueabihf
+
#include <string.h>
char kString[] = "foo";
@@ -14,7 +20,8 @@ int main(int argc, char **argv) {
// CHECK: #0 {{.*}}main {{.*}}strdup_oob_test.cc:[[@LINE-2]]
// CHECK-LABEL: allocated by thread T{{.*}} here:
// CHECK: #{{[01]}} {{.*}}strdup
+ // CHECK: #{{.*}}main {{.*}}strdup_oob_test.cc:[[@LINE-6]]
// CHECK-LABEL: SUMMARY
- // CHECK: strdup_oob_test.cc:[[@LINE-6]]
+ // CHECK: strdup_oob_test.cc:[[@LINE-7]]
return x;
}
diff --git a/test/asan/TestCases/strstr-2.c b/test/asan/TestCases/strstr-2.c
index edb700865b83..8bc6e9902dd0 100644
--- a/test/asan/TestCases/strstr-2.c
+++ b/test/asan/TestCases/strstr-2.c
@@ -3,7 +3,7 @@
// Test intercept_strstr asan option
// Disable other interceptors because strlen may be called inside strstr
-// RUN: %env_asan_opts=intercept_strstr=false:replace_str=false %run %t 2>&1
+// RUN: %env_asan_opts=intercept_strstr=false:replace_str=false:intercept_strlen=false %run %t 2>&1
#include <assert.h>
#include <string.h>
diff --git a/test/asan/TestCases/throw_call_test.cc b/test/asan/TestCases/throw_call_test.cc
index 4b3910dce1eb..5a8204a04a54 100644
--- a/test/asan/TestCases/throw_call_test.cc
+++ b/test/asan/TestCases/throw_call_test.cc
@@ -5,9 +5,6 @@
// Android builds with static libstdc++ by default.
// XFAIL: android
-// Clang doesn't support exceptions on Windows yet.
-// XFAIL: win32
-
#include <stdio.h>
static volatile int zero = 0;
inline void pretend_to_do_something(void *x) {
diff --git a/test/asan/TestCases/throw_invoke_test.cc b/test/asan/TestCases/throw_invoke_test.cc
index ec48fc7b6a49..e6e91d1879cb 100644
--- a/test/asan/TestCases/throw_invoke_test.cc
+++ b/test/asan/TestCases/throw_invoke_test.cc
@@ -1,8 +1,5 @@
// RUN: %clangxx_asan %s -o %t && %run %t
-// RUN: %clangxx_asan %s -o %t -static-libstdc++ && %run %t
-
-// Clang doesn't support exceptions on Windows yet.
-// XFAIL: win32
+// RUN: %clangxx_asan %s -o %t -stdlib=libstdc++ -static-libstdc++ && %run %t
#include <stdio.h>
static volatile int zero = 0;
diff --git a/test/asan/TestCases/uar_and_exceptions.cc b/test/asan/TestCases/uar_and_exceptions.cc
index 324e8a52bd54..2357ae803ac2 100644
--- a/test/asan/TestCases/uar_and_exceptions.cc
+++ b/test/asan/TestCases/uar_and_exceptions.cc
@@ -2,9 +2,6 @@
// RUN: %clangxx_asan -O0 %s -o %t
// RUN: %env_asan_opts=detect_stack_use_after_return=1 %run %t
-// Clang doesn't support exceptions on Windows yet.
-// XFAIL: win32
-
#include <stdio.h>
volatile char *g;
diff --git a/test/asan/TestCases/use-after-scope-capture.cc b/test/asan/TestCases/use-after-scope-capture.cc
new file mode 100644
index 000000000000..07aab672eecb
--- /dev/null
+++ b/test/asan/TestCases/use-after-scope-capture.cc
@@ -0,0 +1,17 @@
+// RUN: %clangxx_asan -std=c++11 -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+#include <functional>
+
+int main() {
+ std::function<int()> f;
+ {
+ int x = 0;
+ f = [&x]() {
+ return x; // BOOM
+ // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
+ // CHECK: #0 0x{{.*}} in {{.*}}use-after-scope-capture.cc:[[@LINE-2]]
+ };
+ }
+ return f(); // BOOM
+}
diff --git a/test/asan/TestCases/use-after-scope-chars.cc b/test/asan/TestCases/use-after-scope-chars.cc
new file mode 100644
index 000000000000..51fc5fa38747
--- /dev/null
+++ b/test/asan/TestCases/use-after-scope-chars.cc
@@ -0,0 +1,15 @@
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+// XFAIL: *
+
+// FIXME: This works only for arraysize <= 8.
+
+char *p = 0;
+
+int main() {
+ {
+ char x[1024] = {};
+ p = x;
+ }
+ return *p; // BOOM
+}
diff --git a/test/asan/TestCases/use-after-scope-dtor-order.cc b/test/asan/TestCases/use-after-scope-dtor-order.cc
index 7896dd30c400..8cdfa6a1cd41 100644
--- a/test/asan/TestCases/use-after-scope-dtor-order.cc
+++ b/test/asan/TestCases/use-after-scope-dtor-order.cc
@@ -1,6 +1,6 @@
-// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
// RUN: not %run %t 2>&1 | FileCheck %s
-// XFAIL: *
+
#include <stdio.h>
struct IntHolder {
@@ -8,7 +8,7 @@ struct IntHolder {
~IntHolder() {
printf("Value: %d\n", *val_); // BOOM
// CHECK: ERROR: AddressSanitizer: stack-use-after-scope
- // CHECK: #0 0x{{.*}} in IntHolder::~IntHolder{{.*}}use-after-scope-dtor-order.cc:[[@LINE-2]]
+ // CHECK: #0 0x{{.*}} in IntHolder::~IntHolder{{.*}}.cc:[[@LINE-2]]
}
void set(int *val) { val_ = val; }
int *get() { return val_; }
diff --git a/test/asan/TestCases/use-after-scope-if.cc b/test/asan/TestCases/use-after-scope-if.cc
new file mode 100644
index 000000000000..8180077a0cc1
--- /dev/null
+++ b/test/asan/TestCases/use-after-scope-if.cc
@@ -0,0 +1,15 @@
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+int *p;
+bool b = true;
+
+int main() {
+ if (b) {
+ int x[5];
+ p = x+1;
+ }
+ return *p; // BOOM
+ // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
+ // CHECK: #0 0x{{.*}} in main {{.*}}.cc:[[@LINE-2]]
+}
diff --git a/test/asan/TestCases/use-after-scope-inlined.cc b/test/asan/TestCases/use-after-scope-inlined.cc
index a0a0d9461cb9..fc8c7f7bb87d 100644
--- a/test/asan/TestCases/use-after-scope-inlined.cc
+++ b/test/asan/TestCases/use-after-scope-inlined.cc
@@ -2,8 +2,8 @@
// happens. "always_inline" is not enough, as Clang doesn't emit
// llvm.lifetime intrinsics at -O0.
//
-// RUN: %clangxx_asan -O2 -fsanitize=use-after-scope %s -o %t && not %run %t 2>&1 | FileCheck %s
-// XFAIL: *
+// RUN: %clangxx_asan -O2 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
int *arr;
diff --git a/test/asan/TestCases/use-after-scope-loop-bug.cc b/test/asan/TestCases/use-after-scope-loop-bug.cc
new file mode 100644
index 000000000000..6ad9bf3260cc
--- /dev/null
+++ b/test/asan/TestCases/use-after-scope-loop-bug.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+//
+// FIXME: @llvm.lifetime.* are not emitted for x.
+// XFAIL: *
+
+int *p;
+
+int main() {
+ // Variable goes in and out of scope.
+ for (int i = 0; i < 3; ++i) {
+ int x[3] = {i, i, i};
+ p = x + i;
+ }
+ return *p; // BOOM
+}
diff --git a/test/asan/TestCases/use-after-scope-loop-removed.cc b/test/asan/TestCases/use-after-scope-loop-removed.cc
new file mode 100644
index 000000000000..cd71a5046cd4
--- /dev/null
+++ b/test/asan/TestCases/use-after-scope-loop-removed.cc
@@ -0,0 +1,19 @@
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+//
+// FIXME: Compiler removes for-loop but keeps x variable. For unknown reason
+// @llvm.lifetime.* are not emitted for x.
+// XFAIL: *
+
+#include <stdlib.h>
+
+int *p;
+
+int main() {
+ for (int i = 0; i < 3; i++) {
+ int x;
+ p = &x;
+ }
+ return **p; // BOOM
+ // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
+}
diff --git a/test/asan/TestCases/use-after-scope-loop.cc b/test/asan/TestCases/use-after-scope-loop.cc
new file mode 100644
index 000000000000..d99761bc7a84
--- /dev/null
+++ b/test/asan/TestCases/use-after-scope-loop.cc
@@ -0,0 +1,14 @@
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+int *p[3];
+
+int main() {
+ for (int i = 0; i < 3; i++) {
+ int x;
+ p[i] = &x;
+ }
+ return **p; // BOOM
+ // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
+ // CHECK: #0 0x{{.*}} in main {{.*}}.cc:[[@LINE-2]]
+}
diff --git a/test/asan/TestCases/use-after-scope-nobug.cc b/test/asan/TestCases/use-after-scope-nobug.cc
index 21b085c96275..cf471dc345fa 100644
--- a/test/asan/TestCases/use-after-scope-nobug.cc
+++ b/test/asan/TestCases/use-after-scope-nobug.cc
@@ -1,14 +1,15 @@
-// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && %run %t
-// XFAIL: *
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && %run %t
#include <stdio.h>
+#include <stdlib.h>
+
+int *p[3];
int main() {
- int *p = 0;
// Variable goes in and out of scope.
for (int i = 0; i < 3; i++) {
- int x = 0;
- p = &x;
+ int x;
+ p[i] = &x;
}
printf("PASSED\n");
return 0;
diff --git a/test/asan/TestCases/use-after-scope-temp.cc b/test/asan/TestCases/use-after-scope-temp.cc
index f9bd779ac1a2..3736f914d072 100644
--- a/test/asan/TestCases/use-after-scope-temp.cc
+++ b/test/asan/TestCases/use-after-scope-temp.cc
@@ -1,15 +1,10 @@
-// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \
-// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
//
// Lifetime for temporaries is not emitted yet.
// XFAIL: *
-#include <stdio.h>
-
struct IntHolder {
- explicit IntHolder(int val) : val(val) {
- printf("IntHolder: %d\n", val);
- }
int val;
};
@@ -20,10 +15,9 @@ void save(const IntHolder &holder) {
}
int main(int argc, char *argv[]) {
- save(IntHolder(10));
+ save({10});
int x = saved->val; // BOOM
- // CHECK: ERROR: AddressSanitizer: stack-use-after-scope
- // CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope-temp.cc:[[@LINE-2]]
- printf("saved value: %d\n", x);
- return 0;
+// CHECK: ERROR: AddressSanitizer: stack-use-after-scope
+// CHECK: #0 0x{{.*}} in main {{.*}}use-after-scope-temp.cc:[[@LINE-2]]
+ return x;
}
diff --git a/test/asan/TestCases/use-after-scope.cc b/test/asan/TestCases/use-after-scope.cc
index 59a0e0cd6e44..1aa6758229dd 100644
--- a/test/asan/TestCases/use-after-scope.cc
+++ b/test/asan/TestCases/use-after-scope.cc
@@ -1,10 +1,9 @@
-// RUN: %clangxx_asan -O0 -fsanitize=use-after-scope %s -o %t && \
-// RUN: not %run %t 2>&1 | FileCheck %s
-// RUN: %env_asan_opts=detect_stack_use_after_return=1 not %run %t 2>&1 | FileCheck %s
-// XFAIL: *
+// RUN: %clangxx_asan -O1 -fsanitize-address-use-after-scope %s -o %t && \
+// RUN: not %run %t 2>&1 | FileCheck %s
+
+int *p = 0;
int main() {
- int *p = 0;
{
int x = 0;
p = &x;
diff --git a/test/asan/Unit/lit.site.cfg.in b/test/asan/Unit/lit.site.cfg.in
index b5991023ee8a..55631a6d927f 100644
--- a/test/asan/Unit/lit.site.cfg.in
+++ b/test/asan/Unit/lit.site.cfg.in
@@ -1,5 +1,4 @@
-## Autogenerated by LLVM/Clang configuration.
-# Do not edit!
+@LIT_SITE_CFG_IN_HEADER@
import os
diff --git a/test/asan/android_commands/android_common.py b/test/asan/android_commands/android_common.py
index 43ac7b48d770..1a295b7817aa 100644
--- a/test/asan/android_commands/android_common.py
+++ b/test/asan/android_commands/android_common.py
@@ -8,15 +8,30 @@ verbose = False
if os.environ.get('ANDROID_RUN_VERBOSE') == '1':
verbose = True
-def adb(args):
+def adb(args, attempts = 1):
if verbose:
print args
- devnull = open(os.devnull, 'w')
- return subprocess.call([ADB] + args, stdout=devnull, stderr=subprocess.STDOUT)
+ tmpname = tempfile.mktemp()
+ out = open(tmpname, 'w')
+ ret = 255
+ while attempts > 0 and ret != 0:
+ attempts -= 1
+ ret = subprocess.call([ADB] + args, stdout=out, stderr=subprocess.STDOUT)
+ if attempts != 0:
+ ret = 5
+ if ret != 0:
+ print "adb command failed", args
+ print tmpname
+ out.close()
+ out = open(tmpname, 'r')
+ print out.read()
+ out.close()
+ os.unlink(tmpname)
+ return ret
def pull_from_device(path):
tmp = tempfile.mktemp()
- adb(['pull', path, tmp])
+ adb(['pull', path, tmp], 5)
text = open(tmp, 'r').read()
os.unlink(tmp)
return text
@@ -25,5 +40,5 @@ def push_to_device(path):
# Workaround for https://code.google.com/p/android/issues/detail?id=65857
dst_path = os.path.join(ANDROID_TMPDIR, os.path.basename(path))
tmp_path = dst_path + '.push'
- adb(['push', path, tmp_path])
- adb(['shell', 'cp "%s" "%s" 2>&1' % (tmp_path, dst_path)])
+ adb(['push', path, tmp_path], 5)
+ adb(['shell', 'cp "%s" "%s" 2>&1' % (tmp_path, dst_path)], 5)
diff --git a/test/asan/lit.cfg b/test/asan/lit.cfg
index 835547090a17..894c3f859fbd 100644
--- a/test/asan/lit.cfg
+++ b/test/asan/lit.cfg
@@ -73,6 +73,8 @@ clang_asan_static_cflags = (["-fsanitize=address",
"-fno-omit-frame-pointer",
"-fno-optimize-sibling-calls"] +
config.debug_info_flags + target_cflags)
+if config.target_arch == 's390x':
+ clang_asan_static_cflags.append("-mbackchain")
clang_asan_static_cxxflags = config.cxx_mode_flags + clang_asan_static_cflags
if config.asan_dynamic:
@@ -138,7 +140,7 @@ sancov = os.path.join(sanitizer_common_source_dir, "scripts", "sancov.py")
if not os.path.exists(sancov):
lit_config.fatal("Can't find script on path %r" % sancov)
python_exec = get_required_attr(config, "python_executable")
-config.substitutions.append( ("%sancov", python_exec + " " + sancov + " ") )
+config.substitutions.append( ("%sancov ", python_exec + " " + sancov + " ") )
# Determine kernel bitness
if config.host_arch.find('64') != -1 and config.android != "1":
diff --git a/test/asan/lit.site.cfg.in b/test/asan/lit.site.cfg.in
index 332f9ad9f828..1b6fed2cb9d6 100644
--- a/test/asan/lit.site.cfg.in
+++ b/test/asan/lit.site.cfg.in
@@ -1,12 +1,10 @@
-## Autogenerated by LLVM/Clang configuration.
-# Do not edit!
+@LIT_SITE_CFG_IN_HEADER@
# Tool-specific config options.
config.name_suffix = "@ASAN_TEST_CONFIG_SUFFIX@"
config.asan_lit_source_dir = "@ASAN_LIT_SOURCE_DIR@"
config.target_cflags = "@ASAN_TEST_TARGET_CFLAGS@"
config.clang = "@ASAN_TEST_TARGET_CC@"
-config.llvm_tools_dir = "@LLVM_TOOLS_BINARY_DIR@"
config.bits = "@ASAN_TEST_BITS@"
config.android = "@ANDROID@"
config.asan_dynamic = @ASAN_TEST_DYNAMIC@