aboutsummaryrefslogtreecommitdiff
path: root/test/sanitizer_common/TestCases
diff options
context:
space:
mode:
Diffstat (limited to 'test/sanitizer_common/TestCases')
-rw-r--r--test/sanitizer_common/TestCases/Darwin/abort_on_error.cc19
-rw-r--r--test/sanitizer_common/TestCases/Darwin/lit.local.cfg9
-rw-r--r--test/sanitizer_common/TestCases/Linux/abort_on_error.cc20
-rw-r--r--test/sanitizer_common/TestCases/Linux/assert.cc4
-rw-r--r--test/sanitizer_common/TestCases/Linux/fpe.cc30
-rw-r--r--test/sanitizer_common/TestCases/Linux/getpass.cc1
-rw-r--r--test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc6
-rw-r--r--test/sanitizer_common/TestCases/Linux/ill.cc27
-rw-r--r--test/sanitizer_common/TestCases/Linux/open_memstream.cc30
-rw-r--r--test/sanitizer_common/TestCases/Linux/ptrace.cc45
-rw-r--r--test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc23
-rw-r--r--test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc32
-rw-r--r--test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc6
-rw-r--r--test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc7
-rw-r--r--test/sanitizer_common/TestCases/fopen_nullptr.c6
-rw-r--r--test/sanitizer_common/TestCases/options-help.cc2
-rw-r--r--test/sanitizer_common/TestCases/options-include.cc39
-rw-r--r--test/sanitizer_common/TestCases/options-invalid.cc4
-rw-r--r--test/sanitizer_common/TestCases/print-stack-trace.cc8
19 files changed, 264 insertions, 54 deletions
diff --git a/test/sanitizer_common/TestCases/Darwin/abort_on_error.cc b/test/sanitizer_common/TestCases/Darwin/abort_on_error.cc
new file mode 100644
index 000000000000..dbab5253d8c1
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Darwin/abort_on_error.cc
@@ -0,0 +1,19 @@
+// Check that sanitizers on OS X crash the process by default (i.e.
+// abort_on_error=1). See also Linux/abort_on_error.cc.
+
+// RUN: %clangxx %s -o %t
+
+// Intentionally don't inherit the default options.
+// RUN: %tool_options='' not --crash %run %t 2>&1
+
+// When we use lit's default options, we shouldn't crash.
+// RUN: not %run %t 2>&1
+
+int global;
+
+int main() {
+ volatile int *a = new int[100];
+ delete[] a;
+ global = a[0]; // use-after-free: triggers ASan report.
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Darwin/lit.local.cfg b/test/sanitizer_common/TestCases/Darwin/lit.local.cfg
new file mode 100644
index 000000000000..a85dfcd24c08
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Darwin/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Darwin']:
+ config.unsupported = True
diff --git a/test/sanitizer_common/TestCases/Linux/abort_on_error.cc b/test/sanitizer_common/TestCases/Linux/abort_on_error.cc
new file mode 100644
index 000000000000..7e444c2103ee
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/abort_on_error.cc
@@ -0,0 +1,20 @@
+// Check that sanitizers call _exit() on Linux by default (i.e.
+// abort_on_error=0). See also Darwin/abort_on_error.cc.
+
+// RUN: %clangxx %s -o %t
+
+// Intentionally don't inherit the default options.
+// RUN: %tool_options='' not %run %t 2>&1
+
+// When we use lit's default options, we shouldn't crash either. On Linux
+// lit doesn't set options anyway.
+// RUN: not %run %t 2>&1
+
+namespace __sanitizer {
+void Die();
+}
+
+int main() {
+ __sanitizer::Die();
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/assert.cc b/test/sanitizer_common/TestCases/Linux/assert.cc
index 7f9b0a061da0..5d58ea4f7e81 100644
--- a/test/sanitizer_common/TestCases/Linux/assert.cc
+++ b/test/sanitizer_common/TestCases/Linux/assert.cc
@@ -1,8 +1,8 @@
// Test the handle_abort option.
// RUN: %clang %s -o %t
// RUN: not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
-// RUN: %tool_options=handle_abort=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
-// RUN: %tool_options=handle_abort=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
+// RUN: %env_tool_opts=handle_abort=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
+// RUN: %env_tool_opts=handle_abort=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
// FIXME: implement in other sanitizers, not just asan.
// XFAIL: msan
// XFAIL: lsan
diff --git a/test/sanitizer_common/TestCases/Linux/fpe.cc b/test/sanitizer_common/TestCases/Linux/fpe.cc
new file mode 100644
index 000000000000..b4be500732b7
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/fpe.cc
@@ -0,0 +1,30 @@
+// Test the handle_sigfpe option.
+// RUN: %clang %s -o %t
+// RUN: not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
+// RUN: %env_tool_opts=handle_sigfpe=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
+// RUN: %env_tool_opts=handle_sigfpe=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
+// FIXME: implement in other sanitizers, not just asan.
+// XFAIL: msan
+// XFAIL: lsan
+// XFAIL: tsan
+//
+// FIXME: seems to fail on ARM
+// REQUIRES: x86_64-supported-target
+#include <assert.h>
+#include <stdio.h>
+#include <sanitizer/asan_interface.h>
+
+void death() {
+ fprintf(stderr, "DEATH CALLBACK\n");
+}
+
+int main(int argc, char **argv) {
+ __sanitizer_set_death_callback(death);
+ volatile int one = 1;
+ volatile int zero = 0;
+ volatile int sink;
+ sink = one / zero;
+}
+// CHECK1: ERROR: {{.*}}Sanitizer:
+// CHECK1: DEATH CALLBACK
+// CHECK0-NOT: Sanitizer
diff --git a/test/sanitizer_common/TestCases/Linux/getpass.cc b/test/sanitizer_common/TestCases/Linux/getpass.cc
index c9a2276cc248..902c9cb5655c 100644
--- a/test/sanitizer_common/TestCases/Linux/getpass.cc
+++ b/test/sanitizer_common/TestCases/Linux/getpass.cc
@@ -1,4 +1,5 @@
// RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t | FileCheck %s
+// REQUIRES: stable-runtime
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
diff --git a/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc b/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
index 225c44e25cd0..d4a60a0d3731 100644
--- a/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
+++ b/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
@@ -2,12 +2,12 @@
// RUN: %clangxx -O2 %s -o %t
//
// Run with limit should fail:
-// RUN: %tool_options=hard_rss_limit_mb=100 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=hard_rss_limit_mb=100 not %run %t 2>&1 | FileCheck %s
// This run uses getrusage:
-// RUN: %tool_options=hard_rss_limit_mb=100:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=hard_rss_limit_mb=100:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s
//
// Run w/o limit or with a large enough limit should pass:
-// RUN: %tool_options=hard_rss_limit_mb=1000 %run %t
+// RUN: %env_tool_opts=hard_rss_limit_mb=1000 %run %t
// RUN: %run %t
//
// FIXME: make it work for other sanitizers.
diff --git a/test/sanitizer_common/TestCases/Linux/ill.cc b/test/sanitizer_common/TestCases/Linux/ill.cc
new file mode 100644
index 000000000000..1edad4817a2f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/ill.cc
@@ -0,0 +1,27 @@
+// Test the handle_sigill option.
+// RUN: %clang %s -o %t -O1
+// RUN: not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
+// RUN: %env_tool_opts=handle_sigill=0 not --crash %run %t 2>&1 | FileCheck --check-prefix=CHECK0 %s
+// RUN: %env_tool_opts=handle_sigill=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK1 %s
+// FIXME: implement in other sanitizers, not just asan.
+// XFAIL: msan
+// XFAIL: lsan
+// XFAIL: tsan
+//
+// FIXME: seems to fail on ARM
+// REQUIRES: x86_64-supported-target
+#include <assert.h>
+#include <stdio.h>
+#include <sanitizer/asan_interface.h>
+
+void death() {
+ fprintf(stderr, "DEATH CALLBACK\n");
+}
+
+int main(int argc, char **argv) {
+ __sanitizer_set_death_callback(death);
+ __builtin_trap();
+}
+// CHECK1: ERROR: {{.*}}Sanitizer:
+// CHECK1: DEATH CALLBACK
+// CHECK0-NOT: Sanitizer
diff --git a/test/sanitizer_common/TestCases/Linux/open_memstream.cc b/test/sanitizer_common/TestCases/Linux/open_memstream.cc
index 69097c094a93..3bce030ddb23 100644
--- a/test/sanitizer_common/TestCases/Linux/open_memstream.cc
+++ b/test/sanitizer_common/TestCases/Linux/open_memstream.cc
@@ -25,16 +25,18 @@ static void check_mem_is_good(void *p, size_t s) {
static void check_mem_is_good(void *p, size_t s) {}
#endif
-static void run(void) {
+static void run(bool flush) {
char *buf;
size_t buf_len;
fprintf(stderr, " &buf %p, &buf_len %p\n", &buf, &buf_len);
FILE *fp = open_memstream(&buf, &buf_len);
fprintf(fp, "hello");
- fflush(fp);
- check_mem_is_good(&buf, sizeof(buf));
- check_mem_is_good(&buf_len, sizeof(buf_len));
- check_mem_is_good(buf, buf_len);
+ if (flush) {
+ fflush(fp);
+ check_mem_is_good(&buf, sizeof(buf));
+ check_mem_is_good(&buf_len, sizeof(buf_len));
+ check_mem_is_good(buf, buf_len);
+ }
char *p = new char[1024];
memset(p, 'a', 1023);
@@ -42,17 +44,27 @@ static void run(void) {
for (int i = 0; i < 100; ++i)
fprintf(fp, "%s", p);
delete[] p;
- fflush(fp);
- fprintf(stderr, " %p addr %p, len %zu\n", &buf, buf, buf_len);
+
+ if (flush) {
+ fflush(fp);
+ fprintf(stderr, " %p addr %p, len %zu\n", &buf, buf, buf_len);
+ check_mem_is_good(&buf, sizeof(buf));
+ check_mem_is_good(&buf_len, sizeof(buf_len));
+ check_mem_is_good(buf, buf_len);\
+ }
+
+ fclose(fp);
check_mem_is_good(&buf, sizeof(buf));
check_mem_is_good(&buf_len, sizeof(buf_len));
check_mem_is_good(buf, buf_len);
- fclose(fp);
+
free(buf);
}
int main(void) {
for (int i = 0; i < 100; ++i)
- run();
+ run(false);
+ for (int i = 0; i < 100; ++i)
+ run(true);
return 0;
}
diff --git a/test/sanitizer_common/TestCases/Linux/ptrace.cc b/test/sanitizer_common/TestCases/Linux/ptrace.cc
index ba318169ee7d..67b64743043b 100644
--- a/test/sanitizer_common/TestCases/Linux/ptrace.cc
+++ b/test/sanitizer_common/TestCases/Linux/ptrace.cc
@@ -7,11 +7,17 @@
#include <sys/types.h>
#include <sys/user.h>
#include <sys/wait.h>
+#include <sys/uio.h>
#include <unistd.h>
-#if __mips64
+#include <elf.h>
+#if __mips64 || __arm__
#include <asm/ptrace.h>
#include <sys/procfs.h>
#endif
+#ifdef __aarch64__
+// GLIBC 2.20+ sys/user does not include asm/ptrace.h
+ #include <asm/ptrace.h>
+#endif
int main(void) {
pid_t pid;
@@ -37,23 +43,54 @@ int main(void) {
printf("%x\n", fpregs.mxcsr);
#endif // __x86_64__
-#if (__powerpc64__ || __mips64)
+#if (__powerpc64__ || __mips64 || __arm__)
struct pt_regs regs;
res = ptrace((enum __ptrace_request)PTRACE_GETREGS, pid, NULL, &regs);
assert(!res);
#if (__powerpc64__)
if (regs.nip)
printf("%lx\n", regs.nip);
-#else
+#elif (__mips64)
if (regs.cp0_epc)
printf("%lx\n", regs.cp0_epc);
+#elif (__arm__)
+ if (regs.ARM_pc)
+ printf("%lx\n", regs.ARM_pc);
#endif
+#if (__powerpc64 || __mips64)
elf_fpregset_t fpregs;
res = ptrace((enum __ptrace_request)PTRACE_GETFPREGS, pid, NULL, &fpregs);
assert(!res);
if ((elf_greg_t)fpregs[32]) // fpscr
printf("%lx\n", (elf_greg_t)fpregs[32]);
-#endif // (__powerpc64__ || __mips64)
+#elif (__arm__)
+ char regbuf[ARM_VFPREGS_SIZE];
+ res = ptrace((enum __ptrace_request)PTRACE_GETVFPREGS, pid, 0, regbuf);
+ assert(!res);
+ unsigned fpscr = *(unsigned*)(regbuf + (32 * 8));
+ printf ("%x\n", fpscr);
+#endif
+#endif // (__powerpc64__ || __mips64 || __arm__)
+
+#if (__aarch64__)
+ struct iovec regset_io;
+
+ struct user_pt_regs regs;
+ regset_io.iov_base = &regs;
+ regset_io.iov_len = sizeof(regs);
+ res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_PRSTATUS, (void*)&regset_io);
+ assert(!res);
+ if (regs.pc)
+ printf("%llx\n", regs.pc);
+
+ struct user_fpsimd_state fpregs;
+ regset_io.iov_base = &fpregs;
+ regset_io.iov_len = sizeof(fpregs);
+ res = ptrace(PTRACE_GETREGSET, pid, (void*)NT_FPREGSET, (void*)&regset_io);
+ assert(!res);
+ if (fpregs.fpsr)
+ printf("%x\n", fpregs.fpsr);
+#endif // (__aarch64__)
siginfo_t siginfo;
res = ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);
diff --git a/test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc b/test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc
index ee3d59c72172..fdb68c0cdea5 100644
--- a/test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc
+++ b/test/sanitizer_common/TestCases/Linux/sanitizer_set_death_callback_test.cc
@@ -1,11 +1,9 @@
// RUN: %clangxx -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
-// Check __sanitizer_set_death_callback. Not all sanitizers implement it yet.
-// XFAIL: lsan
-// XFAIL: tsan
+
+// REQUIRES: stable-runtime
#include <sanitizer/common_interface_defs.h>
#include <stdio.h>
-#include <pthread.h>
volatile char *zero = 0;
@@ -14,14 +12,9 @@ void Death() {
}
// CHECK: DEATH CALLBACK EXECUTED
-int global[10];
+char global;
volatile char *sink;
-void *Thread(void *x) {
- global[0]++;
- return x;
-}
-
__attribute__((noinline))
void MaybeInit(int *uninitialized) {
if (zero)
@@ -38,12 +31,10 @@ int main(int argc, char **argv) {
__sanitizer_set_death_callback(Death);
MaybeInit(&uninitialized);
if (uninitialized) // trigger msan report.
- global[0] = 77;
- pthread_t t;
- pthread_create(&t, 0, Thread, 0);
- global[0]++; // trigger tsan report.
- pthread_join(t, 0);
- global[argc + 10]++; // trigger asan report.
+ global = 77;
+ sink = new char[100];
+ delete[] sink;
+ global = sink[0]; // use-after-free: trigger asan/tsan report.
Leak();
sink = 0;
}
diff --git a/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc b/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
new file mode 100644
index 000000000000..f17453b2d517
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/sem_init_glibc.cc
@@ -0,0 +1,32 @@
+// RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t
+// This test depends on the glibc layout of struct sem_t and checks that we
+// don't leave sem_t::private uninitialized.
+// UNSUPPORTED: android
+#include <assert.h>
+#include <semaphore.h>
+#include <string.h>
+
+void my_sem_init(bool priv, int value, unsigned *a, unsigned char *b) {
+ sem_t sem;
+ memset(&sem, 0xAB, sizeof(sem));
+ sem_init(&sem, priv, value);
+
+ char *p = (char *)&sem;
+ memcpy(a, p, sizeof(unsigned));
+ memcpy(b, p + sizeof(unsigned), sizeof(char));
+
+ sem_destroy(&sem);
+}
+
+int main() {
+ unsigned a;
+ unsigned char b;
+
+ my_sem_init(false, 42, &a, &b);
+ assert(a == 42);
+ assert(b != 0xAB);
+
+ my_sem_init(true, 43, &a, &b);
+ assert(a == 43);
+ assert(b != 0xAB);
+}
diff --git a/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc b/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
index 145cc5d05769..d329122ae7f8 100644
--- a/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
+++ b/test/sanitizer_common/TestCases/Linux/soft_rss_limit_mb_test.cc
@@ -2,12 +2,12 @@
// RUN: %clangxx -O2 %s -o %t
//
// Run with limit should fail:
-// RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_1
-// RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
+// RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_1
+// RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
// This run uses getrusage. We can only test getrusage when allocator_may_return_null=0
// because getrusage gives us max-rss, not current-rss.
-// RUN: %tool_options=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
+// RUN: %env_tool_opts=soft_rss_limit_mb=220:quarantine_size=1:allocator_may_return_null=0:can_use_proc_maps_statm=0 not %run %t 2>&1 | FileCheck %s -check-prefix=CHECK_MAY_RETURN_0
// FIXME: make it work for other sanitizers.
// XFAIL: lsan
diff --git a/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc b/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc
index 622471767655..36d4df567ee7 100644
--- a/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc
+++ b/test/sanitizer_common/TestCases/Posix/decorate_proc_maps.cc
@@ -1,5 +1,6 @@
// RUN: %clangxx -g %s -o %t
-// RUN: %tool_options=decorate_proc_maps=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%tool_name
+// RUN: %env_tool_opts=decorate_proc_maps=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%tool_name
+// REQUIRES: stable-runtime
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
@@ -46,8 +47,8 @@ int main(void) {
// CHECK-asan: rw-p {{.*}} [high shadow]
// CHECK-msan: ---p {{.*}} [invalid]
-// CHECK-msan: rw-p {{.*}} [shadow]
-// CHECK-msan: ---p {{.*}} [origin]
+// CHECK-msan: rw-p {{.*}} [shadow{{.*}}]
+// CHECK-msan: ---p {{.*}} [origin{{.*}}]
// CHECK-tsan: rw-p {{.*}} [shadow]
// CHECK-tsan: rw-p {{.*}} [meta shadow]
diff --git a/test/sanitizer_common/TestCases/fopen_nullptr.c b/test/sanitizer_common/TestCases/fopen_nullptr.c
new file mode 100644
index 000000000000..960dda334a61
--- /dev/null
+++ b/test/sanitizer_common/TestCases/fopen_nullptr.c
@@ -0,0 +1,6 @@
+// Check that fopen(NULL, "r") is ok.
+// RUN: %clang -O2 %s -o %t && %run %t
+#include <stdio.h>
+const char *fn = NULL;
+FILE *f;
+int main() { f = fopen(fn, "r"); }
diff --git a/test/sanitizer_common/TestCases/options-help.cc b/test/sanitizer_common/TestCases/options-help.cc
index eaa04a494be4..913377db70f1 100644
--- a/test/sanitizer_common/TestCases/options-help.cc
+++ b/test/sanitizer_common/TestCases/options-help.cc
@@ -1,5 +1,5 @@
// RUN: %clangxx -O0 %s -o %t
-// RUN: %tool_options=help=1 %run %t 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=help=1 %run %t 2>&1 | FileCheck %s
int main() {
}
diff --git a/test/sanitizer_common/TestCases/options-include.cc b/test/sanitizer_common/TestCases/options-include.cc
index ae8995164853..1528b15b9e9a 100644
--- a/test/sanitizer_common/TestCases/options-include.cc
+++ b/test/sanitizer_common/TestCases/options-include.cc
@@ -1,21 +1,46 @@
// RUN: %clangxx -O0 %s -o %t
+
+// Recursive include: options1 includes options2
// RUN: echo -e "symbolize=1\ninclude='%t.options2.txt'" >%t.options1.txt
// RUN: echo -e "help=1\n" >%t.options2.txt
+// RUN: echo -e "help=1\n" >%t.options.options-include.cc.tmp
// RUN: cat %t.options1.txt
// RUN: cat %t.options2.txt
-// RUN: %tool_options="help=0:include='%t.options1.txt'" %run %t 2>&1 | tee %t.out
-// RUN: FileCheck %s --check-prefix=CHECK-VERBOSITY1 <%t.out
-// RUN: %tool_options="include='%t.options1.txt',help=0" %run %t 2>&1 | tee %t.out
-// RUN: FileCheck %s --check-prefix=CHECK-VERBOSITY0 <%t.out
-// RUN: %tool_options="include='%t.options-not-found.txt',help=1" not %run %t 2>&1 | tee %t.out
+
+// RUN: %env_tool_opts=help=0:include='"%t.options1.txt"' %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND <%t.out
+
+// RUN: %env_tool_opts=include='"%t.options1.txt"',help=0 %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITHOUT-HELP --check-prefix=CHECK-FOUND <%t.out
+
+// RUN: %env_tool_opts=include='"%t.options-not-found.txt"',help=1 not %run %t 2>&1 | tee %t.out
// RUN: FileCheck %s --check-prefix=CHECK-NOT-FOUND < %t.out
+// include_if_exists does not fail when the file is missing
+// RUN: %env_tool_opts=include_if_exists='"%t.options-not-found.txt"',help=1 %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND < %t.out
+
+// %b (binary basename substitution)
+// RUN: %env_tool_opts=include='"%t.options.%b"' %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND < %t.out
+
+// RUN: %env_tool_opts=include='"%t.options-not-found.%b"' not %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITHOUT-HELP --check-prefix=CHECK-NOT-FOUND < %t.out
+
+// RUN: %env_tool_opts=include_if_exists='"%t.options.%b"' %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITH-HELP --check-prefix=CHECK-FOUND < %t.out
+
+// RUN: %env_tool_opts=include_if_exists='"%t.options-not-found.%b"' %run %t 2>&1 | tee %t.out
+// RUN: FileCheck %s --check-prefix=CHECK-WITHOUT-HELP --check-prefix=CHECK-FOUND < %t.out
+
+
#include <stdio.h>
int main() {
fprintf(stderr, "done\n");
}
-// CHECK-VERBOSITY1: Available flags for
-// CHECK-VERBOSITY0-NOT: Available flags for
+// CHECK-WITH-HELP: Available flags for
+// CHECK-WITHOUT-HELP-NOT: Available flags for
+// CHECK-FOUND-NOT: Failed to read options from
// CHECK-NOT-FOUND: Failed to read options from
diff --git a/test/sanitizer_common/TestCases/options-invalid.cc b/test/sanitizer_common/TestCases/options-invalid.cc
index 3c261405c992..572c4912cfd9 100644
--- a/test/sanitizer_common/TestCases/options-invalid.cc
+++ b/test/sanitizer_common/TestCases/options-invalid.cc
@@ -1,6 +1,6 @@
// RUN: %clangxx -O0 %s -o %t
-// RUN: %tool_options=invalid_option_name=10,verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V1
-// RUN: %tool_options=invalid_option_name=10 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V0
+// RUN: %env_tool_opts=invalid_option_name=10,verbosity=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V1
+// RUN: %env_tool_opts=invalid_option_name=10 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-V0
#include <stdio.h>
diff --git a/test/sanitizer_common/TestCases/print-stack-trace.cc b/test/sanitizer_common/TestCases/print-stack-trace.cc
index 1251f67b83cd..9134a88dac17 100644
--- a/test/sanitizer_common/TestCases/print-stack-trace.cc
+++ b/test/sanitizer_common/TestCases/print-stack-trace.cc
@@ -1,7 +1,7 @@
-// RUN: %clangxx -O0 %s -o %t && %tool_options=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s
-// RUN: %clangxx -O3 %s -o %t && %tool_options=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s
-// RUN: %tool_options='stack_trace_format="frame:%n lineno:%l"' %run %t 2>&1 | FileCheck %s --check-prefix=CUSTOM
-// RUN: %tool_options=symbolize_inline_frames=false:stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s --check-prefix=NOINLINE
+// RUN: %clangxx -O0 %s -o %t && %env_tool_opts=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -O3 %s -o %t && %env_tool_opts=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=stack_trace_format='"frame:%n lineno:%l"' %run %t 2>&1 | FileCheck %s --check-prefix=CUSTOM
+// RUN: %env_tool_opts=symbolize_inline_frames=false:stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s --check-prefix=NOINLINE
#include <sanitizer/common_interface_defs.h>