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