xref: /llvm-project/clang/lib/Driver/SanitizerArgs.cpp (revision 1295aa2e814d1747d69520e34e2c5fb2888e666d)
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 "clang/Basic/Sanitizers.h"
10 #include "clang/Driver/Driver.h"
11 #include "clang/Driver/Options.h"
12 #include "clang/Driver/ToolChain.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/Support/Path.h"
17 #include "llvm/Support/SpecialCaseList.h"
18 #include "llvm/Support/VirtualFileSystem.h"
19 #include "llvm/TargetParser/AArch64TargetParser.h"
20 #include "llvm/TargetParser/RISCVTargetParser.h"
21 #include "llvm/TargetParser/TargetParser.h"
22 #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
23 #include <memory>
24 
25 using namespace clang;
26 using namespace clang::driver;
27 using namespace llvm::opt;
28 
29 static const SanitizerMask NeedsUbsanRt =
30     SanitizerKind::Undefined | SanitizerKind::Integer |
31     SanitizerKind::LocalBounds | SanitizerKind::ImplicitConversion |
32     SanitizerKind::Nullability | SanitizerKind::CFI |
33     SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
34 static const SanitizerMask NeedsUbsanCxxRt =
35     SanitizerKind::Vptr | SanitizerKind::CFI;
36 static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
37 static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr;
38 static const SanitizerMask NotAllowedWithExecuteOnly =
39     SanitizerKind::Function | SanitizerKind::KCFI;
40 static const SanitizerMask NeedsUnwindTables =
41     SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Type |
42     SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::DataFlow |
43     SanitizerKind::NumericalStability;
44 static const SanitizerMask SupportsCoverage =
45     SanitizerKind::Address | SanitizerKind::HWAddress |
46     SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
47     SanitizerKind::Type | SanitizerKind::MemtagStack |
48     SanitizerKind::MemtagHeap | SanitizerKind::MemtagGlobals |
49     SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak |
50     SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::Bounds |
51     SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
52     SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
53     SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero |
54     SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack |
55     SanitizerKind::Thread | SanitizerKind::ObjCCast | SanitizerKind::KCFI |
56     SanitizerKind::NumericalStability;
57 static const SanitizerMask RecoverableByDefault =
58     SanitizerKind::Undefined | SanitizerKind::Integer |
59     SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
60     SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
61 static const SanitizerMask Unrecoverable =
62     SanitizerKind::Unreachable | SanitizerKind::Return;
63 static const SanitizerMask AlwaysRecoverable = SanitizerKind::KernelAddress |
64                                                SanitizerKind::KernelHWAddress |
65                                                SanitizerKind::KCFI;
66 static const SanitizerMask NeedsLTO = SanitizerKind::CFI;
67 static const SanitizerMask TrappingSupported =
68     (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | SanitizerKind::Integer |
69     SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
70     SanitizerKind::LocalBounds | SanitizerKind::CFI |
71     SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
72 static const SanitizerMask MergeDefault = SanitizerKind::Undefined;
73 static const SanitizerMask TrappingDefault =
74     SanitizerKind::CFI | SanitizerKind::LocalBounds;
75 static const SanitizerMask CFIClasses =
76     SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
77     SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
78     SanitizerKind::CFIUnrelatedCast;
79 static const SanitizerMask CompatibleWithMinimalRuntime =
80     TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack |
81     SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap |
82     SanitizerKind::MemtagGlobals | SanitizerKind::KCFI;
83 
84 enum CoverageFeature {
85   CoverageFunc = 1 << 0,
86   CoverageBB = 1 << 1,
87   CoverageEdge = 1 << 2,
88   CoverageIndirCall = 1 << 3,
89   CoverageTraceBB = 1 << 4, // Deprecated.
90   CoverageTraceCmp = 1 << 5,
91   CoverageTraceDiv = 1 << 6,
92   CoverageTraceGep = 1 << 7,
93   Coverage8bitCounters = 1 << 8, // Deprecated.
94   CoverageTracePC = 1 << 9,
95   CoverageTracePCGuard = 1 << 10,
96   CoverageNoPrune = 1 << 11,
97   CoverageInline8bitCounters = 1 << 12,
98   CoveragePCTable = 1 << 13,
99   CoverageStackDepth = 1 << 14,
100   CoverageInlineBoolFlag = 1 << 15,
101   CoverageTraceLoads = 1 << 16,
102   CoverageTraceStores = 1 << 17,
103   CoverageControlFlow = 1 << 18,
104 };
105 
106 enum BinaryMetadataFeature {
107   BinaryMetadataCovered = 1 << 0,
108   BinaryMetadataAtomics = 1 << 1,
109   BinaryMetadataUAR = 1 << 2,
110 };
111 
112 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
113 /// invalid components. Returns a SanitizerMask.
114 static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
115                                     bool DiagnoseErrors);
116 
117 /// Parse a -fsanitize=<sanitizer1>=<value1>... or -fno-sanitize= argument's
118 /// values, diagnosing any invalid components.
119 /// Cutoffs are stored in the passed parameter.
120 static void parseArgCutoffs(const Driver &D, const llvm::opt::Arg *A,
121                             bool DiagnoseErrors, SanitizerMaskCutoffs &Cutoffs);
122 
123 /// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid
124 /// components. Returns OR of members of \c CoverageFeature enumeration.
125 static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A,
126                                  bool DiagnoseErrors);
127 
128 /// Parse -fsanitize-undefined-ignore-overflow-pattern= flag values, diagnosing
129 /// any invalid values. Returns a mask of excluded overflow patterns.
130 static int parseOverflowPatternExclusionValues(const Driver &D,
131                                                const llvm::opt::Arg *A,
132                                                bool DiagnoseErrors);
133 
134 /// Parse -f(no-)?sanitize-metadata= flag values, diagnosing any invalid
135 /// components. Returns OR of members of \c BinaryMetadataFeature enumeration.
136 static int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A,
137                                        bool DiagnoseErrors);
138 
139 /// Produce an argument string from ArgList \p Args, which shows how it
140 /// provides some sanitizer kind from \p Mask. For example, the argument list
141 /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
142 /// would produce "-fsanitize=vptr".
143 static std::string lastArgumentForMask(const Driver &D,
144                                        const llvm::opt::ArgList &Args,
145                                        SanitizerMask Mask);
146 
147 /// Produce an argument string from argument \p A, which shows how it provides
148 /// a value in \p Mask. For instance, the argument
149 /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
150 /// "-fsanitize=alignment".
151 static std::string describeSanitizeArg(const llvm::opt::Arg *A,
152                                        SanitizerMask Mask);
153 
154 /// Produce a string containing comma-separated names of sanitizers in \p
155 /// Sanitizers set.
156 static std::string toString(const clang::SanitizerSet &Sanitizers);
157 
158 /// Return true if an execute-only target disallows data access to code
159 /// sections.
160 static bool isExecuteOnlyTarget(const llvm::Triple &Triple,
161                                 const llvm::opt::ArgList &Args) {
162   if (Triple.isPS5())
163     return true;
164   return Args.hasFlagNoClaim(options::OPT_mexecute_only,
165                              options::OPT_mno_execute_only, false);
166 }
167 
168 static void validateSpecialCaseListFormat(const Driver &D,
169                                           std::vector<std::string> &SCLFiles,
170                                           unsigned MalformedSCLErrorDiagID,
171                                           bool DiagnoseErrors) {
172   if (SCLFiles.empty())
173     return;
174 
175   std::string BLError;
176   std::unique_ptr<llvm::SpecialCaseList> SCL(
177       llvm::SpecialCaseList::create(SCLFiles, D.getVFS(), BLError));
178   if (!SCL.get() && DiagnoseErrors)
179     D.Diag(MalformedSCLErrorDiagID) << BLError;
180 }
181 
182 static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds,
183                                   std::vector<std::string> &IgnorelistFiles,
184                                   bool DiagnoseErrors) {
185   struct Ignorelist {
186     const char *File;
187     SanitizerMask Mask;
188   } Ignorelists[] = {{"asan_ignorelist.txt", SanitizerKind::Address},
189                      {"hwasan_ignorelist.txt", SanitizerKind::HWAddress},
190                      {"memtag_ignorelist.txt", SanitizerKind::MemTag},
191                      {"msan_ignorelist.txt", SanitizerKind::Memory},
192                      {"nsan_ignorelist.txt", SanitizerKind::NumericalStability},
193                      {"tsan_ignorelist.txt", SanitizerKind::Thread},
194                      {"tysan_blacklist.txt", SanitizerKind::Type},
195                      {"dfsan_abilist.txt", SanitizerKind::DataFlow},
196                      {"cfi_ignorelist.txt", SanitizerKind::CFI},
197                      {"ubsan_ignorelist.txt",
198                       SanitizerKind::Undefined | SanitizerKind::Integer |
199                           SanitizerKind::Nullability |
200                           SanitizerKind::FloatDivideByZero}};
201 
202   for (auto BL : Ignorelists) {
203     if (!(Kinds & BL.Mask))
204       continue;
205 
206     clang::SmallString<64> Path(D.ResourceDir);
207     llvm::sys::path::append(Path, "share", BL.File);
208     if (D.getVFS().exists(Path))
209       IgnorelistFiles.push_back(std::string(Path));
210     else if (BL.Mask == SanitizerKind::CFI && DiagnoseErrors)
211       // If cfi_ignorelist.txt cannot be found in the resource dir, driver
212       // should fail.
213       D.Diag(clang::diag::err_drv_missing_sanitizer_ignorelist) << Path;
214   }
215   validateSpecialCaseListFormat(
216       D, IgnorelistFiles, clang::diag::err_drv_malformed_sanitizer_ignorelist,
217       DiagnoseErrors);
218 }
219 
220 /// Parse -f(no-)?sanitize-(coverage-)?(allow|ignore)list argument's values,
221 /// diagnosing any invalid file paths and validating special case list format.
222 static void parseSpecialCaseListArg(const Driver &D,
223                                     const llvm::opt::ArgList &Args,
224                                     std::vector<std::string> &SCLFiles,
225                                     llvm::opt::OptSpecifier SCLOptionID,
226                                     llvm::opt::OptSpecifier NoSCLOptionID,
227                                     unsigned MalformedSCLErrorDiagID,
228                                     bool DiagnoseErrors) {
229   for (const auto *Arg : Args) {
230     // Match -fsanitize-(coverage-)?(allow|ignore)list.
231     if (Arg->getOption().matches(SCLOptionID)) {
232       Arg->claim();
233       std::string SCLPath = Arg->getValue();
234       if (D.getVFS().exists(SCLPath)) {
235         SCLFiles.push_back(SCLPath);
236       } else if (DiagnoseErrors) {
237         D.Diag(clang::diag::err_drv_no_such_file) << SCLPath;
238       }
239       // Match -fno-sanitize-ignorelist.
240     } else if (Arg->getOption().matches(NoSCLOptionID)) {
241       Arg->claim();
242       SCLFiles.clear();
243     }
244   }
245   validateSpecialCaseListFormat(D, SCLFiles, MalformedSCLErrorDiagID,
246                                 DiagnoseErrors);
247 }
248 
249 /// Sets group bits for every group that has at least one representative already
250 /// enabled in \p Kinds.
251 static SanitizerMask setGroupBits(SanitizerMask Kinds) {
252 #define SANITIZER(NAME, ID)
253 #define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
254   if (Kinds & SanitizerKind::ID)                                               \
255     Kinds |= SanitizerKind::ID##Group;
256 #include "clang/Basic/Sanitizers.def"
257   return Kinds;
258 }
259 
260 // Computes the sanitizer mask as:
261 //     Default + Arguments (in or out)
262 // with arguments parsed from left to right.
263 //
264 // Error messages are printed if the AlwaysIn or AlwaysOut invariants are
265 // violated, but the caller must enforce these invariants themselves.
266 static SanitizerMask
267 parseSanitizeArgs(const Driver &D, const llvm::opt::ArgList &Args,
268                   bool DiagnoseErrors, SanitizerMask Default,
269                   SanitizerMask AlwaysIn, SanitizerMask AlwaysOut, int OptInID,
270                   int OptOutID) {
271   assert(!(AlwaysIn & AlwaysOut) &&
272          "parseSanitizeArgs called with contradictory in/out requirements");
273 
274   SanitizerMask Output = Default;
275   // Keep track of which violations we have already reported, to avoid
276   // duplicate error messages.
277   SanitizerMask DiagnosedAlwaysInViolations;
278   SanitizerMask DiagnosedAlwaysOutViolations;
279   for (const auto *Arg : Args) {
280     if (Arg->getOption().matches(OptInID)) {
281       SanitizerMask Add = parseArgValues(D, Arg, DiagnoseErrors);
282       // Report error if user explicitly tries to opt-in to an always-out
283       // sanitizer.
284       if (SanitizerMask KindsToDiagnose =
285               Add & AlwaysOut & ~DiagnosedAlwaysOutViolations) {
286         if (DiagnoseErrors) {
287           SanitizerSet SetToDiagnose;
288           SetToDiagnose.Mask |= KindsToDiagnose;
289           D.Diag(diag::err_drv_unsupported_option_argument)
290               << Arg->getSpelling() << toString(SetToDiagnose);
291           DiagnosedAlwaysOutViolations |= KindsToDiagnose;
292         }
293       }
294       Output |= expandSanitizerGroups(Add);
295       Arg->claim();
296     } else if (Arg->getOption().matches(OptOutID)) {
297       SanitizerMask Remove = parseArgValues(D, Arg, DiagnoseErrors);
298       // Report error if user explicitly tries to opt-out of an always-in
299       // sanitizer.
300       if (SanitizerMask KindsToDiagnose =
301               Remove & AlwaysIn & ~DiagnosedAlwaysInViolations) {
302         if (DiagnoseErrors) {
303           SanitizerSet SetToDiagnose;
304           SetToDiagnose.Mask |= KindsToDiagnose;
305           D.Diag(diag::err_drv_unsupported_option_argument)
306               << Arg->getSpelling() << toString(SetToDiagnose);
307           DiagnosedAlwaysInViolations |= KindsToDiagnose;
308         }
309       }
310       Output &= ~expandSanitizerGroups(Remove);
311       Arg->claim();
312     }
313   }
314 
315   return Output;
316 }
317 
318 static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
319                                            const llvm::opt::ArgList &Args,
320                                            bool DiagnoseErrors) {
321   SanitizerMask AlwaysTrap; // Empty
322   SanitizerMask NeverTrap = ~(setGroupBits(TrappingSupported));
323 
324   // N.B. We do *not* enforce NeverTrap. This maintains the behavior of
325   // '-fsanitize=undefined -fsanitize-trap=undefined'
326   // (clang/test/Driver/fsanitize.c ), which is that vptr is not enabled at all
327   // (not even in recover mode) in order to avoid the need for a ubsan runtime.
328   return parseSanitizeArgs(D, Args, DiagnoseErrors, TrappingDefault, AlwaysTrap,
329                            NeverTrap, options::OPT_fsanitize_trap_EQ,
330                            options::OPT_fno_sanitize_trap_EQ);
331 }
332 
333 static SanitizerMaskCutoffs
334 parseSanitizeSkipHotCutoffArgs(const Driver &D, const llvm::opt::ArgList &Args,
335                                bool DiagnoseErrors) {
336   SanitizerMaskCutoffs Cutoffs;
337   for (const auto *Arg : Args)
338     if (Arg->getOption().matches(options::OPT_fsanitize_skip_hot_cutoff_EQ)) {
339       Arg->claim();
340       parseArgCutoffs(D, Arg, DiagnoseErrors, Cutoffs);
341     }
342 
343   return Cutoffs;
344 }
345 
346 bool SanitizerArgs::needsFuzzerInterceptors() const {
347   return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt();
348 }
349 
350 bool SanitizerArgs::needsUbsanRt() const {
351   // All of these include ubsan.
352   if (needsAsanRt() || needsMsanRt() || needsNsanRt() || needsHwasanRt() ||
353       needsTsanRt() || needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
354       (needsScudoRt() && !requiresMinimalRuntime()))
355     return false;
356 
357   return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
358          CoverageFeatures;
359 }
360 
361 bool SanitizerArgs::needsUbsanCXXRt() const {
362   // Link UBSAN C++ runtime very selectively, as it's needed in only very
363   // specific cases, but forces the program to depend on C++ ABI. UBSAN C++
364   // runtime is not included with other sanitizers.
365   return static_cast<bool>(Sanitizers.Mask & NeedsUbsanCxxRt &
366                            ~TrapSanitizers.Mask);
367 }
368 
369 bool SanitizerArgs::needsCfiRt() const {
370   return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
371          CfiCrossDso && !ImplicitCfiRuntime;
372 }
373 
374 bool SanitizerArgs::needsCfiDiagRt() const {
375   return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
376          CfiCrossDso && !ImplicitCfiRuntime;
377 }
378 
379 bool SanitizerArgs::requiresPIE() const { return NeedPIE; }
380 
381 bool SanitizerArgs::needsUnwindTables() const {
382   return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
383 }
384 
385 bool SanitizerArgs::needsLTO() const {
386   return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
387 }
388 
389 SanitizerArgs::SanitizerArgs(const ToolChain &TC,
390                              const llvm::opt::ArgList &Args,
391                              bool DiagnoseErrors) {
392   SanitizerMask AllRemove;      // During the loop below, the accumulated set of
393                                 // sanitizers disabled by the current sanitizer
394                                 // argument or any argument after it.
395   SanitizerMask AllAddedKinds;  // Mask of all sanitizers ever enabled by
396                                 // -fsanitize= flags (directly or via group
397                                 // expansion), some of which may be disabled
398                                 // later. Used to carefully prune
399                                 // unused-argument diagnostics.
400   SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now.
401                                 // Used to deduplicate diagnostics.
402   SanitizerMask Kinds;
403   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
404 
405   CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
406                              options::OPT_fno_sanitize_cfi_cross_dso, false);
407 
408   ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
409 
410   const Driver &D = TC.getDriver();
411   SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args, DiagnoseErrors);
412   SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
413 
414   MinimalRuntime =
415       Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
416                    options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
417 
418   // The object size sanitizer should not be enabled at -O0.
419   Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
420   bool RemoveObjectSizeAtO0 =
421       !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
422 
423   for (const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
424     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
425       Arg->claim();
426       SanitizerMask Add = parseArgValues(D, Arg, DiagnoseErrors);
427 
428       if (RemoveObjectSizeAtO0) {
429         AllRemove |= SanitizerKind::ObjectSize;
430 
431         // The user explicitly enabled the object size sanitizer. Warn
432         // that this does nothing at -O0.
433         if ((Add & SanitizerKind::ObjectSize) && DiagnoseErrors)
434           D.Diag(diag::warn_drv_object_size_disabled_O0)
435               << Arg->getAsString(Args);
436       }
437 
438       AllAddedKinds |= expandSanitizerGroups(Add);
439 
440       // Avoid diagnosing any sanitizer which is disabled later.
441       Add &= ~AllRemove;
442       // At this point we have not expanded groups, so any unsupported
443       // sanitizers in Add are those which have been explicitly enabled.
444       // Diagnose them.
445       if (SanitizerMask KindsToDiagnose =
446               Add & InvalidTrappingKinds & ~DiagnosedKinds) {
447         if (DiagnoseErrors) {
448           std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
449           D.Diag(diag::err_drv_argument_not_allowed_with)
450               << Desc << "-fsanitize-trap=undefined";
451         }
452         DiagnosedKinds |= KindsToDiagnose;
453       }
454       Add &= ~InvalidTrappingKinds;
455 
456       if (MinimalRuntime) {
457         if (SanitizerMask KindsToDiagnose =
458                 Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
459           if (DiagnoseErrors) {
460             std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
461             D.Diag(diag::err_drv_argument_not_allowed_with)
462                 << Desc << "-fsanitize-minimal-runtime";
463           }
464           DiagnosedKinds |= KindsToDiagnose;
465         }
466         Add &= ~NotAllowedWithMinimalRuntime;
467       }
468 
469       if (llvm::opt::Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
470         StringRef CM = A->getValue();
471         if (CM != "small" &&
472             (Add & SanitizerKind::Function & ~DiagnosedKinds)) {
473           if (DiagnoseErrors)
474             D.Diag(diag::err_drv_argument_only_allowed_with)
475                 << "-fsanitize=function"
476                 << "-mcmodel=small";
477           Add &= ~SanitizerKind::Function;
478           DiagnosedKinds |= SanitizerKind::Function;
479         }
480       }
481       // -fsanitize=function and -fsanitize=kcfi instrument indirect function
482       // calls to load a type hash before the function label. Therefore, an
483       // execute-only target doesn't support the function and kcfi sanitizers.
484       const llvm::Triple &Triple = TC.getTriple();
485       if (isExecuteOnlyTarget(Triple, Args)) {
486         if (SanitizerMask KindsToDiagnose =
487                 Add & NotAllowedWithExecuteOnly & ~DiagnosedKinds) {
488           if (DiagnoseErrors) {
489             std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
490             llvm::opt::Arg *A = Args.getLastArgNoClaim(
491                 options::OPT_mexecute_only, options::OPT_mno_execute_only);
492             if (A && A->getOption().matches(options::OPT_mexecute_only))
493               D.Diag(diag::err_drv_argument_not_allowed_with)
494                   << Desc << A->getAsString(Args);
495             else
496               D.Diag(diag::err_drv_unsupported_opt_for_target)
497                   << Desc << Triple.str();
498           }
499           DiagnosedKinds |= KindsToDiagnose;
500         }
501         Add &= ~NotAllowedWithExecuteOnly;
502       }
503 
504       // FIXME: Make CFI on member function calls compatible with cross-DSO CFI.
505       // There are currently two problems:
506       // - Virtual function call checks need to pass a pointer to the function
507       //   address to llvm.type.test and a pointer to the address point to the
508       //   diagnostic function. Currently we pass the same pointer to both
509       //   places.
510       // - Non-virtual function call checks may need to check multiple type
511       //   identifiers.
512       // Fixing both of those may require changes to the cross-DSO CFI
513       // interface.
514       if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
515         if (DiagnoseErrors)
516           D.Diag(diag::err_drv_argument_not_allowed_with)
517               << "-fsanitize=cfi-mfcall"
518               << "-fsanitize-cfi-cross-dso";
519         Add &= ~SanitizerKind::CFIMFCall;
520         DiagnosedKinds |= SanitizerKind::CFIMFCall;
521       }
522 
523       if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
524         if (DiagnoseErrors) {
525           std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose);
526           D.Diag(diag::err_drv_unsupported_opt_for_target)
527               << Desc << TC.getTriple().str();
528         }
529         DiagnosedKinds |= KindsToDiagnose;
530       }
531       Add &= Supported;
532 
533       // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
534       // so we don't error out if -fno-rtti and -fsanitize=undefined were
535       // passed.
536       if ((Add & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
537         if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) {
538           assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
539                  "RTTI disabled without -fno-rtti option?");
540           // The user explicitly passed -fno-rtti with -fsanitize=vptr, but
541           // the vptr sanitizer requires RTTI, so this is a user error.
542           if (DiagnoseErrors)
543             D.Diag(diag::err_drv_argument_not_allowed_with)
544                 << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
545         } else {
546           // The vptr sanitizer requires RTTI, but RTTI is disabled (by
547           // default). Warn that the vptr sanitizer is being disabled.
548           if (DiagnoseErrors)
549             D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
550         }
551 
552         // Take out the Vptr sanitizer from the enabled sanitizers
553         AllRemove |= SanitizerKind::Vptr;
554       }
555 
556       Add = expandSanitizerGroups(Add);
557       // Group expansion may have enabled a sanitizer which is disabled later.
558       Add &= ~AllRemove;
559       // Silently discard any unsupported sanitizers implicitly enabled through
560       // group expansion.
561       Add &= ~InvalidTrappingKinds;
562       if (MinimalRuntime) {
563         Add &= ~NotAllowedWithMinimalRuntime;
564       }
565       // NotAllowedWithExecuteOnly is silently discarded on an execute-only
566       // target if implicitly enabled through group expansion.
567       if (isExecuteOnlyTarget(Triple, Args))
568         Add &= ~NotAllowedWithExecuteOnly;
569       if (CfiCrossDso)
570         Add &= ~SanitizerKind::CFIMFCall;
571       // -fsanitize=undefined does not expand to signed-integer-overflow in
572       // -fwrapv (implied by -fno-strict-overflow) mode.
573       if (Add & SanitizerKind::UndefinedGroup) {
574         bool S = Args.hasFlagNoClaim(options::OPT_fno_strict_overflow,
575                                      options::OPT_fstrict_overflow, false);
576         if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S))
577           Add &= ~SanitizerKind::SignedIntegerOverflow;
578         if (Args.hasFlagNoClaim(options::OPT_fwrapv_pointer,
579                                 options::OPT_fno_wrapv_pointer, S))
580           Add &= ~SanitizerKind::PointerOverflow;
581       }
582       Add &= Supported;
583 
584       if (Add & SanitizerKind::Fuzzer)
585         Add |= SanitizerKind::FuzzerNoLink;
586 
587       // Enable coverage if the fuzzing flag is set.
588       if (Add & SanitizerKind::FuzzerNoLink) {
589         CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall |
590                             CoverageTraceCmp | CoveragePCTable;
591         // Due to TLS differences, stack depth tracking is only enabled on Linux
592         if (TC.getTriple().isOSLinux())
593           CoverageFeatures |= CoverageStackDepth;
594       }
595 
596       Kinds |= Add;
597     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
598       Arg->claim();
599       SanitizerMask Remove = parseArgValues(D, Arg, DiagnoseErrors);
600       AllRemove |= expandSanitizerGroups(Remove);
601     }
602   }
603 
604   std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
605       std::make_pair(SanitizerKind::Address,
606                      SanitizerKind::Thread | SanitizerKind::Memory),
607       std::make_pair(SanitizerKind::Type,
608                      SanitizerKind::Address | SanitizerKind::KernelAddress |
609                          SanitizerKind::Memory | SanitizerKind::Leak |
610                          SanitizerKind::Thread | SanitizerKind::KernelAddress),
611       std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
612       std::make_pair(SanitizerKind::Leak,
613                      SanitizerKind::Thread | SanitizerKind::Memory),
614       std::make_pair(SanitizerKind::KernelAddress,
615                      SanitizerKind::Address | SanitizerKind::Leak |
616                          SanitizerKind::Thread | SanitizerKind::Memory),
617       std::make_pair(SanitizerKind::HWAddress,
618                      SanitizerKind::Address | SanitizerKind::Thread |
619                          SanitizerKind::Memory | SanitizerKind::KernelAddress),
620       std::make_pair(SanitizerKind::Scudo,
621                      SanitizerKind::Address | SanitizerKind::HWAddress |
622                          SanitizerKind::Leak | SanitizerKind::Thread |
623                          SanitizerKind::Memory | SanitizerKind::KernelAddress),
624       std::make_pair(SanitizerKind::SafeStack,
625                      (TC.getTriple().isOSFuchsia() ? SanitizerMask()
626                                                    : SanitizerKind::Leak) |
627                          SanitizerKind::Address | SanitizerKind::HWAddress |
628                          SanitizerKind::Thread | SanitizerKind::Memory |
629                          SanitizerKind::KernelAddress),
630       std::make_pair(SanitizerKind::KernelHWAddress,
631                      SanitizerKind::Address | SanitizerKind::HWAddress |
632                          SanitizerKind::Leak | SanitizerKind::Thread |
633                          SanitizerKind::Memory | SanitizerKind::KernelAddress |
634                          SanitizerKind::SafeStack),
635       std::make_pair(SanitizerKind::KernelMemory,
636                      SanitizerKind::Address | SanitizerKind::HWAddress |
637                          SanitizerKind::Leak | SanitizerKind::Thread |
638                          SanitizerKind::Memory | SanitizerKind::KernelAddress |
639                          SanitizerKind::Scudo | SanitizerKind::SafeStack),
640       std::make_pair(SanitizerKind::MemTag, SanitizerKind::Address |
641                                                 SanitizerKind::KernelAddress |
642                                                 SanitizerKind::HWAddress |
643                                                 SanitizerKind::KernelHWAddress),
644       std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function),
645       std::make_pair(SanitizerKind::Realtime,
646                      SanitizerKind::Address | SanitizerKind::Thread |
647                          SanitizerKind::Undefined | SanitizerKind::Memory)};
648 
649   // Enable toolchain specific default sanitizers if not explicitly disabled.
650   SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
651 
652   // Disable default sanitizers that are incompatible with explicitly requested
653   // ones.
654   for (auto G : IncompatibleGroups) {
655     SanitizerMask Group = G.first;
656     if ((Default & Group) && (Kinds & G.second))
657       Default &= ~Group;
658   }
659 
660   Kinds |= Default;
661 
662   // We disable the vptr sanitizer if it was enabled by group expansion but RTTI
663   // is disabled.
664   if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
665     Kinds &= ~SanitizerKind::Vptr;
666   }
667 
668   // Check that LTO is enabled if we need it.
669   if ((Kinds & NeedsLTO) && !D.isUsingLTO() && DiagnoseErrors) {
670     D.Diag(diag::err_drv_argument_only_allowed_with)
671         << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
672   }
673 
674   if ((Kinds & SanitizerKind::ShadowCallStack) && TC.getTriple().isAArch64() &&
675       !llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) &&
676       !Args.hasArg(options::OPT_ffixed_x18) && DiagnoseErrors) {
677     D.Diag(diag::err_drv_argument_only_allowed_with)
678         << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack)
679         << "-ffixed-x18";
680   }
681 
682   // Report error if there are non-trapping sanitizers that require
683   // c++abi-specific  parts of UBSan runtime, and they are not provided by the
684   // toolchain. We don't have a good way to check the latter, so we just
685   // check if the toolchan supports vptr.
686   if (~Supported & SanitizerKind::Vptr) {
687     SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
688     // The runtime library supports the Microsoft C++ ABI, but only well enough
689     // for CFI. FIXME: Remove this once we support vptr on Windows.
690     if (TC.getTriple().isOSWindows())
691       KindsToDiagnose &= ~SanitizerKind::CFI;
692     if (KindsToDiagnose) {
693       SanitizerSet S;
694       S.Mask = KindsToDiagnose;
695       if (DiagnoseErrors)
696         D.Diag(diag::err_drv_unsupported_opt_for_target)
697             << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str();
698       Kinds &= ~KindsToDiagnose;
699     }
700   }
701 
702   // Warn about incompatible groups of sanitizers.
703   for (auto G : IncompatibleGroups) {
704     SanitizerMask Group = G.first;
705     if (Kinds & Group) {
706       if (SanitizerMask Incompatible = Kinds & G.second) {
707         if (DiagnoseErrors)
708           D.Diag(clang::diag::err_drv_argument_not_allowed_with)
709               << lastArgumentForMask(D, Args, Group)
710               << lastArgumentForMask(D, Args, Incompatible);
711         Kinds &= ~Incompatible;
712       }
713     }
714   }
715   // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
716   // -fsanitize=address. Perhaps it should print an error, or perhaps
717   // -f(-no)sanitize=leak should change whether leak detection is enabled by
718   // default in ASan?
719 
720   // Parse -f(no-)?sanitize-recover flags.
721   SanitizerMask RecoverableKinds = parseSanitizeArgs(
722       D, Args, DiagnoseErrors, RecoverableByDefault, AlwaysRecoverable,
723       Unrecoverable, options::OPT_fsanitize_recover_EQ,
724       options::OPT_fno_sanitize_recover_EQ);
725   RecoverableKinds |= AlwaysRecoverable;
726   RecoverableKinds &= ~Unrecoverable;
727   RecoverableKinds &= Kinds;
728 
729   TrappingKinds &= Kinds;
730   RecoverableKinds &= ~TrappingKinds;
731 
732   // Parse -f(no-)?sanitize-nonmerged-handlers flags
733   SanitizerMask MergeKinds =
734       parseSanitizeArgs(D, Args, DiagnoseErrors, MergeDefault, {}, {},
735                         options::OPT_fsanitize_merge_handlers_EQ,
736                         options::OPT_fno_sanitize_merge_handlers_EQ);
737   MergeKinds &= Kinds;
738 
739   // Parse -fno-sanitize-top-hot flags
740   SkipHotCutoffs = parseSanitizeSkipHotCutoffArgs(D, Args, DiagnoseErrors);
741 
742   // Setup ignorelist files.
743   // Add default ignorelist from resource directory for activated sanitizers,
744   // and validate special case lists format.
745   if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_ignorelist))
746     addDefaultIgnorelists(D, Kinds, SystemIgnorelistFiles, DiagnoseErrors);
747 
748   // Parse -f(no-)?sanitize-ignorelist options.
749   // This also validates special case lists format.
750   parseSpecialCaseListArg(
751       D, Args, UserIgnorelistFiles, options::OPT_fsanitize_ignorelist_EQ,
752       options::OPT_fno_sanitize_ignorelist,
753       clang::diag::err_drv_malformed_sanitizer_ignorelist, DiagnoseErrors);
754 
755   // Parse -f[no-]sanitize-memory-track-origins[=level] options.
756   if (AllAddedKinds & SanitizerKind::Memory) {
757     if (Arg *A =
758             Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
759                             options::OPT_fno_sanitize_memory_track_origins)) {
760       if (!A->getOption().matches(
761               options::OPT_fno_sanitize_memory_track_origins)) {
762         StringRef S = A->getValue();
763         if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
764             MsanTrackOrigins > 2) {
765           if (DiagnoseErrors)
766             D.Diag(clang::diag::err_drv_invalid_value)
767                 << A->getAsString(Args) << S;
768         }
769       }
770     }
771     MsanUseAfterDtor = Args.hasFlag(
772         options::OPT_fsanitize_memory_use_after_dtor,
773         options::OPT_fno_sanitize_memory_use_after_dtor, MsanUseAfterDtor);
774     MsanParamRetval = Args.hasFlag(
775         options::OPT_fsanitize_memory_param_retval,
776         options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
777   } else if (AllAddedKinds & SanitizerKind::KernelMemory) {
778     MsanUseAfterDtor = false;
779     MsanParamRetval = Args.hasFlag(
780         options::OPT_fsanitize_memory_param_retval,
781         options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
782   } else {
783     MsanUseAfterDtor = false;
784     MsanParamRetval = false;
785   }
786 
787   if (AllAddedKinds & SanitizerKind::MemTag) {
788     StringRef S =
789         Args.getLastArgValue(options::OPT_fsanitize_memtag_mode_EQ, "sync");
790     if (S == "async" || S == "sync") {
791       MemtagMode = S.str();
792     } else {
793       D.Diag(clang::diag::err_drv_invalid_value_with_suggestion)
794           << "-fsanitize-memtag-mode=" << S << "{async, sync}";
795       MemtagMode = "sync";
796     }
797   }
798 
799   if (AllAddedKinds & SanitizerKind::Thread) {
800     TsanMemoryAccess = Args.hasFlag(
801         options::OPT_fsanitize_thread_memory_access,
802         options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
803     TsanFuncEntryExit = Args.hasFlag(
804         options::OPT_fsanitize_thread_func_entry_exit,
805         options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
806     TsanAtomics =
807         Args.hasFlag(options::OPT_fsanitize_thread_atomics,
808                      options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
809   }
810 
811   if (AllAddedKinds & SanitizerKind::CFI) {
812     // Without PIE, external function address may resolve to a PLT record, which
813     // can not be verified by the target module.
814     NeedPIE |= CfiCrossDso;
815     CfiICallGeneralizePointers =
816         Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
817 
818     CfiICallNormalizeIntegers =
819         Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
820 
821     if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors)
822       D.Diag(diag::err_drv_argument_not_allowed_with)
823           << "-fsanitize-cfi-cross-dso"
824           << "-fsanitize-cfi-icall-generalize-pointers";
825 
826     CfiCanonicalJumpTables =
827         Args.hasFlag(options::OPT_fsanitize_cfi_canonical_jump_tables,
828                      options::OPT_fno_sanitize_cfi_canonical_jump_tables, true);
829   }
830 
831   if (AllAddedKinds & SanitizerKind::KCFI) {
832     CfiICallNormalizeIntegers =
833         Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
834 
835     if (AllAddedKinds & SanitizerKind::CFI && DiagnoseErrors)
836       D.Diag(diag::err_drv_argument_not_allowed_with)
837           << "-fsanitize=kcfi"
838           << lastArgumentForMask(D, Args, SanitizerKind::CFI);
839   }
840 
841   Stats = Args.hasFlag(options::OPT_fsanitize_stats,
842                        options::OPT_fno_sanitize_stats, false);
843 
844   if (MinimalRuntime) {
845     SanitizerMask IncompatibleMask =
846         Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
847     if (IncompatibleMask && DiagnoseErrors)
848       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
849           << "-fsanitize-minimal-runtime"
850           << lastArgumentForMask(D, Args, IncompatibleMask);
851 
852     SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
853     if (NonTrappingCfi && DiagnoseErrors)
854       D.Diag(clang::diag::err_drv_argument_only_allowed_with)
855           << "fsanitize-minimal-runtime"
856           << "fsanitize-trap=cfi";
857   }
858 
859   for (const auto *Arg : Args.filtered(
860            options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
861     Arg->claim();
862     OverflowPatternExclusions |=
863         parseOverflowPatternExclusionValues(D, Arg, DiagnoseErrors);
864   }
865 
866   // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
867   // enabled sanitizers.
868   for (const auto *Arg : Args) {
869     if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
870       int LegacySanitizeCoverage;
871       if (Arg->getNumValues() == 1 &&
872           !StringRef(Arg->getValue(0))
873                .getAsInteger(0, LegacySanitizeCoverage)) {
874         CoverageFeatures = 0;
875         Arg->claim();
876         if (LegacySanitizeCoverage != 0 && DiagnoseErrors) {
877           D.Diag(diag::warn_drv_deprecated_arg)
878               << Arg->getAsString(Args) << /*hasReplacement=*/true
879               << "-fsanitize-coverage=trace-pc-guard";
880         }
881         continue;
882       }
883       CoverageFeatures |= parseCoverageFeatures(D, Arg, DiagnoseErrors);
884 
885       // Disable coverage and not claim the flags if there is at least one
886       // non-supporting sanitizer.
887       if (!(AllAddedKinds & ~AllRemove & ~setGroupBits(SupportsCoverage))) {
888         Arg->claim();
889       } else {
890         CoverageFeatures = 0;
891       }
892     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
893       Arg->claim();
894       CoverageFeatures &= ~parseCoverageFeatures(D, Arg, DiagnoseErrors);
895     }
896   }
897   // Choose at most one coverage type: function, bb, or edge.
898   if (DiagnoseErrors) {
899     if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageBB))
900       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
901           << "-fsanitize-coverage=func"
902           << "-fsanitize-coverage=bb";
903     if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageEdge))
904       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
905           << "-fsanitize-coverage=func"
906           << "-fsanitize-coverage=edge";
907     if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
908       D.Diag(clang::diag::err_drv_argument_not_allowed_with)
909           << "-fsanitize-coverage=bb"
910           << "-fsanitize-coverage=edge";
911     // Basic block tracing and 8-bit counters require some type of coverage
912     // enabled.
913     if (CoverageFeatures & CoverageTraceBB)
914       D.Diag(clang::diag::warn_drv_deprecated_arg)
915           << "-fsanitize-coverage=trace-bb" << /*hasReplacement=*/true
916           << "-fsanitize-coverage=trace-pc-guard";
917     if (CoverageFeatures & Coverage8bitCounters)
918       D.Diag(clang::diag::warn_drv_deprecated_arg)
919           << "-fsanitize-coverage=8bit-counters" << /*hasReplacement=*/true
920           << "-fsanitize-coverage=trace-pc-guard";
921   }
922 
923   int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
924   int InstrumentationTypes = CoverageTracePC | CoverageTracePCGuard |
925                              CoverageInline8bitCounters | CoverageTraceLoads |
926                              CoverageTraceStores | CoverageInlineBoolFlag |
927                              CoverageControlFlow;
928   if ((CoverageFeatures & InsertionPointTypes) &&
929       !(CoverageFeatures & InstrumentationTypes) && DiagnoseErrors) {
930     D.Diag(clang::diag::warn_drv_deprecated_arg)
931         << "-fsanitize-coverage=[func|bb|edge]" << /*hasReplacement=*/true
932         << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc],["
933            "control-flow]";
934   }
935 
936   // trace-pc w/o func/bb/edge implies edge.
937   if (!(CoverageFeatures & InsertionPointTypes)) {
938     if (CoverageFeatures &
939         (CoverageTracePC | CoverageTracePCGuard | CoverageInline8bitCounters |
940          CoverageInlineBoolFlag | CoverageControlFlow))
941       CoverageFeatures |= CoverageEdge;
942 
943     if (CoverageFeatures & CoverageStackDepth)
944       CoverageFeatures |= CoverageFunc;
945   }
946 
947   // Parse -fsanitize-coverage-(allow|ignore)list options if coverage enabled.
948   // This also validates special case lists format.
949   // Here, OptSpecifier() acts as a never-matching command-line argument.
950   // So, there is no way to clear coverage lists but you can append to them.
951   if (CoverageFeatures) {
952     parseSpecialCaseListArg(
953         D, Args, CoverageAllowlistFiles,
954         options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
955         clang::diag::err_drv_malformed_sanitizer_coverage_allowlist,
956         DiagnoseErrors);
957     parseSpecialCaseListArg(
958         D, Args, CoverageIgnorelistFiles,
959         options::OPT_fsanitize_coverage_ignorelist, OptSpecifier(),
960         clang::diag::err_drv_malformed_sanitizer_coverage_ignorelist,
961         DiagnoseErrors);
962   }
963 
964   // Parse -f(no-)?sanitize-metadata.
965   for (const auto *Arg :
966        Args.filtered(options::OPT_fexperimental_sanitize_metadata_EQ,
967                      options::OPT_fno_experimental_sanitize_metadata_EQ)) {
968     if (Arg->getOption().matches(
969             options::OPT_fexperimental_sanitize_metadata_EQ)) {
970       Arg->claim();
971       BinaryMetadataFeatures |=
972           parseBinaryMetadataFeatures(D, Arg, DiagnoseErrors);
973     } else {
974       Arg->claim();
975       BinaryMetadataFeatures &=
976           ~parseBinaryMetadataFeatures(D, Arg, DiagnoseErrors);
977     }
978   }
979 
980   // Parse -fsanitize-metadata-ignorelist option if enabled.
981   if (BinaryMetadataFeatures) {
982     parseSpecialCaseListArg(
983         D, Args, BinaryMetadataIgnorelistFiles,
984         options::OPT_fexperimental_sanitize_metadata_ignorelist_EQ,
985         OptSpecifier(), // Cannot clear ignore list, only append.
986         clang::diag::err_drv_malformed_sanitizer_metadata_ignorelist,
987         DiagnoseErrors);
988   }
989 
990   SharedRuntime = Args.hasFlag(
991       options::OPT_shared_libsan, options::OPT_static_libsan,
992       TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
993           TC.getTriple().isOSDarwin() || TC.getTriple().isOSWindows());
994   if (!SharedRuntime && TC.getTriple().isOSWindows()) {
995     Arg *A =
996         Args.getLastArg(options::OPT_shared_libsan, options::OPT_static_libsan);
997     D.Diag(clang::diag::err_drv_unsupported_opt_for_target)
998         << A->getSpelling() << TC.getTriple().str();
999   }
1000 
1001   ImplicitCfiRuntime = TC.getTriple().isAndroid();
1002 
1003   if (AllAddedKinds & SanitizerKind::Address) {
1004     NeedPIE |= TC.getTriple().isOSFuchsia();
1005     if (Arg *A =
1006             Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
1007       StringRef S = A->getValue();
1008       // Legal values are 0 and 1, 2, but in future we may add more levels.
1009       if ((S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
1010            AsanFieldPadding > 2) &&
1011           DiagnoseErrors) {
1012         D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
1013       }
1014     }
1015 
1016     if (Arg *WindowsDebugRTArg =
1017             Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
1018                             options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
1019                             options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
1020       switch (WindowsDebugRTArg->getOption().getID()) {
1021       case options::OPT__SLASH_MTd:
1022       case options::OPT__SLASH_MDd:
1023       case options::OPT__SLASH_LDd:
1024         if (DiagnoseErrors) {
1025           D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1026               << WindowsDebugRTArg->getAsString(Args)
1027               << lastArgumentForMask(D, Args, SanitizerKind::Address);
1028           D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
1029         }
1030       }
1031     }
1032 
1033     StableABI = Args.hasFlag(options::OPT_fsanitize_stable_abi,
1034                              options::OPT_fno_sanitize_stable_abi, false);
1035 
1036     AsanUseAfterScope = Args.hasFlag(
1037         options::OPT_fsanitize_address_use_after_scope,
1038         options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
1039 
1040     AsanPoisonCustomArrayCookie = Args.hasFlag(
1041         options::OPT_fsanitize_address_poison_custom_array_cookie,
1042         options::OPT_fno_sanitize_address_poison_custom_array_cookie,
1043         AsanPoisonCustomArrayCookie);
1044 
1045     AsanOutlineInstrumentation =
1046         Args.hasFlag(options::OPT_fsanitize_address_outline_instrumentation,
1047                      options::OPT_fno_sanitize_address_outline_instrumentation,
1048                      AsanOutlineInstrumentation);
1049 
1050     AsanGlobalsDeadStripping = Args.hasFlag(
1051         options::OPT_fsanitize_address_globals_dead_stripping,
1052         options::OPT_fno_sanitize_address_globals_dead_stripping, true);
1053 
1054     // Enable ODR indicators which allow better handling of mixed instrumented
1055     // and uninstrumented globals. Disable them for Windows where weak odr
1056     // indicators (.weak.__odr_asan_gen*) may cause multiple definition linker
1057     // errors in the absence of -lldmingw.
1058     AsanUseOdrIndicator =
1059         Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
1060                      options::OPT_fno_sanitize_address_use_odr_indicator,
1061                      !TC.getTriple().isOSWindows());
1062 
1063     if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
1064       AsanInvalidPointerCmp = true;
1065     }
1066 
1067     if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
1068       AsanInvalidPointerSub = true;
1069     }
1070 
1071     if (TC.getTriple().isOSDarwin() &&
1072         (Args.hasArg(options::OPT_mkernel) ||
1073          Args.hasArg(options::OPT_fapple_kext))) {
1074       AsanDtorKind = llvm::AsanDtorKind::None;
1075     }
1076 
1077     if (const auto *Arg =
1078             Args.getLastArg(options::OPT_sanitize_address_destructor_EQ)) {
1079       auto parsedAsanDtorKind = AsanDtorKindFromString(Arg->getValue());
1080       if (parsedAsanDtorKind == llvm::AsanDtorKind::Invalid && DiagnoseErrors) {
1081         TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
1082             << Arg->getSpelling() << Arg->getValue();
1083       }
1084       AsanDtorKind = parsedAsanDtorKind;
1085     }
1086 
1087     if (const auto *Arg = Args.getLastArg(
1088             options::OPT_sanitize_address_use_after_return_EQ)) {
1089       auto parsedAsanUseAfterReturn =
1090           AsanDetectStackUseAfterReturnModeFromString(Arg->getValue());
1091       if (parsedAsanUseAfterReturn ==
1092               llvm::AsanDetectStackUseAfterReturnMode::Invalid &&
1093           DiagnoseErrors) {
1094         TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
1095             << Arg->getSpelling() << Arg->getValue();
1096       }
1097       AsanUseAfterReturn = parsedAsanUseAfterReturn;
1098     }
1099 
1100   } else {
1101     AsanUseAfterScope = false;
1102     // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
1103     SanitizerMask DetectInvalidPointerPairs =
1104         SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
1105     if ((AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) &&
1106         DiagnoseErrors) {
1107       TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
1108           << lastArgumentForMask(D, Args,
1109                                  SanitizerKind::PointerCompare |
1110                                      SanitizerKind::PointerSubtract)
1111           << "-fsanitize=address";
1112     }
1113   }
1114 
1115   if (AllAddedKinds & SanitizerKind::HWAddress) {
1116     if (Arg *HwasanAbiArg =
1117             Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
1118       HwasanAbi = HwasanAbiArg->getValue();
1119       if (HwasanAbi != "platform" && HwasanAbi != "interceptor" &&
1120           DiagnoseErrors)
1121         D.Diag(clang::diag::err_drv_invalid_value)
1122             << HwasanAbiArg->getAsString(Args) << HwasanAbi;
1123     } else {
1124       HwasanAbi = "interceptor";
1125     }
1126     if (TC.getTriple().getArch() == llvm::Triple::x86_64)
1127       HwasanUseAliases = Args.hasFlag(
1128           options::OPT_fsanitize_hwaddress_experimental_aliasing,
1129           options::OPT_fno_sanitize_hwaddress_experimental_aliasing,
1130           HwasanUseAliases);
1131   }
1132 
1133   if (AllAddedKinds & SanitizerKind::SafeStack) {
1134     // SafeStack runtime is built into the system on Android and Fuchsia.
1135     SafeStackRuntime =
1136         !TC.getTriple().isAndroid() && !TC.getTriple().isOSFuchsia();
1137   }
1138 
1139   LinkRuntimes =
1140       Args.hasFlag(options::OPT_fsanitize_link_runtime,
1141                    options::OPT_fno_sanitize_link_runtime, LinkRuntimes);
1142 
1143   // Parse -link-cxx-sanitizer flag.
1144   LinkCXXRuntimes = D.CCCIsCXX();
1145   LinkCXXRuntimes =
1146       Args.hasFlag(options::OPT_fsanitize_link_cxx_runtime,
1147                    options::OPT_fno_sanitize_link_cxx_runtime, LinkCXXRuntimes);
1148 
1149   NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile,
1150                                 options::OPT_fmemory_profile_EQ,
1151                                 options::OPT_fno_memory_profile, false);
1152 
1153   // Finally, initialize the set of available and recoverable sanitizers.
1154   Sanitizers.Mask |= Kinds;
1155   RecoverableSanitizers.Mask |= RecoverableKinds;
1156   TrapSanitizers.Mask |= TrappingKinds;
1157   assert(!(RecoverableKinds & TrappingKinds) &&
1158          "Overlap between recoverable and trapping sanitizers");
1159 
1160   MergeHandlers.Mask |= MergeKinds;
1161 
1162   // Zero out SkipHotCutoffs for unused sanitizers
1163   SkipHotCutoffs.clear(~Sanitizers.Mask);
1164 }
1165 
1166 static std::string toString(const clang::SanitizerSet &Sanitizers) {
1167   std::string Res;
1168 #define SANITIZER(NAME, ID)                                                    \
1169   if (Sanitizers.has(SanitizerKind::ID)) {                                     \
1170     if (!Res.empty())                                                          \
1171       Res += ",";                                                              \
1172     Res += NAME;                                                               \
1173   }
1174 #include "clang/Basic/Sanitizers.def"
1175   return Res;
1176 }
1177 
1178 static std::string toString(const clang::SanitizerMaskCutoffs &Cutoffs) {
1179   llvm::SmallVector<std::string, 4> Res;
1180   serializeSanitizerMaskCutoffs(Cutoffs, Res);
1181   return llvm::join(Res, ",");
1182 }
1183 
1184 static void addSpecialCaseListOpt(const llvm::opt::ArgList &Args,
1185                                   llvm::opt::ArgStringList &CmdArgs,
1186                                   const char *SCLOptFlag,
1187                                   const std::vector<std::string> &SCLFiles) {
1188   for (const auto &SCLPath : SCLFiles) {
1189     SmallString<64> SCLOpt(SCLOptFlag);
1190     SCLOpt += SCLPath;
1191     CmdArgs.push_back(Args.MakeArgString(SCLOpt));
1192   }
1193 }
1194 
1195 static void addIncludeLinkerOption(const ToolChain &TC,
1196                                    const llvm::opt::ArgList &Args,
1197                                    llvm::opt::ArgStringList &CmdArgs,
1198                                    StringRef SymbolName) {
1199   SmallString<64> LinkerOptionFlag;
1200   LinkerOptionFlag = "--linker-option=/include:";
1201   if (TC.getTriple().getArch() == llvm::Triple::x86) {
1202     // Win32 mangles C function names with a '_' prefix.
1203     LinkerOptionFlag += '_';
1204   }
1205   LinkerOptionFlag += SymbolName;
1206   CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
1207 }
1208 
1209 static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs) {
1210   for (auto Start = CmdArgs.begin(), End = CmdArgs.end(); Start != End;
1211        ++Start) {
1212     auto It = std::find(Start, End, StringRef("+mte"));
1213     if (It == End)
1214       break;
1215     if (It > Start && *std::prev(It) == StringRef("-target-feature"))
1216       return true;
1217     Start = It;
1218   }
1219   return false;
1220 }
1221 
1222 void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
1223                             llvm::opt::ArgStringList &CmdArgs,
1224                             types::ID InputType) const {
1225   // NVPTX doesn't currently support sanitizers.  Bailing out here means
1226   // that e.g. -fsanitize=address applies only to host code, which is what we
1227   // want for now.
1228   if (TC.getTriple().isNVPTX())
1229     return;
1230   // AMDGPU sanitizer support is experimental and controlled by -fgpu-sanitize.
1231   bool GPUSanitize = false;
1232   if (TC.getTriple().isAMDGPU()) {
1233     if (!Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
1234                       true))
1235       return;
1236     GPUSanitize = true;
1237   }
1238 
1239   // Translate available CoverageFeatures to corresponding clang-cc1 flags.
1240   // Do it even if Sanitizers.empty() since some forms of coverage don't require
1241   // sanitizers.
1242   std::pair<int, const char *> CoverageFlags[] = {
1243       std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
1244       std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
1245       std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
1246       std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
1247       std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
1248       std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
1249       std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
1250       std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
1251       std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
1252       std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
1253       std::make_pair(CoverageTracePCGuard,
1254                      "-fsanitize-coverage-trace-pc-guard"),
1255       std::make_pair(CoverageInline8bitCounters,
1256                      "-fsanitize-coverage-inline-8bit-counters"),
1257       std::make_pair(CoverageInlineBoolFlag,
1258                      "-fsanitize-coverage-inline-bool-flag"),
1259       std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
1260       std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
1261       std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth"),
1262       std::make_pair(CoverageTraceLoads, "-fsanitize-coverage-trace-loads"),
1263       std::make_pair(CoverageTraceStores, "-fsanitize-coverage-trace-stores"),
1264       std::make_pair(CoverageControlFlow, "-fsanitize-coverage-control-flow")};
1265   for (auto F : CoverageFlags) {
1266     if (CoverageFeatures & F.first)
1267       CmdArgs.push_back(F.second);
1268   }
1269   addSpecialCaseListOpt(
1270       Args, CmdArgs, "-fsanitize-coverage-allowlist=", CoverageAllowlistFiles);
1271   addSpecialCaseListOpt(Args, CmdArgs, "-fsanitize-coverage-ignorelist=",
1272                         CoverageIgnorelistFiles);
1273 
1274   if (!GPUSanitize) {
1275     // Translate available BinaryMetadataFeatures to corresponding clang-cc1
1276     // flags. Does not depend on any other sanitizers. Unsupported on GPUs.
1277     const std::pair<int, std::string> BinaryMetadataFlags[] = {
1278         std::make_pair(BinaryMetadataCovered, "covered"),
1279         std::make_pair(BinaryMetadataAtomics, "atomics"),
1280         std::make_pair(BinaryMetadataUAR, "uar")};
1281     for (const auto &F : BinaryMetadataFlags) {
1282       if (BinaryMetadataFeatures & F.first)
1283         CmdArgs.push_back(
1284             Args.MakeArgString("-fexperimental-sanitize-metadata=" + F.second));
1285     }
1286     addSpecialCaseListOpt(Args, CmdArgs,
1287                           "-fexperimental-sanitize-metadata-ignorelist=",
1288                           BinaryMetadataIgnorelistFiles);
1289   }
1290 
1291   if (TC.getTriple().isOSWindows() && needsUbsanRt() &&
1292       Args.hasFlag(options::OPT_frtlib_defaultlib,
1293                    options::OPT_fno_rtlib_defaultlib, true)) {
1294     // Instruct the code generator to embed linker directives in the object file
1295     // that cause the required runtime libraries to be linked.
1296     CmdArgs.push_back(
1297         Args.MakeArgString("--dependent-lib=" +
1298                            TC.getCompilerRTBasename(Args, "ubsan_standalone")));
1299     if (types::isCXX(InputType))
1300       CmdArgs.push_back(Args.MakeArgString(
1301           "--dependent-lib=" +
1302           TC.getCompilerRTBasename(Args, "ubsan_standalone_cxx")));
1303   }
1304   if (TC.getTriple().isOSWindows() && needsStatsRt() &&
1305       Args.hasFlag(options::OPT_frtlib_defaultlib,
1306                    options::OPT_fno_rtlib_defaultlib, true)) {
1307     CmdArgs.push_back(Args.MakeArgString(
1308         "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats_client")));
1309 
1310     // The main executable must export the stats runtime.
1311     // FIXME: Only exporting from the main executable (e.g. based on whether the
1312     // translation unit defines main()) would save a little space, but having
1313     // multiple copies of the runtime shouldn't hurt.
1314     CmdArgs.push_back(Args.MakeArgString(
1315         "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats")));
1316     addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
1317   }
1318 
1319   if (Sanitizers.empty())
1320     return;
1321   CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
1322 
1323   if (!RecoverableSanitizers.empty())
1324     CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
1325                                          toString(RecoverableSanitizers)));
1326 
1327   if (!TrapSanitizers.empty())
1328     CmdArgs.push_back(
1329         Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
1330 
1331   if (!MergeHandlers.empty())
1332     CmdArgs.push_back(
1333         Args.MakeArgString("-fsanitize-merge=" + toString(MergeHandlers)));
1334 
1335   std::string SkipHotCutoffsStr = toString(SkipHotCutoffs);
1336   if (!SkipHotCutoffsStr.empty())
1337     CmdArgs.push_back(
1338         Args.MakeArgString("-fsanitize-skip-hot-cutoff=" + SkipHotCutoffsStr));
1339 
1340   addSpecialCaseListOpt(Args, CmdArgs,
1341                         "-fsanitize-ignorelist=", UserIgnorelistFiles);
1342   addSpecialCaseListOpt(Args, CmdArgs,
1343                         "-fsanitize-system-ignorelist=", SystemIgnorelistFiles);
1344 
1345   if (OverflowPatternExclusions)
1346     Args.AddAllArgs(
1347         CmdArgs, options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ);
1348 
1349   if (MsanTrackOrigins)
1350     CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
1351                                          Twine(MsanTrackOrigins)));
1352 
1353   if (MsanUseAfterDtor)
1354     CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
1355 
1356   if (!MsanParamRetval)
1357     CmdArgs.push_back("-fno-sanitize-memory-param-retval");
1358 
1359   // FIXME: Pass these parameters as function attributes, not as -llvm flags.
1360   if (!TsanMemoryAccess) {
1361     CmdArgs.push_back("-mllvm");
1362     CmdArgs.push_back("-tsan-instrument-memory-accesses=0");
1363     CmdArgs.push_back("-mllvm");
1364     CmdArgs.push_back("-tsan-instrument-memintrinsics=0");
1365   }
1366   if (!TsanFuncEntryExit) {
1367     CmdArgs.push_back("-mllvm");
1368     CmdArgs.push_back("-tsan-instrument-func-entry-exit=0");
1369   }
1370   if (!TsanAtomics) {
1371     CmdArgs.push_back("-mllvm");
1372     CmdArgs.push_back("-tsan-instrument-atomics=0");
1373   }
1374 
1375   if (HwasanUseAliases) {
1376     CmdArgs.push_back("-mllvm");
1377     CmdArgs.push_back("-hwasan-experimental-use-page-aliases=1");
1378   }
1379 
1380   if (CfiCrossDso)
1381     CmdArgs.push_back("-fsanitize-cfi-cross-dso");
1382 
1383   if (CfiICallGeneralizePointers)
1384     CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers");
1385 
1386   if (CfiICallNormalizeIntegers)
1387     CmdArgs.push_back("-fsanitize-cfi-icall-experimental-normalize-integers");
1388 
1389   if (CfiCanonicalJumpTables)
1390     CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables");
1391 
1392   if (Stats)
1393     CmdArgs.push_back("-fsanitize-stats");
1394 
1395   if (MinimalRuntime)
1396     CmdArgs.push_back("-fsanitize-minimal-runtime");
1397 
1398   if (AsanFieldPadding)
1399     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
1400                                          Twine(AsanFieldPadding)));
1401 
1402   if (AsanUseAfterScope)
1403     CmdArgs.push_back("-fsanitize-address-use-after-scope");
1404 
1405   if (AsanPoisonCustomArrayCookie)
1406     CmdArgs.push_back("-fsanitize-address-poison-custom-array-cookie");
1407 
1408   if (AsanGlobalsDeadStripping)
1409     CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
1410 
1411   if (!AsanUseOdrIndicator)
1412     CmdArgs.push_back("-fno-sanitize-address-use-odr-indicator");
1413 
1414   if (AsanInvalidPointerCmp) {
1415     CmdArgs.push_back("-mllvm");
1416     CmdArgs.push_back("-asan-detect-invalid-pointer-cmp");
1417   }
1418 
1419   if (AsanInvalidPointerSub) {
1420     CmdArgs.push_back("-mllvm");
1421     CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
1422   }
1423 
1424   if (AsanOutlineInstrumentation) {
1425     CmdArgs.push_back("-mllvm");
1426     CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
1427   }
1428 
1429   // When emitting Stable ABI instrumentation, force outlining calls and avoid
1430   // inlining shadow memory poisoning. While this is a big performance burden
1431   // for now it allows full abstraction from implementation details.
1432   if (StableABI) {
1433     CmdArgs.push_back("-mllvm");
1434     CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
1435     CmdArgs.push_back("-mllvm");
1436     CmdArgs.push_back("-asan-max-inline-poisoning-size=0");
1437     CmdArgs.push_back("-mllvm");
1438     CmdArgs.push_back("-asan-guard-against-version-mismatch=0");
1439   }
1440 
1441   // Only pass the option to the frontend if the user requested,
1442   // otherwise the frontend will just use the codegen default.
1443   if (AsanDtorKind != llvm::AsanDtorKind::Invalid) {
1444     CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-destructor=" +
1445                                          AsanDtorKindToString(AsanDtorKind)));
1446   }
1447 
1448   if (AsanUseAfterReturn != llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
1449     CmdArgs.push_back(Args.MakeArgString(
1450         "-fsanitize-address-use-after-return=" +
1451         AsanDetectStackUseAfterReturnModeToString(AsanUseAfterReturn)));
1452   }
1453 
1454   if (!HwasanAbi.empty()) {
1455     CmdArgs.push_back("-default-function-attr");
1456     CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
1457   }
1458 
1459   if (Sanitizers.has(SanitizerKind::HWAddress) && !HwasanUseAliases) {
1460     CmdArgs.push_back("-target-feature");
1461     CmdArgs.push_back("+tagged-globals");
1462   }
1463 
1464   // MSan: Workaround for PR16386.
1465   // ASan: This is mainly to help LSan with cases such as
1466   // https://github.com/google/sanitizers/issues/373
1467   // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
1468   // affect compilation.
1469   if (Sanitizers.has(SanitizerKind::Memory) ||
1470       Sanitizers.has(SanitizerKind::Address))
1471     CmdArgs.push_back("-fno-assume-sane-operator-new");
1472 
1473   // libFuzzer wants to intercept calls to certain library functions, so the
1474   // following -fno-builtin-* flags force the compiler to emit interposable
1475   // libcalls to these functions. Other sanitizers effectively do the same thing
1476   // by marking all library call sites with NoBuiltin attribute in their LLVM
1477   // pass. (see llvm::maybeMarkSanitizerLibraryCallNoBuiltin)
1478   if (Sanitizers.has(SanitizerKind::FuzzerNoLink)) {
1479     CmdArgs.push_back("-fno-builtin-bcmp");
1480     CmdArgs.push_back("-fno-builtin-memcmp");
1481     CmdArgs.push_back("-fno-builtin-strncmp");
1482     CmdArgs.push_back("-fno-builtin-strcmp");
1483     CmdArgs.push_back("-fno-builtin-strncasecmp");
1484     CmdArgs.push_back("-fno-builtin-strcasecmp");
1485     CmdArgs.push_back("-fno-builtin-strstr");
1486     CmdArgs.push_back("-fno-builtin-strcasestr");
1487     CmdArgs.push_back("-fno-builtin-memmem");
1488   }
1489 
1490   // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
1491   // enabled.
1492   if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
1493       !Args.hasArg(options::OPT_fvisibility_EQ)) {
1494     TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
1495         << lastArgumentForMask(TC.getDriver(), Args,
1496                                Sanitizers.Mask & CFIClasses)
1497         << "-fvisibility=";
1498   }
1499 
1500   if (Sanitizers.has(SanitizerKind::MemtagStack) &&
1501       !hasTargetFeatureMTE(CmdArgs))
1502     TC.getDriver().Diag(diag::err_stack_tagging_requires_hardware_feature);
1503 }
1504 
1505 SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
1506                              bool DiagnoseErrors) {
1507   assert(
1508       (A->getOption().matches(options::OPT_fsanitize_EQ) ||
1509        A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1510        A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1511        A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1512        A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1513        A->getOption().matches(options::OPT_fno_sanitize_trap_EQ) ||
1514        A->getOption().matches(options::OPT_fsanitize_merge_handlers_EQ) ||
1515        A->getOption().matches(options::OPT_fno_sanitize_merge_handlers_EQ)) &&
1516       "Invalid argument in parseArgValues!");
1517   SanitizerMask Kinds;
1518   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1519     const char *Value = A->getValue(i);
1520     SanitizerMask Kind;
1521     // Special case: don't accept -fsanitize=all.
1522     if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
1523         0 == strcmp("all", Value))
1524       Kind = SanitizerMask();
1525     else
1526       Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
1527 
1528     if (Kind)
1529       Kinds |= Kind;
1530     else if (DiagnoseErrors)
1531       D.Diag(clang::diag::err_drv_unsupported_option_argument)
1532           << A->getSpelling() << Value;
1533   }
1534   return Kinds;
1535 }
1536 
1537 void parseArgCutoffs(const Driver &D, const llvm::opt::Arg *A,
1538                      bool DiagnoseErrors, SanitizerMaskCutoffs &Cutoffs) {
1539   assert(A->getOption().matches(options::OPT_fsanitize_skip_hot_cutoff_EQ) &&
1540          "Invalid argument in parseArgCutoffs!");
1541   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1542     const char *Value = A->getValue(i);
1543 
1544     // We don't check the value of Cutoffs[i]: it's legal to specify
1545     // a cutoff of 0.
1546     if (!parseSanitizerWeightedValue(Value, /*AllowGroups=*/true, Cutoffs) &&
1547         DiagnoseErrors)
1548       D.Diag(clang::diag::err_drv_unsupported_option_argument)
1549           << A->getSpelling() << Value;
1550   }
1551 }
1552 
1553 static int parseOverflowPatternExclusionValues(const Driver &D,
1554                                                const llvm::opt::Arg *A,
1555                                                bool DiagnoseErrors) {
1556   int Exclusions = 0;
1557   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1558     const char *Value = A->getValue(i);
1559     int E =
1560         llvm::StringSwitch<int>(Value)
1561             .Case("none", LangOptionsBase::None)
1562             .Case("all", LangOptionsBase::All)
1563             .Case("add-unsigned-overflow-test",
1564                   LangOptionsBase::AddUnsignedOverflowTest)
1565             .Case("add-signed-overflow-test",
1566                   LangOptionsBase::AddSignedOverflowTest)
1567             .Case("negated-unsigned-const", LangOptionsBase::NegUnsignedConst)
1568             .Case("unsigned-post-decr-while", LangOptionsBase::PostDecrInWhile)
1569             .Default(0);
1570     if (E == 0)
1571       D.Diag(clang::diag::err_drv_unsupported_option_argument)
1572           << A->getSpelling() << Value;
1573     Exclusions |= E;
1574   }
1575   return Exclusions;
1576 }
1577 
1578 int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A,
1579                           bool DiagnoseErrors) {
1580   assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
1581          A->getOption().matches(options::OPT_fno_sanitize_coverage));
1582   int Features = 0;
1583   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1584     const char *Value = A->getValue(i);
1585     int F = llvm::StringSwitch<int>(Value)
1586                 .Case("func", CoverageFunc)
1587                 .Case("bb", CoverageBB)
1588                 .Case("edge", CoverageEdge)
1589                 .Case("indirect-calls", CoverageIndirCall)
1590                 .Case("trace-bb", CoverageTraceBB)
1591                 .Case("trace-cmp", CoverageTraceCmp)
1592                 .Case("trace-div", CoverageTraceDiv)
1593                 .Case("trace-gep", CoverageTraceGep)
1594                 .Case("8bit-counters", Coverage8bitCounters)
1595                 .Case("trace-pc", CoverageTracePC)
1596                 .Case("trace-pc-guard", CoverageTracePCGuard)
1597                 .Case("no-prune", CoverageNoPrune)
1598                 .Case("inline-8bit-counters", CoverageInline8bitCounters)
1599                 .Case("inline-bool-flag", CoverageInlineBoolFlag)
1600                 .Case("pc-table", CoveragePCTable)
1601                 .Case("stack-depth", CoverageStackDepth)
1602                 .Case("trace-loads", CoverageTraceLoads)
1603                 .Case("trace-stores", CoverageTraceStores)
1604                 .Case("control-flow", CoverageControlFlow)
1605                 .Default(0);
1606     if (F == 0 && DiagnoseErrors)
1607       D.Diag(clang::diag::err_drv_unsupported_option_argument)
1608           << A->getSpelling() << Value;
1609     Features |= F;
1610   }
1611   return Features;
1612 }
1613 
1614 int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A,
1615                                 bool DiagnoseErrors) {
1616   assert(
1617       A->getOption().matches(options::OPT_fexperimental_sanitize_metadata_EQ) ||
1618       A->getOption().matches(
1619           options::OPT_fno_experimental_sanitize_metadata_EQ));
1620   int Features = 0;
1621   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1622     const char *Value = A->getValue(i);
1623     int F = llvm::StringSwitch<int>(Value)
1624                 .Case("covered", BinaryMetadataCovered)
1625                 .Case("atomics", BinaryMetadataAtomics)
1626                 .Case("uar", BinaryMetadataUAR)
1627                 .Case("all", ~0)
1628                 .Default(0);
1629     if (F == 0 && DiagnoseErrors)
1630       D.Diag(clang::diag::err_drv_unsupported_option_argument)
1631           << A->getSpelling() << Value;
1632     Features |= F;
1633   }
1634   return Features;
1635 }
1636 
1637 std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
1638                                 SanitizerMask Mask) {
1639   for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1640                                                   E = Args.rend();
1641        I != E; ++I) {
1642     const auto *Arg = *I;
1643     if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1644       SanitizerMask AddKinds =
1645           expandSanitizerGroups(parseArgValues(D, Arg, false));
1646       if (AddKinds & Mask)
1647         return describeSanitizeArg(Arg, Mask);
1648     } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1649       SanitizerMask RemoveKinds =
1650           expandSanitizerGroups(parseArgValues(D, Arg, false));
1651       Mask &= ~RemoveKinds;
1652     }
1653   }
1654   llvm_unreachable("arg list didn't provide expected value");
1655 }
1656 
1657 std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
1658   assert(A->getOption().matches(options::OPT_fsanitize_EQ) &&
1659          "Invalid argument in describeSanitizerArg!");
1660 
1661   std::string Sanitizers;
1662   for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1663     if (expandSanitizerGroups(
1664             parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
1665         Mask) {
1666       if (!Sanitizers.empty())
1667         Sanitizers += ",";
1668       Sanitizers += A->getValue(i);
1669     }
1670   }
1671 
1672   assert(!Sanitizers.empty() && "arg didn't provide expected value");
1673   return "-fsanitize=" + Sanitizers;
1674 }
1675