Home | History | Annotate | Line # | Download | only in Driver
      1 //===--- SanitizerArgs.cpp - Arguments for sanitizer tools  ---------------===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 #include "clang/Driver/SanitizerArgs.h"
      9 #include "ToolChains/CommonArgs.h"
     10 #include "clang/Basic/Sanitizers.h"
     11 #include "clang/Driver/Driver.h"
     12 #include "clang/Driver/DriverDiagnostic.h"
     13 #include "clang/Driver/Options.h"
     14 #include "clang/Driver/ToolChain.h"
     15 #include "llvm/ADT/StringExtras.h"
     16 #include "llvm/ADT/StringSwitch.h"
     17 #include "llvm/Support/Path.h"
     18 #include "llvm/Support/SpecialCaseList.h"
     19 #include "llvm/Support/TargetParser.h"
     20 #include "llvm/Support/VirtualFileSystem.h"
     21 #include <memory>
     22 
     23 using namespace clang;
     24 using namespace clang::driver;
     25 using namespace llvm::opt;
     26 
     27 static const SanitizerMask NeedsUbsanRt =
     28     SanitizerKind::Undefined | SanitizerKind::Integer |
     29     SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
     30     SanitizerKind::CFI | SanitizerKind::FloatDivideByZero |
     31     SanitizerKind::ObjCCast;
     32 static const SanitizerMask NeedsUbsanCxxRt =
     33     SanitizerKind::Vptr | SanitizerKind::CFI;
     34 static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
     35 static const SanitizerMask NotAllowedWithMinimalRuntime =
     36     SanitizerKind::Function | SanitizerKind::Vptr;
     37 static const SanitizerMask RequiresPIE =
     38     SanitizerKind::DataFlow | SanitizerKind::HWAddress | SanitizerKind::Scudo;
     39 static const SanitizerMask NeedsUnwindTables =
     40     SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread |
     41     SanitizerKind::Memory | SanitizerKind::DataFlow;
     42 static const SanitizerMask SupportsCoverage =
     43     SanitizerKind::Address | SanitizerKind::HWAddress |
     44     SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
     45     SanitizerKind::MemTag | SanitizerKind::Memory |
     46     SanitizerKind::KernelMemory | SanitizerKind::Leak |
     47     SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::Bounds |
     48     SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
     49     SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
     50     SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero |
     51     SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack |
     52     SanitizerKind::Thread | SanitizerKind::ObjCCast;
     53 static const SanitizerMask RecoverableByDefault =
     54     SanitizerKind::Undefined | SanitizerKind::Integer |
     55     SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
     56     SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
     57 static const SanitizerMask Unrecoverable =
     58     SanitizerKind::Unreachable | SanitizerKind::Return;
     59 static const SanitizerMask AlwaysRecoverable =
     60     SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress;
     61 static const SanitizerMask NeedsLTO = SanitizerKind::CFI;
     62 static const SanitizerMask TrappingSupported =
     63     (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | SanitizerKind::Integer |
     64     SanitizerKind::Nullability | SanitizerKind::LocalBounds |
     65     SanitizerKind::CFI | SanitizerKind::FloatDivideByZero |
     66     SanitizerKind::ObjCCast;
     67 static const SanitizerMask TrappingDefault = SanitizerKind::CFI;
     68 static const SanitizerMask CFIClasses =
     69     SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
     70     SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
     71     SanitizerKind::CFIUnrelatedCast;
     72 static const SanitizerMask CompatibleWithMinimalRuntime =
     73     TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack |
     74     SanitizerKind::MemTag;
     75 
     76 enum CoverageFeature {
     77   CoverageFunc = 1 << 0,
     78   CoverageBB = 1 << 1,
     79   CoverageEdge = 1 << 2,
     80   CoverageIndirCall = 1 << 3,
     81   CoverageTraceBB = 1 << 4, // Deprecated.
     82   CoverageTraceCmp = 1 << 5,
     83   CoverageTraceDiv = 1 << 6,
     84   CoverageTraceGep = 1 << 7,
     85   Coverage8bitCounters = 1 << 8, // Deprecated.
     86   CoverageTracePC = 1 << 9,
     87   CoverageTracePCGuard = 1 << 10,
     88   CoverageNoPrune = 1 << 11,
     89   CoverageInline8bitCounters = 1 << 12,
     90   CoveragePCTable = 1 << 13,
     91   CoverageStackDepth = 1 << 14,
     92   CoverageInlineBoolFlag = 1 << 15,
     93 };
     94 
     95 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
     96 /// invalid components. Returns a SanitizerMask.
     97 static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
     98                                     bool DiagnoseErrors);
     99 
    100 /// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid
    101 /// components. Returns OR of members of \c CoverageFeature enumeration.
    102 static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A);
    103 
    104 /// Produce an argument string from ArgList \p Args, which shows how it
    105 /// provides some sanitizer kind from \p Mask. For example, the argument list
    106 /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
    107 /// would produce "-fsanitize=vptr".
    108 static std::string lastArgumentForMask(const Driver &D,
    109                                        const llvm::opt::ArgList &Args,
    110                                        SanitizerMask Mask);
    111 
    112 /// Produce an argument string from argument \p A, which shows how it provides
    113 /// a value in \p Mask. For instance, the argument
    114 /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
    115 /// "-fsanitize=alignment".
    116 static std::string describeSanitizeArg(const llvm::opt::Arg *A,
    117                                        SanitizerMask Mask);
    118 
    119 /// Produce a string containing comma-separated names of sanitizers in \p
    120 /// Sanitizers set.
    121 static std::string toString(const clang::SanitizerSet &Sanitizers);
    122 
    123 static void validateSpecialCaseListFormat(const Driver &D,
    124                                           std::vector<std::string> &SCLFiles,
    125                                           unsigned MalformedSCLErrorDiagID) {
    126   if (SCLFiles.empty())
    127     return;
    128 
    129   std::string BLError;
    130   std::unique_ptr<llvm::SpecialCaseList> SCL(
    131       llvm::SpecialCaseList::create(SCLFiles, D.getVFS(), BLError));
    132   if (!SCL.get())
    133     D.Diag(MalformedSCLErrorDiagID) << BLError;
    134 }
    135 
    136 static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds,
    137                                  std::vector<std::string> &IgnorelistFiles) {
    138   struct Ignorelist {
    139     const char *File;
    140     SanitizerMask Mask;
    141   } Ignorelists[] = {{"asan_ignorelist.txt", SanitizerKind::Address},
    142                      {"hwasan_ignorelist.txt", SanitizerKind::HWAddress},
    143                      {"memtag_ignorelist.txt", SanitizerKind::MemTag},
    144                      {"msan_ignorelist.txt", SanitizerKind::Memory},
    145                      {"tsan_ignorelist.txt", SanitizerKind::Thread},
    146                      {"dfsan_abilist.txt", SanitizerKind::DataFlow},
    147                      {"cfi_ignorelist.txt", SanitizerKind::CFI},
    148                      {"ubsan_ignorelist.txt",
    149                       SanitizerKind::Undefined | SanitizerKind::Integer |
    150                           SanitizerKind::Nullability |
    151                           SanitizerKind::FloatDivideByZero}};
    152 
    153   for (auto BL : Ignorelists) {
    154     if (!(Kinds & BL.Mask))
    155       continue;
    156 
    157     clang::SmallString<64> Path(D.ResourceDir);
    158     llvm::sys::path::append(Path, "share", BL.File);
    159     if (D.getVFS().exists(Path))
    160       IgnorelistFiles.push_back(std::string(Path.str()));
    161     else if (BL.Mask == SanitizerKind::CFI)
    162       // If cfi_ignorelist.txt cannot be found in the resource dir, driver
    163       // should fail.
    164       D.Diag(clang::diag::err_drv_no_such_file) << Path;
    165   }
    166   validateSpecialCaseListFormat(
    167       D, IgnorelistFiles, clang::diag::err_drv_malformed_sanitizer_ignorelist);
    168 }
    169 
    170 /// Parse -f(no-)?sanitize-(coverage-)?(white|ignore)list argument's values,
    171 /// diagnosing any invalid file paths and validating special case list format.
    172 static void parseSpecialCaseListArg(const Driver &D,
    173                                     const llvm::opt::ArgList &Args,
    174                                     std::vector<std::string> &SCLFiles,
    175                                     llvm::opt::OptSpecifier SCLOptionID,
    176                                     llvm::opt::OptSpecifier NoSCLOptionID,
    177                                     unsigned MalformedSCLErrorDiagID) {
    178   for (const auto *Arg : Args) {
    179     // Match -fsanitize-(coverage-)?(white|ignore)list.
    180     if (Arg->getOption().matches(SCLOptionID)) {
    181       Arg->claim();
    182       std::string SCLPath = Arg->getValue();
    183       if (D.getVFS().exists(SCLPath)) {
    184         SCLFiles.push_back(SCLPath);
    185       } else {
    186         D.Diag(clang::diag::err_drv_no_such_file) << SCLPath;
    187       }
    188       // Match -fno-sanitize-ignorelist.
    189     } else if (Arg->getOption().matches(NoSCLOptionID)) {
    190       Arg->claim();
    191       SCLFiles.clear();
    192     }
    193   }
    194   validateSpecialCaseListFormat(D, SCLFiles, MalformedSCLErrorDiagID);
    195 }
    196 
    197 /// Sets group bits for every group that has at least one representative already
    198 /// enabled in \p Kinds.
    199 static SanitizerMask setGroupBits(SanitizerMask Kinds) {
    200 #define SANITIZER(NAME, ID)
    201 #define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
    202   if (Kinds & SanitizerKind::ID)                                               \
    203     Kinds |= SanitizerKind::ID##Group;
    204 #include "clang/Basic/Sanitizers.def"
    205   return Kinds;
    206 }
    207 
    208 static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
    209                                            const llvm::opt::ArgList &Args) {
    210   SanitizerMask TrapRemove;     // During the loop below, the accumulated set of
    211                                 // sanitizers disabled by the current sanitizer
    212                                 // argument or any argument after it.
    213   SanitizerMask TrappingKinds;
    214   SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
    215 
    216   for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
    217        I != E; ++I) {
    218     const auto *Arg = *I;
    219     if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
    220       Arg->claim();
    221       SanitizerMask Add = parseArgValues(D, Arg, true);
    222       Add &= ~TrapRemove;
    223       if (SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
    224         SanitizerSet S;
    225         S.Mask = InvalidValues;
    226         D.Diag(diag::err_drv_unsupported_option_argument) << "-fsanitize-trap"
    227                                                           << toString(S);
    228       }
    229       TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove;
    230     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
    231       Arg->claim();
    232       TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true));
    233     }
    234   }
    235 
    236   // Apply default trapping behavior.
    237   TrappingKinds |= TrappingDefault & ~TrapRemove;
    238 
    239   return TrappingKinds;
    240 }
    241 
    242 bool SanitizerArgs::needsFuzzerInterceptors() const {
    243   return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt();
    244 }
    245 
    246 bool SanitizerArgs::needsUbsanRt() const {
    247   // All of these include ubsan.
    248   if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
    249       needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
    250       (needsScudoRt() && !requiresMinimalRuntime()))
    251     return false;
    252 
    253   return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
    254          CoverageFeatures;
    255 }
    256 
    257 bool SanitizerArgs::needsCfiRt() const {
    258   return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
    259          CfiCrossDso && !ImplicitCfiRuntime;
    260 }
    261 
    262 bool SanitizerArgs::needsCfiDiagRt() const {
    263   return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
    264          CfiCrossDso && !ImplicitCfiRuntime;
    265 }
    266 
    267 bool SanitizerArgs::requiresPIE() const {
    268   return NeedPIE || (Sanitizers.Mask & RequiresPIE);
    269 }
    270 
    271 bool SanitizerArgs::needsUnwindTables() const {
    272   return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
    273 }
    274 
    275 bool SanitizerArgs::needsLTO() const {
    276   return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
    277 }
    278 
    279 SanitizerArgs::SanitizerArgs(const ToolChain &TC,
    280                              const llvm::opt::ArgList &Args) {
    281   SanitizerMask AllRemove;      // During the loop below, the accumulated set of
    282                                 // sanitizers disabled by the current sanitizer
    283                                 // argument or any argument after it.
    284   SanitizerMask AllAddedKinds;      // Mask of all sanitizers ever enabled by
    285                                     // -fsanitize= flags (directly or via group
    286                                     // expansion), some of which may be disabled
    287                                     // later. Used to carefully prune
    288                                     // unused-argument diagnostics.
    289   SanitizerMask DiagnosedKinds;      // All Kinds we have diagnosed up to now.
    290                                      // Used to deduplicate diagnostics.
    291   SanitizerMask Kinds;
    292   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
    293 
    294   CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
    295                              options::OPT_fno_sanitize_cfi_cross_dso, false);
    296 
    297   ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
    298 
    299   const Driver &D = TC.getDriver();
    300   SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
    301   SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
    302 
    303   MinimalRuntime =
    304       Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
    305                    options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
    306 
    307   // The object size sanitizer should not be enabled at -O0.
    308   Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
    309   bool RemoveObjectSizeAtO0 =
    310       !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
    311 
    312   for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
    313        I != E; ++I) {
    314     const auto *Arg = *I;
    315     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
    316       Arg->claim();
    317       SanitizerMask Add = parseArgValues(D, Arg, /*AllowGroups=*/true);
    318 
    319       if (RemoveObjectSizeAtO0) {
    320         AllRemove |= SanitizerKind::ObjectSize;
    321 
    322         // The user explicitly enabled the object size sanitizer. Warn
    323         // that this does nothing at -O0.
    324         if (Add & SanitizerKind::ObjectSize)
    325           D.Diag(diag::warn_drv_object_size_disabled_O0)
    326               << Arg->getAsString(Args);
    327       }
    328 
    329       AllAddedKinds |= expandSanitizerGroups(Add);
    330 
    331       // Avoid diagnosing any sanitizer which is disabled later.
    332       Add &= ~AllRemove;
    333       // At this point we have not expanded groups, so any unsupported
    334       // sanitizers in Add are those which have been explicitly enabled.
    335       // Diagnose them.
    336       if (SanitizerMask KindsToDiagnose =
    337               Add & InvalidTrappingKinds & ~DiagnosedKinds) {
    338         std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
    339         D.Diag(diag::err_drv_argument_not_allowed_with)
    340             << Desc << "-fsanitize-trap=undefined";
    341         DiagnosedKinds |= KindsToDiagnose;
    342       }
    343       Add &= ~InvalidTrappingKinds;
    344 
    345       if (MinimalRuntime) {
    346         if (SanitizerMask KindsToDiagnose =
    347                 Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
    348           std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
    349           D.Diag(diag::err_drv_argument_not_allowed_with)
    350               << Desc << "-fsanitize-minimal-runtime";
    351           DiagnosedKinds |= KindsToDiagnose;
    352         }
    353         Add &= ~NotAllowedWithMinimalRuntime;
    354       }
    355 
    356       // FIXME: Make CFI on member function calls compatible with cross-DSO CFI.
    357       // There are currently two problems:
    358       // - Virtual function call checks need to pass a pointer to the function
    359       //   address to llvm.type.test and a pointer to the address point to the
    360       //   diagnostic function. Currently we pass the same pointer to both
    361       //   places.
    362       // - Non-virtual function call checks may need to check multiple type
    363       //   identifiers.
    364       // Fixing both of those may require changes to the cross-DSO CFI
    365       // interface.
    366       if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
    367         D.Diag(diag::err_drv_argument_not_allowed_with)
    368             << "-fsanitize=cfi-mfcall"
    369             << "-fsanitize-cfi-cross-dso";
    370         Add &= ~SanitizerKind::CFIMFCall;
    371         DiagnosedKinds |= SanitizerKind::CFIMFCall;
    372       }
    373 
    374       if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
    375         std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
    376         D.Diag(diag::err_drv_unsupported_opt_for_target)
    377             << Desc << TC.getTriple().str();
    378         DiagnosedKinds |= KindsToDiagnose;
    379       }
    380       Add &= Supported;
    381 
    382       // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
    383       // so we don't error out if -fno-rtti and -fsanitize=undefined were
    384       // passed.
    385       if ((Add & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
    386         if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) {
    387           assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
    388                   "RTTI disabled without -fno-rtti option?");
    389           // The user explicitly passed -fno-rtti with -fsanitize=vptr, but
    390           // the vptr sanitizer requires RTTI, so this is a user error.
    391           D.Diag(diag::err_drv_argument_not_allowed_with)
    392               << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
    393         } else {
    394           // The vptr sanitizer requires RTTI, but RTTI is disabled (by
    395           // default). Warn that the vptr sanitizer is being disabled.
    396           D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
    397         }
    398 
    399         // Take out the Vptr sanitizer from the enabled sanitizers
    400         AllRemove |= SanitizerKind::Vptr;
    401       }
    402 
    403       Add = expandSanitizerGroups(Add);
    404       // Group expansion may have enabled a sanitizer which is disabled later.
    405       Add &= ~AllRemove;
    406       // Silently discard any unsupported sanitizers implicitly enabled through
    407       // group expansion.
    408       Add &= ~InvalidTrappingKinds;
    409       if (MinimalRuntime) {
    410         Add &= ~NotAllowedWithMinimalRuntime;
    411       }
    412       if (CfiCrossDso)
    413         Add &= ~SanitizerKind::CFIMFCall;
    414       Add &= Supported;
    415 
    416       if (Add & SanitizerKind::Fuzzer)
    417         Add |= SanitizerKind::FuzzerNoLink;
    418 
    419       // Enable coverage if the fuzzing flag is set.
    420       if (Add & SanitizerKind::FuzzerNoLink) {
    421         CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall |
    422                             CoverageTraceCmp | CoveragePCTable;
    423         // Due to TLS differences, stack depth tracking is only enabled on Linux
    424         if (TC.getTriple().isOSLinux())
    425           CoverageFeatures |= CoverageStackDepth;
    426       }
    427 
    428       Kinds |= Add;
    429     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
    430       Arg->claim();
    431       SanitizerMask Remove = parseArgValues(D, Arg, true);
    432       AllRemove |= expandSanitizerGroups(Remove);
    433     }
    434   }
    435 
    436   std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
    437       std::make_pair(SanitizerKind::Address,
    438                      SanitizerKind::Thread | SanitizerKind::Memory),
    439       std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
    440       std::make_pair(SanitizerKind::Leak,
    441                      SanitizerKind::Thread | SanitizerKind::Memory),
    442       std::make_pair(SanitizerKind::KernelAddress,
    443                      SanitizerKind::Address | SanitizerKind::Leak |
    444                          SanitizerKind::Thread | SanitizerKind::Memory),
    445       std::make_pair(SanitizerKind::HWAddress,
    446                      SanitizerKind::Address | SanitizerKind::Thread |
    447                          SanitizerKind::Memory | SanitizerKind::KernelAddress),
    448       std::make_pair(SanitizerKind::Scudo,
    449                      SanitizerKind::Address | SanitizerKind::HWAddress |
    450                          SanitizerKind::Leak | SanitizerKind::Thread |
    451                          SanitizerKind::Memory | SanitizerKind::KernelAddress),
    452       std::make_pair(SanitizerKind::SafeStack,
    453                      (TC.getTriple().isOSFuchsia() ? SanitizerMask()
    454                                                    : SanitizerKind::Leak) |
    455                          SanitizerKind::Address | SanitizerKind::HWAddress |
    456                          SanitizerKind::Thread | SanitizerKind::Memory |
    457                          SanitizerKind::KernelAddress),
    458       std::make_pair(SanitizerKind::KernelHWAddress,
    459                      SanitizerKind::Address | SanitizerKind::HWAddress |
    460                          SanitizerKind::Leak | SanitizerKind::Thread |
    461                          SanitizerKind::Memory | SanitizerKind::KernelAddress |
    462                          SanitizerKind::SafeStack),
    463       std::make_pair(SanitizerKind::KernelMemory,
    464                      SanitizerKind::Address | SanitizerKind::HWAddress |
    465                          SanitizerKind::Leak | SanitizerKind::Thread |
    466                          SanitizerKind::Memory | SanitizerKind::KernelAddress |
    467                          SanitizerKind::Scudo | SanitizerKind::SafeStack),
    468       std::make_pair(SanitizerKind::MemTag,
    469                      SanitizerKind::Address | SanitizerKind::KernelAddress |
    470                          SanitizerKind::HWAddress |
    471                          SanitizerKind::KernelHWAddress)};
    472   // Enable toolchain specific default sanitizers if not explicitly disabled.
    473   SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
    474 
    475   // Disable default sanitizers that are incompatible with explicitly requested
    476   // ones.
    477   for (auto G : IncompatibleGroups) {
    478     SanitizerMask Group = G.first;
    479     if ((Default & Group) && (Kinds & G.second))
    480       Default &= ~Group;
    481   }
    482 
    483   Kinds |= Default;
    484 
    485   // We disable the vptr sanitizer if it was enabled by group expansion but RTTI
    486   // is disabled.
    487   if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
    488     Kinds &= ~SanitizerKind::Vptr;
    489   }
    490 
    491   // Check that LTO is enabled if we need it.
    492   if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {
    493     D.Diag(diag::err_drv_argument_only_allowed_with)
    494         << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
    495   }
    496 
    497   if ((Kinds & SanitizerKind::ShadowCallStack) &&
    498       ((TC.getTriple().isAArch64() &&
    499         !llvm::AArch64::isX18ReservedByDefault(TC.getTriple())) ||
    500        TC.getTriple().isRISCV()) &&
    501       !Args.hasArg(options::OPT_ffixed_x18)) {
    502     D.Diag(diag::err_drv_argument_only_allowed_with)
    503         << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack)
    504         << "-ffixed-x18";
    505   }
    506 
    507   // Report error if there are non-trapping sanitizers that require
    508   // c++abi-specific  parts of UBSan runtime, and they are not provided by the
    509   // toolchain. We don't have a good way to check the latter, so we just
    510   // check if the toolchan supports vptr.
    511   if (~Supported & SanitizerKind::Vptr) {
    512     SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
    513     // The runtime library supports the Microsoft C++ ABI, but only well enough
    514     // for CFI. FIXME: Remove this once we support vptr on Windows.
    515     if (TC.getTriple().isOSWindows())
    516       KindsToDiagnose &= ~SanitizerKind::CFI;
    517     if (KindsToDiagnose) {
    518       SanitizerSet S;
    519       S.Mask = KindsToDiagnose;
    520       D.Diag(diag::err_drv_unsupported_opt_for_target)
    521           << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str();
    522       Kinds &= ~KindsToDiagnose;
    523     }
    524   }
    525 
    526   // Warn about incompatible groups of sanitizers.
    527   for (auto G : IncompatibleGroups) {
    528     SanitizerMask Group = G.first;
    529     if (Kinds & Group) {
    530       if (SanitizerMask Incompatible = Kinds & G.second) {
    531         D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    532             << lastArgumentForMask(D, Args, Group)
    533             << lastArgumentForMask(D, Args, Incompatible);
    534         Kinds &= ~Incompatible;
    535       }
    536     }
    537   }
    538   // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
    539   // -fsanitize=address. Perhaps it should print an error, or perhaps
    540   // -f(-no)sanitize=leak should change whether leak detection is enabled by
    541   // default in ASan?
    542 
    543   // Parse -f(no-)?sanitize-recover flags.
    544   SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable;
    545   SanitizerMask DiagnosedUnrecoverableKinds;
    546   SanitizerMask DiagnosedAlwaysRecoverableKinds;
    547   for (const auto *Arg : Args) {
    548     if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
    549       SanitizerMask Add = parseArgValues(D, Arg, true);
    550       // Report error if user explicitly tries to recover from unrecoverable
    551       // sanitizer.
    552       if (SanitizerMask KindsToDiagnose =
    553               Add & Unrecoverable & ~DiagnosedUnrecoverableKinds) {
    554         SanitizerSet SetToDiagnose;
    555         SetToDiagnose.Mask |= KindsToDiagnose;
    556         D.Diag(diag::err_drv_unsupported_option_argument)
    557             << Arg->getOption().getName() << toString(SetToDiagnose);
    558         DiagnosedUnrecoverableKinds |= KindsToDiagnose;
    559       }
    560       RecoverableKinds |= expandSanitizerGroups(Add);
    561       Arg->claim();
    562     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
    563       SanitizerMask Remove = parseArgValues(D, Arg, true);
    564       // Report error if user explicitly tries to disable recovery from
    565       // always recoverable sanitizer.
    566       if (SanitizerMask KindsToDiagnose =
    567               Remove & AlwaysRecoverable & ~DiagnosedAlwaysRecoverableKinds) {
    568         SanitizerSet SetToDiagnose;
    569         SetToDiagnose.Mask |= KindsToDiagnose;
    570         D.Diag(diag::err_drv_unsupported_option_argument)
    571             << Arg->getOption().getName() << toString(SetToDiagnose);
    572         DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose;
    573       }
    574       RecoverableKinds &= ~expandSanitizerGroups(Remove);
    575       Arg->claim();
    576     }
    577   }
    578   RecoverableKinds &= Kinds;
    579   RecoverableKinds &= ~Unrecoverable;
    580 
    581   TrappingKinds &= Kinds;
    582   RecoverableKinds &= ~TrappingKinds;
    583 
    584   // Setup ignorelist files.
    585   // Add default ignorelist from resource directory for activated sanitizers,
    586   // and validate special case lists format.
    587   if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_ignorelist))
    588     addDefaultIgnorelists(D, Kinds, SystemIgnorelistFiles);
    589 
    590   // Parse -f(no-)?sanitize-ignorelist options.
    591   // This also validates special case lists format.
    592   parseSpecialCaseListArg(D, Args, UserIgnorelistFiles,
    593                           options::OPT_fsanitize_ignorelist_EQ,
    594                           options::OPT_fno_sanitize_ignorelist,
    595                           clang::diag::err_drv_malformed_sanitizer_ignorelist);
    596 
    597   // Parse -f[no-]sanitize-memory-track-origins[=level] options.
    598   if (AllAddedKinds & SanitizerKind::Memory) {
    599     if (Arg *A =
    600             Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
    601                             options::OPT_fsanitize_memory_track_origins,
    602                             options::OPT_fno_sanitize_memory_track_origins)) {
    603       if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
    604         MsanTrackOrigins = 2;
    605       } else if (A->getOption().matches(
    606                      options::OPT_fno_sanitize_memory_track_origins)) {
    607         MsanTrackOrigins = 0;
    608       } else {
    609         StringRef S = A->getValue();
    610         if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
    611             MsanTrackOrigins > 2) {
    612           D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
    613         }
    614       }
    615     }
    616     MsanUseAfterDtor =
    617         Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor,
    618                      options::OPT_fno_sanitize_memory_use_after_dtor,
    619                      MsanUseAfterDtor);
    620     NeedPIE |= !(TC.getTriple().isOSLinux() &&
    621                  TC.getTriple().getArch() == llvm::Triple::x86_64);
    622   } else {
    623     MsanUseAfterDtor = false;
    624   }
    625 
    626   if (AllAddedKinds & SanitizerKind::Thread) {
    627     TsanMemoryAccess = Args.hasFlag(
    628         options::OPT_fsanitize_thread_memory_access,
    629         options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
    630     TsanFuncEntryExit = Args.hasFlag(
    631         options::OPT_fsanitize_thread_func_entry_exit,
    632         options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
    633     TsanAtomics =
    634         Args.hasFlag(options::OPT_fsanitize_thread_atomics,
    635                      options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
    636   }
    637 
    638   if (AllAddedKinds & SanitizerKind::CFI) {
    639     // Without PIE, external function address may resolve to a PLT record, which
    640     // can not be verified by the target module.
    641     NeedPIE |= CfiCrossDso;
    642     CfiICallGeneralizePointers =
    643         Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
    644 
    645     if (CfiCrossDso && CfiICallGeneralizePointers)
    646       D.Diag(diag::err_drv_argument_not_allowed_with)
    647           << "-fsanitize-cfi-cross-dso"
    648           << "-fsanitize-cfi-icall-generalize-pointers";
    649 
    650     CfiCanonicalJumpTables =
    651         Args.hasFlag(options::OPT_fsanitize_cfi_canonical_jump_tables,
    652                      options::OPT_fno_sanitize_cfi_canonical_jump_tables, true);
    653   }
    654 
    655   Stats = Args.hasFlag(options::OPT_fsanitize_stats,
    656                        options::OPT_fno_sanitize_stats, false);
    657 
    658   if (MinimalRuntime) {
    659     SanitizerMask IncompatibleMask =
    660         Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
    661     if (IncompatibleMask)
    662       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    663           << "-fsanitize-minimal-runtime"
    664           << lastArgumentForMask(D, Args, IncompatibleMask);
    665 
    666     SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
    667     if (NonTrappingCfi)
    668       D.Diag(clang::diag::err_drv_argument_only_allowed_with)
    669           << "fsanitize-minimal-runtime"
    670           << "fsanitize-trap=cfi";
    671   }
    672 
    673   // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
    674   // enabled sanitizers.
    675   for (const auto *Arg : Args) {
    676     if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
    677       int LegacySanitizeCoverage;
    678       if (Arg->getNumValues() == 1 &&
    679           !StringRef(Arg->getValue(0))
    680                .getAsInteger(0, LegacySanitizeCoverage)) {
    681         CoverageFeatures = 0;
    682         Arg->claim();
    683         if (LegacySanitizeCoverage != 0) {
    684           D.Diag(diag::warn_drv_deprecated_arg)
    685               << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard";
    686         }
    687         continue;
    688       }
    689       CoverageFeatures |= parseCoverageFeatures(D, Arg);
    690 
    691       // Disable coverage and not claim the flags if there is at least one
    692       // non-supporting sanitizer.
    693       if (!(AllAddedKinds & ~AllRemove & ~setGroupBits(SupportsCoverage))) {
    694         Arg->claim();
    695       } else {
    696         CoverageFeatures = 0;
    697       }
    698     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
    699       Arg->claim();
    700       CoverageFeatures &= ~parseCoverageFeatures(D, Arg);
    701     }
    702   }
    703   // Choose at most one coverage type: function, bb, or edge.
    704   if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageBB))
    705     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    706         << "-fsanitize-coverage=func"
    707         << "-fsanitize-coverage=bb";
    708   if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageEdge))
    709     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    710         << "-fsanitize-coverage=func"
    711         << "-fsanitize-coverage=edge";
    712   if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
    713     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    714         << "-fsanitize-coverage=bb"
    715         << "-fsanitize-coverage=edge";
    716   // Basic block tracing and 8-bit counters require some type of coverage
    717   // enabled.
    718   if (CoverageFeatures & CoverageTraceBB)
    719     D.Diag(clang::diag::warn_drv_deprecated_arg)
    720         << "-fsanitize-coverage=trace-bb"
    721         << "-fsanitize-coverage=trace-pc-guard";
    722   if (CoverageFeatures & Coverage8bitCounters)
    723     D.Diag(clang::diag::warn_drv_deprecated_arg)
    724         << "-fsanitize-coverage=8bit-counters"
    725         << "-fsanitize-coverage=trace-pc-guard";
    726 
    727   int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
    728   int InstrumentationTypes = CoverageTracePC | CoverageTracePCGuard |
    729                              CoverageInline8bitCounters |
    730                              CoverageInlineBoolFlag;
    731   if ((CoverageFeatures & InsertionPointTypes) &&
    732       !(CoverageFeatures & InstrumentationTypes)) {
    733     D.Diag(clang::diag::warn_drv_deprecated_arg)
    734         << "-fsanitize-coverage=[func|bb|edge]"
    735         << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
    736   }
    737 
    738   // trace-pc w/o func/bb/edge implies edge.
    739   if (!(CoverageFeatures & InsertionPointTypes)) {
    740     if (CoverageFeatures &
    741         (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters |
    742          CoverageInlineBoolFlag))
    743       CoverageFeatures |= CoverageEdge;
    744 
    745     if (CoverageFeatures & CoverageStackDepth)
    746       CoverageFeatures |= CoverageFunc;
    747   }
    748 
    749   // Parse -fsanitize-coverage-(ignore|white)list options if coverage enabled.
    750   // This also validates special case lists format.
    751   // Here, OptSpecifier() acts as a never-matching command-line argument.
    752   // So, there is no way to clear coverage lists but you can append to them.
    753   if (CoverageFeatures) {
    754     parseSpecialCaseListArg(
    755         D, Args, CoverageAllowlistFiles,
    756         options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
    757         clang::diag::err_drv_malformed_sanitizer_coverage_whitelist);
    758     parseSpecialCaseListArg(
    759         D, Args, CoverageIgnorelistFiles,
    760         options::OPT_fsanitize_coverage_ignorelist, OptSpecifier(),
    761         clang::diag::err_drv_malformed_sanitizer_coverage_ignorelist);
    762   }
    763 
    764   SharedRuntime =
    765       Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
    766                    TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
    767                        TC.getTriple().isOSDarwin());
    768 
    769   ImplicitCfiRuntime = TC.getTriple().isAndroid();
    770 
    771   if (AllAddedKinds & SanitizerKind::Address) {
    772     NeedPIE |= TC.getTriple().isOSFuchsia();
    773     if (Arg *A =
    774             Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
    775         StringRef S = A->getValue();
    776         // Legal values are 0 and 1, 2, but in future we may add more levels.
    777         if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
    778             AsanFieldPadding > 2) {
    779           D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
    780         }
    781     }
    782 
    783     if (Arg *WindowsDebugRTArg =
    784             Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
    785                             options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
    786                             options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
    787       switch (WindowsDebugRTArg->getOption().getID()) {
    788       case options::OPT__SLASH_MTd:
    789       case options::OPT__SLASH_MDd:
    790       case options::OPT__SLASH_LDd:
    791         D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    792             << WindowsDebugRTArg->getAsString(Args)
    793             << lastArgumentForMask(D, Args, SanitizerKind::Address);
    794         D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
    795       }
    796     }
    797 
    798     AsanUseAfterScope = Args.hasFlag(
    799         options::OPT_fsanitize_address_use_after_scope,
    800         options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
    801 
    802     AsanPoisonCustomArrayCookie = Args.hasFlag(
    803         options::OPT_fsanitize_address_poison_custom_array_cookie,
    804         options::OPT_fno_sanitize_address_poison_custom_array_cookie,
    805         AsanPoisonCustomArrayCookie);
    806 
    807     // As a workaround for a bug in gold 2.26 and earlier, dead stripping of
    808     // globals in ASan is disabled by default on ELF targets.
    809     // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
    810     AsanGlobalsDeadStripping =
    811         !TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSFuchsia() ||
    812         TC.getTriple().isPS4() ||
    813         Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
    814 
    815     AsanUseOdrIndicator =
    816         Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
    817                      options::OPT_fno_sanitize_address_use_odr_indicator,
    818                      AsanUseOdrIndicator);
    819 
    820     if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
    821       AsanInvalidPointerCmp = true;
    822     }
    823 
    824     if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
    825       AsanInvalidPointerSub = true;
    826     }
    827 
    828     if (TC.getTriple().isOSDarwin() &&
    829         (Args.hasArg(options::OPT_mkernel) ||
    830          Args.hasArg(options::OPT_fapple_kext))) {
    831       AsanDtorKind = llvm::AsanDtorKind::None;
    832     }
    833 
    834     if (const auto *Arg =
    835             Args.getLastArg(options::OPT_sanitize_address_destructor_EQ)) {
    836       auto parsedAsanDtorKind = AsanDtorKindFromString(Arg->getValue());
    837       if (parsedAsanDtorKind == llvm::AsanDtorKind::Invalid) {
    838         TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
    839             << Arg->getOption().getName() << Arg->getValue();
    840       }
    841       AsanDtorKind = parsedAsanDtorKind;
    842     }
    843 
    844   } else {
    845     AsanUseAfterScope = false;
    846     // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
    847     SanitizerMask DetectInvalidPointerPairs =
    848         SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
    849     if (AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) {
    850       TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
    851           << lastArgumentForMask(D, Args,
    852                                  SanitizerKind::PointerCompare |
    853                                      SanitizerKind::PointerSubtract)
    854           << "-fsanitize=address";
    855     }
    856   }
    857 
    858   if (AllAddedKinds & SanitizerKind::HWAddress) {
    859     if (Arg *HwasanAbiArg =
    860             Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
    861       HwasanAbi = HwasanAbiArg->getValue();
    862       if (HwasanAbi != "platform" && HwasanAbi != "interceptor")
    863         D.Diag(clang::diag::err_drv_invalid_value)
    864             << HwasanAbiArg->getAsString(Args) << HwasanAbi;
    865     } else {
    866       HwasanAbi = "interceptor";
    867     }
    868     if (TC.getTriple().getArch() == llvm::Triple::x86_64)
    869       HwasanUseAliases = Args.hasFlag(
    870           options::OPT_fsanitize_hwaddress_experimental_aliasing,
    871           options::OPT_fno_sanitize_hwaddress_experimental_aliasing,
    872           HwasanUseAliases);
    873   }
    874 
    875   if (AllAddedKinds & SanitizerKind::SafeStack) {
    876     // SafeStack runtime is built into the system on Android and Fuchsia.
    877     SafeStackRuntime =
    878         !TC.getTriple().isAndroid() && !TC.getTriple().isOSFuchsia();
    879   }
    880 
    881   LinkRuntimes =
    882       Args.hasFlag(options::OPT_fsanitize_link_runtime,
    883                    options::OPT_fno_sanitize_link_runtime, LinkRuntimes);
    884 
    885   // Parse -link-cxx-sanitizer flag.
    886   LinkCXXRuntimes = Args.hasArg(options::OPT_fsanitize_link_cxx_runtime,
    887                                 options::OPT_fno_sanitize_link_cxx_runtime,
    888                                 LinkCXXRuntimes) ||
    889                     D.CCCIsCXX();
    890 
    891   NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile,
    892                                 options::OPT_fmemory_profile_EQ,
    893                                 options::OPT_fno_memory_profile, false);
    894 
    895   // Finally, initialize the set of available and recoverable sanitizers.
    896   Sanitizers.Mask |= Kinds;
    897   RecoverableSanitizers.Mask |= RecoverableKinds;
    898   TrapSanitizers.Mask |= TrappingKinds;
    899   assert(!(RecoverableKinds & TrappingKinds) &&
    900          "Overlap between recoverable and trapping sanitizers");
    901 }
    902 
    903 static std::string toString(const clang::SanitizerSet &Sanitizers) {
    904   std::string Res;
    905 #define SANITIZER(NAME, ID)                                                    \
    906   if (Sanitizers.has(SanitizerKind::ID)) {                                     \
    907     if (!Res.empty())                                                          \
    908       Res += ",";                                                              \
    909     Res += NAME;                                                               \
    910   }
    911 #include "clang/Basic/Sanitizers.def"
    912   return Res;
    913 }
    914 
    915 static void addSpecialCaseListOpt(const llvm::opt::ArgList &Args,
    916                                   llvm::opt::ArgStringList &CmdArgs,
    917                                   const char *SCLOptFlag,
    918                                   const std::vector<std::string> &SCLFiles) {
    919   for (const auto &SCLPath : SCLFiles) {
    920     SmallString<64> SCLOpt(SCLOptFlag);
    921     SCLOpt += SCLPath;
    922     CmdArgs.push_back(Args.MakeArgString(SCLOpt));
    923   }
    924 }
    925 
    926 static void addIncludeLinkerOption(const ToolChain &TC,
    927                                    const llvm::opt::ArgList &Args,
    928                                    llvm::opt::ArgStringList &CmdArgs,
    929                                    StringRef SymbolName) {
    930   SmallString<64> LinkerOptionFlag;
    931   LinkerOptionFlag = "--linker-option=/include:";
    932   if (TC.getTriple().getArch() == llvm::Triple::x86) {
    933     // Win32 mangles C function names with a '_' prefix.
    934     LinkerOptionFlag += '_';
    935   }
    936   LinkerOptionFlag += SymbolName;
    937   CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
    938 }
    939 
    940 static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs) {
    941   for (auto Start = CmdArgs.begin(), End = CmdArgs.end(); Start != End; ++Start) {
    942     auto It = std::find(Start, End, StringRef("+mte"));
    943     if (It == End)
    944       break;
    945     if (It > Start && *std::prev(It) == StringRef("-target-feature"))
    946       return true;
    947     Start = It;
    948   }
    949   return false;
    950 }
    951 
    952 void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
    953                             llvm::opt::ArgStringList &CmdArgs,
    954                             types::ID InputType) const {
    955   // NVPTX doesn't currently support sanitizers.  Bailing out here means
    956   // that e.g. -fsanitize=address applies only to host code, which is what we
    957   // want for now.
    958   //
    959   // AMDGPU sanitizer support is experimental and controlled by -fgpu-sanitize.
    960   if (TC.getTriple().isNVPTX() ||
    961       (TC.getTriple().isAMDGPU() &&
    962        !Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
    963                      false)))
    964     return;
    965 
    966   // Translate available CoverageFeatures to corresponding clang-cc1 flags.
    967   // Do it even if Sanitizers.empty() since some forms of coverage don't require
    968   // sanitizers.
    969   std::pair<int, const char *> CoverageFlags[] = {
    970       std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
    971       std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
    972       std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
    973       std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
    974       std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
    975       std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
    976       std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
    977       std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
    978       std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
    979       std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
    980       std::make_pair(CoverageTracePCGuard,
    981                      "-fsanitize-coverage-trace-pc-guard"),
    982       std::make_pair(CoverageInline8bitCounters,
    983                      "-fsanitize-coverage-inline-8bit-counters"),
    984       std::make_pair(CoverageInlineBoolFlag,
    985                      "-fsanitize-coverage-inline-bool-flag"),
    986       std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
    987       std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
    988       std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")};
    989   for (auto F : CoverageFlags) {
    990     if (CoverageFeatures & F.first)
    991       CmdArgs.push_back(F.second);
    992   }
    993   addSpecialCaseListOpt(
    994       Args, CmdArgs, "-fsanitize-coverage-allowlist=", CoverageAllowlistFiles);
    995   addSpecialCaseListOpt(Args, CmdArgs, "-fsanitize-coverage-ignorelist=",
    996                         CoverageIgnorelistFiles);
    997 
    998   if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
    999     // Instruct the code generator to embed linker directives in the object file
   1000     // that cause the required runtime libraries to be linked.
   1001     CmdArgs.push_back(
   1002         Args.MakeArgString("--dependent-lib=" +
   1003                            TC.getCompilerRTBasename(Args, "ubsan_standalone")));
   1004     if (types::isCXX(InputType))
   1005       CmdArgs.push_back(Args.MakeArgString(
   1006           "--dependent-lib=" +
   1007           TC.getCompilerRTBasename(Args, "ubsan_standalone_cxx")));
   1008   }
   1009   if (TC.getTriple().isOSWindows() && needsStatsRt()) {
   1010     CmdArgs.push_back(Args.MakeArgString(
   1011         "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats_client")));
   1012 
   1013     // The main executable must export the stats runtime.
   1014     // FIXME: Only exporting from the main executable (e.g. based on whether the
   1015     // translation unit defines main()) would save a little space, but having
   1016     // multiple copies of the runtime shouldn't hurt.
   1017     CmdArgs.push_back(Args.MakeArgString(
   1018         "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats")));
   1019     addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
   1020   }
   1021 
   1022   if (Sanitizers.empty())
   1023     return;
   1024   CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
   1025 
   1026   if (!RecoverableSanitizers.empty())
   1027     CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
   1028                                          toString(RecoverableSanitizers)));
   1029 
   1030   if (!TrapSanitizers.empty())
   1031     CmdArgs.push_back(
   1032         Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
   1033 
   1034   addSpecialCaseListOpt(Args, CmdArgs,
   1035                         "-fsanitize-ignorelist=", UserIgnorelistFiles);
   1036   addSpecialCaseListOpt(Args, CmdArgs,
   1037                         "-fsanitize-system-ignorelist=", SystemIgnorelistFiles);
   1038 
   1039   if (MsanTrackOrigins)
   1040     CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
   1041                                          Twine(MsanTrackOrigins)));
   1042 
   1043   if (MsanUseAfterDtor)
   1044     CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
   1045 
   1046   // FIXME: Pass these parameters as function attributes, not as -llvm flags.
   1047   if (!TsanMemoryAccess) {
   1048     CmdArgs.push_back("-mllvm");
   1049     CmdArgs.push_back("-tsan-instrument-memory-accesses=0");
   1050     CmdArgs.push_back("-mllvm");
   1051     CmdArgs.push_back("-tsan-instrument-memintrinsics=0");
   1052   }
   1053   if (!TsanFuncEntryExit) {
   1054     CmdArgs.push_back("-mllvm");
   1055     CmdArgs.push_back("-tsan-instrument-func-entry-exit=0");
   1056   }
   1057   if (!TsanAtomics) {
   1058     CmdArgs.push_back("-mllvm");
   1059     CmdArgs.push_back("-tsan-instrument-atomics=0");
   1060   }
   1061 
   1062   if (CfiCrossDso)
   1063     CmdArgs.push_back("-fsanitize-cfi-cross-dso");
   1064 
   1065   if (CfiICallGeneralizePointers)
   1066     CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers");
   1067 
   1068   if (CfiCanonicalJumpTables)
   1069     CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables");
   1070 
   1071   if (Stats)
   1072     CmdArgs.push_back("-fsanitize-stats");
   1073 
   1074   if (MinimalRuntime)
   1075     CmdArgs.push_back("-fsanitize-minimal-runtime");
   1076 
   1077   if (AsanFieldPadding)
   1078     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
   1079                                          Twine(AsanFieldPadding)));
   1080 
   1081   if (AsanUseAfterScope)
   1082     CmdArgs.push_back("-fsanitize-address-use-after-scope");
   1083 
   1084   if (AsanPoisonCustomArrayCookie)
   1085     CmdArgs.push_back("-fsanitize-address-poison-custom-array-cookie");
   1086 
   1087   if (AsanGlobalsDeadStripping)
   1088     CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
   1089 
   1090   if (AsanUseOdrIndicator)
   1091     CmdArgs.push_back("-fsanitize-address-use-odr-indicator");
   1092 
   1093   if (AsanInvalidPointerCmp) {
   1094     CmdArgs.push_back("-mllvm");
   1095     CmdArgs.push_back("-asan-detect-invalid-pointer-cmp");
   1096   }
   1097 
   1098   if (AsanInvalidPointerSub) {
   1099     CmdArgs.push_back("-mllvm");
   1100     CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
   1101   }
   1102 
   1103   // Only pass the option to the frontend if the user requested,
   1104   // otherwise the frontend will just use the codegen default.
   1105   if (AsanDtorKind != llvm::AsanDtorKind::Invalid) {
   1106     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-destructor=" +
   1107                                          AsanDtorKindToString(AsanDtorKind)));
   1108   }
   1109 
   1110   if (!HwasanAbi.empty()) {
   1111     CmdArgs.push_back("-default-function-attr");
   1112     CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
   1113   }
   1114 
   1115   if (Sanitizers.has(SanitizerKind::HWAddress) && TC.getTriple().isAArch64()) {
   1116     CmdArgs.push_back("-target-feature");
   1117     CmdArgs.push_back("+tagged-globals");
   1118   }
   1119 
   1120   // MSan: Workaround for PR16386.
   1121   // ASan: This is mainly to help LSan with cases such as
   1122   // https://github.com/google/sanitizers/issues/373
   1123   // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
   1124   // affect compilation.
   1125   if (Sanitizers.has(SanitizerKind::Memory) ||
   1126       Sanitizers.has(SanitizerKind::Address))
   1127     CmdArgs.push_back("-fno-assume-sane-operator-new");
   1128 
   1129   // libFuzzer wants to intercept calls to certain library functions, so the
   1130   // following -fno-builtin-* flags force the compiler to emit interposable
   1131   // libcalls to these functions. Other sanitizers effectively do the same thing
   1132   // by marking all library call sites with NoBuiltin attribute in their LLVM
   1133   // pass. (see llvm::maybeMarkSanitizerLibraryCallNoBuiltin)
   1134   if (Sanitizers.has(SanitizerKind::FuzzerNoLink)) {
   1135     CmdArgs.push_back("-fno-builtin-bcmp");
   1136     CmdArgs.push_back("-fno-builtin-memcmp");
   1137     CmdArgs.push_back("-fno-builtin-strncmp");
   1138     CmdArgs.push_back("-fno-builtin-strcmp");
   1139     CmdArgs.push_back("-fno-builtin-strncasecmp");
   1140     CmdArgs.push_back("-fno-builtin-strcasecmp");
   1141     CmdArgs.push_back("-fno-builtin-strstr");
   1142     CmdArgs.push_back("-fno-builtin-strcasestr");
   1143     CmdArgs.push_back("-fno-builtin-memmem");
   1144   }
   1145 
   1146   // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
   1147   // enabled.
   1148   if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
   1149       !Args.hasArg(options::OPT_fvisibility_EQ)) {
   1150     TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
   1151         << lastArgumentForMask(TC.getDriver(), Args,
   1152                                Sanitizers.Mask & CFIClasses)
   1153         << "-fvisibility=";
   1154   }
   1155 
   1156   if (Sanitizers.has(SanitizerKind::MemTag) && !hasTargetFeatureMTE(CmdArgs))
   1157     TC.getDriver().Diag(diag::err_stack_tagging_requires_hardware_feature);
   1158 }
   1159 
   1160 SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
   1161                              bool DiagnoseErrors) {
   1162   assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
   1163           A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
   1164           A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
   1165           A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
   1166           A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
   1167           A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
   1168          "Invalid argument in parseArgValues!");
   1169   SanitizerMask Kinds;
   1170   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
   1171     const char *Value = A->getValue(i);
   1172     SanitizerMask Kind;
   1173     // Special case: don't accept -fsanitize=all.
   1174     if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
   1175         0 == strcmp("all", Value))
   1176       Kind = SanitizerMask();
   1177     else
   1178       Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
   1179 
   1180     if (Kind)
   1181       Kinds |= Kind;
   1182     else if (DiagnoseErrors)
   1183       D.Diag(clang::diag::err_drv_unsupported_option_argument)
   1184           << A->getOption().getName() << Value;
   1185   }
   1186   return Kinds;
   1187 }
   1188 
   1189 int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
   1190   assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
   1191          A->getOption().matches(options::OPT_fno_sanitize_coverage));
   1192   int Features = 0;
   1193   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
   1194     const char *Value = A->getValue(i);
   1195     int F = llvm::StringSwitch<int>(Value)
   1196                 .Case("func", CoverageFunc)
   1197                 .Case("bb", CoverageBB)
   1198                 .Case("edge", CoverageEdge)
   1199                 .Case("indirect-calls", CoverageIndirCall)
   1200                 .Case("trace-bb", CoverageTraceBB)
   1201                 .Case("trace-cmp", CoverageTraceCmp)
   1202                 .Case("trace-div", CoverageTraceDiv)
   1203                 .Case("trace-gep", CoverageTraceGep)
   1204                 .Case("8bit-counters", Coverage8bitCounters)
   1205                 .Case("trace-pc", CoverageTracePC)
   1206                 .Case("trace-pc-guard", CoverageTracePCGuard)
   1207                 .Case("no-prune", CoverageNoPrune)
   1208                 .Case("inline-8bit-counters", CoverageInline8bitCounters)
   1209                 .Case("inline-bool-flag", CoverageInlineBoolFlag)
   1210                 .Case("pc-table", CoveragePCTable)
   1211                 .Case("stack-depth", CoverageStackDepth)
   1212                 .Default(0);
   1213     if (F == 0)
   1214       D.Diag(clang::diag::err_drv_unsupported_option_argument)
   1215           << A->getOption().getName() << Value;
   1216     Features |= F;
   1217   }
   1218   return Features;
   1219 }
   1220 
   1221 std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
   1222                                 SanitizerMask Mask) {
   1223   for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
   1224                                                   E = Args.rend();
   1225        I != E; ++I) {
   1226     const auto *Arg = *I;
   1227     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
   1228       SanitizerMask AddKinds =
   1229           expandSanitizerGroups(parseArgValues(D, Arg, false));
   1230       if (AddKinds & Mask)
   1231         return describeSanitizeArg(Arg, Mask);
   1232     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
   1233       SanitizerMask RemoveKinds =
   1234           expandSanitizerGroups(parseArgValues(D, Arg, false));
   1235       Mask &= ~RemoveKinds;
   1236     }
   1237   }
   1238   llvm_unreachable("arg list didn't provide expected value");
   1239 }
   1240 
   1241 std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
   1242   assert(A->getOption().matches(options::OPT_fsanitize_EQ)
   1243          && "Invalid argument in describeSanitizerArg!");
   1244 
   1245   std::string Sanitizers;
   1246   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
   1247     if (expandSanitizerGroups(
   1248             parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
   1249         Mask) {
   1250       if (!Sanitizers.empty())
   1251         Sanitizers += ",";
   1252       Sanitizers += A->getValue(i);
   1253     }
   1254   }
   1255 
   1256   assert(!Sanitizers.empty() && "arg didn't provide expected value");
   1257   return "-fsanitize=" + Sanitizers;
   1258 }
   1259