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 | KernelMemory | Leak | Undefined |
Integer |
38 ImplicitConversion |
Nullability | DataFlow | Fuzzer |
46 ImplicitConversion |
Nullability | LocalBounds | CFI,
49 CFIVCall | CFINVCall | CFIMFCall | CFIDerivedCast | CFIUnrelatedCast,
85 const llvm::opt::ArgList &Args,
100 std::vector<std::string> &BlacklistFiles) {
104 } Blacklists[] = {{
"asan_blacklist.txt", Address},
105 {
"hwasan_blacklist.txt", HWAddress},
106 {
"msan_blacklist.txt", Memory},
107 {
"tsan_blacklist.txt", Thread},
108 {
"dfsan_abilist.txt", DataFlow},
109 {
"cfi_blacklist.txt", CFI},
112 for (
auto BL : Blacklists) {
113 if (!(Kinds & BL.Mask))
117 llvm::sys::path::append(Path,
"share", BL.File);
118 if (llvm::sys::fs::exists(Path))
119 BlacklistFiles.push_back(Path.str());
120 else if (BL.Mask == CFI)
123 D.
Diag(clang::diag::err_drv_no_such_file) << Path;
130 #define SANITIZER(NAME, ID) 131 #define SANITIZER_GROUP(NAME, ID, ALIAS) \ 132 if (Kinds & SanitizerKind::ID) \ 133 Kinds |= SanitizerKind::ID##Group; 134 #include "clang/Basic/Sanitizers.def" 139 const llvm::opt::ArgList &Args) {
146 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
148 const auto *Arg = *I;
149 if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
153 if (
SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups) {
155 S.
Mask = InvalidValues;
156 D.
Diag(diag::err_drv_unsupported_option_argument) <<
"-fsanitize-trap" 160 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
163 }
else if (Arg->getOption().matches(
164 options::OPT_fsanitize_undefined_trap_on_error)) {
168 }
else if (Arg->getOption().matches(
169 options::OPT_fno_sanitize_undefined_trap_on_error)) {
178 return TrappingKinds;
181 bool SanitizerArgs::needsUbsanRt()
const {
183 if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
184 needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
185 (needsScudoRt() && !requiresMinimalRuntime()))
188 return (Sanitizers.Mask &
NeedsUbsanRt & ~TrapSanitizers.Mask) ||
192 bool SanitizerArgs::needsCfiRt()
const {
193 return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
197 bool SanitizerArgs::needsCfiDiagRt()
const {
198 return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso &&
202 bool SanitizerArgs::requiresPIE()
const {
206 bool SanitizerArgs::needsUnwindTables()
const {
210 bool SanitizerArgs::needsLTO()
const {
return Sanitizers.Mask &
NeedsLTO; }
213 const llvm::opt::ArgList &Args) {
227 CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
228 options::OPT_fno_sanitize_cfi_cross_dso,
false);
237 Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
238 options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
241 Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
242 bool RemoveObjectSizeAtO0 =
243 !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
245 for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
247 const auto *Arg = *I;
248 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
252 if (RemoveObjectSizeAtO0) {
253 AllRemove |= SanitizerKind::ObjectSize;
257 if (Add & SanitizerKind::ObjectSize)
258 D.
Diag(diag::warn_drv_object_size_disabled_O0)
259 << Arg->getAsString(Args);
270 Add & InvalidTrappingKinds & ~DiagnosedKinds) {
272 D.
Diag(diag::err_drv_argument_not_allowed_with)
273 << Desc <<
"-fsanitize-trap=undefined";
274 DiagnosedKinds |= KindsToDiagnose;
276 Add &= ~InvalidTrappingKinds;
278 if (MinimalRuntime) {
282 D.
Diag(diag::err_drv_argument_not_allowed_with)
283 << Desc <<
"-fsanitize-minimal-runtime";
284 DiagnosedKinds |= KindsToDiagnose;
299 if (CfiCrossDso && (Add & CFIMFCall & ~DiagnosedKinds)) {
300 D.
Diag(diag::err_drv_argument_not_allowed_with)
301 <<
"-fsanitize=cfi-mfcall" 302 <<
"-fsanitize-cfi-cross-dso";
304 DiagnosedKinds |= CFIMFCall;
307 if (
SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
309 D.
Diag(diag::err_drv_unsupported_opt_for_target)
311 DiagnosedKinds |= KindsToDiagnose;
318 if ((Add & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
319 if (
const llvm::opt::Arg *NoRTTIArg = TC.
getRTTIArg()) {
320 assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
321 "RTTI disabled without -fno-rtti option?");
324 D.
Diag(diag::err_drv_argument_not_allowed_with)
325 <<
"-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
329 D.
Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
341 Add &= ~InvalidTrappingKinds;
342 if (MinimalRuntime) {
353 if (Add & FuzzerNoLink) {
362 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
369 std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
370 std::make_pair(Address, Thread | Memory),
371 std::make_pair(Thread, Memory),
372 std::make_pair(Leak, Thread | Memory),
373 std::make_pair(KernelAddress, Address | Leak | Thread | Memory),
374 std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress),
375 std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory |
377 std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory |
378 KernelAddress | Efficiency),
379 std::make_pair(SafeStack, Address | HWAddress | Leak | Thread | Memory |
380 KernelAddress | Efficiency),
381 std::make_pair(KernelHWAddress, Address | HWAddress | Leak | Thread |
382 Memory | KernelAddress | Efficiency |
384 std::make_pair(KernelMemory, Address | HWAddress | Leak | Thread |
385 Memory | KernelAddress | Efficiency |
392 for (
auto G : IncompatibleGroups) {
394 if ((Default & Group) && (Kinds & G.second))
402 if ((Kinds & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) {
408 D.
Diag(diag::err_drv_argument_only_allowed_with)
412 if ((Kinds & ShadowCallStack) &&
413 TC.
getTriple().getArch() == llvm::Triple::aarch64 &&
414 !llvm::AArch64::isX18ReservedByDefault(TC.
getTriple()) &&
415 !Args.hasArg(options::OPT_ffixed_x18)) {
416 D.
Diag(diag::err_drv_argument_only_allowed_with)
425 if (~Supported & Vptr) {
430 KindsToDiagnose &= ~CFI;
431 if (KindsToDiagnose) {
433 S.
Mask = KindsToDiagnose;
434 D.
Diag(diag::err_drv_unsupported_opt_for_target)
436 Kinds &= ~KindsToDiagnose;
441 for (
auto G : IncompatibleGroups) {
445 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
448 Kinds &= ~Incompatible;
461 for (
const auto *Arg : Args) {
462 const char *DeprecatedReplacement =
nullptr;
463 if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
464 DeprecatedReplacement =
465 "-fsanitize-recover=undefined,integer' or '-fsanitize-recover=all";
468 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover)) {
469 DeprecatedReplacement =
"-fno-sanitize-recover=undefined,integer' or " 470 "'-fno-sanitize-recover=all";
473 }
else if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
480 SetToDiagnose.
Mask |= KindsToDiagnose;
481 D.
Diag(diag::err_drv_unsupported_option_argument)
482 << Arg->getOption().getName() <<
toString(SetToDiagnose);
483 DiagnosedUnrecoverableKinds |= KindsToDiagnose;
487 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
494 SetToDiagnose.
Mask |= KindsToDiagnose;
495 D.
Diag(diag::err_drv_unsupported_option_argument)
496 << Arg->getOption().getName() <<
toString(SetToDiagnose);
497 DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose;
502 if (DeprecatedReplacement) {
503 D.
Diag(diag::warn_drv_deprecated_arg) << Arg->getAsString(Args)
504 << DeprecatedReplacement;
507 RecoverableKinds &= Kinds;
510 TrappingKinds &= Kinds;
511 RecoverableKinds &= ~TrappingKinds;
517 for (
const auto *Arg : Args) {
518 if (Arg->getOption().matches(options::OPT_fsanitize_blacklist)) {
520 std::string BLPath = Arg->getValue();
521 if (llvm::sys::fs::exists(BLPath)) {
522 BlacklistFiles.push_back(BLPath);
523 ExtraDeps.push_back(BLPath);
525 D.
Diag(clang::diag::err_drv_no_such_file) << BLPath;
527 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_blacklist)) {
529 BlacklistFiles.clear();
536 std::unique_ptr<llvm::SpecialCaseList> SCL(
539 D.
Diag(clang::diag::err_drv_malformed_sanitizer_blacklist) << BLError;
543 if (AllAddedKinds & Memory) {
545 Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
546 options::OPT_fsanitize_memory_track_origins,
547 options::OPT_fno_sanitize_memory_track_origins)) {
548 if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
549 MsanTrackOrigins = 2;
550 }
else if (A->getOption().matches(
551 options::OPT_fno_sanitize_memory_track_origins)) {
552 MsanTrackOrigins = 0;
554 StringRef S = A->getValue();
555 if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
556 MsanTrackOrigins > 2) {
557 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
562 Args.hasFlag(options::OPT_fsanitize_memory_use_after_dtor,
563 options::OPT_fno_sanitize_memory_use_after_dtor,
565 NeedPIE |= !(TC.
getTriple().isOSLinux() &&
566 TC.
getTriple().getArch() == llvm::Triple::x86_64);
568 MsanUseAfterDtor =
false;
571 if (AllAddedKinds & Thread) {
572 TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access,
573 options::OPT_fno_sanitize_thread_memory_access,
575 TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit,
576 options::OPT_fno_sanitize_thread_func_entry_exit,
578 TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics,
579 options::OPT_fno_sanitize_thread_atomics,
583 if (AllAddedKinds & CFI) {
586 NeedPIE |= CfiCrossDso;
587 CfiICallGeneralizePointers =
588 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
590 if (CfiCrossDso && CfiICallGeneralizePointers)
591 D.
Diag(diag::err_drv_argument_not_allowed_with)
592 <<
"-fsanitize-cfi-cross-dso" 593 <<
"-fsanitize-cfi-icall-generalize-pointers";
596 Stats = Args.hasFlag(options::OPT_fsanitize_stats,
597 options::OPT_fno_sanitize_stats,
false);
599 if (MinimalRuntime) {
602 if (IncompatibleMask)
603 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
604 <<
"-fsanitize-minimal-runtime" 609 D.
Diag(clang::diag::err_drv_argument_only_allowed_with)
610 <<
"fsanitize-minimal-runtime" 611 <<
"fsanitize-trap=cfi";
616 for (
const auto *Arg : Args) {
617 if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
618 int LegacySanitizeCoverage;
619 if (Arg->getNumValues() == 1 &&
620 !StringRef(Arg->getValue(0))
621 .getAsInteger(0, LegacySanitizeCoverage)) {
622 CoverageFeatures = 0;
624 if (LegacySanitizeCoverage != 0) {
625 D.
Diag(diag::warn_drv_deprecated_arg)
626 << Arg->getAsString(Args) <<
"-fsanitize-coverage=trace-pc-guard";
637 CoverageFeatures = 0;
639 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
646 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
647 <<
"-fsanitize-coverage=func" 648 <<
"-fsanitize-coverage=bb";
649 if ((CoverageFeatures & CoverageFunc) && (CoverageFeatures &
CoverageEdge))
650 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
651 <<
"-fsanitize-coverage=func" 652 <<
"-fsanitize-coverage=edge";
653 if ((CoverageFeatures & CoverageBB) && (CoverageFeatures & CoverageEdge))
654 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
655 <<
"-fsanitize-coverage=bb" 656 <<
"-fsanitize-coverage=edge";
660 D.
Diag(clang::diag::warn_drv_deprecated_arg)
661 <<
"-fsanitize-coverage=trace-bb" 662 <<
"-fsanitize-coverage=trace-pc-guard";
664 D.
Diag(clang::diag::warn_drv_deprecated_arg)
665 <<
"-fsanitize-coverage=8bit-counters" 666 <<
"-fsanitize-coverage=trace-pc-guard";
668 int InsertionPointTypes = CoverageFunc | CoverageBB |
CoverageEdge;
669 int InstrumentationTypes =
671 if ((CoverageFeatures & InsertionPointTypes) &&
672 !(CoverageFeatures & InstrumentationTypes)) {
673 D.
Diag(clang::diag::warn_drv_deprecated_arg)
674 <<
"-fsanitize-coverage=[func|bb|edge]" 675 <<
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
679 if (!(CoverageFeatures & InsertionPointTypes)) {
680 if (CoverageFeatures &
689 Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
693 ImplicitCfiRuntime = TC.
getTriple().isAndroid();
695 if (AllAddedKinds & Address) {
698 Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
699 StringRef S = A->getValue();
701 if (S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
702 AsanFieldPadding > 2) {
703 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
707 if (Arg *WindowsDebugRTArg =
708 Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
709 options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
710 options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
711 switch (WindowsDebugRTArg->getOption().getID()) {
712 case options::OPT__SLASH_MTd:
713 case options::OPT__SLASH_MDd:
714 case options::OPT__SLASH_LDd:
715 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
716 << WindowsDebugRTArg->getAsString(Args)
718 D.
Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
722 AsanUseAfterScope = Args.hasFlag(
723 options::OPT_fsanitize_address_use_after_scope,
724 options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
726 AsanPoisonCustomArrayCookie = Args.hasFlag(
727 options::OPT_fsanitize_address_poison_custom_array_cookie,
728 options::OPT_fno_sanitize_address_poison_custom_array_cookie,
729 AsanPoisonCustomArrayCookie);
734 AsanGlobalsDeadStripping =
736 Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
738 AsanUseOdrIndicator =
739 Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
740 options::OPT_fno_sanitize_address_use_odr_indicator,
741 AsanUseOdrIndicator);
743 AsanUseAfterScope =
false;
746 if (AllAddedKinds & HWAddress) {
747 if (Arg *HwasanAbiArg =
748 Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
749 HwasanAbi = HwasanAbiArg->getValue();
750 if (HwasanAbi !=
"platform" && HwasanAbi !=
"interceptor")
751 D.
Diag(clang::diag::err_drv_invalid_value)
752 << HwasanAbiArg->getAsString(Args) << HwasanAbi;
754 HwasanAbi =
"interceptor";
758 if (AllAddedKinds & SafeStack) {
760 SafeStackRuntime = !TC.
getTriple().isOSFuchsia();
765 Args.hasArg(options::OPT_fsanitize_link_cxx_runtime) || D.
CCCIsCXX();
768 Sanitizers.Mask |= Kinds;
769 RecoverableSanitizers.Mask |= RecoverableKinds;
770 TrapSanitizers.Mask |= TrappingKinds;
771 assert(!(RecoverableKinds & TrappingKinds) &&
772 "Overlap between recoverable and trapping sanitizers");
777 #define SANITIZER(NAME, ID) \ 778 if (Sanitizers.has(ID)) { \ 783 #include "clang/Basic/Sanitizers.def" 788 const llvm::opt::ArgList &Args,
789 llvm::opt::ArgStringList &CmdArgs,
790 StringRef SymbolName) {
792 LinkerOptionFlag =
"--linker-option=/include:";
793 if (TC.
getTriple().getArch() == llvm::Triple::x86) {
795 LinkerOptionFlag +=
'_';
797 LinkerOptionFlag += SymbolName;
798 CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
801 void SanitizerArgs::addArgs(
const ToolChain &TC,
const llvm::opt::ArgList &Args,
802 llvm::opt::ArgStringList &CmdArgs,
813 std::pair<int, const char *> CoverageFlags[] = {
814 std::make_pair(
CoverageFunc,
"-fsanitize-coverage-type=1"),
815 std::make_pair(
CoverageBB,
"-fsanitize-coverage-type=2"),
816 std::make_pair(
CoverageEdge,
"-fsanitize-coverage-type=3"),
829 for (
auto F : CoverageFlags) {
830 if (CoverageFeatures & F.first)
831 CmdArgs.push_back(F.second);
834 if (TC.
getTriple().isOSWindows() && needsUbsanRt()) {
837 CmdArgs.push_back(Args.MakeArgString(
838 "--dependent-lib=" + TC.
getCompilerRT(Args,
"ubsan_standalone")));
840 CmdArgs.push_back(Args.MakeArgString(
841 "--dependent-lib=" + TC.
getCompilerRT(Args,
"ubsan_standalone_cxx")));
843 if (TC.
getTriple().isOSWindows() && needsStatsRt()) {
844 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" +
851 CmdArgs.push_back(Args.MakeArgString(
"--dependent-lib=" +
856 if (Sanitizers.empty())
858 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize=" +
toString(Sanitizers)));
860 if (!RecoverableSanitizers.empty())
861 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-recover=" +
864 if (!TrapSanitizers.empty())
866 Args.MakeArgString(
"-fsanitize-trap=" +
toString(TrapSanitizers)));
868 for (
const auto &BLPath : BlacklistFiles) {
870 BlacklistOpt += BLPath;
871 CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
873 for (
const auto &Dep : ExtraDeps) {
876 CmdArgs.push_back(Args.MakeArgString(ExtraDepOpt));
879 if (MsanTrackOrigins)
880 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-memory-track-origins=" +
881 Twine(MsanTrackOrigins)));
883 if (MsanUseAfterDtor)
884 CmdArgs.push_back(
"-fsanitize-memory-use-after-dtor");
887 if (!TsanMemoryAccess) {
888 CmdArgs.push_back(
"-mllvm");
889 CmdArgs.push_back(
"-tsan-instrument-memory-accesses=0");
890 CmdArgs.push_back(
"-mllvm");
891 CmdArgs.push_back(
"-tsan-instrument-memintrinsics=0");
893 if (!TsanFuncEntryExit) {
894 CmdArgs.push_back(
"-mllvm");
895 CmdArgs.push_back(
"-tsan-instrument-func-entry-exit=0");
898 CmdArgs.push_back(
"-mllvm");
899 CmdArgs.push_back(
"-tsan-instrument-atomics=0");
903 CmdArgs.push_back(
"-fsanitize-cfi-cross-dso");
905 if (CfiICallGeneralizePointers)
906 CmdArgs.push_back(
"-fsanitize-cfi-icall-generalize-pointers");
909 CmdArgs.push_back(
"-fsanitize-stats");
912 CmdArgs.push_back(
"-fsanitize-minimal-runtime");
914 if (AsanFieldPadding)
915 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-address-field-padding=" +
916 Twine(AsanFieldPadding)));
918 if (AsanUseAfterScope)
919 CmdArgs.push_back(
"-fsanitize-address-use-after-scope");
921 if (AsanPoisonCustomArrayCookie)
922 CmdArgs.push_back(
"-fsanitize-address-poison-custom-array-cookie");
924 if (AsanGlobalsDeadStripping)
925 CmdArgs.push_back(
"-fsanitize-address-globals-dead-stripping");
927 if (AsanUseOdrIndicator)
928 CmdArgs.push_back(
"-fsanitize-address-use-odr-indicator");
930 if (!HwasanAbi.empty()) {
931 CmdArgs.push_back(
"-default-function-attr");
932 CmdArgs.push_back(Args.MakeArgString(
"hwasan-abi=" + HwasanAbi));
940 if (Sanitizers.has(Memory) || Sanitizers.has(Address))
941 CmdArgs.push_back(
"-fno-assume-sane-operator-new");
946 !Args.hasArg(options::OPT_fvisibility_EQ)) {
947 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
955 bool DiagnoseErrors) {
956 assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
957 A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
958 A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
959 A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
960 A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
961 A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
962 "Invalid argument in parseArgValues!");
964 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
965 const char *
Value = A->getValue(i);
968 if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
969 0 == strcmp(
"all", Value))
972 else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
973 0 == strcmp(
"efficiency-all", Value))
980 else if (DiagnoseErrors)
981 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
982 << A->getOption().getName() <<
Value;
988 assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
989 A->getOption().matches(options::OPT_fno_sanitize_coverage));
991 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
992 const char *
Value = A->getValue(i);
993 int F = llvm::StringSwitch<int>(
Value)
1011 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
1012 << A->getOption().getName() <<
Value;
1020 for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1023 const auto *Arg = *I;
1024 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1027 if (AddKinds & Mask)
1029 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1032 Mask &= ~RemoveKinds;
1035 llvm_unreachable(
"arg list didn't provide expected value");
1039 assert(A->getOption().matches(options::OPT_fsanitize_EQ)
1040 &&
"Invalid argument in describeSanitizerArg!");
1042 std::string Sanitizers;
1043 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1047 if (!Sanitizers.empty())
1049 Sanitizers += A->getValue(i);
1053 assert(!Sanitizers.empty() &&
"arg didn't provide expected value");
1054 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.