r193875 - SanitizerArgs: add ability to filter/diagnose unsupported sanitizers.

Peter Collingbourne peter at pcc.me.uk
Fri Nov 1 11:16:26 PDT 2013


Author: pcc
Date: Fri Nov  1 13:16:25 2013
New Revision: 193875

URL: http://llvm.org/viewvc/llvm-project?rev=193875&view=rev
Log:
SanitizerArgs: add ability to filter/diagnose unsupported sanitizers.

The thread, memory, dataflow and function sanitizers are now diagnosed if
enabled explicitly on an unsupported platform.  Unsupported sanitizers which
are enabled implicitly (as part of a larger group) are silently disabled.  As a
side effect, this makes SanitizerArgs parsing toolchain-dependent (and thus
essentially reverts r188058), and moves SanitizerArgs ownership to ToolChain.

Differential Revision: http://llvm-reviews.chandlerc.com/D1990

Modified:
    cfe/trunk/include/clang/Driver/Driver.h
    cfe/trunk/include/clang/Driver/SanitizerArgs.h
    cfe/trunk/include/clang/Driver/ToolChain.h
    cfe/trunk/lib/Driver/Driver.cpp
    cfe/trunk/lib/Driver/SanitizerArgs.cpp
    cfe/trunk/lib/Driver/ToolChain.cpp
    cfe/trunk/lib/Driver/ToolChains.cpp
    cfe/trunk/lib/Driver/Tools.cpp
    cfe/trunk/test/Driver/fsanitize.c
    cfe/trunk/test/Driver/tsan.c

Modified: cfe/trunk/include/clang/Driver/Driver.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Driver.h?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/Driver.h (original)
+++ cfe/trunk/include/clang/Driver/Driver.h Fri Nov  1 13:16:25 2013
@@ -179,9 +179,6 @@ private:
   /// stored in it, and will clean them up when torn down.
   mutable llvm::StringMap<ToolChain *> ToolChains;
 
-  /// Parsed arguments passed to sanitizer tools.
-  mutable llvm::OwningPtr<SanitizerArgs> SanitizerArguments;
-
 private:
   /// TranslateInputArgs - Create a new derived argument list from the input
   /// arguments, after applying the standard argument translations.
@@ -406,10 +403,6 @@ private:
   std::pair<unsigned, unsigned> getIncludeExcludeOptionFlagMasks() const;
 
 public:
-  /// \brief Returns parsed arguments to sanitizer tools.
-  const SanitizerArgs &
-  getOrParseSanitizerArgs(const llvm::opt::ArgList &Args) const;
-
   /// GetReleaseVersion - Parse (([0-9]+)(.([0-9]+)(.([0-9]+)?))?)? and
   /// return the grouped values as integers. Numbers which are not
   /// provided are set to 0.

Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/SanitizerArgs.h?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/SanitizerArgs.h (original)
+++ cfe/trunk/include/clang/Driver/SanitizerArgs.h Fri Nov  1 13:16:25 2013
@@ -25,6 +25,7 @@ class SanitizerArgs {
   /// bit positions within \c Kind.
   enum SanitizeOrdinal {
 #define SANITIZER(NAME, ID) SO_##ID,
+#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
 #include "clang/Basic/Sanitizers.def"
     SO_Count
   };
@@ -32,7 +33,8 @@ class SanitizerArgs {
   /// Bugs to catch at runtime.
   enum SanitizeKind {
 #define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
-#define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
+#define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
+  ID = ALIAS, ID##Group = 1 << SO_##ID##Group,
 #include "clang/Basic/Sanitizers.def"
     NeedsAsanRt = Address,
     NeedsTsanRt = Thread,
@@ -47,17 +49,13 @@ class SanitizerArgs {
 
   std::string BlacklistFile;
   bool MsanTrackOrigins;
-  enum AsanZeroBaseShadowKind {
-    AZBSK_Default,  // Default value is toolchain-specific.
-    AZBSK_On,
-    AZBSK_Off
-  } AsanZeroBaseShadow;
+  bool AsanZeroBaseShadow;
   bool UbsanTrapOnError;
 
  public:
   SanitizerArgs();
   /// Parses the sanitizer arguments from an argument list.
-  SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args);
+  SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
 
   bool needsAsanRt() const { return Kind & NeedsAsanRt; }
   bool needsTsanRt() const { return Kind & NeedsTsanRt; }
@@ -73,17 +71,15 @@ class SanitizerArgs {
 
   bool sanitizesVptr() const { return Kind & Vptr; }
   bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
-  bool hasZeroBaseShadow(const ToolChain &TC) const {
-    return (Kind & HasZeroBaseShadow) || hasAsanZeroBaseShadow(TC);
+  bool hasZeroBaseShadow() const {
+    return (Kind & HasZeroBaseShadow) || AsanZeroBaseShadow;
   }
-  void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
+  void addArgs(const llvm::opt::ArgList &Args,
                llvm::opt::ArgStringList &CmdArgs) const;
 
  private:
   void clear();
 
-  bool hasAsanZeroBaseShadow(const ToolChain &TC) const;
-
   /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
   /// Returns OR of members of the \c SanitizeKind enumeration, or \c 0
   /// if \p Value is not known.
@@ -119,6 +115,30 @@ class SanitizerArgs {
 
   static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
                                          std::string &BLPath);
+
+  /// Return the smallest superset of sanitizer set \p Kinds such that each
+  /// member of each group whose flag is set in \p Kinds has its flag set in the
+  /// result.
+  static unsigned expandGroups(unsigned Kinds);
+
+  /// Return the subset of \p Kinds supported by toolchain \p TC.  If
+  /// \p DiagnoseErrors is true, produce an error diagnostic for each sanitizer
+  /// removed from \p Kinds.
+  static unsigned filterUnsupportedKinds(const ToolChain &TC, unsigned Kinds,
+                                         const llvm::opt::ArgList &Args,
+                                         const llvm::opt::Arg *A,
+                                         bool DiagnoseErrors,
+                                         unsigned &DiagnosedKinds);
+
+  /// The flags in \p Mask are unsupported by \p TC.  If present in \p Kinds,
+  /// remove them and produce an error diagnostic referring to \p A if
+  /// \p DiagnoseErrors is true.
+  static void filterUnsupportedMask(const ToolChain &TC, unsigned &Kinds,
+                                    unsigned Mask,
+                                    const llvm::opt::ArgList &Args,
+                                    const llvm::opt::Arg *A,
+                                    bool DiagnoseErrors,
+                                    unsigned &DiagnosedKinds);
 };
 
 }  // namespace driver

Modified: cfe/trunk/include/clang/Driver/ToolChain.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/ToolChain.h?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/ToolChain.h (original)
+++ cfe/trunk/include/clang/Driver/ToolChain.h Fri Nov  1 13:16:25 2013
@@ -73,6 +73,8 @@ private:
   Tool *getLink() const;
   Tool *getClangAs() const;
 
+  mutable OwningPtr<SanitizerArgs> SanitizerArguments;
+
 protected:
   ToolChain(const Driver &D, const llvm::Triple &T,
             const llvm::opt::ArgList &Args);

Modified: cfe/trunk/lib/Driver/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Driver.cpp?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Driver.cpp (original)
+++ cfe/trunk/lib/Driver/Driver.cpp Fri Nov  1 13:16:25 2013
@@ -16,7 +16,6 @@
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Job.h"
 #include "clang/Driver/Options.h"
-#include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/Tool.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/ArrayRef.h"
@@ -2056,10 +2055,3 @@ std::pair<unsigned, unsigned> Driver::ge
 
   return std::make_pair(IncludedFlagsBitmask, ExcludedFlagsBitmask);
 }
-
-const SanitizerArgs &
-Driver::getOrParseSanitizerArgs(const ArgList &Args) const {
-  if (!SanitizerArguments.get())
-    SanitizerArguments.reset(new SanitizerArgs(*this, Args));
-  return *SanitizerArguments.get();
-}

Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original)
+++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Fri Nov  1 13:16:25 2013
@@ -25,7 +25,7 @@ void SanitizerArgs::clear() {
   Kind = 0;
   BlacklistFile = "";
   MsanTrackOrigins = false;
-  AsanZeroBaseShadow = AZBSK_Default;
+  AsanZeroBaseShadow = false;
   UbsanTrapOnError = false;
 }
 
@@ -33,18 +33,42 @@ SanitizerArgs::SanitizerArgs() {
   clear();
 }
 
-SanitizerArgs::SanitizerArgs(const Driver &D, const llvm::opt::ArgList &Args) {
+SanitizerArgs::SanitizerArgs(const ToolChain &TC,
+                             const llvm::opt::ArgList &Args) {
   clear();
-  unsigned AllKinds = 0;  // All kinds of sanitizers that were turned on
-                          // at least once (possibly, disabled further).
-  for (ArgList::const_iterator I = Args.begin(), E = Args.end(); I != E; ++I) {
+  unsigned AllAdd = 0;  // All kinds of sanitizers that were turned on
+                        // at least once (possibly, disabled further).
+  unsigned AllRemove = 0;  // During the loop below, the accumulated set of
+                           // sanitizers disabled by the current sanitizer
+                           // argument or any argument after it.
+  unsigned DiagnosedKinds = 0;  // All Kinds we have diagnosed up to now.
+                                // Used to deduplicate diagnostics.
+  const Driver &D = TC.getDriver();
+  for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
+       I != E; ++I) {
     unsigned Add, Remove;
     if (!parse(D, Args, *I, Add, Remove, true))
       continue;
     (*I)->claim();
+
+    AllAdd |= expandGroups(Add);
+    AllRemove |= expandGroups(Remove);
+
+    // Avoid diagnosing any sanitizer which is disabled later.
+    Add &= ~AllRemove;
+    // At this point we have not expanded groups, so any unsupported sanitizers
+    // in Add are those which have been explicitly enabled. Diagnose them.
+    Add = filterUnsupportedKinds(TC, Add, Args, *I, /*DiagnoseErrors=*/true,
+                                 DiagnosedKinds);
+    Add = expandGroups(Add);
+    // Group expansion may have enabled a sanitizer which is disabled later.
+    Add &= ~AllRemove;
+    // Silently discard any unsupported sanitizers implicitly enabled through
+    // group expansion.
+    Add = filterUnsupportedKinds(TC, Add, Args, *I, /*DiagnoseErrors=*/false,
+                                 DiagnosedKinds);
+
     Kind |= Add;
-    Kind &= ~Remove;
-    AllKinds |= Add;
   }
 
   UbsanTrapOnError =
@@ -107,7 +131,7 @@ SanitizerArgs::SanitizerArgs(const Drive
   // If -fsanitize contains extra features of ASan, it should also
   // explicitly contain -fsanitize=address (probably, turned off later in the
   // command line).
-  if ((Kind & AddressFull) != 0 && (AllKinds & Address) == 0)
+  if ((Kind & AddressFull) != 0 && (AllAdd & Address) == 0)
     D.Diag(diag::warn_drv_unused_sanitizer)
      << lastArgumentForKind(D, Args, AddressFull)
      << "-fsanitize=address";
@@ -148,21 +172,25 @@ SanitizerArgs::SanitizerArgs(const Drive
 
   // Parse -f(no-)sanitize-address-zero-base-shadow options.
   if (NeedsAsan) {
-    if (Arg *A = Args.getLastArg(
-        options::OPT_fsanitize_address_zero_base_shadow,
-        options::OPT_fno_sanitize_address_zero_base_shadow))
-      AsanZeroBaseShadow = A->getOption().matches(
-                               options::OPT_fsanitize_address_zero_base_shadow)
-                               ? AZBSK_On
-                               : AZBSK_Off;
+    bool IsAndroid = (TC.getTriple().getEnvironment() == llvm::Triple::Android);
+    bool ZeroBaseShadowDefault = IsAndroid;
+    AsanZeroBaseShadow =
+        Args.hasFlag(options::OPT_fsanitize_address_zero_base_shadow,
+                     options::OPT_fno_sanitize_address_zero_base_shadow,
+                     ZeroBaseShadowDefault);
+    // Zero-base shadow is a requirement on Android.
+    if (IsAndroid && !AsanZeroBaseShadow) {
+      D.Diag(diag::err_drv_argument_not_allowed_with)
+          << "-fno-sanitize-address-zero-base-shadow"
+          << lastArgumentForKind(D, Args, Address);
+    }
   }
 }
 
-void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
+void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
                             llvm::opt::ArgStringList &CmdArgs) const {
   if (!Kind)
     return;
-  const Driver &D = TC.getDriver();
   SmallString<256> SanitizeOpt("-fsanitize=");
 #define SANITIZER(NAME, ID) \
   if (Kind & ID) \
@@ -179,36 +207,19 @@ void SanitizerArgs::addArgs(const ToolCh
   if (MsanTrackOrigins)
     CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
 
-  if (needsAsanRt()) {
-    if (hasAsanZeroBaseShadow(TC)) {
-      CmdArgs.push_back(
-          Args.MakeArgString("-fsanitize-address-zero-base-shadow"));
-    } else if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
-      // Zero-base shadow is a requirement on Android.
-      D.Diag(diag::err_drv_argument_not_allowed_with)
-          << "-fno-sanitize-address-zero-base-shadow"
-          << lastArgumentForKind(D, Args, Address);
-    }
-  }
+  if (AsanZeroBaseShadow)
+    CmdArgs.push_back(
+        Args.MakeArgString("-fsanitize-address-zero-base-shadow"));
 
   // Workaround for PR16386.
   if (needsMsanRt())
     CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new"));
 }
 
-bool SanitizerArgs::hasAsanZeroBaseShadow(const ToolChain &TC) const {
-  if (!needsAsanRt())
-    return false;
-  if (AsanZeroBaseShadow != AZBSK_Default)
-    return AsanZeroBaseShadow == AZBSK_On;
-  // Zero-base shadow is used by default only on Android.
-  return TC.getTriple().getEnvironment() == llvm::Triple::Android;
-}
-
 unsigned SanitizerArgs::parse(const char *Value) {
   unsigned ParsedKind = llvm::StringSwitch<SanitizeKind>(Value)
 #define SANITIZER(NAME, ID) .Case(NAME, ID)
-#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
+#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID##Group)
 #include "clang/Basic/Sanitizers.def"
     .Default(SanitizeKind());
   // Assume -fsanitize=address implies -fsanitize=init-order,use-after-return.
@@ -219,6 +230,54 @@ unsigned SanitizerArgs::parse(const char
   return ParsedKind;
 }
 
+unsigned SanitizerArgs::expandGroups(unsigned Kinds) {
+#define SANITIZER(NAME, ID)
+#define SANITIZER_GROUP(NAME, ID, ALIAS) if (Kinds & ID##Group) Kinds |= ID;
+#include "clang/Basic/Sanitizers.def"
+  return Kinds;
+}
+
+void SanitizerArgs::filterUnsupportedMask(const ToolChain &TC, unsigned &Kinds,
+                                          unsigned Mask,
+                                          const llvm::opt::ArgList &Args,
+                                          const llvm::opt::Arg *A,
+                                          bool DiagnoseErrors,
+                                          unsigned &DiagnosedKinds) {
+  unsigned MaskedKinds = Kinds & Mask;
+  if (!MaskedKinds)
+    return;
+  Kinds &= ~Mask;
+  // Do we have new kinds to diagnose?
+  if (DiagnoseErrors && (DiagnosedKinds & MaskedKinds) != MaskedKinds) {
+    // Only diagnose the new kinds.
+    std::string Desc =
+        describeSanitizeArg(Args, A, MaskedKinds & ~DiagnosedKinds);
+    TC.getDriver().Diag(diag::err_drv_unsupported_opt_for_target)
+        << Desc << TC.getTriple().str();
+    DiagnosedKinds |= MaskedKinds;
+  }
+}
+
+unsigned SanitizerArgs::filterUnsupportedKinds(const ToolChain &TC,
+                                               unsigned Kinds,
+                                               const llvm::opt::ArgList &Args,
+                                               const llvm::opt::Arg *A,
+                                               bool DiagnoseErrors,
+                                               unsigned &DiagnosedKinds) {
+  bool IsLinux = TC.getTriple().getOS() == llvm::Triple::Linux;
+  bool IsX86 = TC.getTriple().getArch() == llvm::Triple::x86;
+  bool IsX86_64 = TC.getTriple().getArch() == llvm::Triple::x86_64;
+  if (!(IsLinux && IsX86_64)) {
+    filterUnsupportedMask(TC, Kinds, Thread | Memory | DataFlow, Args, A,
+                          DiagnoseErrors, DiagnosedKinds);
+  }
+  if (!(IsLinux && (IsX86 || IsX86_64))) {
+    filterUnsupportedMask(TC, Kinds, Function, Args, A, DiagnoseErrors,
+                          DiagnosedKinds);
+  }
+  return Kinds;
+}
+
 unsigned SanitizerArgs::parse(const Driver &D, const llvm::opt::Arg *A,
                               bool DiagnoseErrors) {
   unsigned Kind = 0;
@@ -282,7 +341,7 @@ std::string SanitizerArgs::lastArgumentF
        I != E; ++I) {
     unsigned Add, Remove;
     if (parse(D, Args, *I, Add, Remove, false) &&
-        (Add & Kind))
+        (expandGroups(Add) & Kind))
       return describeSanitizeArg(Args, *I, Kind);
     Kind &= ~Remove;
   }
@@ -295,11 +354,17 @@ std::string SanitizerArgs::describeSanit
   if (!A->getOption().matches(options::OPT_fsanitize_EQ))
     return A->getAsString(Args);
 
-  for (unsigned I = 0, N = A->getNumValues(); I != N; ++I)
-    if (parse(A->getValue(I)) & Mask)
-      return std::string("-fsanitize=") + A->getValue(I);
+  std::string Sanitizers;
+  for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
+    if (expandGroups(parse(A->getValue(I))) & Mask) {
+      if (!Sanitizers.empty())
+        Sanitizers += ",";
+      Sanitizers += A->getValue(I);
+    }
+  }
 
-  llvm_unreachable("arg didn't provide expected value");
+  assert(!Sanitizers.empty() && "arg didn't provide expected value");
+  return "-fsanitize=" + Sanitizers;
 }
 
 bool SanitizerArgs::getDefaultBlacklistForKind(const Driver &D, unsigned Kind,

Modified: cfe/trunk/lib/Driver/ToolChain.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChain.cpp?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChain.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChain.cpp Fri Nov  1 13:16:25 2013
@@ -13,6 +13,7 @@
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
+#include "clang/Driver/SanitizerArgs.h"
 #include "clang/Driver/ToolChain.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Option/Arg.h"
@@ -43,7 +44,9 @@ bool ToolChain::useIntegratedAs() const
 }
 
 const SanitizerArgs& ToolChain::getSanitizerArgs() const {
-  return D.getOrParseSanitizerArgs(Args);
+  if (!SanitizerArguments.get())
+    SanitizerArguments.reset(new SanitizerArgs(*this, Args));
+  return *SanitizerArguments.get();
 }
 
 std::string ToolChain::getDefaultUniversalArchName() const {

Modified: cfe/trunk/lib/Driver/ToolChains.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains.cpp?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/ToolChains.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains.cpp Fri Nov  1 13:16:25 2013
@@ -300,10 +300,11 @@ void DarwinClang::AddLinkRuntimeLibArgs(
     }
   }
 
-  const SanitizerArgs &Sanitize = getDriver().getOrParseSanitizerArgs(Args);
+  const SanitizerArgs &Sanitize = getSanitizerArgs();
 
   // Add Ubsan runtime library, if required.
   if (Sanitize.needsUbsanRt()) {
+    // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
     if (isTargetIPhoneOS()) {
       getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
         << "-fsanitize=undefined";
@@ -318,6 +319,7 @@ void DarwinClang::AddLinkRuntimeLibArgs(
   // Add ASAN runtime library, if required. Dynamic libraries and bundles
   // should not be linked with the runtime library.
   if (Sanitize.needsAsanRt()) {
+    // FIXME: Move this check to SanitizerArgs::filterUnsupportedKinds.
     if (isTargetIPhoneOS() && !isTargetIOSSimulator()) {
       getDriver().Diag(diag::err_drv_clang_unsupported_per_platform)
         << "-fsanitize=address";
@@ -2722,7 +2724,7 @@ void Linux::AddClangCXXStdlibIncludeArgs
 }
 
 bool Linux::isPIEDefault() const {
-  return getSanitizerArgs().hasZeroBaseShadow(*this);
+  return getSanitizerArgs().hasZeroBaseShadow();
 }
 
 /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly.

Modified: cfe/trunk/lib/Driver/Tools.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/lib/Driver/Tools.cpp (original)
+++ cfe/trunk/lib/Driver/Tools.cpp Fri Nov  1 13:16:25 2013
@@ -2942,8 +2942,8 @@ void Clang::ConstructJob(Compilation &C,
   Args.AddLastArg(CmdArgs, options::OPT_fdiagnostics_show_template_tree);
   Args.AddLastArg(CmdArgs, options::OPT_fno_elide_type);
 
-  const SanitizerArgs &Sanitize = D.getOrParseSanitizerArgs(Args);
-  Sanitize.addArgs(getToolChain(), Args, CmdArgs);
+  const SanitizerArgs &Sanitize = getToolChain().getSanitizerArgs();
+  Sanitize.addArgs(Args, CmdArgs);
 
   if (!Args.hasFlag(options::OPT_fsanitize_recover,
                     options::OPT_fno_sanitize_recover,
@@ -6188,10 +6188,10 @@ void gnutools::Link::ConstructJob(Compil
   const Driver &D = ToolChain.getDriver();
   const bool isAndroid =
     ToolChain.getTriple().getEnvironment() == llvm::Triple::Android;
-  const SanitizerArgs &Sanitize = D.getOrParseSanitizerArgs(Args);
+  const SanitizerArgs &Sanitize = ToolChain.getSanitizerArgs();
   const bool IsPIE =
     !Args.hasArg(options::OPT_shared) &&
-    (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow(ToolChain));
+    (Args.hasArg(options::OPT_pie) || Sanitize.hasZeroBaseShadow());
 
   ArgStringList CmdArgs;
 
@@ -6722,7 +6722,7 @@ void visualstudio::Link::ConstructJob(Co
                                          ImplibName.str()));
   }
 
-  if (getToolChain().getDriver().getOrParseSanitizerArgs(Args).needsAsanRt()) {
+  if (getToolChain().getSanitizerArgs().needsAsanRt()) {
     CmdArgs.push_back(Args.MakeArgString("-debug"));
     CmdArgs.push_back(Args.MakeArgString("-incremental:no"));
     SmallString<128> LibSanitizer(getToolChain().getDriver().ResourceDir);

Modified: cfe/trunk/test/Driver/fsanitize.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/test/Driver/fsanitize.c (original)
+++ cfe/trunk/test/Driver/fsanitize.c Fri Nov  1 13:16:25 2013
@@ -7,6 +7,9 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED
 // CHECK-UNDEFINED: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|function|shift|unreachable|return|vla-bound|alignment|null|vptr|object-size|float-cast-overflow|array-bounds|enum|bool),?){16}"}}
 
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UNDEFINED-DARWIN
+// CHECK-UNDEFINED-DARWIN: "-fsanitize={{((signed-integer-overflow|integer-divide-by-zero|float-divide-by-zero|shift|unreachable|return|vla-bound|alignment|null|vptr|object-size|float-cast-overflow|array-bounds|enum|bool),?){15}"}}
+
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER
 // CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift),?){4}"}}
 
@@ -96,12 +99,12 @@
 // OK
 
 // RUN: %clang -target x86_64-linux-gnu -fcatch-undefined-behavior -fthread-sanitizer -fno-thread-sanitizer -faddress-sanitizer -fno-address-sanitizer -fbounds-checking -### %s 2>&1 | FileCheck %s --check-prefix=CHECK-DEPRECATED
-// CHECK-DEPRECATED: argument '-fcatch-undefined-behavior' is deprecated, use '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error' instead
-// CHECK-DEPRECATED: argument '-fthread-sanitizer' is deprecated, use '-fsanitize=thread' instead
-// CHECK-DEPRECATED: argument '-fno-thread-sanitizer' is deprecated, use '-fno-sanitize=thread' instead
-// CHECK-DEPRECATED: argument '-faddress-sanitizer' is deprecated, use '-fsanitize=address' instead
-// CHECK-DEPRECATED: argument '-fno-address-sanitizer' is deprecated, use '-fno-sanitize=address' instead
 // CHECK-DEPRECATED: argument '-fbounds-checking' is deprecated, use '-fsanitize=local-bounds' instead
+// CHECK-DEPRECATED: argument '-fno-address-sanitizer' is deprecated, use '-fno-sanitize=address' instead
+// CHECK-DEPRECATED: argument '-faddress-sanitizer' is deprecated, use '-fsanitize=address' instead
+// CHECK-DEPRECATED: argument '-fno-thread-sanitizer' is deprecated, use '-fno-sanitize=thread' instead
+// CHECK-DEPRECATED: argument '-fthread-sanitizer' is deprecated, use '-fsanitize=thread' instead
+// CHECK-DEPRECATED: argument '-fcatch-undefined-behavior' is deprecated, use '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error' instead
 
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-NO-PIE
 // CHECK-TSAN-NO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pie-level" "2"
@@ -152,3 +155,27 @@
 // RUN: %clang -target x86_64-linux-gnu -fsanitize=zzz %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-DIAG1
 // CHECK-DIAG1: unsupported argument 'zzz' to option 'fsanitize='
 // CHECK-DIAG1-NOT: unsupported argument 'zzz' to option 'fsanitize='
+
+// RUN: %clang -target i686-linux-gnu -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-X86
+// CHECK-MSAN-X86: error: unsupported option '-fsanitize=memory' for target 'i686--linux-gnu'
+
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-DARWIN
+// CHECK-MSAN-DARWIN: unsupported option '-fsanitize=memory' for target 'x86_64-apple-darwin10'
+
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory -fno-sanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-NOMSAN-DARWIN
+// CHECK-MSAN-NOMSAN-DARWIN-NOT: unsupported option
+
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=memory -fsanitize=thread,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-MSAN-TSAN-MSAN-DARWIN
+// CHECK-MSAN-TSAN-MSAN-DARWIN: unsupported option '-fsanitize=thread,memory' for target 'x86_64-apple-darwin10'
+// CHECK-MSAN-TSAN-MSAN-DARWIN-NOT: unsupported option
+
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=thread,memory -fsanitize=memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-TSAN-MSAN-MSAN-DARWIN
+// CHECK-TSAN-MSAN-MSAN-DARWIN: unsupported option '-fsanitize=memory' for target 'x86_64-apple-darwin10'
+// CHECK-TSAN-MSAN-MSAN-DARWIN: unsupported option '-fsanitize=thread' for target 'x86_64-apple-darwin10'
+// CHECK-TSAN-MSAN-MSAN-DARWIN-NOT: unsupported option
+
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-DARWIN
+// CHECK-FSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'
+
+// RUN: %clang -target x86_64-apple-darwin10 -fsanitize=function -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-FSAN-UBSAN-DARWIN
+// CHECK-FSAN-UBSAN-DARWIN: unsupported option '-fsanitize=function' for target 'x86_64-apple-darwin10'

Modified: cfe/trunk/test/Driver/tsan.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/tsan.c?rev=193875&r1=193874&r2=193875&view=diff
==============================================================================
--- cfe/trunk/test/Driver/tsan.c (original)
+++ cfe/trunk/test/Driver/tsan.c Fri Nov  1 13:16:25 2013
@@ -1,8 +1,8 @@
-// RUN: %clang     -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O1 -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O2 -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang -O3 -target i386-unknown-unknown -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
-// RUN: %clang     -target i386-unknown-unknown -fsanitize=thread  %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang     -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O1 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O2 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang -O3 -target x86_64-unknown-linux -fsanitize=thread %s -S -emit-llvm -o - | FileCheck %s
+// RUN: %clang     -target x86_64-unknown-linux -fsanitize=thread  %s -S -emit-llvm -o - | FileCheck %s
 // Verify that -fsanitize=thread invokes tsan instrumentation.
 
 int foo(int *a) { return *a; }





More information about the cfe-commits mailing list