clang  20.0.0git
SanitizerArgs.cpp
Go to the documentation of this file.
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 //===----------------------------------------------------------------------===//
10 #include "clang/Basic/Sanitizers.h"
11 #include "clang/Driver/Driver.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 
32  SanitizerKind::Undefined | SanitizerKind::Integer |
33  SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
34  SanitizerKind::CFI | SanitizerKind::FloatDivideByZero |
35  SanitizerKind::ObjCCast;
37  SanitizerKind::Vptr | SanitizerKind::CFI;
38 static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
39 static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr;
41  SanitizerKind::Function | SanitizerKind::KCFI;
43  SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread |
44  SanitizerKind::Memory | SanitizerKind::DataFlow |
45  SanitizerKind::NumericalStability;
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;
60  SanitizerKind::Undefined | SanitizerKind::Integer |
61  SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
62  SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
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;
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;
80  TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack |
81  SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap |
82  SanitizerKind::MemtagGlobals | SanitizerKind::KCFI;
83 
85  CoverageFunc = 1 << 0,
86  CoverageBB = 1 << 1,
87  CoverageEdge = 1 << 2,
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,
96  CoverageNoPrune = 1 << 11,
98  CoveragePCTable = 1 << 13,
99  CoverageStackDepth = 1 << 14,
104 };
105 
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.
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 
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 
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 |
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  }
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.
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.
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 
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 
283  return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt();
284 }
285 
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 
298  return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
299  CfiCrossDso && !ImplicitCfiRuntime;
300 }
301 
303  return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
304  CfiCrossDso && !ImplicitCfiRuntime;
305 }
306 
307 bool SanitizerArgs::requiresPIE() const { return NeedPIE; }
308 
310  return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
311 }
312 
314  return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
315 }
316 
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  }
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  }
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) {
486  }
487  // NotAllowedWithExecuteOnly is silently discarded on an execute-only
488  // target if implicitly enabled through group expansion.
489  if (isExecuteOnlyTarget(Triple, Args))
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 |
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.
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.
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 =
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 |
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 &
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) {
878  D, Args, CoverageAllowlistFiles,
879  options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
880  clang::diag::err_drv_malformed_sanitizer_coverage_allowlist,
881  DiagnoseErrors);
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) {
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 =
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 
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 
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 
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 
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 
1130 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  // SPIR/SPIRV sanitizer support is experimental and will pass a fixed set of
1147  // flags
1148  if (TC.getTriple().isSPIROrSPIRV()) {
1149  if (Sanitizers.has(SanitizerKind::Address)) {
1150  CmdArgs.push_back("-fsanitize=address");
1151  CmdArgs.push_back("-fsanitize-address-use-after-return=never");
1152  CmdArgs.push_back("-fno-sanitize-address-use-after-scope");
1153 
1154  // -fsanitize-address-outline-instrumentation
1155  CmdArgs.push_back("-mllvm");
1156  CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
1157 
1158  // asan initialization is done in unified runtime rather than in ctor.
1159  CmdArgs.push_back("-mllvm");
1160  CmdArgs.push_back("-asan-constructor-kind=none");
1161 
1162  CmdArgs.push_back("-mllvm");
1163  CmdArgs.push_back("-asan-stack=0");
1164  CmdArgs.push_back("-mllvm");
1165  CmdArgs.push_back("-asan-globals=0");
1166  CmdArgs.push_back("-mllvm");
1167  CmdArgs.push_back("-asan-stack-dynamic-alloca=0");
1168  CmdArgs.push_back("-mllvm");
1169  CmdArgs.push_back("-asan-use-after-return=never");
1170 
1171  if (!RecoverableSanitizers.empty())
1172  CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
1173  toString(RecoverableSanitizers)));
1174 
1175  CmdArgs.push_back("-mllvm");
1176  CmdArgs.push_back("-asan-mapping-scale=4");
1177  }
1178  return;
1179  }
1180 
1181  // Translate available CoverageFeatures to corresponding clang-cc1 flags.
1182  // Do it even if Sanitizers.empty() since some forms of coverage don't require
1183  // sanitizers.
1184  std::pair<int, const char *> CoverageFlags[] = {
1185  std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
1186  std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
1187  std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
1188  std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
1189  std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
1190  std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
1191  std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
1192  std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
1193  std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
1194  std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
1195  std::make_pair(CoverageTracePCGuard,
1196  "-fsanitize-coverage-trace-pc-guard"),
1197  std::make_pair(CoverageInline8bitCounters,
1198  "-fsanitize-coverage-inline-8bit-counters"),
1199  std::make_pair(CoverageInlineBoolFlag,
1200  "-fsanitize-coverage-inline-bool-flag"),
1201  std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
1202  std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
1203  std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth"),
1204  std::make_pair(CoverageTraceLoads, "-fsanitize-coverage-trace-loads"),
1205  std::make_pair(CoverageTraceStores, "-fsanitize-coverage-trace-stores"),
1206  std::make_pair(CoverageControlFlow, "-fsanitize-coverage-control-flow")};
1207  for (auto F : CoverageFlags) {
1208  if (CoverageFeatures & F.first)
1209  CmdArgs.push_back(F.second);
1210  }
1212  Args, CmdArgs, "-fsanitize-coverage-allowlist=", CoverageAllowlistFiles);
1213  addSpecialCaseListOpt(Args, CmdArgs, "-fsanitize-coverage-ignorelist=",
1214  CoverageIgnorelistFiles);
1215 
1216  if (!GPUSanitize) {
1217  // Translate available BinaryMetadataFeatures to corresponding clang-cc1
1218  // flags. Does not depend on any other sanitizers. Unsupported on GPUs.
1219  const std::pair<int, std::string> BinaryMetadataFlags[] = {
1220  std::make_pair(BinaryMetadataCovered, "covered"),
1221  std::make_pair(BinaryMetadataAtomics, "atomics"),
1222  std::make_pair(BinaryMetadataUAR, "uar")};
1223  for (const auto &F : BinaryMetadataFlags) {
1224  if (BinaryMetadataFeatures & F.first)
1225  CmdArgs.push_back(
1226  Args.MakeArgString("-fexperimental-sanitize-metadata=" + F.second));
1227  }
1228  addSpecialCaseListOpt(Args, CmdArgs,
1229  "-fexperimental-sanitize-metadata-ignorelist=",
1230  BinaryMetadataIgnorelistFiles);
1231  }
1232 
1233  if (TC.getTriple().isOSWindows() && needsUbsanRt() &&
1234  Args.hasFlag(options::OPT_frtlib_defaultlib,
1235  options::OPT_fno_rtlib_defaultlib, true)) {
1236  // Instruct the code generator to embed linker directives in the object file
1237  // that cause the required runtime libraries to be linked.
1238  CmdArgs.push_back(
1239  Args.MakeArgString("--dependent-lib=" +
1240  TC.getCompilerRTBasename(Args, "ubsan_standalone")));
1241  if (types::isCXX(InputType))
1242  CmdArgs.push_back(Args.MakeArgString(
1243  "--dependent-lib=" +
1244  TC.getCompilerRTBasename(Args, "ubsan_standalone_cxx")));
1245  }
1246  if (TC.getTriple().isOSWindows() && needsStatsRt() &&
1247  Args.hasFlag(options::OPT_frtlib_defaultlib,
1248  options::OPT_fno_rtlib_defaultlib, true)) {
1249  CmdArgs.push_back(Args.MakeArgString(
1250  "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats_client")));
1251 
1252  // The main executable must export the stats runtime.
1253  // FIXME: Only exporting from the main executable (e.g. based on whether the
1254  // translation unit defines main()) would save a little space, but having
1255  // multiple copies of the runtime shouldn't hurt.
1256  CmdArgs.push_back(Args.MakeArgString(
1257  "--dependent-lib=" + TC.getCompilerRTBasename(Args, "stats")));
1258  addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
1259  }
1260 
1261  if (Sanitizers.empty())
1262  return;
1263  CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
1264 
1265  if (!RecoverableSanitizers.empty())
1266  CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
1267  toString(RecoverableSanitizers)));
1268 
1269  if (!TrapSanitizers.empty())
1270  CmdArgs.push_back(
1271  Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
1272 
1273  addSpecialCaseListOpt(Args, CmdArgs,
1274  "-fsanitize-ignorelist=", UserIgnorelistFiles);
1275  addSpecialCaseListOpt(Args, CmdArgs,
1276  "-fsanitize-system-ignorelist=", SystemIgnorelistFiles);
1277 
1278  if (MsanTrackOrigins)
1279  CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
1280  Twine(MsanTrackOrigins)));
1281 
1282  if (MsanUseAfterDtor)
1283  CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
1284 
1285  if (!MsanParamRetval)
1286  CmdArgs.push_back("-fno-sanitize-memory-param-retval");
1287 
1288  // FIXME: Pass these parameters as function attributes, not as -llvm flags.
1289  if (!TsanMemoryAccess) {
1290  CmdArgs.push_back("-mllvm");
1291  CmdArgs.push_back("-tsan-instrument-memory-accesses=0");
1292  CmdArgs.push_back("-mllvm");
1293  CmdArgs.push_back("-tsan-instrument-memintrinsics=0");
1294  }
1295  if (!TsanFuncEntryExit) {
1296  CmdArgs.push_back("-mllvm");
1297  CmdArgs.push_back("-tsan-instrument-func-entry-exit=0");
1298  }
1299  if (!TsanAtomics) {
1300  CmdArgs.push_back("-mllvm");
1301  CmdArgs.push_back("-tsan-instrument-atomics=0");
1302  }
1303 
1304  if (HwasanUseAliases) {
1305  CmdArgs.push_back("-mllvm");
1306  CmdArgs.push_back("-hwasan-experimental-use-page-aliases=1");
1307  }
1308 
1309  if (CfiCrossDso)
1310  CmdArgs.push_back("-fsanitize-cfi-cross-dso");
1311 
1312  if (CfiICallGeneralizePointers)
1313  CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers");
1314 
1315  if (CfiICallNormalizeIntegers)
1316  CmdArgs.push_back("-fsanitize-cfi-icall-experimental-normalize-integers");
1317 
1318  if (CfiCanonicalJumpTables)
1319  CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables");
1320 
1321  if (Stats)
1322  CmdArgs.push_back("-fsanitize-stats");
1323 
1324  if (MinimalRuntime)
1325  CmdArgs.push_back("-fsanitize-minimal-runtime");
1326 
1327  if (AsanFieldPadding)
1328  CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
1329  Twine(AsanFieldPadding)));
1330 
1331  if (AsanUseAfterScope)
1332  CmdArgs.push_back("-fsanitize-address-use-after-scope");
1333 
1334  if (AsanPoisonCustomArrayCookie)
1335  CmdArgs.push_back("-fsanitize-address-poison-custom-array-cookie");
1336 
1337  if (AsanGlobalsDeadStripping)
1338  CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
1339 
1340  if (!AsanUseOdrIndicator)
1341  CmdArgs.push_back("-fno-sanitize-address-use-odr-indicator");
1342 
1343  if (AsanInvalidPointerCmp) {
1344  CmdArgs.push_back("-mllvm");
1345  CmdArgs.push_back("-asan-detect-invalid-pointer-cmp");
1346  }
1347 
1348  if (AsanInvalidPointerSub) {
1349  CmdArgs.push_back("-mllvm");
1350  CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
1351  }
1352 
1353  if (AsanOutlineInstrumentation) {
1354  CmdArgs.push_back("-mllvm");
1355  CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
1356  }
1357 
1358  // When emitting Stable ABI instrumentation, force outlining calls and avoid
1359  // inlining shadow memory poisoning. While this is a big performance burden
1360  // for now it allows full abstraction from implementation details.
1361  if (StableABI) {
1362  CmdArgs.push_back("-mllvm");
1363  CmdArgs.push_back("-asan-instrumentation-with-call-threshold=0");
1364  CmdArgs.push_back("-mllvm");
1365  CmdArgs.push_back("-asan-max-inline-poisoning-size=0");
1366  CmdArgs.push_back("-mllvm");
1367  CmdArgs.push_back("-asan-guard-against-version-mismatch=0");
1368  }
1369 
1370  // Only pass the option to the frontend if the user requested,
1371  // otherwise the frontend will just use the codegen default.
1372  if (AsanDtorKind != llvm::AsanDtorKind::Invalid) {
1373  CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-destructor=" +
1374  AsanDtorKindToString(AsanDtorKind)));
1375  }
1376 
1377  if (AsanUseAfterReturn != llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
1378  CmdArgs.push_back(Args.MakeArgString(
1379  "-fsanitize-address-use-after-return=" +
1380  AsanDetectStackUseAfterReturnModeToString(AsanUseAfterReturn)));
1381  }
1382 
1383  if (!HwasanAbi.empty()) {
1384  CmdArgs.push_back("-default-function-attr");
1385  CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
1386  }
1387 
1388  if (Sanitizers.has(SanitizerKind::HWAddress) && !HwasanUseAliases) {
1389  CmdArgs.push_back("-target-feature");
1390  CmdArgs.push_back("+tagged-globals");
1391  }
1392 
1393  // MSan: Workaround for PR16386.
1394  // ASan: This is mainly to help LSan with cases such as
1395  // https://github.com/google/sanitizers/issues/373
1396  // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
1397  // affect compilation.
1398  if (Sanitizers.has(SanitizerKind::Memory) ||
1399  Sanitizers.has(SanitizerKind::Address))
1400  CmdArgs.push_back("-fno-assume-sane-operator-new");
1401 
1402  // libFuzzer wants to intercept calls to certain library functions, so the
1403  // following -fno-builtin-* flags force the compiler to emit interposable
1404  // libcalls to these functions. Other sanitizers effectively do the same thing
1405  // by marking all library call sites with NoBuiltin attribute in their LLVM
1406  // pass. (see llvm::maybeMarkSanitizerLibraryCallNoBuiltin)
1407  if (Sanitizers.has(SanitizerKind::FuzzerNoLink)) {
1408  CmdArgs.push_back("-fno-builtin-bcmp");
1409  CmdArgs.push_back("-fno-builtin-memcmp");
1410  CmdArgs.push_back("-fno-builtin-strncmp");
1411  CmdArgs.push_back("-fno-builtin-strcmp");
1412  CmdArgs.push_back("-fno-builtin-strncasecmp");
1413  CmdArgs.push_back("-fno-builtin-strcasecmp");
1414  CmdArgs.push_back("-fno-builtin-strstr");
1415  CmdArgs.push_back("-fno-builtin-strcasestr");
1416  CmdArgs.push_back("-fno-builtin-memmem");
1417  }
1418 
1419  // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
1420  // enabled.
1421  if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
1422  !Args.hasArg(options::OPT_fvisibility_EQ)) {
1423  TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
1424  << lastArgumentForMask(TC.getDriver(), Args,
1425  Sanitizers.Mask & CFIClasses)
1426  << "-fvisibility=";
1427  }
1428 
1429  if (Sanitizers.has(SanitizerKind::MemtagStack) &&
1430  !hasTargetFeatureMTE(CmdArgs))
1431  TC.getDriver().Diag(diag::err_stack_tagging_requires_hardware_feature);
1432 }
1433 
1434 SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
1435  bool DiagnoseErrors) {
1436  assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
1437  A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1438  A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1439  A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1440  A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1441  A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
1442  "Invalid argument in parseArgValues!");
1443  SanitizerMask Kinds;
1444  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1445  const char *Value = A->getValue(i);
1447  // Special case: don't accept -fsanitize=all.
1448  if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
1449  0 == strcmp("all", Value))
1450  Kind = SanitizerMask();
1451  else
1452  Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
1453 
1454  if (Kind)
1455  Kinds |= Kind;
1456  else if (DiagnoseErrors)
1457  D.Diag(clang::diag::err_drv_unsupported_option_argument)
1458  << A->getSpelling() << Value;
1459  }
1460  return Kinds;
1461 }
1462 
1463 int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A,
1464  bool DiagnoseErrors) {
1465  assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
1466  A->getOption().matches(options::OPT_fno_sanitize_coverage));
1467  int Features = 0;
1468  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1469  const char *Value = A->getValue(i);
1470  int F = llvm::StringSwitch<int>(Value)
1471  .Case("func", CoverageFunc)
1472  .Case("bb", CoverageBB)
1473  .Case("edge", CoverageEdge)
1474  .Case("indirect-calls", CoverageIndirCall)
1475  .Case("trace-bb", CoverageTraceBB)
1476  .Case("trace-cmp", CoverageTraceCmp)
1477  .Case("trace-div", CoverageTraceDiv)
1478  .Case("trace-gep", CoverageTraceGep)
1479  .Case("8bit-counters", Coverage8bitCounters)
1480  .Case("trace-pc", CoverageTracePC)
1481  .Case("trace-pc-guard", CoverageTracePCGuard)
1482  .Case("no-prune", CoverageNoPrune)
1483  .Case("inline-8bit-counters", CoverageInline8bitCounters)
1484  .Case("inline-bool-flag", CoverageInlineBoolFlag)
1485  .Case("pc-table", CoveragePCTable)
1486  .Case("stack-depth", CoverageStackDepth)
1487  .Case("trace-loads", CoverageTraceLoads)
1488  .Case("trace-stores", CoverageTraceStores)
1489  .Case("control-flow", CoverageControlFlow)
1490  .Default(0);
1491  if (F == 0 && DiagnoseErrors)
1492  D.Diag(clang::diag::err_drv_unsupported_option_argument)
1493  << A->getSpelling() << Value;
1494  Features |= F;
1495  }
1496  return Features;
1497 }
1498 
1499 int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A,
1500  bool DiagnoseErrors) {
1501  assert(
1502  A->getOption().matches(options::OPT_fexperimental_sanitize_metadata_EQ) ||
1503  A->getOption().matches(
1504  options::OPT_fno_experimental_sanitize_metadata_EQ));
1505  int Features = 0;
1506  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1507  const char *Value = A->getValue(i);
1508  int F = llvm::StringSwitch<int>(Value)
1509  .Case("covered", BinaryMetadataCovered)
1510  .Case("atomics", BinaryMetadataAtomics)
1511  .Case("uar", BinaryMetadataUAR)
1512  .Case("all", ~0)
1513  .Default(0);
1514  if (F == 0 && DiagnoseErrors)
1515  D.Diag(clang::diag::err_drv_unsupported_option_argument)
1516  << A->getSpelling() << Value;
1517  Features |= F;
1518  }
1519  return Features;
1520 }
1521 
1522 std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
1523  SanitizerMask Mask) {
1524  for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1525  E = Args.rend();
1526  I != E; ++I) {
1527  const auto *Arg = *I;
1528  if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1529  SanitizerMask AddKinds =
1530  expandSanitizerGroups(parseArgValues(D, Arg, false));
1531  if (AddKinds & Mask)
1532  return describeSanitizeArg(Arg, Mask);
1533  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1534  SanitizerMask RemoveKinds =
1535  expandSanitizerGroups(parseArgValues(D, Arg, false));
1536  Mask &= ~RemoveKinds;
1537  }
1538  }
1539  llvm_unreachable("arg list didn't provide expected value");
1540 }
1541 
1542 std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
1543  assert(A->getOption().matches(options::OPT_fsanitize_EQ) &&
1544  "Invalid argument in describeSanitizerArg!");
1545 
1546  std::string Sanitizers;
1547  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1549  parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
1550  Mask) {
1551  if (!Sanitizers.empty())
1552  Sanitizers += ",";
1553  Sanitizers += A->getValue(i);
1554  }
1555  }
1556 
1557  assert(!Sanitizers.empty() && "arg didn't provide expected value");
1558  return "-fsanitize=" + Sanitizers;
1559 }
const Decl * D
IndirectLocalPath & Path
enum clang::sema::@1659::IndirectLocalPathEntry::EntryKind Kind
Expr * E
static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds, std::vector< std::string > &IgnorelistFiles, bool DiagnoseErrors)
static std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask)
Produce an argument string from argument A, which shows how it provides a value in Mask.
static SanitizerMask parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args, bool DiagnoseErrors)
static void addIncludeLinkerOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, StringRef SymbolName)
static bool isExecuteOnlyTarget(const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Return true if an execute-only target disallows data access to code sections.
static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs)
BinaryMetadataFeature
@ BinaryMetadataUAR
@ BinaryMetadataCovered
@ BinaryMetadataAtomics
static const SanitizerMask SupportsCoverage
static const SanitizerMask CFIClasses
static int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors)
Parse -f(no-)?sanitize-metadata= flag values, diagnosing any invalid components.
static const SanitizerMask TrappingSupported
static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors)
Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any invalid components.
static const SanitizerMask NeedsUnwindTables
static void addSpecialCaseListOpt(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const char *SCLOptFlag, const std::vector< std::string > &SCLFiles)
static const SanitizerMask NotAllowedWithMinimalRuntime
static const SanitizerMask AlwaysRecoverable
static std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args, SanitizerMask Mask)
Produce an argument string from ArgList Args, which shows how it provides some sanitizer kind from Ma...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static const SanitizerMask NeedsUbsanCxxRt
static const SanitizerMask TrappingDefault
static const SanitizerMask CompatibleWithMinimalRuntime
static const SanitizerMask Unrecoverable
static const SanitizerMask RecoverableByDefault
static const SanitizerMask NeedsLTO
static SanitizerMask setGroupBits(SanitizerMask Kinds)
Sets group bits for every group that has at least one representative already enabled in Kinds.
static const SanitizerMask NeedsUbsanRt
static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors)
Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid components.
static void validateSpecialCaseListFormat(const Driver &D, std::vector< std::string > &SCLFiles, unsigned MalformedSCLErrorDiagID, bool DiagnoseErrors)
static const SanitizerMask NotAllowedWithTrap
static void 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)
Parse -f(no-)?sanitize-(coverage-)?(allow|ignore)list argument's values, diagnosing any invalid file ...
static const SanitizerMask NotAllowedWithExecuteOnly
CoverageFeature
@ CoverageTracePCGuard
@ CoverageTraceLoads
@ CoverageTracePC
@ CoverageFunc
@ Coverage8bitCounters
@ CoverageTraceCmp
@ CoverageBB
@ CoverageTraceDiv
@ CoverageInlineBoolFlag
@ CoverageTraceStores
@ CoverageTraceGep
@ CoverageStackDepth
@ CoverageControlFlow
@ CoverageNoPrune
@ CoveragePCTable
@ CoverageIndirCall
@ CoverageInline8bitCounters
@ CoverageTraceBB
@ CoverageEdge
Defines the clang::SanitizerKind enum.
SourceLocation End
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:77
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:146
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, bool DiagnoseErrors=true)
Parses the sanitizer arguments from an argument list.
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:92
const Driver & getDriver() const
Definition: ToolChain.h:269
const llvm::opt::Arg * getRTTIArg() const
Definition: ToolChain.h:340
const llvm::Triple & getTriple() const
Definition: ToolChain.h:271
RTTIMode getRTTIMode() const
Definition: ToolChain.h:343
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:1478
std::string getCompilerRTBasename(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:743
virtual SanitizerMask getDefaultSanitizers() const
Return sanitizers which are enabled by default.
Definition: ToolChain.h:806
constexpr XRayInstrMask None
Definition: XRayInstr.h:38
bool isCXX(ID Id)
isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
Definition: Types.cpp:236
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
The JSON file list parser is used to communicate input to InstallAPI.
StringRef AsanDtorKindToString(llvm::AsanDtorKind kind)
Definition: Sanitizers.cpp:72
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables.
Definition: Sanitizers.cpp:47
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Definition: Sanitizers.cpp:29
llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind)
Definition: Sanitizers.cpp:84
llvm::AsanDetectStackUseAfterReturnMode AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr)
Definition: Sanitizers.cpp:107
StringRef AsanDetectStackUseAfterReturnModeToString(llvm::AsanDetectStackUseAfterReturnMode mode)
Definition: Sanitizers.cpp:91
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:182