]> granicus.if.org Git - clang/commitdiff
Add a flag -fthread-sanitizer.
authorKostya Serebryany <kcc@google.com>
Thu, 1 Mar 2012 22:27:08 +0000 (22:27 +0000)
committerKostya Serebryany <kcc@google.com>
Thu, 1 Mar 2012 22:27:08 +0000 (22:27 +0000)
This flag enables ThreadSanitizer instrumentation committed to llvm as r150423.
The patch includes one test for -fthread-sanitizer and one similar test for -faddress-sanitizer.
This patch does not modify the linker flags (as we do it for -faddress-sanitizer) because the run-time library is not yet
committed and it's structure in compiler-rt is not 100% clear.
The users manual wil be changed in a separate commit.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151846 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/LangOptions.def
include/clang/Driver/CC1Options.td
include/clang/Driver/Options.td
lib/CodeGen/BackendUtil.cpp
lib/Driver/Tools.cpp
lib/Frontend/CompilerInvocation.cpp
test/Driver/asan.c [new file with mode: 0644]
test/Driver/tsan.c [new file with mode: 0644]

index d2dff8947ced12734afbc603a214a1d80eb148f8..d68afc737ddf7335cecf9b28aa412b60dfbf7780 100644 (file)
@@ -125,6 +125,7 @@ BENIGN_LANGOPT(ParseUnknownAnytype, 1, 0, "__unknown_anytype")
 BENIGN_LANGOPT(DebuggerSupport , 1, 0, "debugger support")
 BENIGN_LANGOPT(DebuggerCastResultToId, 1, 0, "for 'po' in the debugger, cast the result to id if it is of unknown type")
 BENIGN_LANGOPT(AddressSanitizer , 1, 0, "AddressSanitizer enabled")
+BENIGN_LANGOPT(ThreadSanitizer , 1, 0, "ThreadSanitizer enabled")
 
 BENIGN_LANGOPT(SpellChecking , 1, 1, "spell-checking")
 LANGOPT(SinglePrecisionConstants , 1, 0, "treating double-precision floating point constants as single precision constants")
index 9789a85da7b2293d80224a069f3d4a04f2693e52..9d44280874ee5db73a3bbe389c9e0ec718229720 100644 (file)
@@ -127,6 +127,8 @@ def dwarf_debug_flags : Separate<"-dwarf-debug-flags">,
   HelpText<"The string to embed in the Dwarf debug flags record.">;
 def faddress_sanitizer: Flag<"-faddress-sanitizer">,
   HelpText<"Enable AddressSanitizer instrumentation (memory error detection)">;
+def fthread_sanitizer: Flag<"-fthread-sanitizer">,
+  HelpText<"Enable ThreadSanitizer instrumentation (race detection)">;
 def fforbid_guard_variables : Flag<"-fforbid-guard-variables">,
   HelpText<"Emit an error if a C++ static local initializer would need a guard variable">;
 def g : Flag<"-g">, HelpText<"Generate source level debug information">;
index a9b8aa9ceb14a84b91da3ac7e17ec00a8f573201..dcc0e7bedc003410db73d435112d94ce21596cc9 100644 (file)
@@ -264,6 +264,8 @@ def fapple_kext : Flag<"-fapple-kext">, Group<f_Group>;
 def fapple_pragma_pack : Flag<"-fapple-pragma-pack">, Group<f_Group>;
 def faddress_sanitizer : Flag<"-faddress-sanitizer">, Group<f_Group>;
 def fno_address_sanitizer : Flag<"-fno-address-sanitizer">, Group<f_Group>;
+def fthread_sanitizer : Flag<"-fthread-sanitizer">, Group<f_Group>;
+def fno_thread_sanitizer : Flag<"-fno-thread-sanitizer">, Group<f_Group>;
 def fasm : Flag<"-fasm">, Group<f_Group>;
 
 def fasm_blocks : Flag<"-fasm-blocks">, Group<f_Group>;
index d9bdc325c10d158767209a6a940919728794ea7f..79cdb3c240ba77dff8836b505b2f2a59af08fafc 100644 (file)
@@ -126,6 +126,11 @@ static void addAddressSanitizerPass(const PassManagerBuilder &Builder,
   PM.add(createAddressSanitizerPass());
 }
 
+static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
+                                   PassManagerBase &PM) {
+  PM.add(createThreadSanitizerPass());
+}
+
 void EmitAssemblyHelper::CreatePasses() {
   unsigned OptLevel = CodeGenOpts.OptimizationLevel;
   CodeGenOptions::InliningMethod Inlining = CodeGenOpts.Inlining;
@@ -161,7 +166,14 @@ void EmitAssemblyHelper::CreatePasses() {
     PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
                            addAddressSanitizerPass);
   }
-  
+
+  if (LangOpts.ThreadSanitizer) {
+    PMBuilder.addExtension(PassManagerBuilder::EP_ScalarOptimizerLate,
+                           addThreadSanitizerPass);
+    PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
+                           addThreadSanitizerPass);
+  }
+
   // Figure out TargetLibraryInfo.
   Triple TargetTriple(TheModule->getTargetTriple());
   PMBuilder.LibraryInfo = new TargetLibraryInfo(TargetTriple);
index 7e539e57dc1e9e78ce10d5ec5264c12bd9ee9203..1d77c5f1a84c473e3c4b2bbeab7ea193191acb4b 100644 (file)
@@ -1928,6 +1928,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                    options::OPT_fno_address_sanitizer, false))
     CmdArgs.push_back("-faddress-sanitizer");
 
+  if (Args.hasFlag(options::OPT_fthread_sanitizer,
+                   options::OPT_fno_thread_sanitizer, false))
+    CmdArgs.push_back("-fthread-sanitizer");
+
   // -flax-vector-conversions is default.
   if (!Args.hasFlag(options::OPT_flax_vector_conversions,
                     options::OPT_fno_lax_vector_conversions))
index c46c52c7bdd239eca2891c5e263100420ee7cb61..d792dc7730f9d84a8807a7010a6b5d8e9a629d54 100644 (file)
@@ -684,6 +684,8 @@ static void LangOptsToArgs(const LangOptions &Opts,
     Res.push_back("-fcatch-undefined-behavior");
   if (Opts.AddressSanitizer)
     Res.push_back("-faddress-sanitizer");
+  if (Opts.ThreadSanitizer)
+    Res.push_back("-fthread-sanitizer");
   if (Opts.WritableStrings)
     Res.push_back("-fwritable-strings");
   if (Opts.ConstStrings)
@@ -1888,6 +1890,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
   Opts.DebuggerSupport = Args.hasArg(OPT_fdebugger_support);
   Opts.DebuggerCastResultToId = Args.hasArg(OPT_fdebugger_cast_result_to_id);
   Opts.AddressSanitizer = Args.hasArg(OPT_faddress_sanitizer);
+  Opts.ThreadSanitizer = Args.hasArg(OPT_fthread_sanitizer);
   Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
   Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name);
 
diff --git a/test/Driver/asan.c b/test/Driver/asan.c
new file mode 100644 (file)
index 0000000..4c9a1b6
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clang     -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O1 -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O2 -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O3 -target i386-unknown-unknown -faddress-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// Verify that -faddress-sanitizer invokes asan instrumentation.
+
+int foo(int *a) { return *a; }
+// CHECK: __asan_init
diff --git a/test/Driver/tsan.c b/test/Driver/tsan.c
new file mode 100644 (file)
index 0000000..1dadb8e
--- /dev/null
@@ -0,0 +1,8 @@
+// RUN: %clang     -target i386-unknown-unknown -fthread-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O1 -target i386-unknown-unknown -fthread-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O2 -target i386-unknown-unknown -fthread-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O3 -target i386-unknown-unknown -fthread-sanitizer %s -S -emit-llvm -o - | FileCheck %s
+// Verify that -fthread-sanitizer invokes tsan instrumentation.
+
+int foo(int *a) { return *a; }
+// CHECK: __tsan_init