From 3c93122d31924d6d4a6265f36a0c98a164002da6 Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Thu, 1 Mar 2012 22:27:08 +0000 Subject: [PATCH] Add a flag -fthread-sanitizer. 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 | 1 + include/clang/Driver/CC1Options.td | 2 ++ include/clang/Driver/Options.td | 2 ++ lib/CodeGen/BackendUtil.cpp | 14 +++++++++++++- lib/Driver/Tools.cpp | 4 ++++ lib/Frontend/CompilerInvocation.cpp | 3 +++ test/Driver/asan.c | 8 ++++++++ test/Driver/tsan.c | 8 ++++++++ 8 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 test/Driver/asan.c create mode 100644 test/Driver/tsan.c diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index d2dff8947c..d68afc737d 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -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") diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 9789a85da7..9d44280874 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -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">; diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index a9b8aa9ceb..dcc0e7bedc 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -264,6 +264,8 @@ def fapple_kext : Flag<"-fapple-kext">, Group; def fapple_pragma_pack : Flag<"-fapple-pragma-pack">, Group; def faddress_sanitizer : Flag<"-faddress-sanitizer">, Group; def fno_address_sanitizer : Flag<"-fno-address-sanitizer">, Group; +def fthread_sanitizer : Flag<"-fthread-sanitizer">, Group; +def fno_thread_sanitizer : Flag<"-fno-thread-sanitizer">, Group; def fasm : Flag<"-fasm">, Group; def fasm_blocks : Flag<"-fasm-blocks">, Group; diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index d9bdc325c1..79cdb3c240 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -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); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 7e539e57dc..1d77c5f1a8 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -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)) diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index c46c52c7bd..d792dc7730 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -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 index 0000000000..4c9a1b6c44 --- /dev/null +++ b/test/Driver/asan.c @@ -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 index 0000000000..1dadb8ea26 --- /dev/null +++ b/test/Driver/tsan.c @@ -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 -- 2.40.0