16 #include "llvm/ADT/StringExtras.h" 17 #include "llvm/ADT/StringSwitch.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/Path.h" 20 #include "llvm/Support/SpecialCaseList.h" 23 using namespace clang;
36 Undefined | Integer |
Nullability | DataFlow | Fuzzer |
45 CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
81 const llvm::opt::ArgList &Args,
96 std::string &BLPath) {
97 const char *BlacklistFile =
nullptr;
99 BlacklistFile =
"asan_blacklist.txt";
100 else if (Kinds & HWAddress)
101 BlacklistFile =
"hwasan_blacklist.txt";
102 else if (Kinds & Memory)
103 BlacklistFile =
"msan_blacklist.txt";
104 else if (Kinds & Thread)
105 BlacklistFile =
"tsan_blacklist.txt";
106 else if (Kinds & DataFlow)
107 BlacklistFile =
"dfsan_abilist.txt";
108 else if (Kinds & CFI)
109 BlacklistFile =
"cfi_blacklist.txt";
110 else if (Kinds & (Undefined | Integer |
Nullability))
111 BlacklistFile =
"ubsan_blacklist.txt";
115 llvm::sys::path::append(Path, BlacklistFile);
125 #define SANITIZER(NAME, ID) 126 #define SANITIZER_GROUP(NAME, ID, ALIAS) \ 127 if (Kinds & SanitizerKind::ID) \ 128 Kinds |= SanitizerKind::ID##Group; 129 #include "clang/Basic/Sanitizers.def" 134 const llvm::opt::ArgList &Args) {
141 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
143 const auto *Arg = *I;
144 if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
148 if (
SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
150 S.
Mask = InvalidValues;
151 D.
Diag(diag::err_drv_unsupported_option_argument) <<
"-fsanitize-trap" 155 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
158 }
else if (Arg->getOption().matches(
159 options::OPT_fsanitize_undefined_trap_on_error)) {
163 }
else if (Arg->getOption().matches(
164 options::OPT_fno_sanitize_undefined_trap_on_error)) {
173 return TrappingKinds;
176 bool SanitizerArgs::needsUbsanRt()
const {
178 if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
179 needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() || needsScudoRt())
182 return (Sanitizers.Mask &
NeedsUbsanRt & ~TrapSanitizers.Mask) ||
186 bool SanitizerArgs::needsCfiRt()
const {
187 return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
191 bool SanitizerArgs::needsCfiDiagRt()
const {
192 return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
196 bool SanitizerArgs::requiresPIE()
const {
200 bool SanitizerArgs::needsUnwindTables()
const {
205 const llvm::opt::ArgList &Args) {
225 Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
226 options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
229 Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
230 bool RemoveObjectSizeAtO0 =
231 !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
233 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
235 const auto *Arg = *I;
236 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
240 if (RemoveObjectSizeAtO0) {
241 AllRemove |= SanitizerKind::ObjectSize;
245 if (Add & SanitizerKind::ObjectSize)
246 D.
Diag(diag::warn_drv_object_size_disabled_O0)
247 << Arg->getAsString(Args);
258 Add & InvalidTrappingKinds & ~DiagnosedKinds) {
260 D.
Diag(diag::err_drv_argument_not_allowed_with)
261 << Desc <<
"-fsanitize-trap=undefined";
262 DiagnosedKinds |= KindsToDiagnose;
264 Add &= ~InvalidTrappingKinds;
266 if (MinimalRuntime) {
270 D.
Diag(diag::err_drv_argument_not_allowed_with)
271 << Desc <<
"-fsanitize-minimal-runtime";
272 DiagnosedKinds |= KindsToDiagnose;
277 if (
SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
279 D.
Diag(diag::err_drv_unsupported_opt_for_target)
281 DiagnosedKinds |= KindsToDiagnose;
289 (RTTIMode == ToolChain::RM_DisabledImplicitly ||
290 RTTIMode == ToolChain::RM_DisabledExplicitly)) {
291 if (RTTIMode == ToolChain::RM_DisabledImplicitly)
294 D.
Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
296 const llvm::opt::Arg *NoRTTIArg = TC.
getRTTIArg();
298 "RTTI disabled explicitly but we have no argument!");
299 D.
Diag(diag::err_drv_argument_not_allowed_with)
300 <<
"-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
312 Add &= ~InvalidTrappingKinds;
313 if (MinimalRuntime) {
322 if (Add & FuzzerNoLink) {
331 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
343 if ((Kinds & Vptr) &&
344 (RTTIMode == ToolChain::RM_DisabledImplicitly ||
345 RTTIMode == ToolChain::RM_DisabledExplicitly)) {
351 D.
Diag(diag::err_drv_argument_only_allowed_with)
359 if (~Supported & Vptr) {
364 KindsToDiagnose &= ~CFI;
365 if (KindsToDiagnose) {
367 S.
Mask = KindsToDiagnose;
368 D.
Diag(diag::err_drv_unsupported_opt_for_target)
370 Kinds &= ~KindsToDiagnose;
375 std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
376 std::make_pair(Address, Thread | Memory),
377 std::make_pair(Thread, Memory),
378 std::make_pair(Leak, Thread | Memory),
379 std::make_pair(KernelAddress, Address | Leak | Thread | Memory),
380 std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress),
381 std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory |
383 std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory |
384 KernelAddress | Efficiency)};
385 for (
auto G : IncompatibleGroups) {
389 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
392 Kinds &= ~Incompatible;
404 for (
const auto *Arg : Args) {
405 const char *DeprecatedReplacement =
nullptr;
406 if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
407 DeprecatedReplacement =
408 "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all";
411 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
412 DeprecatedReplacement =
"-fno-sanitize-recover=undefined,integer' or " 413 "'-fno-sanitize-recover=all";
416 }
else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
423 SetToDiagnose.
Mask |= KindsToDiagnose;
424 D.
Diag(diag::err_drv_unsupported_option_argument)
425 << Arg->getOption().getName() <<
toString(SetToDiagnose);
426 DiagnosedUnrecoverableKinds |= KindsToDiagnose;
430 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
434 if (DeprecatedReplacement) {
435 D.
Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
436 << DeprecatedReplacement;
439 RecoverableKinds &= Kinds;
442 TrappingKinds &= Kinds;
443 RecoverableKinds &= ~TrappingKinds;
450 BlacklistFiles.push_back(BLPath);
453 for (
const auto *Arg : Args) {
454 if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
456 std::string BLPath = Arg->getValue();
457 if (llvm::sys::fs::exists(BLPath)) {
458 BlacklistFiles.push_back(BLPath);
459 ExtraDeps.push_back(BLPath);
461 D.
Diag(clang::diag::err_drv_no_such_file) << BLPath;
463 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
465 BlacklistFiles.clear();
472 std::unique_ptr<llvm::SpecialCaseList> SCL(
475 D.
Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
479 if (AllAddedKinds & Memory) {
481 Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
482 options::OPT_fsanitize_memory_track_origins,
483 options::OPT_fno_sanitize_memory_track_origins)) {
484 if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
485 MsanTrackOrigins = 2;
486 }
else if (A->getOption().matches(
487 options::OPT_fno_sanitize_memory_track_origins)) {
488 MsanTrackOrigins = 0;
490 StringRef S = A->getValue();
491 if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
492 MsanTrackOrigins > 2) {
493 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
498 Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor,
499 options::OPT_fno_sanitize_memory_use_after_dtor,
501 NeedPIE |= !(TC.
getTriple().isOSLinux() &&
502 TC.
getTriple().getArch() == llvm::Triple::x86_64);
504 MsanUseAfterDtor =
false;
507 if (AllAddedKinds & Thread) {
508 TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access,
509 options::OPT_fno_sanitize_thread_memory_access,
511 TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit,
512 options::OPT_fno_sanitize_thread_func_entry_exit,
514 TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics,
515 options::OPT_fno_sanitize_thread_atomics,
519 if (AllAddedKinds & CFI) {
520 CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
521 options::OPT_fno_sanitize_cfi_cross_dso,
false);
524 NeedPIE |= CfiCrossDso;
525 CfiICallGeneralizePointers =
526 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
528 if (CfiCrossDso && CfiICallGeneralizePointers)
529 D.
Diag(diag::err_drv_argument_not_allowed_with)
530 <<
"-fsanitize-cfi-cross-dso" 531 <<
"-fsanitize-cfi-icall-generalize-pointers";
534 Stats = Args.hasFlag(options::OPT_fsanitize_stats,
535 options::OPT_fno_sanitize_stats,
false);
537 if (MinimalRuntime) {
540 if (IncompatibleMask)
541 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
542 <<
"-fsanitize-minimal-runtime" 547 D.
Diag(clang::diag::err_drv_argument_only_allowed_with)
548 <<
"fsanitize-minimal-runtime" 549 <<
"fsanitize-trap=cfi";
554 for (
const auto *Arg : Args) {
555 if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
556 int LegacySanitizeCoverage;
557 if (Arg->getNumValues() == 1 &&
558 !StringRef(Arg->getValue(0))
559 .getAsInteger(0, LegacySanitizeCoverage)) {
560 CoverageFeatures = 0;
562 if (LegacySanitizeCoverage != 0) {
563 D.
Diag(diag::warn_drv_deprecated_arg)
564 << Arg->getAsString(Args) <<
"-fsanitize-coverage=trace-pc-guard";
575 CoverageFeatures = 0;
577 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
584 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
585 <<
"-fsanitize-coverage=func" 586 <<
"-fsanitize-coverage=bb";
587 if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures &
CoverageEdge))
588 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
589 <<
"-fsanitize-coverage=func" 590 <<
"-fsanitize-coverage=edge";
591 if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
592 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
593 <<
"-fsanitize-coverage=bb" 594 <<
"-fsanitize-coverage=edge";
598 D.
Diag(clang::diag::warn_drv_deprecated_arg)
599 <<
"-fsanitize-coverage=trace-bb" 600 <<
"-fsanitize-coverage=trace-pc-guard";
602 D.
Diag(clang::diag::warn_drv_deprecated_arg)
603 <<
"-fsanitize-coverage=8bit-counters" 604 <<
"-fsanitize-coverage=trace-pc-guard";
606 int InsertionPointTypes = CoverageFunc | CoverageBB |
CoverageEdge;
607 int InstrumentationTypes =
609 if ((CoverageFeatures & InsertionPointTypes) &&
610 !(CoverageFeatures & InstrumentationTypes)) {
611 D.
Diag(clang::diag::warn_drv_deprecated_arg)
612 <<
"-fsanitize-coverage=[func|bb|edge]" 613 <<
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
617 if (!(CoverageFeatures & InsertionPointTypes)) {
618 if (CoverageFeatures &
627 Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
631 ImplicitCfiRuntime = TC.
getTriple().isAndroid();
633 if (AllAddedKinds & Address) {
636 Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
637 StringRef S = A->getValue();
639 if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
640 AsanFieldPadding > 2) {
641 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
645 if (Arg *WindowsDebugRTArg =
646 Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
647 options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
648 options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
649 switch (WindowsDebugRTArg->getOption().getID()) {
650 case options::OPT__SLASH_MTd:
651 case options::OPT__SLASH_MDd:
652 case options::OPT__SLASH_LDd:
653 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
654 << WindowsDebugRTArg->getAsString(Args)
656 D.
Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
660 AsanUseAfterScope = Args.hasFlag(
661 options::OPT_fsanitize_address_use_after_scope,
662 options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
667 AsanGlobalsDeadStripping =
669 Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
671 AsanUseAfterScope =
false;
674 if (AllAddedKinds & SafeStack) {
676 SafeStackRuntime = !TC.
getTriple().isOSFuchsia();
681 Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.
CCCIsCXX();
684 Sanitizers.Mask |= Kinds;
685 RecoverableSanitizers.Mask |= RecoverableKinds;
686 TrapSanitizers.Mask |= TrappingKinds;
687 assert(!(RecoverableKinds & TrappingKinds) &&
688 "Overlap between recoverable and trapping sanitizers");
693 #define SANITIZER(NAME, ID) \ 694 if (Sanitizers.has(ID)) { \ 699 #include "clang/Basic/Sanitizers.def" 704 const llvm::opt::ArgList &Args,
705 llvm::opt::ArgStringList &CmdArgs,
706 StringRef SymbolName) {
708 LinkerOptionFlag =
"--linker-option=/include:";
709 if (TC.
getTriple().getArch() == llvm::Triple::x86) {
711 LinkerOptionFlag +=
'_';
713 LinkerOptionFlag += SymbolName;
714 CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
717 void SanitizerArgs::addArgs(
const ToolChain &TC,
const llvm::opt::ArgList &Args,
718 llvm::opt::ArgStringList &CmdArgs,
729 std::pair<int, const char *> CoverageFlags[] = {
730 std::make_pair(
CoverageFunc,
"-fsanitize-coverage-type=1"),
731 std::make_pair(
CoverageBB,
"-fsanitize-coverage-type=2"),
732 std::make_pair(
CoverageEdge,
"-fsanitize-coverage-type=3"),
745 for (
auto F : CoverageFlags) {
746 if (CoverageFeatures & F.first)
747 CmdArgs.push_back(F.second);
750 if (TC.
getTriple().isOSWindows() && needsUbsanRt()) {
753 CmdArgs.push_back(Args.MakeArgString(
754 "--dependent-lib=" + TC.
getCompilerRT(Args,
"ubsan_standalone")));
756 CmdArgs.push_back(Args.MakeArgString(
757 "--dependent-lib=" + TC.
getCompilerRT(Args,
"ubsan_standalone_cxx")));
759 if (TC.
getTriple().isOSWindows() && needsStatsRt()) {
760 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" +
767 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" +
772 if (Sanitizers.empty())
774 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize=" +
toString(Sanitizers)));
776 if (!RecoverableSanitizers.empty())
777 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-recover=" +
780 if (!TrapSanitizers.empty())
782 Args.MakeArgString(
"-fsanitize-trap=" +
toString(TrapSanitizers)));
784 for (
const auto &BLPath : BlacklistFiles) {
786 BlacklistOpt += BLPath;
787 CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
789 for (
const auto &Dep : ExtraDeps) {
792 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
795 if (MsanTrackOrigins)
796 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-memory-track-origins=" +
797 Twine(MsanTrackOrigins)));
799 if (MsanUseAfterDtor)
800 CmdArgs.push_back(
"-fsanitize-memory-use-after-dtor");
803 if (!TsanMemoryAccess) {
804 CmdArgs.push_back(
"-mllvm");
805 CmdArgs.push_back(
"-tsan-instrument-memory-accesses=0");
806 CmdArgs.push_back(
"-mllvm");
807 CmdArgs.push_back(
"-tsan-instrument-memintrinsics=0");
809 if (!TsanFuncEntryExit) {
810 CmdArgs.push_back(
"-mllvm");
811 CmdArgs.push_back(
"-tsan-instrument-func-entry-exit=0");
814 CmdArgs.push_back(
"-mllvm");
815 CmdArgs.push_back(
"-tsan-instrument-atomics=0");
819 CmdArgs.push_back(
"-fsanitize-cfi-cross-dso");
821 if (CfiICallGeneralizePointers)
822 CmdArgs.push_back(
"-fsanitize-cfi-icall-generalize-pointers");
825 CmdArgs.push_back(
"-fsanitize-stats");
828 CmdArgs.push_back(
"-fsanitize-minimal-runtime");
830 if (AsanFieldPadding)
831 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-address-field-padding=" +
832 Twine(AsanFieldPadding)));
834 if (AsanUseAfterScope)
835 CmdArgs.push_back(
"-fsanitize-address-use-after-scope");
837 if (AsanGlobalsDeadStripping)
838 CmdArgs.push_back(
"-fsanitize-address-globals-dead-stripping");
845 if (Sanitizers.has(Memory) || Sanitizers.has(Address))
846 CmdArgs.push_back(
"-fno-assume-sane-operator-new");
851 !Args.hasArg(options::OPT_fvisibility_EQ)) {
852 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
860 bool DiagnoseErrors) {
861 assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
862 A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
863 A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
864 A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
865 A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
866 A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
867 "Invalid argument in parseArgValues!");
869 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
870 const char *
Value = A->getValue(i);
873 if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
874 0 == strcmp(
"all", Value))
877 else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
878 0 == strcmp(
"efficiency-all", Value))
885 else if (DiagnoseErrors)
886 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
887 << A->getOption().getName() <<
Value;
893 assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
894 A->getOption().matches(options::OPT_fno_sanitize_coverage));
896 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
897 const char *
Value = A->getValue(i);
898 int F = llvm::StringSwitch<int>(
Value)
916 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
917 << A->getOption().getName() <<
Value;
925 for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
928 const auto *Arg = *I;
929 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
934 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
937 Mask &= ~RemoveKinds;
940 llvm_unreachable(
"arg list didn't provide expected value");
944 assert(A->getOption().matches(options::OPT_fsanitize_EQ)
945 &&
"Invalid argument in describeSanitizerArg!");
947 std::string Sanitizers;
948 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
952 if (!Sanitizers.empty())
954 Sanitizers += A->getValue(i);
958 assert(!Sanitizers.empty() &&
"arg didn't provide expected value");
959 return "-fsanitize=" + Sanitizers;
bool isUsingLTO() const
Returns true if we are performing any kind of LTO.
DiagnosticBuilder Diag(unsigned DiagID) const
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.
SanitizerMask Mask
Bitmask of enabled sanitizers.
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
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 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)
bool CCCIsCXX() const
Whether the driver should follow g++ like behavior.
Dataflow Directional Tag Classes.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
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).
static bool getDefaultBlacklist(const Driver &D, SanitizerMask Kinds, std::string &BLPath)
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables...
static SanitizerMask parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args)
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...
std::string ResourceDir
The path to the compiler resource directory.