Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -728,6 +728,24 @@ def fno_sanitize_stats : Flag<["-"], "fno-sanitize-stats">, Group, Flags<[CC1Option]>, HelpText<"Disable sanitizer statistics gathering.">; +def fsanitize_thread_memory_access : Flag<["-"], "fsanitize-thread-memory-access">, + Group, Flags<[CC1Option]>, + HelpText<"Enable memory access instrumentation in ThreadSanitizer (default)">; +def fno_sanitize_thread_memory_access : Flag<["-"], "fno-sanitize-thread-memory-access">, + Group, Flags<[CC1Option]>, + HelpText<"Disable memory access instrumentation in ThreadSanitizer">; +def fsanitize_thread_func_entry_exit : Flag<["-"], "fsanitize-thread-func-entry-exit">, + Group, Flags<[CC1Option]>, + HelpText<"Enable function entry/exit instrumentation in ThreadSanitizer (default)">; +def fno_sanitize_thread_func_entry_exit : Flag<["-"], "fno-sanitize-thread-func-entry-exit">, + Group, Flags<[CC1Option]>, + HelpText<"Disable function entry/exit instrumentation in ThreadSanitizer">; +def fsanitize_thread_atomics : Flag<["-"], "fsanitize-thread-atomics">, + Group, Flags<[CC1Option]>, + HelpText<"Enable atomic operations instrumentation in ThreadSanitizer (default)">; +def fno_sanitize_thread_atomics : Flag<["-"], "fno-sanitize-thread-atomics">, + Group, Flags<[CC1Option]>, + HelpText<"Disable atomic operations instrumentation in ThreadSanitizer">; def fsanitize_undefined_strip_path_components_EQ : Joined<["-"], "fsanitize-undefined-strip-path-components=">, Group, Flags<[CC1Option]>, MetaVarName<"">, HelpText<"Strip (or keep only, if negative) a given number of path components " Index: include/clang/Driver/SanitizerArgs.h =================================================================== --- include/clang/Driver/SanitizerArgs.h +++ include/clang/Driver/SanitizerArgs.h @@ -38,6 +38,9 @@ bool LinkCXXRuntimes = false; bool NeedPIE = false; bool Stats = false; + bool TsanMemoryAccess = true; + bool TsanFuncEntryExit = true; + bool TsanAtomics = true; public: /// Parses the sanitizer arguments from an argument list. Index: lib/Driver/SanitizerArgs.cpp =================================================================== --- lib/Driver/SanitizerArgs.cpp +++ lib/Driver/SanitizerArgs.cpp @@ -437,6 +437,18 @@ TC.getTriple().getArch() == llvm::Triple::x86_64); } + if (AllAddedKinds & Thread) { + TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access, + options::OPT_fno_sanitize_thread_memory_access, + TsanMemoryAccess); + TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit, + options::OPT_fno_sanitize_thread_func_entry_exit, + TsanFuncEntryExit); + TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics, + options::OPT_fno_sanitize_thread_atomics, + TsanAtomics); + } + if (AllAddedKinds & CFI) { CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso, options::OPT_fno_sanitize_cfi_cross_dso, false); @@ -685,6 +697,22 @@ if (MsanUseAfterDtor) CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-use-after-dtor")); + // FIXME: Pass these parameters as function attributes, not as -llvm flags. + if (!TsanMemoryAccess) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-tsan-instrument-memory-accesses=0"); + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-tsan-instrument-memintrinsics=0"); + } + if (!TsanFuncEntryExit) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-tsan-instrument-func-entry-exit=0"); + } + if (!TsanAtomics) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-tsan-instrument-atomics=0"); + } + if (CfiCrossDso) CmdArgs.push_back(Args.MakeArgString("-fsanitize-cfi-cross-dso")); Index: test/Driver/fsanitize.c =================================================================== --- test/Driver/fsanitize.c +++ test/Driver/fsanitize.c @@ -278,6 +278,35 @@ // RUN: %clang -target i386-apple-tvossimulator -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-I386-TVOSSIMULATOR // CHECK-TSAN-I386-TVOSSIMULATOR: unsupported option '-fsanitize=thread' for target 'i386-apple-tvossimulator' +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-memory-access %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MEMORY-ACCESS +// CHECK-TSAN-MEMORY-ACCESS-NOT: -cc1{{.*}}tsan-instrument-memory-accesses=0 +// CHECK-TSAN-MEMORY-ACCESS-NOT: -cc1{{.*}}tsan-instrument-memintrinsics=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fno-sanitize-thread-memory-access %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MEMORY-ACCESS-OFF +// CHECK-TSAN-MEMORY-ACCESS-OFF: -cc1{{.*}}tsan-instrument-memory-accesses=0{{.*}}tsan-instrument-memintrinsics=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fno-sanitize-thread-memory-access -fsanitize-thread-memory-access %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MEMORY-ACCESS-BOTH +// CHECK-TSAN-MEMORY-ACCESS-BOTH-NOT: -cc1{{.*}}tsan-instrument-memory-accesses=0 +// CHECK-TSAN-MEMORY-ACCESS-BOTH-NOT: -cc1{{.*}}tsan-instrument-memintrinsics=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-memory-access -fno-sanitize-thread-memory-access %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MEMORY-ACCESS-BOTH-OFF +// CHECK-TSAN-MEMORY-ACCESS-BOTH-OFF: -cc1{{.*}}tsan-instrument-memory-accesses=0{{.*}}tsan-instrument-memintrinsics=0 + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-func-entry-exit %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-FUNC-ENTRY-EXIT +// CHECK-TSAN-FUNC-ENTRY-EXIT-NOT: -cc1{{.*}}tsan-instrument-func-entry-exit=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fno-sanitize-thread-func-entry-exit %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-FUNC-ENTRY-EXIT-OFF +// CHECK-TSAN-FUNC-ENTRY-EXIT-OFF: -cc1{{.*}}tsan-instrument-func-entry-exit=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fno-sanitize-thread-func-entry-exit -fsanitize-thread-func-entry-exit %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-FUNC-ENTRY-EXIT-BOTH +// CHECK-TSAN-FUNC-ENTRY-EXIT-BOTH-NOT: -cc1{{.*}}tsan-instrument-func-entry-exit=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-func-entry-exit -fno-sanitize-thread-func-entry-exit %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-FUNC-ENTRY-EXIT-BOTH-OFF +// CHECK-TSAN-FUNC-ENTRY-EXIT-BOTH-OFF: -cc1{{.*}}tsan-instrument-func-entry-exit=0 + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-atomics %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ATOMICS +// CHECK-TSAN-ATOMICS-NOT: -cc1{{.*}}tsan-instrument-atomics=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fno-sanitize-thread-atomics %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ATOMICS-OFF +// CHECK-TSAN-ATOMICS-OFF: -cc1{{.*}}tsan-instrument-atomics=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fno-sanitize-thread-atomics -fsanitize-thread-atomics %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ATOMICS-BOTH +// CHECK-TSAN-ATOMICS-BOTH-NOT: -cc1{{.*}}tsan-instrument-atomics=0 +// RUN: %clang -target x86_64-linux-gnu -fsanitize=thread -fsanitize-thread-atomics -fno-sanitize-thread-atomics %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-ATOMICS-BOTH-OFF +// CHECK-TSAN-ATOMICS-BOTH-OFF: -cc1{{.*}}tsan-instrument-atomics=0 + // RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN // CHECK-FSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'