1bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov//===--- SanitizerArgs.h - Arguments for sanitizer tools  -------*- C++ -*-===//
2bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov//
3bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov//                     The LLVM Compiler Infrastructure
4bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov//
5bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov// This file is distributed under the University of Illinois Open Source
6bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov// License. See LICENSE.TXT for details.
7bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov//
8bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov//===----------------------------------------------------------------------===//
9bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#ifndef CLANG_LIB_DRIVER_SANITIZERARGS_H_
10bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#define CLANG_LIB_DRIVER_SANITIZERARGS_H_
11bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
1255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Driver/Arg.h"
13bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#include "clang/Driver/ArgList.h"
1455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Driver/Driver.h"
1555fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Driver/DriverDiagnostic.h"
1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/Driver/Options.h"
1755fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/StringSwitch.h"
1824697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov#include "llvm/Support/Path.h"
19bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
20bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonovnamespace clang {
21bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonovnamespace driver {
22bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
23bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonovclass SanitizerArgs {
24bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// Assign ordinals to sanitizer flags. We'll use the ordinal values as
25bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// bit positions within \c Kind.
26bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  enum SanitizeOrdinal {
27bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#define SANITIZER(NAME, ID) SO_##ID,
28bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#include "clang/Basic/Sanitizers.def"
29bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    SO_Count
30bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  };
31bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
32bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// Bugs to catch at runtime.
33bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  enum SanitizeKind {
34bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#define SANITIZER(NAME, ID) ID = 1 << SO_##ID,
35bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#define SANITIZER_GROUP(NAME, ID, ALIAS) ID = ALIAS,
36bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#include "clang/Basic/Sanitizers.def"
373e335c118140c40b264a26b13e44af368514cb87Alexey Samsonov    NeedsAsanRt = Address,
38bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    NeedsTsanRt = Thread,
3909ccf39c13cfca102deea2986f45cb908bc232fdEvgeniy Stepanov    NeedsMsanRt = Memory,
40a0a628f839cf50844cc0f226bd9cb72485f98f91Richard Smith    NeedsUbsanRt = Undefined | Integer,
4178d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier    NotAllowedWithTrap = Vptr
42bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  };
43bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  unsigned Kind;
4491ecfa6af51836d3ccc90beddab1193b0c060739Alexey Samsonov  std::string BlacklistFile;
4534ef11be9d09ebf916ab02a521e37be6e9e102d3Evgeniy Stepanov  bool MsanTrackOrigins;
464bdc60434c79126b75aee2bb391275f3bb746364Alexey Samsonov  bool AsanZeroBaseShadow;
4778d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier  bool UbsanTrapOnError;
48bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
49bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov public:
504bdc60434c79126b75aee2bb391275f3bb746364Alexey Samsonov  SanitizerArgs() : Kind(0), BlacklistFile(""), MsanTrackOrigins(false),
5178d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier                    AsanZeroBaseShadow(false), UbsanTrapOnError(false) {}
52bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// Parses the sanitizer arguments from an argument list.
53bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  SanitizerArgs(const Driver &D, const ArgList &Args);
54bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
55bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  bool needsAsanRt() const { return Kind & NeedsAsanRt; }
56bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  bool needsTsanRt() const { return Kind & NeedsTsanRt; }
5709ccf39c13cfca102deea2986f45cb908bc232fdEvgeniy Stepanov  bool needsMsanRt() const { return Kind & NeedsMsanRt; }
5878d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier  bool needsUbsanRt() const {
5978d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier    if (UbsanTrapOnError)
6078d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier      return false;
6178d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier    return Kind & NeedsUbsanRt;
6278d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier  }
63bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
64bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  bool sanitizesVptr() const { return Kind & Vptr; }
6578d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier  bool notAllowedWithTrap() const { return Kind & NotAllowedWithTrap; }
664d1a6e41e1eaeaf5a4672c802519f15c8fb91e91Alexey Samsonov
67bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  void addArgs(const ArgList &Args, ArgStringList &CmdArgs) const {
68bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    if (!Kind)
69bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov      return;
70cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko    SmallString<256> SanitizeOpt("-fsanitize=");
71bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#define SANITIZER(NAME, ID) \
72bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    if (Kind & ID) \
73bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov      SanitizeOpt += NAME ",";
74bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#include "clang/Basic/Sanitizers.def"
75bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    SanitizeOpt.pop_back();
76bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    CmdArgs.push_back(Args.MakeArgString(SanitizeOpt));
7791ecfa6af51836d3ccc90beddab1193b0c060739Alexey Samsonov    if (!BlacklistFile.empty()) {
78cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenko      SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
7991ecfa6af51836d3ccc90beddab1193b0c060739Alexey Samsonov      BlacklistOpt += BlacklistFile;
8091ecfa6af51836d3ccc90beddab1193b0c060739Alexey Samsonov      CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
8191ecfa6af51836d3ccc90beddab1193b0c060739Alexey Samsonov    }
8234ef11be9d09ebf916ab02a521e37be6e9e102d3Evgeniy Stepanov
8334ef11be9d09ebf916ab02a521e37be6e9e102d3Evgeniy Stepanov    if (MsanTrackOrigins)
8434ef11be9d09ebf916ab02a521e37be6e9e102d3Evgeniy Stepanov      CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins"));
854bdc60434c79126b75aee2bb391275f3bb746364Alexey Samsonov
864bdc60434c79126b75aee2bb391275f3bb746364Alexey Samsonov    if (AsanZeroBaseShadow)
874bdc60434c79126b75aee2bb391275f3bb746364Alexey Samsonov      CmdArgs.push_back(Args.MakeArgString(
884bdc60434c79126b75aee2bb391275f3bb746364Alexey Samsonov          "-fsanitize-address-zero-base-shadow"));
89bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  }
90bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
91bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov private:
92bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
93bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// Returns a member of the \c SanitizeKind enumeration, or \c 0 if \p Value
94bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// is not known.
95bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  static unsigned parse(const char *Value) {
96bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    return llvm::StringSwitch<SanitizeKind>(Value)
97bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#define SANITIZER(NAME, ID) .Case(NAME, ID)
98bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#define SANITIZER_GROUP(NAME, ID, ALIAS) .Case(NAME, ID)
99bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#include "clang/Basic/Sanitizers.def"
100bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov      .Default(SanitizeKind());
101bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  }
102bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
103bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
104bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// invalid components.
1053325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  static unsigned parse(const Driver &D, const Arg *A, bool DiagnoseErrors) {
106bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    unsigned Kind = 0;
107bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    for (unsigned I = 0, N = A->getNumValues(); I != N; ++I) {
108bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov      if (unsigned K = parse(A->getValue(I)))
109bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov        Kind |= K;
1103325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      else if (DiagnoseErrors)
111bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov        D.Diag(diag::err_drv_unsupported_option_argument)
112bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov          << A->getOption().getName() << A->getValue(I);
113bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    }
114bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    return Kind;
115bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  }
116bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
1173325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  /// Parse a single flag of the form -f[no]sanitize=, or
1183325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  /// -f*-sanitizer. Sets the masks defining required change of Kind value.
1193325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  /// Returns true if the flag was parsed successfully.
1203325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  static bool parse(const Driver &D, const ArgList &Args, const Arg *A,
1213325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov                    unsigned &Add, unsigned &Remove, bool DiagnoseErrors) {
1223325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    Add = 0;
1233325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    Remove = 0;
1243325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    const char *DeprecatedReplacement = 0;
1253325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    if (A->getOption().matches(options::OPT_faddress_sanitizer)) {
1263325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Add = Address;
1273325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      DeprecatedReplacement = "-fsanitize=address";
1283325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else if (A->getOption().matches(options::OPT_fno_address_sanitizer)) {
1293325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Remove = Address;
1303325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      DeprecatedReplacement = "-fno-sanitize=address";
1313325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else if (A->getOption().matches(options::OPT_fthread_sanitizer)) {
1323325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Add = Thread;
1333325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      DeprecatedReplacement = "-fsanitize=thread";
1343325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else if (A->getOption().matches(options::OPT_fno_thread_sanitizer)) {
1353325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Remove = Thread;
1363325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      DeprecatedReplacement = "-fno-sanitize=thread";
1373325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else if (A->getOption().matches(options::OPT_fcatch_undefined_behavior)) {
13878d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier      Add = UndefinedTrap;
13978d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier      DeprecatedReplacement =
14078d85b1c5830a881c0a20a1b3fea99ee73149590Chad Rosier        "-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error";
1413325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else if (A->getOption().matches(options::OPT_fbounds_checking) ||
1423325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov               A->getOption().matches(options::OPT_fbounds_checking_EQ)) {
1433325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Add = Bounds;
1443325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      DeprecatedReplacement = "-fsanitize=bounds";
1453325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else if (A->getOption().matches(options::OPT_fsanitize_EQ)) {
1463325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Add = parse(D, A, DiagnoseErrors);
1473325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else if (A->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1483325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Remove = parse(D, A, DiagnoseErrors);
1493325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    } else {
1503325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      // Flag is not relevant to sanitizers.
1513325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      return false;
1523325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    }
1533325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    // If this is a deprecated synonym, produce a warning directing users
1543325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    // towards the new spelling.
1553325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    if (DeprecatedReplacement && DiagnoseErrors)
1563325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      D.Diag(diag::warn_drv_deprecated_arg)
1573325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov        << A->getAsString(Args) << DeprecatedReplacement;
1583325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    return true;
1593325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  }
1603325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov
1613325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  /// Produce an argument string from ArgList \p Args, which shows how it
1623325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  /// provides a sanitizer kind in \p Mask. For example, the argument list
1633325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  /// "-fsanitize=thread,vptr -faddress-sanitizer" with mask \c NeedsUbsanRt
1643325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  /// would produce "-fsanitize=vptr".
1653325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  static std::string lastArgumentForKind(const Driver &D, const ArgList &Args,
1663325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov                                         unsigned Kind) {
1673325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
1683325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov         I != E; ++I) {
1693325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      unsigned Add, Remove;
1703325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      if (parse(D, Args, *I, Add, Remove, false) &&
1713325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov          (Add & Kind))
1723325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov        return describeSanitizeArg(Args, *I, Kind);
1733325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov      Kind &= ~Remove;
1743325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    }
1753325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov    llvm_unreachable("arg list didn't provide expected value");
1763325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov  }
1773325b1617fce0c8c399b3010f8a65420e623d6f7Alexey Samsonov
178bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// Produce an argument string from argument \p A, which shows how it provides
179bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// a value in \p Mask. For instance, the argument
180bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
181bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  /// "-fsanitize=alignment".
182bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  static std::string describeSanitizeArg(const ArgList &Args, const Arg *A,
183bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov                                         unsigned Mask) {
184bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    if (!A->getOption().matches(options::OPT_fsanitize_EQ))
185bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov      return A->getAsString(Args);
186bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
187bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    for (unsigned I = 0, N = A->getNumValues(); I != N; ++I)
188bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov      if (parse(A->getValue(I)) & Mask)
189bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov        return std::string("-fsanitize=") + A->getValue(I);
190bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
191bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov    llvm_unreachable("arg didn't provide expected value");
192bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov  }
19324697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov
19424697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov  static bool getDefaultBlacklistForKind(const Driver &D, unsigned Kind,
19524697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov                                         std::string &BLPath) {
19624697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov    // For now, specify the default blacklist location for ASan only.
19724697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov    if (Kind & NeedsAsanRt) {
19824697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov      SmallString<64> Path(D.ResourceDir);
19924697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov      llvm::sys::path::append(Path, "asan_blacklist.txt");
20024697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov      BLPath = Path.str();
20124697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov      return true;
20224697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov    }
20324697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov    return false;
20424697b0a7297f530822dac42e36feb77738c1885Alexey Samsonov  }
205bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov};
206bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
207bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov}  // namespace driver
208bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov}  // namespace clang
209bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov
210bb1071c0568db9bd7934e869a53d671632eb9291Alexey Samsonov#endif // CLANG_LIB_DRIVER_SANITIZERARGS_H_
211