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" 21 #include "llvm/Support/TargetParser.h" 24 using namespace clang;
37 Memory | Leak | Undefined |
Integer | ImplicitConversion |
45 ImplicitConversion |
Nullability | LocalBounds | CFI,
48 CFIVCall | CFINVCall | CFIMFCall | CFIDerivedCast | CFIUnrelatedCast,
84 const llvm::opt::ArgList &Args,
99 std::vector<std::string> &BlacklistFiles) {
103 } Blacklists[] = {{
"asan_blacklist.txt", Address},
104 {
"hwasan_blacklist.txt", HWAddress},
105 {
"msan_blacklist.txt", Memory},
106 {
"tsan_blacklist.txt", Thread},
107 {
"dfsan_abilist.txt", DataFlow},
108 {
"cfi_blacklist.txt", CFI},
111 for (
auto BL : Blacklists) {
112 if (!(Kinds & BL.Mask))
116 llvm::sys::path::append(Path,
"share", BL.File);
117 if (llvm::sys::fs::exists(Path))
118 BlacklistFiles.push_back(Path.str());
119 else if (BL.Mask == CFI)
122 D.
Diag(clang::diag::err_drv_no_such_file) << Path;
129 #define SANITIZER(NAME, ID) 130 #define SANITIZER_GROUP(NAME, ID, ALIAS) \ 131 if (Kinds & SanitizerKind::ID) \ 132 Kinds |= SanitizerKind::ID##Group; 133 #include "clang/Basic/Sanitizers.def" 138 const llvm::opt::ArgList &Args) {
145 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
147 const auto *Arg = *I;
148 if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
152 if (
SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
154 S.
Mask = InvalidValues;
155 D.
Diag(diag::err_drv_unsupported_option_argument) <<
"-fsanitize-trap" 159 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
162 }
else if (Arg->getOption().matches(
163 options::OPT_fsanitize_undefined_trap_on_error)) {
167 }
else if (Arg->getOption().matches(
168 options::OPT_fno_sanitize_undefined_trap_on_error)) {
177 return TrappingKinds;
180 bool SanitizerArgs::needsUbsanRt()
const {
182 if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
183 needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
184 (needsScudoRt() && !requiresMinimalRuntime()))
187 return (Sanitizers.Mask &
NeedsUbsanRt & ~TrapSanitizers.Mask) ||
191 bool SanitizerArgs::needsCfiRt()
const {
192 return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
196 bool SanitizerArgs::needsCfiDiagRt()
const {
197 return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
201 bool SanitizerArgs::requiresPIE()
const {
205 bool SanitizerArgs::needsUnwindTables()
const {
210 const llvm::opt::ArgList &Args) {
224 CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
225 options::OPT_fno_sanitize_cfi_cross_dso,
false);
234 Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
235 options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
238 Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
239 bool RemoveObjectSizeAtO0 =
240 !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
242 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
244 const auto *Arg = *I;
245 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
249 if (RemoveObjectSizeAtO0) {
250 AllRemove |= SanitizerKind::ObjectSize;
254 if (Add & SanitizerKind::ObjectSize)
255 D.
Diag(diag::warn_drv_object_size_disabled_O0)
256 << Arg->getAsString(Args);
267 Add & InvalidTrappingKinds & ~DiagnosedKinds) {
269 D.
Diag(diag::err_drv_argument_not_allowed_with)
270 << Desc <<
"-fsanitize-trap=undefined";
271 DiagnosedKinds |= KindsToDiagnose;
273 Add &= ~InvalidTrappingKinds;
275 if (MinimalRuntime) {
279 D.
Diag(diag::err_drv_argument_not_allowed_with)
280 << Desc <<
"-fsanitize-minimal-runtime";
281 DiagnosedKinds |= KindsToDiagnose;
296 if (CfiCrossDso && (Add & CFIMFCall & ~DiagnosedKinds)) {
297 D.
Diag(diag::err_drv_argument_not_allowed_with)
298 <<
"-fsanitize=cfi-mfcall" 299 <<
"-fsanitize-cfi-cross-dso";
301 DiagnosedKinds |= CFIMFCall;
304 if (
SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
306 D.
Diag(diag::err_drv_unsupported_opt_for_target)
308 DiagnosedKinds |= KindsToDiagnose;
315 if ((Add & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
316 if (
const llvm::opt::Arg *NoRTTIArg = TC.
getRTTIArg()) {
317 assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
318 "RTTI disabled without -fno-rtti option?");
321 D.
Diag(diag::err_drv_argument_not_allowed_with)
322 <<
"-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
326 D.
Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
338 Add &= ~InvalidTrappingKinds;
339 if (MinimalRuntime) {
350 if (Add & FuzzerNoLink) {
359 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
366 std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
367 std::make_pair(Address, Thread | Memory),
368 std::make_pair(Thread, Memory),
369 std::make_pair(Leak, Thread | Memory),
370 std::make_pair(KernelAddress, Address | Leak | Thread | Memory),
371 std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress),
372 std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory |
374 std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory |
375 KernelAddress | Efficiency),
376 std::make_pair(SafeStack, Address | HWAddress | Leak | Thread | Memory |
377 KernelAddress | Efficiency),
378 std::make_pair(ShadowCallStack, Address | HWAddress | Leak | Thread |
379 Memory | KernelAddress | Efficiency |
381 std::make_pair(KernelHWAddress, Address | HWAddress | Leak | Thread |
382 Memory | KernelAddress | Efficiency |
383 SafeStack | ShadowCallStack)};
390 for (
auto G : IncompatibleGroups) {
392 if ((Default & Group) && (Kinds & G.second))
400 if ((Kinds & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
406 D.
Diag(diag::err_drv_argument_only_allowed_with)
410 if ((Kinds & ShadowCallStack) &&
411 TC.
getTriple().getArch() == llvm::Triple::aarch64 &&
412 !llvm::AArch64::isX18ReservedByDefault(TC.
getTriple()) &&
413 !Args.hasArg(options::OPT_ffixed_x18)) {
414 D.
Diag(diag::err_drv_argument_only_allowed_with)
423 if (~Supported & Vptr) {
428 KindsToDiagnose &= ~CFI;
429 if (KindsToDiagnose) {
431 S.
Mask = KindsToDiagnose;
432 D.
Diag(diag::err_drv_unsupported_opt_for_target)
434 Kinds &= ~KindsToDiagnose;
439 for (
auto G : IncompatibleGroups) {
443 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
446 Kinds &= ~Incompatible;
459 for (
const auto *Arg : Args) {
460 const char *DeprecatedReplacement =
nullptr;
461 if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
462 DeprecatedReplacement =
463 "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all";
466 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
467 DeprecatedReplacement =
"-fno-sanitize-recover=undefined,integer' or " 468 "'-fno-sanitize-recover=all";
471 }
else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
478 SetToDiagnose.
Mask |= KindsToDiagnose;
479 D.
Diag(diag::err_drv_unsupported_option_argument)
480 << Arg->getOption().getName() <<
toString(SetToDiagnose);
481 DiagnosedUnrecoverableKinds |= KindsToDiagnose;
485 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
492 SetToDiagnose.
Mask |= KindsToDiagnose;
493 D.
Diag(diag::err_drv_unsupported_option_argument)
494 << Arg->getOption().getName() <<
toString(SetToDiagnose);
495 DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose;
500 if (DeprecatedReplacement) {
501 D.
Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
502 << DeprecatedReplacement;
505 RecoverableKinds &= Kinds;
508 TrappingKinds &= Kinds;
509 RecoverableKinds &= ~TrappingKinds;
515 for (
const auto *Arg : Args) {
516 if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
518 std::string BLPath = Arg->getValue();
519 if (llvm::sys::fs::exists(BLPath)) {
520 BlacklistFiles.push_back(BLPath);
521 ExtraDeps.push_back(BLPath);
523 D.
Diag(clang::diag::err_drv_no_such_file) << BLPath;
525 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
527 BlacklistFiles.clear();
534 std::unique_ptr<llvm::SpecialCaseList> SCL(
537 D.
Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
541 if (AllAddedKinds & Memory) {
543 Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
544 options::OPT_fsanitize_memory_track_origins,
545 options::OPT_fno_sanitize_memory_track_origins)) {
546 if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
547 MsanTrackOrigins = 2;
548 }
else if (A->getOption().matches(
549 options::OPT_fno_sanitize_memory_track_origins)) {
550 MsanTrackOrigins = 0;
552 StringRef S = A->getValue();
553 if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
554 MsanTrackOrigins > 2) {
555 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
560 Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor,
561 options::OPT_fno_sanitize_memory_use_after_dtor,
563 NeedPIE |= !(TC.
getTriple().isOSLinux() &&
564 TC.
getTriple().getArch() == llvm::Triple::x86_64);
566 MsanUseAfterDtor =
false;
569 if (AllAddedKinds & Thread) {
570 TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access,
571 options::OPT_fno_sanitize_thread_memory_access,
573 TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit,
574 options::OPT_fno_sanitize_thread_func_entry_exit,
576 TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics,
577 options::OPT_fno_sanitize_thread_atomics,
581 if (AllAddedKinds & CFI) {
584 NeedPIE |= CfiCrossDso;
585 CfiICallGeneralizePointers =
586 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
588 if (CfiCrossDso && CfiICallGeneralizePointers)
589 D.
Diag(diag::err_drv_argument_not_allowed_with)
590 <<
"-fsanitize-cfi-cross-dso" 591 <<
"-fsanitize-cfi-icall-generalize-pointers";
594 Stats = Args.hasFlag(options::OPT_fsanitize_stats,
595 options::OPT_fno_sanitize_stats,
false);
597 if (MinimalRuntime) {
600 if (IncompatibleMask)
601 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
602 <<
"-fsanitize-minimal-runtime" 607 D.
Diag(clang::diag::err_drv_argument_only_allowed_with)
608 <<
"fsanitize-minimal-runtime" 609 <<
"fsanitize-trap=cfi";
614 for (
const auto *Arg : Args) {
615 if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
616 int LegacySanitizeCoverage;
617 if (Arg->getNumValues() == 1 &&
618 !StringRef(Arg->getValue(0))
619 .getAsInteger(0, LegacySanitizeCoverage)) {
620 CoverageFeatures = 0;
622 if (LegacySanitizeCoverage != 0) {
623 D.
Diag(diag::warn_drv_deprecated_arg)
624 << Arg->getAsString(Args) <<
"-fsanitize-coverage=trace-pc-guard";
635 CoverageFeatures = 0;
637 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
644 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
645 <<
"-fsanitize-coverage=func" 646 <<
"-fsanitize-coverage=bb";
647 if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures &
CoverageEdge))
648 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
649 <<
"-fsanitize-coverage=func" 650 <<
"-fsanitize-coverage=edge";
651 if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
652 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
653 <<
"-fsanitize-coverage=bb" 654 <<
"-fsanitize-coverage=edge";
658 D.
Diag(clang::diag::warn_drv_deprecated_arg)
659 <<
"-fsanitize-coverage=trace-bb" 660 <<
"-fsanitize-coverage=trace-pc-guard";
662 D.
Diag(clang::diag::warn_drv_deprecated_arg)
663 <<
"-fsanitize-coverage=8bit-counters" 664 <<
"-fsanitize-coverage=trace-pc-guard";
666 int InsertionPointTypes = CoverageFunc | CoverageBB |
CoverageEdge;
667 int InstrumentationTypes =
669 if ((CoverageFeatures & InsertionPointTypes) &&
670 !(CoverageFeatures & InstrumentationTypes)) {
671 D.
Diag(clang::diag::warn_drv_deprecated_arg)
672 <<
"-fsanitize-coverage=[func|bb|edge]" 673 <<
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
677 if (!(CoverageFeatures & InsertionPointTypes)) {
678 if (CoverageFeatures &
687 Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
691 ImplicitCfiRuntime = TC.
getTriple().isAndroid();
693 if (AllAddedKinds & Address) {
696 Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
697 StringRef S = A->getValue();
699 if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
700 AsanFieldPadding > 2) {
701 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
705 if (Arg *WindowsDebugRTArg =
706 Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
707 options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
708 options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
709 switch (WindowsDebugRTArg->getOption().getID()) {
710 case options::OPT__SLASH_MTd:
711 case options::OPT__SLASH_MDd:
712 case options::OPT__SLASH_LDd:
713 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
714 << WindowsDebugRTArg->getAsString(Args)
716 D.
Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
720 AsanUseAfterScope = Args.hasFlag(
721 options::OPT_fsanitize_address_use_after_scope,
722 options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
727 AsanGlobalsDeadStripping =
729 Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
731 AsanUseAfterScope =
false;
734 if (AllAddedKinds & SafeStack) {
736 SafeStackRuntime = !TC.
getTriple().isOSFuchsia();
741 Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.
CCCIsCXX();
744 Sanitizers.Mask |= Kinds;
745 RecoverableSanitizers.Mask |= RecoverableKinds;
746 TrapSanitizers.Mask |= TrappingKinds;
747 assert(!(RecoverableKinds & TrappingKinds) &&
748 "Overlap between recoverable and trapping sanitizers");
753 #define SANITIZER(NAME, ID) \ 754 if (Sanitizers.has(ID)) { \ 759 #include "clang/Basic/Sanitizers.def" 764 const llvm::opt::ArgList &Args,
765 llvm::opt::ArgStringList &CmdArgs,
766 StringRef SymbolName) {
768 LinkerOptionFlag =
"--linker-option=/include:";
769 if (TC.
getTriple().getArch() == llvm::Triple::x86) {
771 LinkerOptionFlag +=
'_';
773 LinkerOptionFlag += SymbolName;
774 CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
777 void SanitizerArgs::addArgs(
const ToolChain &TC,
const llvm::opt::ArgList &Args,
778 llvm::opt::ArgStringList &CmdArgs,
789 std::pair<int, const char *> CoverageFlags[] = {
790 std::make_pair(
CoverageFunc,
"-fsanitize-coverage-type=1"),
791 std::make_pair(
CoverageBB,
"-fsanitize-coverage-type=2"),
792 std::make_pair(
CoverageEdge,
"-fsanitize-coverage-type=3"),
805 for (
auto F : CoverageFlags) {
806 if (CoverageFeatures & F.first)
807 CmdArgs.push_back(F.second);
810 if (TC.
getTriple().isOSWindows() && needsUbsanRt()) {
813 CmdArgs.push_back(Args.MakeArgString(
814 "--dependent-lib=" + TC.
getCompilerRT(Args,
"ubsan_standalone")));
816 CmdArgs.push_back(Args.MakeArgString(
817 "--dependent-lib=" + TC.
getCompilerRT(Args,
"ubsan_standalone_cxx")));
819 if (TC.
getTriple().isOSWindows() && needsStatsRt()) {
820 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" +
827 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" +
832 if (Sanitizers.empty())
834 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize=" +
toString(Sanitizers)));
836 if (!RecoverableSanitizers.empty())
837 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-recover=" +
840 if (!TrapSanitizers.empty())
842 Args.MakeArgString(
"-fsanitize-trap=" +
toString(TrapSanitizers)));
844 for (
const auto &BLPath : BlacklistFiles) {
846 BlacklistOpt += BLPath;
847 CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
849 for (
const auto &Dep : ExtraDeps) {
852 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
855 if (MsanTrackOrigins)
856 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-memory-track-origins=" +
857 Twine(MsanTrackOrigins)));
859 if (MsanUseAfterDtor)
860 CmdArgs.push_back(
"-fsanitize-memory-use-after-dtor");
863 if (!TsanMemoryAccess) {
864 CmdArgs.push_back(
"-mllvm");
865 CmdArgs.push_back(
"-tsan-instrument-memory-accesses=0");
866 CmdArgs.push_back(
"-mllvm");
867 CmdArgs.push_back(
"-tsan-instrument-memintrinsics=0");
869 if (!TsanFuncEntryExit) {
870 CmdArgs.push_back(
"-mllvm");
871 CmdArgs.push_back(
"-tsan-instrument-func-entry-exit=0");
874 CmdArgs.push_back(
"-mllvm");
875 CmdArgs.push_back(
"-tsan-instrument-atomics=0");
879 CmdArgs.push_back(
"-fsanitize-cfi-cross-dso");
881 if (CfiICallGeneralizePointers)
882 CmdArgs.push_back(
"-fsanitize-cfi-icall-generalize-pointers");
885 CmdArgs.push_back(
"-fsanitize-stats");
888 CmdArgs.push_back(
"-fsanitize-minimal-runtime");
890 if (AsanFieldPadding)
891 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-address-field-padding=" +
892 Twine(AsanFieldPadding)));
894 if (AsanUseAfterScope)
895 CmdArgs.push_back(
"-fsanitize-address-use-after-scope");
897 if (AsanGlobalsDeadStripping)
898 CmdArgs.push_back(
"-fsanitize-address-globals-dead-stripping");
905 if (Sanitizers.has(Memory) || Sanitizers.has(Address))
906 CmdArgs.push_back(
"-fno-assume-sane-operator-new");
911 !Args.hasArg(options::OPT_fvisibility_EQ)) {
912 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
920 bool DiagnoseErrors) {
921 assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
922 A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
923 A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
924 A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
925 A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
926 A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
927 "Invalid argument in parseArgValues!");
929 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
930 const char *
Value = A->getValue(i);
933 if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
934 0 == strcmp(
"all", Value))
937 else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
938 0 == strcmp(
"efficiency-all", Value))
945 else if (DiagnoseErrors)
946 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
947 << A->getOption().getName() <<
Value;
953 assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
954 A->getOption().matches(options::OPT_fno_sanitize_coverage));
956 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
957 const char *
Value = A->getValue(i);
958 int F = llvm::StringSwitch<int>(
Value)
976 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
977 << A->getOption().getName() <<
Value;
985 for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
988 const auto *Arg = *I;
989 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
994 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
997 Mask &= ~RemoveKinds;
1000 llvm_unreachable(
"arg list didn't provide expected value");
1004 assert(A->getOption().matches(options::OPT_fsanitize_EQ)
1005 &&
"Invalid argument in describeSanitizerArg!");
1007 std::string Sanitizers;
1008 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1012 if (!Sanitizers.empty())
1014 Sanitizers += A->getValue(i);
1018 assert(!Sanitizers.empty() &&
"arg didn't provide expected value");
1019 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.
static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, std::vector< std::string > &BlacklistFiles)
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).
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.