[PATCH] Add -fsanitize=leak to driver options.

Sergey Matveev earthdok at google.com
Tue May 21 11:23:25 PDT 2013


Hi kcc, glider,

If -fsanitize=leak is specified, link the program with the
LeakSanitizer runtime. Print a warning and ignore this option when it is used
together with -fsanitize=address, since ASan has this functionality built in.

http://llvm-reviews.chandlerc.com/D837

Files:
  include/clang/Basic/DiagnosticDriverKinds.td
  include/clang/Basic/Sanitizers.def
  lib/Driver/SanitizerArgs.h
  lib/Driver/Tools.cpp

Index: include/clang/Basic/DiagnosticDriverKinds.td
===================================================================
--- include/clang/Basic/DiagnosticDriverKinds.td
+++ include/clang/Basic/DiagnosticDriverKinds.td
@@ -125,6 +125,8 @@
   InGroup<UnusedCommandLineArgument>;
 def warn_drv_unused_sanitizer : Warning<"'%0' is ignored in absence of '%1'">,
   InGroup<UnusedSanitizeArgument>;
+def warn_drv_redundant_sanitizer : Warning<"'%0' is redundant in the presence of '%1'">,
+  InGroup<UnusedSanitizeArgument>;
 def warn_drv_clang_unsupported : Warning<
   "the clang compiler does not support '%0'">;
 def warn_drv_deprecated_arg : Warning<
Index: include/clang/Basic/Sanitizers.def
===================================================================
--- include/clang/Basic/Sanitizers.def
+++ include/clang/Basic/Sanitizers.def
@@ -54,6 +54,9 @@
 // ThreadSanitizer
 SANITIZER("thread", Thread)
 
+// LeakSanitizer
+SANITIZER("leak", Leak)
+
 // UndefinedBehaviorSanitizer
 SANITIZER("alignment", Alignment)
 SANITIZER("bool", Bool)
Index: lib/Driver/SanitizerArgs.h
===================================================================
--- lib/Driver/SanitizerArgs.h
+++ lib/Driver/SanitizerArgs.h
@@ -37,6 +37,7 @@
     NeedsAsanRt = Address,
     NeedsTsanRt = Thread,
     NeedsMsanRt = Memory,
+    NeedsLsanRt = Leak,
     NeedsUbsanRt = Undefined | Integer,
     NotAllowedWithTrap = Vptr,
     HasZeroBaseShadow = Thread | Memory
@@ -56,6 +57,7 @@
   bool needsAsanRt() const { return Kind & NeedsAsanRt; }
   bool needsTsanRt() const { return Kind & NeedsTsanRt; }
   bool needsMsanRt() const { return Kind & NeedsMsanRt; }
+  bool needsLsanRt() const { return Kind & NeedsLsanRt; }
   bool needsUbsanRt() const {
     if (UbsanTrapOnError)
       return false;
Index: lib/Driver/Tools.cpp
===================================================================
--- lib/Driver/Tools.cpp
+++ lib/Driver/Tools.cpp
@@ -1587,6 +1587,7 @@
   bool NeedsAsan = needsAsanRt();
   bool NeedsTsan = needsTsanRt();
   bool NeedsMsan = needsMsanRt();
+  bool NeedsLsan = needsLsanRt();
   if (NeedsAsan && NeedsTsan)
     D.Diag(diag::err_drv_argument_not_allowed_with)
       << lastArgumentForKind(D, Args, NeedsAsanRt)
@@ -1599,6 +1600,19 @@
     D.Diag(diag::err_drv_argument_not_allowed_with)
       << lastArgumentForKind(D, Args, NeedsTsanRt)
       << lastArgumentForKind(D, Args, NeedsMsanRt);
+  if (NeedsLsan && NeedsTsan)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+      << lastArgumentForKind(D, Args, NeedsLsanRt)
+      << lastArgumentForKind(D, Args, NeedsTsanRt);
+  if (NeedsLsan && NeedsMsan)
+    D.Diag(diag::err_drv_argument_not_allowed_with)
+      << lastArgumentForKind(D, Args, NeedsLsanRt)
+      << lastArgumentForKind(D, Args, NeedsMsanRt);
+  // LSan is built into ASan, so enabling them both is redundant.
+  if (NeedsLsan && NeedsAsan)
+    D.Diag(diag::warn_drv_redundant_sanitizer)
+     << "-fsanitize=leak"
+     << "-fsanitize=address";
 
   // If -fsanitize contains extra features of ASan, it should also
   // explicitly contain -fsanitize=address (probably, turned off later in the
@@ -1728,6 +1742,15 @@
   }
 }
 
+/// If LeakSanitizer is enabled, add appropriate linker flags (Linux).
+/// This needs to be called before we add the C run-time (malloc, etc).
+static void addLsanRTLinux(const ToolChain &TC, const ArgList &Args,
+                           ArgStringList &CmdArgs) {
+  if (!Args.hasArg(options::OPT_shared)) {
+    addSanitizerRTLinkFlagsLinux(TC, Args, CmdArgs, "lsan", true);
+  }
+}
+
 /// If UndefinedBehaviorSanitizer is enabled, add appropriate linker flags
 /// (Linux).
 static void addUbsanRTLinux(const ToolChain &TC, const ArgList &Args,
@@ -6120,6 +6143,8 @@
     addTsanRTLinux(getToolChain(), Args, CmdArgs);
   if (Sanitize.needsMsanRt())
     addMsanRTLinux(getToolChain(), Args, CmdArgs);
+  if (Sanitize.needsLsanRt() && !Sanitize.needsAsanRt())
+    addLsanRTLinux(getToolChain(), Args, CmdArgs);
 
   if (D.CCCIsCXX &&
       !Args.hasArg(options::OPT_nostdlib) &&
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D837.1.patch
Type: text/x-patch
Size: 4056 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130521/4e14dc8a/attachment.bin>


More information about the cfe-commits mailing list