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