Home | History | Annotate | Download | only in Driver
      1 //===--- SanitizerArgs.cpp - Arguments for sanitizer tools  ---------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 #include "clang/Driver/SanitizerArgs.h"
     10 #include "Tools.h"
     11 #include "clang/Basic/Sanitizers.h"
     12 #include "clang/Driver/Driver.h"
     13 #include "clang/Driver/DriverDiagnostic.h"
     14 #include "clang/Driver/Options.h"
     15 #include "clang/Driver/ToolChain.h"
     16 #include "llvm/ADT/StringExtras.h"
     17 #include "llvm/ADT/StringSwitch.h"
     18 #include "llvm/Support/FileSystem.h"
     19 #include "llvm/Support/Path.h"
     20 #include "llvm/Support/SpecialCaseList.h"
     21 #include <memory>
     22 
     23 using namespace clang;
     24 using namespace clang::SanitizerKind;
     25 using namespace clang::driver;
     26 using namespace llvm::opt;
     27 
     28 enum : SanitizerMask {
     29   NeedsUbsanRt = Undefined | Integer | CFI,
     30   NeedsUbsanCxxRt = Vptr | CFI,
     31   NotAllowedWithTrap = Vptr,
     32   RequiresPIE = DataFlow,
     33   NeedsUnwindTables = Address | Thread | Memory | DataFlow,
     34   SupportsCoverage = Address | Memory | Leak | Undefined | Integer | DataFlow,
     35   RecoverableByDefault = Undefined | Integer,
     36   Unrecoverable = Unreachable | Return,
     37   LegacyFsanitizeRecoverMask = Undefined | Integer,
     38   NeedsLTO = CFI,
     39   TrappingSupported =
     40       (Undefined & ~Vptr) | UnsignedIntegerOverflow | LocalBounds | CFI,
     41   TrappingDefault = CFI,
     42   CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
     43 };
     44 
     45 enum CoverageFeature {
     46   CoverageFunc = 1 << 0,
     47   CoverageBB = 1 << 1,
     48   CoverageEdge = 1 << 2,
     49   CoverageIndirCall = 1 << 3,
     50   CoverageTraceBB = 1 << 4,
     51   CoverageTraceCmp = 1 << 5,
     52   Coverage8bitCounters = 1 << 6,
     53   CoverageTracePC = 1 << 7,
     54 };
     55 
     56 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
     57 /// invalid components. Returns a SanitizerMask.
     58 static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
     59                                     bool DiagnoseErrors);
     60 
     61 /// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid
     62 /// components. Returns OR of members of \c CoverageFeature enumeration.
     63 static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A);
     64 
     65 /// Produce an argument string from ArgList \p Args, which shows how it
     66 /// provides some sanitizer kind from \p Mask. For example, the argument list
     67 /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
     68 /// would produce "-fsanitize=vptr".
     69 static std::string lastArgumentForMask(const Driver &D,
     70                                        const llvm::opt::ArgList &Args,
     71                                        SanitizerMask Mask);
     72 
     73 /// Produce an argument string from argument \p A, which shows how it provides
     74 /// a value in \p Mask. For instance, the argument
     75 /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
     76 /// "-fsanitize=alignment".
     77 static std::string describeSanitizeArg(const llvm::opt::Arg *A,
     78                                        SanitizerMask Mask);
     79 
     80 /// Produce a string containing comma-separated names of sanitizers in \p
     81 /// Sanitizers set.
     82 static std::string toString(const clang::SanitizerSet &Sanitizers);
     83 
     84 static bool getDefaultBlacklist(const Driver &D, SanitizerMask Kinds,
     85                                 std::string &BLPath) {
     86   const char *BlacklistFile = nullptr;
     87   if (Kinds & Address)
     88     BlacklistFile = "asan_blacklist.txt";
     89   else if (Kinds & Memory)
     90     BlacklistFile = "msan_blacklist.txt";
     91   else if (Kinds & Thread)
     92     BlacklistFile = "tsan_blacklist.txt";
     93   else if (Kinds & DataFlow)
     94     BlacklistFile = "dfsan_abilist.txt";
     95   else if (Kinds & CFI)
     96     BlacklistFile = "cfi_blacklist.txt";
     97 
     98   if (BlacklistFile) {
     99     clang::SmallString<64> Path(D.ResourceDir);
    100     llvm::sys::path::append(Path, BlacklistFile);
    101     BLPath = Path.str();
    102     return true;
    103   }
    104   return false;
    105 }
    106 
    107 /// Sets group bits for every group that has at least one representative already
    108 /// enabled in \p Kinds.
    109 static SanitizerMask setGroupBits(SanitizerMask Kinds) {
    110 #define SANITIZER(NAME, ID)
    111 #define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
    112   if (Kinds & SanitizerKind::ID)                                               \
    113     Kinds |= SanitizerKind::ID##Group;
    114 #include "clang/Basic/Sanitizers.def"
    115   return Kinds;
    116 }
    117 
    118 static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
    119                                            const llvm::opt::ArgList &Args) {
    120   SanitizerMask TrapRemove = 0; // During the loop below, the accumulated set of
    121                                 // sanitizers disabled by the current sanitizer
    122                                 // argument or any argument after it.
    123   SanitizerMask TrappingKinds = 0;
    124   SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
    125 
    126   for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
    127        I != E; ++I) {
    128     const auto *Arg = *I;
    129     if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
    130       Arg->claim();
    131       SanitizerMask Add = parseArgValues(D, Arg, true);
    132       Add &= ~TrapRemove;
    133       if (SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
    134         SanitizerSet S;
    135         S.Mask = InvalidValues;
    136         D.Diag(diag::err_drv_unsupported_option_argument) << "-fsanitize-trap"
    137                                                           << toString(S);
    138       }
    139       TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove;
    140     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
    141       Arg->claim();
    142       TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true));
    143     } else if (Arg->getOption().matches(
    144                    options::OPT_fsanitize_undefined_trap_on_error)) {
    145       Arg->claim();
    146       TrappingKinds |=
    147           expandSanitizerGroups(UndefinedGroup & ~TrapRemove) & ~TrapRemove;
    148     } else if (Arg->getOption().matches(
    149                    options::OPT_fno_sanitize_undefined_trap_on_error)) {
    150       Arg->claim();
    151       TrapRemove |= expandSanitizerGroups(UndefinedGroup);
    152     }
    153   }
    154 
    155   // Apply default trapping behavior.
    156   TrappingKinds |= TrappingDefault & ~TrapRemove;
    157 
    158   return TrappingKinds;
    159 }
    160 
    161 bool SanitizerArgs::needsUbsanRt() const {
    162   return ((Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
    163           CoverageFeatures) &&
    164          !Sanitizers.has(Address) && !Sanitizers.has(Memory) &&
    165          !Sanitizers.has(Thread) && !Sanitizers.has(DataFlow) && !CfiCrossDso;
    166 }
    167 
    168 bool SanitizerArgs::needsCfiRt() const {
    169   return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso;
    170 }
    171 
    172 bool SanitizerArgs::needsCfiDiagRt() const {
    173   return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso;
    174 }
    175 
    176 bool SanitizerArgs::requiresPIE() const {
    177   return NeedPIE || (Sanitizers.Mask & RequiresPIE);
    178 }
    179 
    180 bool SanitizerArgs::needsUnwindTables() const {
    181   return Sanitizers.Mask & NeedsUnwindTables;
    182 }
    183 
    184 SanitizerArgs::SanitizerArgs(const ToolChain &TC,
    185                              const llvm::opt::ArgList &Args) {
    186   SanitizerMask AllRemove = 0;  // During the loop below, the accumulated set of
    187                                 // sanitizers disabled by the current sanitizer
    188                                 // argument or any argument after it.
    189   SanitizerMask AllAddedKinds = 0;  // Mask of all sanitizers ever enabled by
    190                                     // -fsanitize= flags (directly or via group
    191                                     // expansion), some of which may be disabled
    192                                     // later. Used to carefully prune
    193                                     // unused-argument diagnostics.
    194   SanitizerMask DiagnosedKinds = 0;  // All Kinds we have diagnosed up to now.
    195                                      // Used to deduplicate diagnostics.
    196   SanitizerMask Kinds = 0;
    197   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
    198   ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
    199 
    200   const Driver &D = TC.getDriver();
    201   SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
    202   SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
    203 
    204   for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
    205        I != E; ++I) {
    206     const auto *Arg = *I;
    207     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
    208       Arg->claim();
    209       SanitizerMask Add = parseArgValues(D, Arg, true);
    210       AllAddedKinds |= expandSanitizerGroups(Add);
    211 
    212       // Avoid diagnosing any sanitizer which is disabled later.
    213       Add &= ~AllRemove;
    214       // At this point we have not expanded groups, so any unsupported
    215       // sanitizers in Add are those which have been explicitly enabled.
    216       // Diagnose them.
    217       if (SanitizerMask KindsToDiagnose =
    218               Add & InvalidTrappingKinds & ~DiagnosedKinds) {
    219         std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
    220         D.Diag(diag::err_drv_argument_not_allowed_with)
    221             << Desc << "-fsanitize-trap=undefined";
    222         DiagnosedKinds |= KindsToDiagnose;
    223       }
    224       Add &= ~InvalidTrappingKinds;
    225       if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
    226         std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
    227         D.Diag(diag::err_drv_unsupported_opt_for_target)
    228             << Desc << TC.getTriple().str();
    229         DiagnosedKinds |= KindsToDiagnose;
    230       }
    231       Add &= Supported;
    232 
    233       // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
    234       // so we don't error out if -fno-rtti and -fsanitize=undefined were
    235       // passed.
    236       if (Add & Vptr &&
    237           (RTTIMode == ToolChain::RM_DisabledImplicitly ||
    238            RTTIMode == ToolChain::RM_DisabledExplicitly)) {
    239         if (RTTIMode == ToolChain::RM_DisabledImplicitly)
    240           // Warn about not having rtti enabled if the vptr sanitizer is
    241           // explicitly enabled
    242           D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
    243         else {
    244           const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg();
    245           assert(NoRTTIArg &&
    246                  "RTTI disabled explicitly but we have no argument!");
    247           D.Diag(diag::err_drv_argument_not_allowed_with)
    248               << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
    249         }
    250 
    251         // Take out the Vptr sanitizer from the enabled sanitizers
    252         AllRemove |= Vptr;
    253       }
    254 
    255       Add = expandSanitizerGroups(Add);
    256       // Group expansion may have enabled a sanitizer which is disabled later.
    257       Add &= ~AllRemove;
    258       // Silently discard any unsupported sanitizers implicitly enabled through
    259       // group expansion.
    260       Add &= ~InvalidTrappingKinds;
    261       Add &= Supported;
    262 
    263       Kinds |= Add;
    264     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
    265       Arg->claim();
    266       SanitizerMask Remove = parseArgValues(D, Arg, true);
    267       AllRemove |= expandSanitizerGroups(Remove);
    268     }
    269   }
    270 
    271   // Enable toolchain specific default sanitizers if not explicitly disabled.
    272   Kinds |= TC.getDefaultSanitizers() & ~AllRemove;
    273 
    274   // We disable the vptr sanitizer if it was enabled by group expansion but RTTI
    275   // is disabled.
    276   if ((Kinds & Vptr) &&
    277       (RTTIMode == ToolChain::RM_DisabledImplicitly ||
    278        RTTIMode == ToolChain::RM_DisabledExplicitly)) {
    279     Kinds &= ~Vptr;
    280   }
    281 
    282   // Check that LTO is enabled if we need it.
    283   if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {
    284     D.Diag(diag::err_drv_argument_only_allowed_with)
    285         << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
    286   }
    287 
    288   // Report error if there are non-trapping sanitizers that require
    289   // c++abi-specific  parts of UBSan runtime, and they are not provided by the
    290   // toolchain. We don't have a good way to check the latter, so we just
    291   // check if the toolchan supports vptr.
    292   if (~Supported & Vptr) {
    293     SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
    294     // The runtime library supports the Microsoft C++ ABI, but only well enough
    295     // for CFI. FIXME: Remove this once we support vptr on Windows.
    296     if (TC.getTriple().isOSWindows())
    297       KindsToDiagnose &= ~CFI;
    298     if (KindsToDiagnose) {
    299       SanitizerSet S;
    300       S.Mask = KindsToDiagnose;
    301       D.Diag(diag::err_drv_unsupported_opt_for_target)
    302           << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str();
    303       Kinds &= ~KindsToDiagnose;
    304     }
    305   }
    306 
    307   // Warn about incompatible groups of sanitizers.
    308   std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
    309       std::make_pair(Address, Thread), std::make_pair(Address, Memory),
    310       std::make_pair(Thread, Memory), std::make_pair(Leak, Thread),
    311       std::make_pair(Leak, Memory), std::make_pair(KernelAddress, Address),
    312       std::make_pair(KernelAddress, Leak),
    313       std::make_pair(KernelAddress, Thread),
    314       std::make_pair(KernelAddress, Memory),
    315       std::make_pair(Efficiency, Address),
    316       std::make_pair(Efficiency, Leak),
    317       std::make_pair(Efficiency, Thread),
    318       std::make_pair(Efficiency, Memory),
    319       std::make_pair(Efficiency, KernelAddress)};
    320   for (auto G : IncompatibleGroups) {
    321     SanitizerMask Group = G.first;
    322     if (Kinds & Group) {
    323       if (SanitizerMask Incompatible = Kinds & G.second) {
    324         D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    325             << lastArgumentForMask(D, Args, Group)
    326             << lastArgumentForMask(D, Args, Incompatible);
    327         Kinds &= ~Incompatible;
    328       }
    329     }
    330   }
    331   // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
    332   // -fsanitize=address. Perhaps it should print an error, or perhaps
    333   // -f(-no)sanitize=leak should change whether leak detection is enabled by
    334   // default in ASan?
    335 
    336   // Parse -f(no-)?sanitize-recover flags.
    337   SanitizerMask RecoverableKinds = RecoverableByDefault;
    338   SanitizerMask DiagnosedUnrecoverableKinds = 0;
    339   for (const auto *Arg : Args) {
    340     const char *DeprecatedReplacement = nullptr;
    341     if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
    342       DeprecatedReplacement =
    343           "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all";
    344       RecoverableKinds |= expandSanitizerGroups(LegacyFsanitizeRecoverMask);
    345       Arg->claim();
    346     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
    347       DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer' or "
    348                               "'-fno-sanitize-recover=all";
    349       RecoverableKinds &= ~expandSanitizerGroups(LegacyFsanitizeRecoverMask);
    350       Arg->claim();
    351     } else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
    352       SanitizerMask Add = parseArgValues(D, Arg, true);
    353       // Report error if user explicitly tries to recover from unrecoverable
    354       // sanitizer.
    355       if (SanitizerMask KindsToDiagnose =
    356               Add & Unrecoverable & ~DiagnosedUnrecoverableKinds) {
    357         SanitizerSet SetToDiagnose;
    358         SetToDiagnose.Mask |= KindsToDiagnose;
    359         D.Diag(diag::err_drv_unsupported_option_argument)
    360             << Arg->getOption().getName() << toString(SetToDiagnose);
    361         DiagnosedUnrecoverableKinds |= KindsToDiagnose;
    362       }
    363       RecoverableKinds |= expandSanitizerGroups(Add);
    364       Arg->claim();
    365     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
    366       RecoverableKinds &= ~expandSanitizerGroups(parseArgValues(D, Arg, true));
    367       Arg->claim();
    368     }
    369     if (DeprecatedReplacement) {
    370       D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
    371                                             << DeprecatedReplacement;
    372     }
    373   }
    374   RecoverableKinds &= Kinds;
    375   RecoverableKinds &= ~Unrecoverable;
    376 
    377   TrappingKinds &= Kinds;
    378 
    379   // Setup blacklist files.
    380   // Add default blacklist from resource directory.
    381   {
    382     std::string BLPath;
    383     if (getDefaultBlacklist(D, Kinds, BLPath) && llvm::sys::fs::exists(BLPath))
    384       BlacklistFiles.push_back(BLPath);
    385   }
    386   // Parse -f(no-)sanitize-blacklist options.
    387   for (const auto *Arg : Args) {
    388     if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
    389       Arg->claim();
    390       std::string BLPath = Arg->getValue();
    391       if (llvm::sys::fs::exists(BLPath)) {
    392         BlacklistFiles.push_back(BLPath);
    393         ExtraDeps.push_back(BLPath);
    394       } else
    395         D.Diag(clang::diag::err_drv_no_such_file) << BLPath;
    396 
    397     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
    398       Arg->claim();
    399       BlacklistFiles.clear();
    400       ExtraDeps.clear();
    401     }
    402   }
    403   // Validate blacklists format.
    404   {
    405     std::string BLError;
    406     std::unique_ptr<llvm::SpecialCaseList> SCL(
    407         llvm::SpecialCaseList::create(BlacklistFiles, BLError));
    408     if (!SCL.get())
    409       D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
    410   }
    411 
    412   // Parse -f[no-]sanitize-memory-track-origins[=level] options.
    413   if (AllAddedKinds & Memory) {
    414     if (Arg *A =
    415             Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
    416                             options::OPT_fsanitize_memory_track_origins,
    417                             options::OPT_fno_sanitize_memory_track_origins)) {
    418       if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
    419         MsanTrackOrigins = 2;
    420       } else if (A->getOption().matches(
    421                      options::OPT_fno_sanitize_memory_track_origins)) {
    422         MsanTrackOrigins = 0;
    423       } else {
    424         StringRef S = A->getValue();
    425         if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
    426             MsanTrackOrigins > 2) {
    427           D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
    428         }
    429       }
    430     }
    431     MsanUseAfterDtor =
    432         Args.hasArg(options::OPT_fsanitize_memory_use_after_dtor);
    433     NeedPIE |= !(TC.getTriple().isOSLinux() &&
    434                  TC.getTriple().getArch() == llvm::Triple::x86_64);
    435   }
    436 
    437   if (AllAddedKinds & CFI) {
    438     CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
    439                                options::OPT_fno_sanitize_cfi_cross_dso, false);
    440     // Without PIE, external function address may resolve to a PLT record, which
    441     // can not be verified by the target module.
    442     NeedPIE |= CfiCrossDso;
    443   }
    444 
    445   Stats = Args.hasFlag(options::OPT_fsanitize_stats,
    446                        options::OPT_fno_sanitize_stats, false);
    447 
    448   // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
    449   // enabled sanitizers.
    450   for (const auto *Arg : Args) {
    451     if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
    452       int LegacySanitizeCoverage;
    453       if (Arg->getNumValues() == 1 &&
    454           !StringRef(Arg->getValue(0))
    455                .getAsInteger(0, LegacySanitizeCoverage) &&
    456           LegacySanitizeCoverage >= 0 && LegacySanitizeCoverage <= 4) {
    457         switch (LegacySanitizeCoverage) {
    458         case 0:
    459           CoverageFeatures = 0;
    460           Arg->claim();
    461           break;
    462         case 1:
    463           D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
    464                                                 << "-fsanitize-coverage=func";
    465           CoverageFeatures = CoverageFunc;
    466           break;
    467         case 2:
    468           D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
    469                                                 << "-fsanitize-coverage=bb";
    470           CoverageFeatures = CoverageBB;
    471           break;
    472         case 3:
    473           D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
    474                                                 << "-fsanitize-coverage=edge";
    475           CoverageFeatures = CoverageEdge;
    476           break;
    477         case 4:
    478           D.Diag(diag::warn_drv_deprecated_arg)
    479               << Arg->getAsString(Args)
    480               << "-fsanitize-coverage=edge,indirect-calls";
    481           CoverageFeatures = CoverageEdge | CoverageIndirCall;
    482           break;
    483         }
    484         continue;
    485       }
    486       CoverageFeatures |= parseCoverageFeatures(D, Arg);
    487 
    488       // Disable coverage and not claim the flags if there is at least one
    489       // non-supporting sanitizer.
    490       if (!(AllAddedKinds & ~setGroupBits(SupportsCoverage))) {
    491         Arg->claim();
    492       } else {
    493         CoverageFeatures = 0;
    494       }
    495     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
    496       Arg->claim();
    497       CoverageFeatures &= ~parseCoverageFeatures(D, Arg);
    498     }
    499   }
    500   // Choose at most one coverage type: function, bb, or edge.
    501   if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageBB))
    502     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    503         << "-fsanitize-coverage=func"
    504         << "-fsanitize-coverage=bb";
    505   if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageEdge))
    506     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    507         << "-fsanitize-coverage=func"
    508         << "-fsanitize-coverage=edge";
    509   if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
    510     D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    511         << "-fsanitize-coverage=bb"
    512         << "-fsanitize-coverage=edge";
    513   // Basic block tracing and 8-bit counters require some type of coverage
    514   // enabled.
    515   int CoverageTypes = CoverageFunc | CoverageBB | CoverageEdge;
    516   if ((CoverageFeatures & CoverageTraceBB) &&
    517       !(CoverageFeatures & CoverageTypes))
    518     D.Diag(clang::diag::err_drv_argument_only_allowed_with)
    519         << "-fsanitize-coverage=trace-bb"
    520         << "-fsanitize-coverage=(func|bb|edge)";
    521   if ((CoverageFeatures & Coverage8bitCounters) &&
    522       !(CoverageFeatures & CoverageTypes))
    523     D.Diag(clang::diag::err_drv_argument_only_allowed_with)
    524         << "-fsanitize-coverage=8bit-counters"
    525         << "-fsanitize-coverage=(func|bb|edge)";
    526   // trace-pc w/o func/bb/edge implies edge.
    527   if ((CoverageFeatures & CoverageTracePC) &&
    528       !(CoverageFeatures & CoverageTypes))
    529     CoverageFeatures |= CoverageEdge;
    530 
    531   if (AllAddedKinds & Address) {
    532     AsanSharedRuntime =
    533         Args.hasArg(options::OPT_shared_libasan) || TC.getTriple().isAndroid();
    534     NeedPIE |= TC.getTriple().isAndroid();
    535     if (Arg *A =
    536             Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
    537         StringRef S = A->getValue();
    538         // Legal values are 0 and 1, 2, but in future we may add more levels.
    539         if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
    540             AsanFieldPadding > 2) {
    541           D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
    542         }
    543     }
    544 
    545     if (Arg *WindowsDebugRTArg =
    546             Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
    547                             options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
    548                             options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
    549       switch (WindowsDebugRTArg->getOption().getID()) {
    550       case options::OPT__SLASH_MTd:
    551       case options::OPT__SLASH_MDd:
    552       case options::OPT__SLASH_LDd:
    553         D.Diag(clang::diag::err_drv_argument_not_allowed_with)
    554             << WindowsDebugRTArg->getAsString(Args)
    555             << lastArgumentForMask(D, Args, Address);
    556         D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
    557       }
    558     }
    559   }
    560 
    561   AsanUseAfterScope =
    562       Args.hasArg(options::OPT_fsanitize_address_use_after_scope);
    563   if (AsanUseAfterScope && !(AllAddedKinds & Address)) {
    564     D.Diag(clang::diag::err_drv_argument_only_allowed_with)
    565         << "-fsanitize-address-use-after-scope"
    566         << "-fsanitize=address";
    567   }
    568 
    569   // Parse -link-cxx-sanitizer flag.
    570   LinkCXXRuntimes =
    571       Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX();
    572 
    573   // Finally, initialize the set of available and recoverable sanitizers.
    574   Sanitizers.Mask |= Kinds;
    575   RecoverableSanitizers.Mask |= RecoverableKinds;
    576   TrapSanitizers.Mask |= TrappingKinds;
    577 }
    578 
    579 static std::string toString(const clang::SanitizerSet &Sanitizers) {
    580   std::string Res;
    581 #define SANITIZER(NAME, ID)                                                    \
    582   if (Sanitizers.has(ID)) {                                                    \
    583     if (!Res.empty())                                                          \
    584       Res += ",";                                                              \
    585     Res += NAME;                                                               \
    586   }
    587 #include "clang/Basic/Sanitizers.def"
    588   return Res;
    589 }
    590 
    591 static void addIncludeLinkerOption(const ToolChain &TC,
    592                                    const llvm::opt::ArgList &Args,
    593                                    llvm::opt::ArgStringList &CmdArgs,
    594                                    StringRef SymbolName) {
    595   SmallString<64> LinkerOptionFlag;
    596   LinkerOptionFlag = "--linker-option=/include:";
    597   if (TC.getTriple().getArch() == llvm::Triple::x86) {
    598     // Win32 mangles C function names with a '_' prefix.
    599     LinkerOptionFlag += '_';
    600   }
    601   LinkerOptionFlag += SymbolName;
    602   CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
    603 }
    604 
    605 void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
    606                             llvm::opt::ArgStringList &CmdArgs,
    607                             types::ID InputType) const {
    608   // Translate available CoverageFeatures to corresponding clang-cc1 flags.
    609   // Do it even if Sanitizers.empty() since some forms of coverage don't require
    610   // sanitizers.
    611   std::pair<int, const char *> CoverageFlags[] = {
    612     std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
    613     std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
    614     std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
    615     std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
    616     std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
    617     std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
    618     std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
    619     std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc")};
    620   for (auto F : CoverageFlags) {
    621     if (CoverageFeatures & F.first)
    622       CmdArgs.push_back(Args.MakeArgString(F.second));
    623   }
    624 
    625   if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
    626     // Instruct the code generator to embed linker directives in the object file
    627     // that cause the required runtime libraries to be linked.
    628     CmdArgs.push_back(Args.MakeArgString(
    629         "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone")));
    630     if (types::isCXX(InputType))
    631       CmdArgs.push_back(Args.MakeArgString(
    632           "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx")));
    633   }
    634   if (TC.getTriple().isOSWindows() && needsStatsRt()) {
    635     CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
    636                                          TC.getCompilerRT(Args, "stats_client")));
    637 
    638     // The main executable must export the stats runtime.
    639     // FIXME: Only exporting from the main executable (e.g. based on whether the
    640     // translation unit defines main()) would save a little space, but having
    641     // multiple copies of the runtime shouldn't hurt.
    642     CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
    643                                          TC.getCompilerRT(Args, "stats")));
    644     addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
    645   }
    646 
    647   if (Sanitizers.empty())
    648     return;
    649   CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
    650 
    651   if (!RecoverableSanitizers.empty())
    652     CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
    653                                          toString(RecoverableSanitizers)));
    654 
    655   if (!TrapSanitizers.empty())
    656     CmdArgs.push_back(
    657         Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
    658 
    659   for (const auto &BLPath : BlacklistFiles) {
    660     SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
    661     BlacklistOpt += BLPath;
    662     CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
    663   }
    664   for (const auto &Dep : ExtraDeps) {
    665     SmallString<64> ExtraDepOpt("-fdepfile-entry=");
    666     ExtraDepOpt += Dep;
    667     CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
    668   }
    669 
    670   if (MsanTrackOrigins)
    671     CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
    672                                          llvm::utostr(MsanTrackOrigins)));
    673 
    674   if (MsanUseAfterDtor)
    675     CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-use-after-dtor"));
    676 
    677   if (CfiCrossDso)
    678     CmdArgs.push_back(Args.MakeArgString("-fsanitize-cfi-cross-dso"));
    679 
    680   if (Stats)
    681     CmdArgs.push_back(Args.MakeArgString("-fsanitize-stats"));
    682 
    683   if (AsanFieldPadding)
    684     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
    685                                          llvm::utostr(AsanFieldPadding)));
    686 
    687   if (AsanUseAfterScope)
    688     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-use-after-scope"));
    689 
    690   // MSan: Workaround for PR16386.
    691   // ASan: This is mainly to help LSan with cases such as
    692   // https://code.google.com/p/address-sanitizer/issues/detail?id=373
    693   // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
    694   // affect compilation.
    695   if (Sanitizers.has(Memory) || Sanitizers.has(Address))
    696     CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new"));
    697 
    698   // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
    699   // enabled.
    700   if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
    701       !Args.hasArg(options::OPT_fvisibility_EQ)) {
    702     TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
    703         << lastArgumentForMask(TC.getDriver(), Args,
    704                                Sanitizers.Mask & CFIClasses)
    705         << "-fvisibility=";
    706   }
    707 }
    708 
    709 SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
    710                              bool DiagnoseErrors) {
    711   assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
    712           A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
    713           A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
    714           A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
    715           A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
    716           A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
    717          "Invalid argument in parseArgValues!");
    718   SanitizerMask Kinds = 0;
    719   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
    720     const char *Value = A->getValue(i);
    721     SanitizerMask Kind;
    722     // Special case: don't accept -fsanitize=all.
    723     if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
    724         0 == strcmp("all", Value))
    725       Kind = 0;
    726     // Similarly, don't accept -fsanitize=efficiency-all.
    727     else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
    728         0 == strcmp("efficiency-all", Value))
    729       Kind = 0;
    730     else
    731       Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
    732 
    733     if (Kind)
    734       Kinds |= Kind;
    735     else if (DiagnoseErrors)
    736       D.Diag(clang::diag::err_drv_unsupported_option_argument)
    737           << A->getOption().getName() << Value;
    738   }
    739   return Kinds;
    740 }
    741 
    742 int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
    743   assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
    744          A->getOption().matches(options::OPT_fno_sanitize_coverage));
    745   int Features = 0;
    746   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
    747     const char *Value = A->getValue(i);
    748     int F = llvm::StringSwitch<int>(Value)
    749         .Case("func", CoverageFunc)
    750         .Case("bb", CoverageBB)
    751         .Case("edge", CoverageEdge)
    752         .Case("indirect-calls", CoverageIndirCall)
    753         .Case("trace-bb", CoverageTraceBB)
    754         .Case("trace-cmp", CoverageTraceCmp)
    755         .Case("8bit-counters", Coverage8bitCounters)
    756         .Case("trace-pc", CoverageTracePC)
    757         .Default(0);
    758     if (F == 0)
    759       D.Diag(clang::diag::err_drv_unsupported_option_argument)
    760           << A->getOption().getName() << Value;
    761     Features |= F;
    762   }
    763   return Features;
    764 }
    765 
    766 std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
    767                                 SanitizerMask Mask) {
    768   for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
    769                                                   E = Args.rend();
    770        I != E; ++I) {
    771     const auto *Arg = *I;
    772     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
    773       SanitizerMask AddKinds =
    774           expandSanitizerGroups(parseArgValues(D, Arg, false));
    775       if (AddKinds & Mask)
    776         return describeSanitizeArg(Arg, Mask);
    777     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
    778       SanitizerMask RemoveKinds =
    779           expandSanitizerGroups(parseArgValues(D, Arg, false));
    780       Mask &= ~RemoveKinds;
    781     }
    782   }
    783   llvm_unreachable("arg list didn't provide expected value");
    784 }
    785 
    786 std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
    787   assert(A->getOption().matches(options::OPT_fsanitize_EQ)
    788          && "Invalid argument in describeSanitizerArg!");
    789 
    790   std::string Sanitizers;
    791   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
    792     if (expandSanitizerGroups(
    793             parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
    794         Mask) {
    795       if (!Sanitizers.empty())
    796         Sanitizers += ",";
    797       Sanitizers += A->getValue(i);
    798     }
    799   }
    800 
    801   assert(!Sanitizers.empty() && "arg didn't provide expected value");
    802   return "-fsanitize=" + Sanitizers;
    803 }
    804