]> granicus.if.org Git - clang/commitdiff
Add -fsanitize=memory.
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Mon, 3 Dec 2012 13:20:43 +0000 (13:20 +0000)
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>
Mon, 3 Dec 2012 13:20:43 +0000 (13:20 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@169124 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticDriverKinds.td
include/clang/Basic/Sanitizers.def
lib/CodeGen/BackendUtil.cpp
lib/Driver/SanitizerArgs.h
lib/Driver/Tools.cpp

index 4b430351756a8f217bfe789353d2c276bf222bf0..4a37ea78371ec4f022af11670f1eec6788521b19 100644 (file)
@@ -101,6 +101,8 @@ def err_drv_mg_requires_m_or_mm : Error<
   "option '-MG' requires '-M' or '-MM'">;
 def err_drv_asan_android_requires_pie : Error<
   "AddressSanitizer on Android requires '-pie'">;
+def err_drv_sanitizer_requires_pie : Error<
+  "%select{Thread|Memory}0Sanitizer requires '-pie'">;
 def err_drv_unknown_objc_runtime : Error<
   "unknown or ill-formed Objective-C runtime '%0'">;
 
index 5b6df6f2c1b1affa7ea7c799fb224d359c1e1eea..57ca6eb1858abf995c6d3efebfc64949338c2490 100644 (file)
@@ -48,6 +48,9 @@ SANITIZER("use-after-scope", UseAfterScope)
 SANITIZER_GROUP("address-full", AddressFull,
                 Address | InitOrder | UseAfterReturn | UseAfterScope)
 
+// MemorySanitizer
+SANITIZER("memory", Memory)
+
 // ThreadSanitizer
 SANITIZER("thread", Thread)
 
index a5cc2ea004154ea97849857d3ccf550fc4f2ae7c..4fe1c80e48ac42e8be61d4c7366e72fa81fd0306 100644 (file)
@@ -179,6 +179,11 @@ static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
   PM.add(createAddressSanitizerModulePass(LangOpts.SanitizeInitOrder));
 }
 
+static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
+                                   PassManagerBase &PM) {
+  PM.add(createMemorySanitizerPass());
+}
+
 static void addThreadSanitizerPass(const PassManagerBuilder &Builder,
                                    PassManagerBase &PM) {
   PM.add(createThreadSanitizerPass());
@@ -227,6 +232,13 @@ void EmitAssemblyHelper::CreatePasses(TargetMachine *TM) {
                            addAddressSanitizerPasses);
   }
 
+  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 af92fa070c3135b89022a25e79ac2608a6db2e22..c7d1ea68dd477db36ac520902041f92a4ac8fab7 100644 (file)
@@ -30,6 +30,7 @@ class SanitizerArgs {
 #include "clang/Basic/Sanitizers.def"
     NeedsAsanRt = AddressFull,
     NeedsTsanRt = Thread,
+    NeedsMsanRt = Memory,
     NeedsUbsanRt = (Undefined & ~Bounds) | Integer
   };
   unsigned Kind;
@@ -41,6 +42,7 @@ class SanitizerArgs {
 
   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 16218e1fc542346df8a64d16a7d720acfe281bf3..92c96b25c9553f70491ae56219348fdba8276707 100644 (file)
@@ -1524,6 +1524,9 @@ static void addAsanRTLinux(const ToolChain &TC, const ArgList &Args,
 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_sanitizer_requires_pie) <<
+        /* Thread */ 0;
     // LibTsan is "libclang_rt.tsan-<ArchName>.a" in the Linux library
     // resource directory.
     SmallString<128> LibTsan(TC.getDriver().ResourceDir);
@@ -1537,6 +1540,27 @@ static void addTsanRTLinux(const ToolChain &TC, const ArgList &Args,
   }
 }
 
+/// 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_sanitizer_requires_pie) <<
+        /* Memory */ 1;
+    // 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,
@@ -5443,6 +5467,8 @@ void linuxtools::Link::ConstructJob(Compilation &C, const JobAction &JA,
     addAsanRTLinux(getToolChain(), Args, CmdArgs);
   if (Sanitize.needsTsanRt())
     addTsanRTLinux(getToolChain(), Args, CmdArgs);
+  if (Sanitize.needsMsanRt())
+    addMsanRTLinux(getToolChain(), Args, CmdArgs);
 
   if (D.CCCIsCXX &&
       !Args.hasArg(options::OPT_nostdlib) &&