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