[cfe-commits] [PATCH] Clang support for MemorySanitizer
Evgeniy Stepanov
eugenis at google.com
Thu Nov 29 03:51:36 PST 2012
Hi kcc, chandlerc, nicholas,
http://llvm-reviews.chandlerc.com/D146
Files:
llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
llvm/tools/clang/include/clang/Basic/Sanitizers.def
llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
llvm/tools/clang/lib/Driver/SanitizerArgs.h
llvm/tools/clang/lib/Driver/Tools.cpp
Index: llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
+++ llvm/tools/clang/include/clang/Basic/DiagnosticDriverKinds.td
@@ -101,6 +101,8 @@
"option '-MG' requires '-M' or '-MM'">;
def err_drv_asan_android_requires_pie : Error<
"AddressSanitizer on Android requires '-pie'">;
+def err_drv_tsan_msan_require_pie : Error<
+ "ThreadSanitizer and MemorySanitizer require '-pie'">;
def err_drv_unknown_objc_runtime : Error<
"unknown or ill-formed Objective-C runtime '%0'">;
Index: llvm/tools/clang/include/clang/Basic/Sanitizers.def
===================================================================
--- llvm/tools/clang/include/clang/Basic/Sanitizers.def
+++ llvm/tools/clang/include/clang/Basic/Sanitizers.def
@@ -41,6 +41,9 @@
// AddressSanitizer
SANITIZER("address", Address)
+// MemorySanitizer
+SANITIZER("memory", Memory)
+
// ThreadSanitizer
SANITIZER("thread", Thread)
Index: llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
===================================================================
--- llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
+++ llvm/tools/clang/lib/CodeGen/BackendUtil.cpp
@@ -163,6 +163,47 @@
PM.add(createAddressSanitizerModulePass());
}
+static cl::opt<bool> ClMSanMoreOpt(
+ "msan-more-opt",
+ cl::desc("add more general purpose optimizations after MemorySanitizer pass"),
+ cl::Hidden, cl::init(true));
+
+static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
+ PassManagerBase &PM) {
+ PM.add(createMemorySanitizerPass());
+
+ // MemorySanitizer pass generates complex instrumentation which can benefit
+ // from re-running common optimizations.
+ if (ClMSanMoreOpt && Builder.OptLevel > 0) {
+ PM.add(createEarlyCSEPass()); // Catch trivial redundancies
+ PM.add(createJumpThreadingPass()); // Thread jumps.
+ PM.add(createCorrelatedValuePropagationPass()); // Propagate conditionals
+ PM.add(createCFGSimplificationPass()); // Merge & remove BBs
+ PM.add(createInstructionCombiningPass()); // Combine silly seq's
+
+ PM.add(createTailCallEliminationPass()); // Eliminate tail calls
+ PM.add(createCFGSimplificationPass()); // Merge & remove BBs
+ PM.add(createReassociatePass()); // Reassociate expressions
+ PM.add(createLoopRotatePass()); // Rotate Loop
+ PM.add(createLICMPass()); // Hoist loop invariants
+ PM.add(createInstructionCombiningPass());
+ PM.add(createIndVarSimplifyPass()); // Canonicalize indvars
+ PM.add(createLoopIdiomPass()); // Recognize idioms like memset.
+ PM.add(createLoopDeletionPass()); // Delete dead loops
+
+ PM.add(createGVNPass()); // Remove redundancies
+ PM.add(createMemCpyOptPass()); // Remove memcpy / form memset
+ PM.add(createSCCPPass()); // Constant prop with SCCP
+
+ // Run instcombine after redundancy elimination to exploit opportunities
+ // opened up by them.
+ PM.add(createInstructionCombiningPass());
+ PM.add(createJumpThreadingPass()); // Thread jumps
+ PM.add(createCorrelatedValuePropagationPass());
+ PM.add(createDeadStoreEliminationPass()); // Delete dead stores
+ }
+}
+
static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
PassManagerBase &PM) {
PM.add(createThreadSanitizerPass());
@@ -211,6 +252,13 @@
addAddressSanitizerPass);
}
+ if (LangOpts.SanitizeMemory) {
+ PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
+ addMemorySanitizerPass);
+ PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
+ addMemorySanitizerPass);
+ }
+
if (LangOpts.SanitizeThread) {
PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
addThreadSanitizerPass);
Index: llvm/tools/clang/lib/Driver/SanitizerArgs.h
===================================================================
--- llvm/tools/clang/lib/Driver/SanitizerArgs.h
+++ llvm/tools/clang/lib/Driver/SanitizerArgs.h
@@ -30,6 +30,7 @@
#include "clang/Basic/Sanitizers.def"
NeedsAsanRt = Address,
NeedsTsanRt = Thread,
+ NeedsMsanRt = Memory,
NeedsUbsanRt = (Undefined & ~Bounds) | Integer
};
unsigned Kind;
@@ -41,6 +42,7 @@
bool needsAsanRt() const { return Kind & NeedsAsanRt; }
bool needsTsanRt() const { return Kind & NeedsTsanRt; }
+ bool needsMsanRt() const { return Kind & NeedsMsanRt; }
bool needsUbsanRt() const { return Kind & NeedsUbsanRt; }
bool sanitizesVptr() const { return Kind & Vptr; }
Index: llvm/tools/clang/lib/Driver/Tools.cpp
===================================================================
--- llvm/tools/clang/lib/Driver/Tools.cpp
+++ llvm/tools/clang/lib/Driver/Tools.cpp
@@ -1512,6 +1512,8 @@
static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
ArgStringList &CmdArgs) {
if (!Args.hasArg(options::OPT_shared)) {
+ if (!Args.hasArg(options::OPT_pie))
+ TC.getDriver().Diag(diag::err_drv_tsan_msan_require_pie);
// LibTsan is "libclang_rt.tsan-<ArchName>.a" in the Linux library
// resource directory.
SmallString<128> LibTsan(TC.getDriver().ResourceDir);
@@ -1525,6 +1527,26 @@
}
}
+/// If MemorySanitizer is enabled, add appropriate linker flags (Linux).
+/// This needs to be called before we add the C run-time (malloc, etc).
+static void addMsanRTLinux(const ToolChain &TC, const ArgList &Args,
+ ArgStringList &CmdArgs) {
+ if (!Args.hasArg(options::OPT_shared)) {
+ if (!Args.hasArg(options::OPT_pie))
+ TC.getDriver().Diag(diag::err_drv_tsan_msan_require_pie);
+ // LibMsan is "libclang_rt.msan-<ArchName>.a" in the Linux library
+ // resource directory.
+ SmallString<128> LibMsan(TC.getDriver().ResourceDir);
+ llvm::sys::path::append(LibMsan, "lib", "linux",
+ (Twine("libclang_rt.msan-") +
+ TC.getArchName() + ".a"));
+ CmdArgs.push_back(Args.MakeArgString(LibMsan));
+ CmdArgs.push_back("-lpthread");
+ CmdArgs.push_back("-ldl");
+ CmdArgs.push_back("-export-dynamic");
+ }
+}
+
/// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
/// (Linux).
static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
@@ -4069,7 +4091,9 @@
// -fsanitize=undefined, unresolved symbols may appear. Mark all
// of them as dynamic_lookup. Linking executables is handled in
// lib/Driver/ToolChains.cpp.
- if (Sanitize.needsAsanRt() || Sanitize.needsUbsanRt()) {
+ if (Sanitize.needsAsanRt() ||
+ Sanitize.needsMsanRt() ||
+ Sanitize.needsUbsanRt()) {
if (Args.hasArg(options::OPT_dynamiclib) ||
Args.hasArg(options::OPT_bundle)) {
CmdArgs.push_back("-undefined");
@@ -5445,6 +5469,8 @@
addAsanRTLinux(getToolChain(), Args, CmdArgs);
if (Sanitize.needsTsanRt())
addTsanRTLinux(getToolChain(), Args, CmdArgs);
+ if (Sanitize.needsMsanRt())
+ addMsanRTLinux(getToolChain(), Args, CmdArgs);
if (!Args.hasArg(options::OPT_nostdlib)) {
if (!Args.hasArg(options::OPT_nodefaultlibs)) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D146.1.patch
Type: text/x-patch
Size: 7446 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20121129/697086bf/attachment.bin>
More information about the cfe-commits
mailing list