clang  9.0.0
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/StringSwitch.h"
17 #include "llvm/Support/FileSystem.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/Support/SpecialCaseList.h"
20 #include "llvm/Support/TargetParser.h"
21 #include <memory>
22 
23 using namespace clang;
24 using namespace clang::driver;
25 using namespace llvm::opt;
26 
28  SanitizerKind::Undefined | SanitizerKind::Integer |
29  SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
30  SanitizerKind::CFI | SanitizerKind::FloatDivideByZero;
32  SanitizerKind::Vptr | SanitizerKind::CFI;
33 static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr;
35  SanitizerKind::Function | SanitizerKind::Vptr;
36 static const SanitizerMask RequiresPIE =
37  SanitizerKind::DataFlow | SanitizerKind::HWAddress | SanitizerKind::Scudo;
39  SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread |
40  SanitizerKind::Memory | SanitizerKind::DataFlow;
42  SanitizerKind::Address | SanitizerKind::HWAddress |
43  SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
44  SanitizerKind::MemTag | SanitizerKind::Memory |
45  SanitizerKind::KernelMemory | SanitizerKind::Leak |
46  SanitizerKind::Undefined | SanitizerKind::Integer |
47  SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
48  SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
49  SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero;
51  SanitizerKind::Undefined | SanitizerKind::Integer |
52  SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
53  SanitizerKind::FloatDivideByZero;
55  SanitizerKind::Unreachable | SanitizerKind::Return;
57  SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress;
59  SanitizerKind::Undefined | SanitizerKind::Integer;
60 static const SanitizerMask NeedsLTO = SanitizerKind::CFI;
62  (SanitizerKind::Undefined & ~SanitizerKind::Vptr) |
63  SanitizerKind::UnsignedIntegerOverflow | SanitizerKind::ImplicitConversion |
64  SanitizerKind::Nullability | SanitizerKind::LocalBounds |
65  SanitizerKind::CFI | SanitizerKind::FloatDivideByZero;
66 static const SanitizerMask TrappingDefault = SanitizerKind::CFI;
67 static const SanitizerMask CFIClasses =
68  SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
69  SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
70  SanitizerKind::CFIUnrelatedCast;
72  TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack;
73 
75  CoverageFunc = 1 << 0,
76  CoverageBB = 1 << 1,
77  CoverageEdge = 1 << 2,
79  CoverageTraceBB = 1 << 4, // Deprecated.
80  CoverageTraceCmp = 1 << 5,
81  CoverageTraceDiv = 1 << 6,
82  CoverageTraceGep = 1 << 7,
83  Coverage8bitCounters = 1 << 8, // Deprecated.
84  CoverageTracePC = 1 << 9,
86  CoverageNoPrune = 1 << 11,
88  CoveragePCTable = 1 << 13,
89  CoverageStackDepth = 1 << 14,
90 };
91 
92 /// Parse a -fsanitize= or -fno-sanitize= argument's values, diagnosing any
93 /// invalid components. Returns a SanitizerMask.
94 static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
95  bool DiagnoseErrors);
96 
97 /// Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid
98 /// components. Returns OR of members of \c CoverageFeature enumeration.
99 static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A);
100 
101 /// Produce an argument string from ArgList \p Args, which shows how it
102 /// provides some sanitizer kind from \p Mask. For example, the argument list
103 /// "-fsanitize=thread,vptr -fsanitize=address" with mask \c NeedsUbsanRt
104 /// would produce "-fsanitize=vptr".
105 static std::string lastArgumentForMask(const Driver &D,
106  const llvm::opt::ArgList &Args,
107  SanitizerMask Mask);
108 
109 /// Produce an argument string from argument \p A, which shows how it provides
110 /// a value in \p Mask. For instance, the argument
111 /// "-fsanitize=address,alignment" with mask \c NeedsUbsanRt would produce
112 /// "-fsanitize=alignment".
113 static std::string describeSanitizeArg(const llvm::opt::Arg *A,
114  SanitizerMask Mask);
115 
116 /// Produce a string containing comma-separated names of sanitizers in \p
117 /// Sanitizers set.
118 static std::string toString(const clang::SanitizerSet &Sanitizers);
119 
120 static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds,
121  std::vector<std::string> &BlacklistFiles) {
122  struct Blacklist {
123  const char *File;
124  SanitizerMask Mask;
125  } Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address},
126  {"hwasan_blacklist.txt", SanitizerKind::HWAddress},
127  {"memtag_blacklist.txt", SanitizerKind::MemTag},
128  {"msan_blacklist.txt", SanitizerKind::Memory},
129  {"tsan_blacklist.txt", SanitizerKind::Thread},
130  {"dfsan_abilist.txt", SanitizerKind::DataFlow},
131  {"cfi_blacklist.txt", SanitizerKind::CFI},
132  {"ubsan_blacklist.txt",
133  SanitizerKind::Undefined | SanitizerKind::Integer |
135  SanitizerKind::FloatDivideByZero}};
136 
137  for (auto BL : Blacklists) {
138  if (!(Kinds & BL.Mask))
139  continue;
140 
142  llvm::sys::path::append(Path, "share", BL.File);
143  if (llvm::sys::fs::exists(Path))
144  BlacklistFiles.push_back(Path.str());
145  else if (BL.Mask == SanitizerKind::CFI)
146  // If cfi_blacklist.txt cannot be found in the resource dir, driver
147  // should fail.
148  D.Diag(clang::diag::err_drv_no_such_file) << Path;
149  }
150 }
151 
152 /// Sets group bits for every group that has at least one representative already
153 /// enabled in \p Kinds.
155 #define SANITIZER(NAME, ID)
156 #define SANITIZER_GROUP(NAME, ID, ALIAS) \
157  if (Kinds & SanitizerKind::ID) \
158  Kinds |= SanitizerKind::ID##Group;
159 #include "clang/Basic/Sanitizers.def"
160  return Kinds;
161 }
162 
164  const llvm::opt::ArgList &Args) {
165  SanitizerMask TrapRemove; // During the loop below, the accumulated set of
166  // sanitizers disabled by the current sanitizer
167  // argument or any argument after it.
168  SanitizerMask TrappingKinds;
169  SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
170 
171  for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
172  I != E; ++I) {
173  const auto *Arg = *I;
174  if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
175  Arg->claim();
176  SanitizerMask Add = parseArgValues(D, Arg, true);
177  Add &= ~TrapRemove;
178  if (SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
179  SanitizerSet S;
180  S.Mask = InvalidValues;
181  D.Diag(diag::err_drv_unsupported_option_argument) << "-fsanitize-trap"
182  << toString(S);
183  }
184  TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove;
185  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
186  Arg->claim();
187  TrapRemove |= expandSanitizerGroups(parseArgValues(D, Arg, true));
188  } else if (Arg->getOption().matches(
189  options::OPT_fsanitize_undefined_trap_on_error)) {
190  Arg->claim();
191  TrappingKinds |=
192  expandSanitizerGroups(SanitizerKind::UndefinedGroup & ~TrapRemove) &
193  ~TrapRemove;
194  } else if (Arg->getOption().matches(
195  options::OPT_fno_sanitize_undefined_trap_on_error)) {
196  Arg->claim();
197  TrapRemove |= expandSanitizerGroups(SanitizerKind::UndefinedGroup);
198  }
199  }
200 
201  // Apply default trapping behavior.
202  TrappingKinds |= TrappingDefault & ~TrapRemove;
203 
204  return TrappingKinds;
205 }
206 
208  // All of these include ubsan.
209  if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
210  needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
211  (needsScudoRt() && !requiresMinimalRuntime()))
212  return false;
213 
214  return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
215  CoverageFeatures;
216 }
217 
219  return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
220  CfiCrossDso && !ImplicitCfiRuntime;
221 }
222 
224  return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
225  CfiCrossDso && !ImplicitCfiRuntime;
226 }
227 
229  return NeedPIE || (Sanitizers.Mask & RequiresPIE);
230 }
231 
233  return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
234 }
235 
237  return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
238 }
239 
241  const llvm::opt::ArgList &Args) {
242  SanitizerMask AllRemove; // During the loop below, the accumulated set of
243  // sanitizers disabled by the current sanitizer
244  // argument or any argument after it.
245  SanitizerMask AllAddedKinds; // Mask of all sanitizers ever enabled by
246  // -fsanitize= flags (directly or via group
247  // expansion), some of which may be disabled
248  // later. Used to carefully prune
249  // unused-argument diagnostics.
250  SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now.
251  // Used to deduplicate diagnostics.
252  SanitizerMask Kinds;
253  const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
254 
255  CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
256  options::OPT_fno_sanitize_cfi_cross_dso, false);
257 
258  ToolChain::RTTIMode RTTIMode = TC.getRTTIMode();
259 
260  const Driver &D = TC.getDriver();
261  SanitizerMask TrappingKinds = parseSanitizeTrapArgs(D, Args);
262  SanitizerMask InvalidTrappingKinds = TrappingKinds & NotAllowedWithTrap;
263 
264  MinimalRuntime =
265  Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
266  options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
267 
268  // The object size sanitizer should not be enabled at -O0.
269  Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
270  bool RemoveObjectSizeAtO0 =
271  !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
272 
273  for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
274  I != E; ++I) {
275  const auto *Arg = *I;
276  if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
277  Arg->claim();
278  SanitizerMask Add = parseArgValues(D, Arg, /*AllowGroups=*/true);
279 
280  if (RemoveObjectSizeAtO0) {
281  AllRemove |= SanitizerKind::ObjectSize;
282 
283  // The user explicitly enabled the object size sanitizer. Warn
284  // that this does nothing at -O0.
285  if (Add & SanitizerKind::ObjectSize)
286  D.Diag(diag::warn_drv_object_size_disabled_O0)
287  << Arg->getAsString(Args);
288  }
289 
290  AllAddedKinds |= expandSanitizerGroups(Add);
291 
292  // Avoid diagnosing any sanitizer which is disabled later.
293  Add &= ~AllRemove;
294  // At this point we have not expanded groups, so any unsupported
295  // sanitizers in Add are those which have been explicitly enabled.
296  // Diagnose them.
297  if (SanitizerMask KindsToDiagnose =
298  Add & InvalidTrappingKinds & ~DiagnosedKinds) {
299  std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
300  D.Diag(diag::err_drv_argument_not_allowed_with)
301  << Desc << "-fsanitize-trap=undefined";
302  DiagnosedKinds |= KindsToDiagnose;
303  }
304  Add &= ~InvalidTrappingKinds;
305 
306  if (MinimalRuntime) {
307  if (SanitizerMask KindsToDiagnose =
308  Add & NotAllowedWithMinimalRuntime & ~DiagnosedKinds) {
309  std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
310  D.Diag(diag::err_drv_argument_not_allowed_with)
311  << Desc << "-fsanitize-minimal-runtime";
312  DiagnosedKinds |= KindsToDiagnose;
313  }
314  Add &= ~NotAllowedWithMinimalRuntime;
315  }
316 
317  // FIXME: Make CFI on member function calls compatible with cross-DSO CFI.
318  // There are currently two problems:
319  // - Virtual function call checks need to pass a pointer to the function
320  // address to llvm.type.test and a pointer to the address point to the
321  // diagnostic function. Currently we pass the same pointer to both
322  // places.
323  // - Non-virtual function call checks may need to check multiple type
324  // identifiers.
325  // Fixing both of those may require changes to the cross-DSO CFI
326  // interface.
327  if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
328  D.Diag(diag::err_drv_argument_not_allowed_with)
329  << "-fsanitize=cfi-mfcall"
330  << "-fsanitize-cfi-cross-dso";
331  Add &= ~SanitizerKind::CFIMFCall;
332  DiagnosedKinds |= SanitizerKind::CFIMFCall;
333  }
334 
335  if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
336  std::string Desc = describeSanitizeArg(*I, KindsToDiagnose);
337  D.Diag(diag::err_drv_unsupported_opt_for_target)
338  << Desc << TC.getTriple().str();
339  DiagnosedKinds |= KindsToDiagnose;
340  }
341  Add &= Supported;
342 
343  // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups
344  // so we don't error out if -fno-rtti and -fsanitize=undefined were
345  // passed.
346  if ((Add & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
347  if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) {
348  assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
349  "RTTI disabled without -fno-rtti option?");
350  // The user explicitly passed -fno-rtti with -fsanitize=vptr, but
351  // the vptr sanitizer requires RTTI, so this is a user error.
352  D.Diag(diag::err_drv_argument_not_allowed_with)
353  << "-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
354  } else {
355  // The vptr sanitizer requires RTTI, but RTTI is disabled (by
356  // default). Warn that the vptr sanitizer is being disabled.
357  D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
358  }
359 
360  // Take out the Vptr sanitizer from the enabled sanitizers
361  AllRemove |= SanitizerKind::Vptr;
362  }
363 
364  Add = expandSanitizerGroups(Add);
365  // Group expansion may have enabled a sanitizer which is disabled later.
366  Add &= ~AllRemove;
367  // Silently discard any unsupported sanitizers implicitly enabled through
368  // group expansion.
369  Add &= ~InvalidTrappingKinds;
370  if (MinimalRuntime) {
371  Add &= ~NotAllowedWithMinimalRuntime;
372  }
373  if (CfiCrossDso)
374  Add &= ~SanitizerKind::CFIMFCall;
375  Add &= Supported;
376 
377  if (Add & SanitizerKind::Fuzzer)
378  Add |= SanitizerKind::FuzzerNoLink;
379 
380  // Enable coverage if the fuzzing flag is set.
381  if (Add & SanitizerKind::FuzzerNoLink) {
382  CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall |
384  // Due to TLS differences, stack depth tracking is only enabled on Linux
385  if (TC.getTriple().isOSLinux())
386  CoverageFeatures |= CoverageStackDepth;
387  }
388 
389  Kinds |= Add;
390  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
391  Arg->claim();
392  SanitizerMask Remove = parseArgValues(D, Arg, true);
393  AllRemove |= expandSanitizerGroups(Remove);
394  }
395  }
396 
397  std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
398  std::make_pair(SanitizerKind::Address,
399  SanitizerKind::Thread | SanitizerKind::Memory),
400  std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
401  std::make_pair(SanitizerKind::Leak,
402  SanitizerKind::Thread | SanitizerKind::Memory),
403  std::make_pair(SanitizerKind::KernelAddress,
404  SanitizerKind::Address | SanitizerKind::Leak |
405  SanitizerKind::Thread | SanitizerKind::Memory),
406  std::make_pair(SanitizerKind::HWAddress,
407  SanitizerKind::Address | SanitizerKind::Thread |
408  SanitizerKind::Memory | SanitizerKind::KernelAddress),
409  std::make_pair(SanitizerKind::Scudo,
410  SanitizerKind::Address | SanitizerKind::HWAddress |
411  SanitizerKind::Leak | SanitizerKind::Thread |
412  SanitizerKind::Memory | SanitizerKind::KernelAddress),
413  std::make_pair(SanitizerKind::SafeStack,
414  SanitizerKind::Address | SanitizerKind::HWAddress |
415  SanitizerKind::Leak | SanitizerKind::Thread |
416  SanitizerKind::Memory | SanitizerKind::KernelAddress),
417  std::make_pair(SanitizerKind::KernelHWAddress,
418  SanitizerKind::Address | SanitizerKind::HWAddress |
419  SanitizerKind::Leak | SanitizerKind::Thread |
420  SanitizerKind::Memory | SanitizerKind::KernelAddress |
421  SanitizerKind::SafeStack),
422  std::make_pair(SanitizerKind::KernelMemory,
423  SanitizerKind::Address | SanitizerKind::HWAddress |
424  SanitizerKind::Leak | SanitizerKind::Thread |
425  SanitizerKind::Memory | SanitizerKind::KernelAddress |
426  SanitizerKind::Scudo | SanitizerKind::SafeStack),
427  std::make_pair(SanitizerKind::MemTag,
428  SanitizerKind::Address | SanitizerKind::KernelAddress |
429  SanitizerKind::HWAddress |
430  SanitizerKind::KernelHWAddress)};
431  // Enable toolchain specific default sanitizers if not explicitly disabled.
432  SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove;
433 
434  // Disable default sanitizers that are incompatible with explicitly requested
435  // ones.
436  for (auto G : IncompatibleGroups) {
437  SanitizerMask Group = G.first;
438  if ((Default & Group) && (Kinds & G.second))
439  Default &= ~Group;
440  }
441 
442  Kinds |= Default;
443 
444  // We disable the vptr sanitizer if it was enabled by group expansion but RTTI
445  // is disabled.
446  if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
447  Kinds &= ~SanitizerKind::Vptr;
448  }
449 
450  // Check that LTO is enabled if we need it.
451  if ((Kinds & NeedsLTO) && !D.isUsingLTO()) {
452  D.Diag(diag::err_drv_argument_only_allowed_with)
453  << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto";
454  }
455 
456  if ((Kinds & SanitizerKind::ShadowCallStack) &&
457  TC.getTriple().getArch() == llvm::Triple::aarch64 &&
458  !llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) &&
459  !Args.hasArg(options::OPT_ffixed_x18)) {
460  D.Diag(diag::err_drv_argument_only_allowed_with)
461  << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack)
462  << "-ffixed-x18";
463  }
464 
465  // Report error if there are non-trapping sanitizers that require
466  // c++abi-specific parts of UBSan runtime, and they are not provided by the
467  // toolchain. We don't have a good way to check the latter, so we just
468  // check if the toolchan supports vptr.
469  if (~Supported & SanitizerKind::Vptr) {
470  SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt;
471  // The runtime library supports the Microsoft C++ ABI, but only well enough
472  // for CFI. FIXME: Remove this once we support vptr on Windows.
473  if (TC.getTriple().isOSWindows())
474  KindsToDiagnose &= ~SanitizerKind::CFI;
475  if (KindsToDiagnose) {
476  SanitizerSet S;
477  S.Mask = KindsToDiagnose;
478  D.Diag(diag::err_drv_unsupported_opt_for_target)
479  << ("-fno-sanitize-trap=" + toString(S)) << TC.getTriple().str();
480  Kinds &= ~KindsToDiagnose;
481  }
482  }
483 
484  // Warn about incompatible groups of sanitizers.
485  for (auto G : IncompatibleGroups) {
486  SanitizerMask Group = G.first;
487  if (Kinds & Group) {
488  if (SanitizerMask Incompatible = Kinds & G.second) {
489  D.Diag(clang::diag::err_drv_argument_not_allowed_with)
490  << lastArgumentForMask(D, Args, Group)
491  << lastArgumentForMask(D, Args, Incompatible);
492  Kinds &= ~Incompatible;
493  }
494  }
495  }
496  // FIXME: Currently -fsanitize=leak is silently ignored in the presence of
497  // -fsanitize=address. Perhaps it should print an error, or perhaps
498  // -f(-no)sanitize=leak should change whether leak detection is enabled by
499  // default in ASan?
500 
501  // Parse -f(no-)?sanitize-recover flags.
502  SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable;
503  SanitizerMask DiagnosedUnrecoverableKinds;
504  SanitizerMask DiagnosedAlwaysRecoverableKinds;
505  for (const auto *Arg : Args) {
506  const char *DeprecatedReplacement = nullptr;
507  if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
508  DeprecatedReplacement =
509  "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all";
510  RecoverableKinds |= expandSanitizerGroups(LegacyFsanitizeRecoverMask);
511  Arg->claim();
512  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
513  DeprecatedReplacement = "-fno-sanitize-recover=undefined,integer' or "
514  "'-fno-sanitize-recover=all";
515  RecoverableKinds &= ~expandSanitizerGroups(LegacyFsanitizeRecoverMask);
516  Arg->claim();
517  } else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
518  SanitizerMask Add = parseArgValues(D, Arg, true);
519  // Report error if user explicitly tries to recover from unrecoverable
520  // sanitizer.
521  if (SanitizerMask KindsToDiagnose =
522  Add & Unrecoverable & ~DiagnosedUnrecoverableKinds) {
523  SanitizerSet SetToDiagnose;
524  SetToDiagnose.Mask |= KindsToDiagnose;
525  D.Diag(diag::err_drv_unsupported_option_argument)
526  << Arg->getOption().getName() << toString(SetToDiagnose);
527  DiagnosedUnrecoverableKinds |= KindsToDiagnose;
528  }
529  RecoverableKinds |= expandSanitizerGroups(Add);
530  Arg->claim();
531  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
532  SanitizerMask Remove = parseArgValues(D, Arg, true);
533  // Report error if user explicitly tries to disable recovery from
534  // always recoverable sanitizer.
535  if (SanitizerMask KindsToDiagnose =
536  Remove & AlwaysRecoverable & ~DiagnosedAlwaysRecoverableKinds) {
537  SanitizerSet SetToDiagnose;
538  SetToDiagnose.Mask |= KindsToDiagnose;
539  D.Diag(diag::err_drv_unsupported_option_argument)
540  << Arg->getOption().getName() << toString(SetToDiagnose);
541  DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose;
542  }
543  RecoverableKinds &= ~expandSanitizerGroups(Remove);
544  Arg->claim();
545  }
546  if (DeprecatedReplacement) {
547  D.Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
548  << DeprecatedReplacement;
549  }
550  }
551  RecoverableKinds &= Kinds;
552  RecoverableKinds &= ~Unrecoverable;
553 
554  TrappingKinds &= Kinds;
555  RecoverableKinds &= ~TrappingKinds;
556 
557  // Setup blacklist files.
558  // Add default blacklist from resource directory.
559  addDefaultBlacklists(D, Kinds, BlacklistFiles);
560  // Parse -f(no-)sanitize-blacklist options.
561  for (const auto *Arg : Args) {
562  if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
563  Arg->claim();
564  std::string BLPath = Arg->getValue();
565  if (llvm::sys::fs::exists(BLPath)) {
566  BlacklistFiles.push_back(BLPath);
567  ExtraDeps.push_back(BLPath);
568  } else {
569  D.Diag(clang::diag::err_drv_no_such_file) << BLPath;
570  }
571  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
572  Arg->claim();
573  BlacklistFiles.clear();
574  ExtraDeps.clear();
575  }
576  }
577  // Validate blacklists format.
578  {
579  std::string BLError;
580  std::unique_ptr<llvm::SpecialCaseList> SCL(
581  llvm::SpecialCaseList::create(BlacklistFiles, BLError));
582  if (!SCL.get())
583  D.Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
584  }
585 
586  // Parse -f[no-]sanitize-memory-track-origins[=level] options.
587  if (AllAddedKinds & SanitizerKind::Memory) {
588  if (Arg *A =
589  Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
590  options::OPT_fsanitize_memory_track_origins,
591  options::OPT_fno_sanitize_memory_track_origins)) {
592  if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
593  MsanTrackOrigins = 2;
594  } else if (A->getOption().matches(
595  options::OPT_fno_sanitize_memory_track_origins)) {
596  MsanTrackOrigins = 0;
597  } else {
598  StringRef S = A->getValue();
599  if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
600  MsanTrackOrigins > 2) {
601  D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
602  }
603  }
604  }
605  MsanUseAfterDtor =
606  Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor,
607  options::OPT_fno_sanitize_memory_use_after_dtor,
608  MsanUseAfterDtor);
609  NeedPIE |= !(TC.getTriple().isOSLinux() &&
610  TC.getTriple().getArch() == llvm::Triple::x86_64);
611  } else {
612  MsanUseAfterDtor = false;
613  }
614 
615  if (AllAddedKinds & SanitizerKind::Thread) {
616  TsanMemoryAccess = Args.hasFlag(
617  options::OPT_fsanitize_thread_memory_access,
618  options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
619  TsanFuncEntryExit = Args.hasFlag(
620  options::OPT_fsanitize_thread_func_entry_exit,
621  options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
622  TsanAtomics =
623  Args.hasFlag(options::OPT_fsanitize_thread_atomics,
624  options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
625  }
626 
627  if (AllAddedKinds & SanitizerKind::CFI) {
628  // Without PIE, external function address may resolve to a PLT record, which
629  // can not be verified by the target module.
630  NeedPIE |= CfiCrossDso;
631  CfiICallGeneralizePointers =
632  Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
633 
634  if (CfiCrossDso && CfiICallGeneralizePointers)
635  D.Diag(diag::err_drv_argument_not_allowed_with)
636  << "-fsanitize-cfi-cross-dso"
637  << "-fsanitize-cfi-icall-generalize-pointers";
638  }
639 
640  Stats = Args.hasFlag(options::OPT_fsanitize_stats,
641  options::OPT_fno_sanitize_stats, false);
642 
643  if (MinimalRuntime) {
644  SanitizerMask IncompatibleMask =
645  Kinds & ~setGroupBits(CompatibleWithMinimalRuntime);
646  if (IncompatibleMask)
647  D.Diag(clang::diag::err_drv_argument_not_allowed_with)
648  << "-fsanitize-minimal-runtime"
649  << lastArgumentForMask(D, Args, IncompatibleMask);
650 
651  SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
652  if (NonTrappingCfi)
653  D.Diag(clang::diag::err_drv_argument_only_allowed_with)
654  << "fsanitize-minimal-runtime"
655  << "fsanitize-trap=cfi";
656  }
657 
658  // Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
659  // enabled sanitizers.
660  for (const auto *Arg : Args) {
661  if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
662  int LegacySanitizeCoverage;
663  if (Arg->getNumValues() == 1 &&
664  !StringRef(Arg->getValue(0))
665  .getAsInteger(0, LegacySanitizeCoverage)) {
666  CoverageFeatures = 0;
667  Arg->claim();
668  if (LegacySanitizeCoverage != 0) {
669  D.Diag(diag::warn_drv_deprecated_arg)
670  << Arg->getAsString(Args) << "-fsanitize-coverage=trace-pc-guard";
671  }
672  continue;
673  }
674  CoverageFeatures |= parseCoverageFeatures(D, Arg);
675 
676  // Disable coverage and not claim the flags if there is at least one
677  // non-supporting sanitizer.
678  if (!(AllAddedKinds & ~AllRemove & ~setGroupBits(SupportsCoverage))) {
679  Arg->claim();
680  } else {
681  CoverageFeatures = 0;
682  }
683  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
684  Arg->claim();
685  CoverageFeatures &= ~parseCoverageFeatures(D, Arg);
686  }
687  }
688  // Choose at most one coverage type: function, bb, or edge.
689  if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageBB))
690  D.Diag(clang::diag::err_drv_argument_not_allowed_with)
691  << "-fsanitize-coverage=func"
692  << "-fsanitize-coverage=bb";
693  if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures & CoverageEdge))
694  D.Diag(clang::diag::err_drv_argument_not_allowed_with)
695  << "-fsanitize-coverage=func"
696  << "-fsanitize-coverage=edge";
697  if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
698  D.Diag(clang::diag::err_drv_argument_not_allowed_with)
699  << "-fsanitize-coverage=bb"
700  << "-fsanitize-coverage=edge";
701  // Basic block tracing and 8-bit counters require some type of coverage
702  // enabled.
703  if (CoverageFeatures & CoverageTraceBB)
704  D.Diag(clang::diag::warn_drv_deprecated_arg)
705  << "-fsanitize-coverage=trace-bb"
706  << "-fsanitize-coverage=trace-pc-guard";
707  if (CoverageFeatures & Coverage8bitCounters)
708  D.Diag(clang::diag::warn_drv_deprecated_arg)
709  << "-fsanitize-coverage=8bit-counters"
710  << "-fsanitize-coverage=trace-pc-guard";
711 
712  int InsertionPointTypes = CoverageFunc | CoverageBB | CoverageEdge;
713  int InstrumentationTypes =
715  if ((CoverageFeatures & InsertionPointTypes) &&
716  !(CoverageFeatures & InstrumentationTypes)) {
717  D.Diag(clang::diag::warn_drv_deprecated_arg)
718  << "-fsanitize-coverage=[func|bb|edge]"
719  << "-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
720  }
721 
722  // trace-pc w/o func/bb/edge implies edge.
723  if (!(CoverageFeatures & InsertionPointTypes)) {
724  if (CoverageFeatures &
726  CoverageFeatures |= CoverageEdge;
727 
728  if (CoverageFeatures & CoverageStackDepth)
729  CoverageFeatures |= CoverageFunc;
730  }
731 
732  SharedRuntime =
733  Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
734  TC.getTriple().isAndroid() || TC.getTriple().isOSFuchsia() ||
735  TC.getTriple().isOSDarwin());
736 
737  ImplicitCfiRuntime = TC.getTriple().isAndroid();
738 
739  if (AllAddedKinds & SanitizerKind::Address) {
740  NeedPIE |= TC.getTriple().isOSFuchsia();
741  if (Arg *A =
742  Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
743  StringRef S = A->getValue();
744  // Legal values are 0 and 1, 2, but in future we may add more levels.
745  if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
746  AsanFieldPadding > 2) {
747  D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
748  }
749  }
750 
751  if (Arg *WindowsDebugRTArg =
752  Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
753  options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
754  options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
755  switch (WindowsDebugRTArg->getOption().getID()) {
756  case options::OPT__SLASH_MTd:
757  case options::OPT__SLASH_MDd:
758  case options::OPT__SLASH_LDd:
759  D.Diag(clang::diag::err_drv_argument_not_allowed_with)
760  << WindowsDebugRTArg->getAsString(Args)
761  << lastArgumentForMask(D, Args, SanitizerKind::Address);
762  D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
763  }
764  }
765 
766  AsanUseAfterScope = Args.hasFlag(
767  options::OPT_fsanitize_address_use_after_scope,
768  options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
769 
770  AsanPoisonCustomArrayCookie = Args.hasFlag(
771  options::OPT_fsanitize_address_poison_custom_array_cookie,
772  options::OPT_fno_sanitize_address_poison_custom_array_cookie,
773  AsanPoisonCustomArrayCookie);
774 
775  // As a workaround for a bug in gold 2.26 and earlier, dead stripping of
776  // globals in ASan is disabled by default on ELF targets.
777  // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
778  AsanGlobalsDeadStripping =
779  !TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSFuchsia() ||
780  TC.getTriple().isPS4() ||
781  Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
782 
783  AsanUseOdrIndicator =
784  Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
785  options::OPT_fno_sanitize_address_use_odr_indicator,
786  AsanUseOdrIndicator);
787 
788  if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
789  AsanInvalidPointerCmp = true;
790  }
791 
792  if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
793  AsanInvalidPointerSub = true;
794  }
795 
796  } else {
797  AsanUseAfterScope = false;
798  // -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
799  SanitizerMask DetectInvalidPointerPairs =
800  SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
801  if (AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) {
802  TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
803  << lastArgumentForMask(D, Args,
804  SanitizerKind::PointerCompare |
805  SanitizerKind::PointerSubtract)
806  << "-fsanitize=address";
807  }
808  }
809 
810  if (AllAddedKinds & SanitizerKind::HWAddress) {
811  if (Arg *HwasanAbiArg =
812  Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
813  HwasanAbi = HwasanAbiArg->getValue();
814  if (HwasanAbi != "platform" && HwasanAbi != "interceptor")
815  D.Diag(clang::diag::err_drv_invalid_value)
816  << HwasanAbiArg->getAsString(Args) << HwasanAbi;
817  } else {
818  HwasanAbi = "interceptor";
819  }
820  }
821 
822  if (AllAddedKinds & SanitizerKind::SafeStack) {
823  // SafeStack runtime is built into the system on Fuchsia.
824  SafeStackRuntime = !TC.getTriple().isOSFuchsia();
825  }
826 
827  // Parse -link-cxx-sanitizer flag.
828  LinkCXXRuntimes =
829  Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.CCCIsCXX();
830 
831  // Finally, initialize the set of available and recoverable sanitizers.
832  Sanitizers.Mask |= Kinds;
833  RecoverableSanitizers.Mask |= RecoverableKinds;
834  TrapSanitizers.Mask |= TrappingKinds;
835  assert(!(RecoverableKinds & TrappingKinds) &&
836  "Overlap between recoverable and trapping sanitizers");
837 }
838 
839 static std::string toString(const clang::SanitizerSet &Sanitizers) {
840  std::string Res;
841 #define SANITIZER(NAME, ID) \
842  if (Sanitizers.has(SanitizerKind::ID)) { \
843  if (!Res.empty()) \
844  Res += ","; \
845  Res += NAME; \
846  }
847 #include "clang/Basic/Sanitizers.def"
848  return Res;
849 }
850 
851 static void addIncludeLinkerOption(const ToolChain &TC,
852  const llvm::opt::ArgList &Args,
853  llvm::opt::ArgStringList &CmdArgs,
854  StringRef SymbolName) {
855  SmallString<64> LinkerOptionFlag;
856  LinkerOptionFlag = "--linker-option=/include:";
857  if (TC.getTriple().getArch() == llvm::Triple::x86) {
858  // Win32 mangles C function names with a '_' prefix.
859  LinkerOptionFlag += '_';
860  }
861  LinkerOptionFlag += SymbolName;
862  CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
863 }
864 
865 void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
866  llvm::opt::ArgStringList &CmdArgs,
867  types::ID InputType) const {
868  // NVPTX doesn't currently support sanitizers. Bailing out here means that
869  // e.g. -fsanitize=address applies only to host code, which is what we want
870  // for now.
871  if (TC.getTriple().isNVPTX())
872  return;
873 
874  // Translate available CoverageFeatures to corresponding clang-cc1 flags.
875  // Do it even if Sanitizers.empty() since some forms of coverage don't require
876  // sanitizers.
877  std::pair<int, const char *> CoverageFlags[] = {
878  std::make_pair(CoverageFunc, "-fsanitize-coverage-type=1"),
879  std::make_pair(CoverageBB, "-fsanitize-coverage-type=2"),
880  std::make_pair(CoverageEdge, "-fsanitize-coverage-type=3"),
881  std::make_pair(CoverageIndirCall, "-fsanitize-coverage-indirect-calls"),
882  std::make_pair(CoverageTraceBB, "-fsanitize-coverage-trace-bb"),
883  std::make_pair(CoverageTraceCmp, "-fsanitize-coverage-trace-cmp"),
884  std::make_pair(CoverageTraceDiv, "-fsanitize-coverage-trace-div"),
885  std::make_pair(CoverageTraceGep, "-fsanitize-coverage-trace-gep"),
886  std::make_pair(Coverage8bitCounters, "-fsanitize-coverage-8bit-counters"),
887  std::make_pair(CoverageTracePC, "-fsanitize-coverage-trace-pc"),
888  std::make_pair(CoverageTracePCGuard, "-fsanitize-coverage-trace-pc-guard"),
889  std::make_pair(CoverageInline8bitCounters, "-fsanitize-coverage-inline-8bit-counters"),
890  std::make_pair(CoveragePCTable, "-fsanitize-coverage-pc-table"),
891  std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune"),
892  std::make_pair(CoverageStackDepth, "-fsanitize-coverage-stack-depth")};
893  for (auto F : CoverageFlags) {
894  if (CoverageFeatures & F.first)
895  CmdArgs.push_back(F.second);
896  }
897 
898  if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
899  // Instruct the code generator to embed linker directives in the object file
900  // that cause the required runtime libraries to be linked.
901  CmdArgs.push_back(Args.MakeArgString(
902  "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone")));
903  if (types::isCXX(InputType))
904  CmdArgs.push_back(Args.MakeArgString(
905  "--dependent-lib=" + TC.getCompilerRT(Args, "ubsan_standalone_cxx")));
906  }
907  if (TC.getTriple().isOSWindows() && needsStatsRt()) {
908  CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
909  TC.getCompilerRT(Args, "stats_client")));
910 
911  // The main executable must export the stats runtime.
912  // FIXME: Only exporting from the main executable (e.g. based on whether the
913  // translation unit defines main()) would save a little space, but having
914  // multiple copies of the runtime shouldn't hurt.
915  CmdArgs.push_back(Args.MakeArgString("--dependent-lib=" +
916  TC.getCompilerRT(Args, "stats")));
917  addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
918  }
919 
920  if (Sanitizers.empty())
921  return;
922  CmdArgs.push_back(Args.MakeArgString("-fsanitize=" + toString(Sanitizers)));
923 
924  if (!RecoverableSanitizers.empty())
925  CmdArgs.push_back(Args.MakeArgString("-fsanitize-recover=" +
926  toString(RecoverableSanitizers)));
927 
928  if (!TrapSanitizers.empty())
929  CmdArgs.push_back(
930  Args.MakeArgString("-fsanitize-trap=" + toString(TrapSanitizers)));
931 
932  for (const auto &BLPath : BlacklistFiles) {
933  SmallString<64> BlacklistOpt("-fsanitize-blacklist=");
934  BlacklistOpt += BLPath;
935  CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
936  }
937  for (const auto &Dep : ExtraDeps) {
938  SmallString<64> ExtraDepOpt("-fdepfile-entry=");
939  ExtraDepOpt += Dep;
940  CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
941  }
942 
943  if (MsanTrackOrigins)
944  CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-track-origins=" +
945  Twine(MsanTrackOrigins)));
946 
947  if (MsanUseAfterDtor)
948  CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
949 
950  // FIXME: Pass these parameters as function attributes, not as -llvm flags.
951  if (!TsanMemoryAccess) {
952  CmdArgs.push_back("-mllvm");
953  CmdArgs.push_back("-tsan-instrument-memory-accesses=0");
954  CmdArgs.push_back("-mllvm");
955  CmdArgs.push_back("-tsan-instrument-memintrinsics=0");
956  }
957  if (!TsanFuncEntryExit) {
958  CmdArgs.push_back("-mllvm");
959  CmdArgs.push_back("-tsan-instrument-func-entry-exit=0");
960  }
961  if (!TsanAtomics) {
962  CmdArgs.push_back("-mllvm");
963  CmdArgs.push_back("-tsan-instrument-atomics=0");
964  }
965 
966  if (CfiCrossDso)
967  CmdArgs.push_back("-fsanitize-cfi-cross-dso");
968 
969  if (CfiICallGeneralizePointers)
970  CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers");
971 
972  if (Stats)
973  CmdArgs.push_back("-fsanitize-stats");
974 
975  if (MinimalRuntime)
976  CmdArgs.push_back("-fsanitize-minimal-runtime");
977 
978  if (AsanFieldPadding)
979  CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
980  Twine(AsanFieldPadding)));
981 
982  if (AsanUseAfterScope)
983  CmdArgs.push_back("-fsanitize-address-use-after-scope");
984 
985  if (AsanPoisonCustomArrayCookie)
986  CmdArgs.push_back("-fsanitize-address-poison-custom-array-cookie");
987 
988  if (AsanGlobalsDeadStripping)
989  CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
990 
991  if (AsanUseOdrIndicator)
992  CmdArgs.push_back("-fsanitize-address-use-odr-indicator");
993 
994  if (AsanInvalidPointerCmp) {
995  CmdArgs.push_back("-mllvm");
996  CmdArgs.push_back("-asan-detect-invalid-pointer-cmp");
997  }
998 
999  if (AsanInvalidPointerSub) {
1000  CmdArgs.push_back("-mllvm");
1001  CmdArgs.push_back("-asan-detect-invalid-pointer-sub");
1002  }
1003 
1004  if (!HwasanAbi.empty()) {
1005  CmdArgs.push_back("-default-function-attr");
1006  CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
1007  }
1008 
1009  // MSan: Workaround for PR16386.
1010  // ASan: This is mainly to help LSan with cases such as
1011  // https://github.com/google/sanitizers/issues/373
1012  // We can't make this conditional on -fsanitize=leak, as that flag shouldn't
1013  // affect compilation.
1014  if (Sanitizers.has(SanitizerKind::Memory) ||
1015  Sanitizers.has(SanitizerKind::Address))
1016  CmdArgs.push_back("-fno-assume-sane-operator-new");
1017 
1018  // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
1019  // enabled.
1020  if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
1021  !Args.hasArg(options::OPT_fvisibility_EQ)) {
1022  TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
1023  << lastArgumentForMask(TC.getDriver(), Args,
1024  Sanitizers.Mask & CFIClasses)
1025  << "-fvisibility=";
1026  }
1027 }
1028 
1029 SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
1030  bool DiagnoseErrors) {
1031  assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
1032  A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1033  A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1034  A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1035  A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1036  A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
1037  "Invalid argument in parseArgValues!");
1038  SanitizerMask Kinds;
1039  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1040  const char *Value = A->getValue(i);
1042  // Special case: don't accept -fsanitize=all.
1043  if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
1044  0 == strcmp("all", Value))
1045  Kind = SanitizerMask();
1046  else
1047  Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
1048 
1049  if (Kind)
1050  Kinds |= Kind;
1051  else if (DiagnoseErrors)
1052  D.Diag(clang::diag::err_drv_unsupported_option_argument)
1053  << A->getOption().getName() << Value;
1054  }
1055  return Kinds;
1056 }
1057 
1058 int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A) {
1059  assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
1060  A->getOption().matches(options::OPT_fno_sanitize_coverage));
1061  int Features = 0;
1062  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1063  const char *Value = A->getValue(i);
1064  int F = llvm::StringSwitch<int>(Value)
1065  .Case("func", CoverageFunc)
1066  .Case("bb", CoverageBB)
1067  .Case("edge", CoverageEdge)
1068  .Case("indirect-calls", CoverageIndirCall)
1069  .Case("trace-bb", CoverageTraceBB)
1070  .Case("trace-cmp", CoverageTraceCmp)
1071  .Case("trace-div", CoverageTraceDiv)
1072  .Case("trace-gep", CoverageTraceGep)
1073  .Case("8bit-counters", Coverage8bitCounters)
1074  .Case("trace-pc", CoverageTracePC)
1075  .Case("trace-pc-guard", CoverageTracePCGuard)
1076  .Case("no-prune", CoverageNoPrune)
1077  .Case("inline-8bit-counters", CoverageInline8bitCounters)
1078  .Case("pc-table", CoveragePCTable)
1079  .Case("stack-depth", CoverageStackDepth)
1080  .Default(0);
1081  if (F == 0)
1082  D.Diag(clang::diag::err_drv_unsupported_option_argument)
1083  << A->getOption().getName() << Value;
1084  Features |= F;
1085  }
1086  return Features;
1087 }
1088 
1089 std::string lastArgumentForMask(const Driver &D, const llvm::opt::ArgList &Args,
1090  SanitizerMask Mask) {
1091  for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1092  E = Args.rend();
1093  I != E; ++I) {
1094  const auto *Arg = *I;
1095  if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1096  SanitizerMask AddKinds =
1097  expandSanitizerGroups(parseArgValues(D, Arg, false));
1098  if (AddKinds & Mask)
1099  return describeSanitizeArg(Arg, Mask);
1100  } else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1101  SanitizerMask RemoveKinds =
1102  expandSanitizerGroups(parseArgValues(D, Arg, false));
1103  Mask &= ~RemoveKinds;
1104  }
1105  }
1106  llvm_unreachable("arg list didn't provide expected value");
1107 }
1108 
1109 std::string describeSanitizeArg(const llvm::opt::Arg *A, SanitizerMask Mask) {
1110  assert(A->getOption().matches(options::OPT_fsanitize_EQ)
1111  && "Invalid argument in describeSanitizerArg!");
1112 
1113  std::string Sanitizers;
1114  for (int i = 0, n = A->getNumValues(); i != n; ++i) {
1116  parseSanitizerValue(A->getValue(i), /*AllowGroups=*/true)) &
1117  Mask) {
1118  if (!Sanitizers.empty())
1119  Sanitizers += ",";
1120  Sanitizers += A->getValue(i);
1121  }
1122  }
1123 
1124  assert(!Sanitizers.empty() && "arg didn't provide expected value");
1125  return "-fsanitize=" + Sanitizers;
1126 }
static const SanitizerMask NeedsUbsanRt
static const SanitizerMask RecoverableByDefault
static const SanitizerMask AlwaysRecoverable
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
Definition: Driver.h:530
static const SanitizerMask SupportsCoverage
constexpr XRayInstrMask Function
Definition: XRayInstr.h:38
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:108
static const SanitizerMask NeedsUnwindTables
long i
Definition: xmmintrin.h:1456
Defines the clang::SanitizerKind enum.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static const SanitizerMask CFIClasses
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:173
CoverageFeature
static const SanitizerMask NotAllowedWithMinimalRuntime
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:57
const llvm::opt::Arg * getRTTIArg() const
Definition: ToolChain.h:246
static const SanitizerMask NeedsUbsanCxxRt
static const SanitizerMask NeedsLTO
static SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors)
Parse a -fsanitize= or -fno-sanitize= argument&#39;s values, diagnosing any invalid components.
static const SanitizerMask NotAllowedWithTrap
static const SanitizerMask TrappingSupported
static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A)
Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid components.
static void addIncludeLinkerOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, StringRef SymbolName)
Kind
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component, FileType Type=ToolChain::FT_Static) const
Definition: ToolChain.cpp:364
const Driver & getDriver() const
Definition: ToolChain.h:193
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Definition: Driver.h:172
static const SanitizerMask TrappingDefault
virtual SanitizerMask getDefaultSanitizers() const
Return sanitizers which are enabled by default.
Definition: ToolChain.h:591
Dataflow Directional Tag Classes.
static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, std::vector< std::string > &BlacklistFiles)
static const SanitizerMask RequiresPIE
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
static const SanitizerMask CompatibleWithMinimalRuntime
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Definition: Sanitizers.cpp:27
static SanitizerMask setGroupBits(SanitizerMask Kinds)
Sets group bits for every group that has at least one representative already enabled in Kinds...
bool isCXX(ID Id)
isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
Definition: Types.cpp:135
RTTIMode getRTTIMode() const
Definition: ToolChain.h:249
const llvm::Triple & getTriple() const
Definition: ToolChain.h:195
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:894
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables...
Definition: Sanitizers.cpp:37
static const SanitizerMask Unrecoverable
static const SanitizerMask LegacyFsanitizeRecoverMask
static SanitizerMask parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args)
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args)
Parses the sanitizer arguments from an argument list.
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 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...
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:88
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:131