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.

llvm-svn: 151846
This commit is contained in:
Kostya Serebryany 2012-03-01 22:27:08 +00:00
parent c429b80da1
commit 28a7a1198b
8 changed files with 41 additions and 1 deletions

View 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")

View 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">;

View 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>;

View 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);

View 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))

View 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);

8
clang/test/Driver/asan.c Normal file
View File

@ -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

8
clang/test/Driver/tsan.c Normal file
View File

@ -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