396 const llvm::opt::ArgList &Args,
397 bool DiagnoseErrors) {
411 CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
412 options::OPT_fno_sanitize_cfi_cross_dso,
false);
421 Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
422 options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
425 Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
426 bool RemoveObjectSizeAtO0 =
427 !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
429 for (
const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
430 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
434 if (RemoveObjectSizeAtO0) {
435 AllRemove |= SanitizerKind::ObjectSize;
439 if ((Add & SanitizerKind::ObjectSize) && DiagnoseErrors)
440 D.
Diag(diag::warn_drv_object_size_disabled_O0)
441 << Arg->getAsString(Args);
452 Add & InvalidTrappingKinds & ~DiagnosedKinds) {
453 if (DiagnoseErrors) {
455 D.
Diag(diag::err_drv_argument_not_allowed_with)
456 << Desc <<
"-fsanitize-trap=undefined";
458 DiagnosedKinds |= KindsToDiagnose;
460 Add &= ~InvalidTrappingKinds;
462 if (MinimalRuntime) {
465 if (DiagnoseErrors) {
467 D.
Diag(diag::err_drv_argument_not_allowed_with)
468 << Desc <<
"-fsanitize-minimal-runtime";
470 DiagnosedKinds |= KindsToDiagnose;
475 if (llvm::opt::Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
476 StringRef CM = A->getValue();
478 (Add & SanitizerKind::Function & ~DiagnosedKinds)) {
480 D.
Diag(diag::err_drv_argument_only_allowed_with)
481 <<
"-fsanitize=function"
484 DiagnosedKinds |= SanitizerKind::Function;
490 const llvm::Triple &Triple = TC.
getTriple();
494 if (DiagnoseErrors) {
496 llvm::opt::Arg *A = Args.getLastArgNoClaim(
497 options::OPT_mexecute_only, options::OPT_mno_execute_only);
498 if (A && A->getOption().matches(options::OPT_mexecute_only))
499 D.
Diag(diag::err_drv_argument_not_allowed_with)
500 << Desc << A->getAsString(Args);
502 D.
Diag(diag::err_drv_unsupported_opt_for_target)
503 << Desc << Triple.str();
505 DiagnosedKinds |= KindsToDiagnose;
520 if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
522 D.
Diag(diag::err_drv_argument_not_allowed_with)
523 <<
"-fsanitize=cfi-mfcall"
524 <<
"-fsanitize-cfi-cross-dso";
526 DiagnosedKinds |= SanitizerKind::CFIMFCall;
529 if (
SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
530 if (DiagnoseErrors) {
532 D.
Diag(diag::err_drv_unsupported_opt_for_target)
535 DiagnosedKinds |= KindsToDiagnose;
543 if (
const llvm::opt::Arg *NoRTTIArg = TC.
getRTTIArg()) {
544 assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
545 "RTTI disabled without -fno-rtti option?");
549 D.
Diag(diag::err_drv_argument_not_allowed_with)
550 <<
"-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
555 D.
Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
559 AllRemove |= SanitizerKind::Vptr;
567 Add &= ~InvalidTrappingKinds;
568 if (MinimalRuntime) {
579 if (Add & SanitizerKind::UndefinedGroup) {
580 bool S = Args.hasFlagNoClaim(options::OPT_fno_strict_overflow,
581 options::OPT_fstrict_overflow,
false);
582 if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S))
584 if (Args.hasFlagNoClaim(options::OPT_fwrapv_pointer,
585 options::OPT_fno_wrapv_pointer, S))
590 if (Add & SanitizerKind::Fuzzer)
591 Add |= SanitizerKind::FuzzerNoLink;
594 if (Add & SanitizerKind::FuzzerNoLink) {
603 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
610 std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
611 std::make_pair(SanitizerKind::Address,
612 SanitizerKind::Thread | SanitizerKind::Memory),
613 std::make_pair(SanitizerKind::Type,
614 SanitizerKind::Address | SanitizerKind::KernelAddress |
615 SanitizerKind::Memory | SanitizerKind::Leak |
616 SanitizerKind::Thread | SanitizerKind::KernelAddress),
617 std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
618 std::make_pair(SanitizerKind::Leak,
619 SanitizerKind::Thread | SanitizerKind::Memory),
620 std::make_pair(SanitizerKind::KernelAddress,
621 SanitizerKind::Address | SanitizerKind::Leak |
622 SanitizerKind::Thread | SanitizerKind::Memory),
623 std::make_pair(SanitizerKind::HWAddress,
624 SanitizerKind::Address | SanitizerKind::Thread |
625 SanitizerKind::Memory | SanitizerKind::KernelAddress),
626 std::make_pair(SanitizerKind::Scudo,
627 SanitizerKind::Address | SanitizerKind::HWAddress |
628 SanitizerKind::Leak | SanitizerKind::Thread |
629 SanitizerKind::Memory | SanitizerKind::KernelAddress),
630 std::make_pair(SanitizerKind::SafeStack,
632 : SanitizerKind::Leak) |
633 SanitizerKind::Address | SanitizerKind::HWAddress |
634 SanitizerKind::Thread | SanitizerKind::Memory |
635 SanitizerKind::KernelAddress),
636 std::make_pair(SanitizerKind::KernelHWAddress,
637 SanitizerKind::Address | SanitizerKind::HWAddress |
638 SanitizerKind::Leak | SanitizerKind::Thread |
639 SanitizerKind::Memory | SanitizerKind::KernelAddress |
640 SanitizerKind::SafeStack),
641 std::make_pair(SanitizerKind::KernelMemory,
642 SanitizerKind::Address | SanitizerKind::HWAddress |
643 SanitizerKind::Leak | SanitizerKind::Thread |
644 SanitizerKind::Memory | SanitizerKind::KernelAddress |
645 SanitizerKind::Scudo | SanitizerKind::SafeStack),
646 std::make_pair(SanitizerKind::MemTag, SanitizerKind::Address |
647 SanitizerKind::KernelAddress |
648 SanitizerKind::HWAddress |
649 SanitizerKind::KernelHWAddress),
650 std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function),
651 std::make_pair(SanitizerKind::Realtime,
652 SanitizerKind::Address | SanitizerKind::Thread |
653 SanitizerKind::Undefined | SanitizerKind::Memory)};
660 for (
auto G : IncompatibleGroups) {
662 if ((
Default & Group) && (Kinds & G.second))
676 D.
Diag(diag::err_drv_argument_only_allowed_with)
680 if ((Kinds & SanitizerKind::ShadowCallStack) && TC.
getTriple().isAArch64() &&
681 !llvm::AArch64::isX18ReservedByDefault(TC.
getTriple()) &&
682 !Args.hasArg(options::OPT_ffixed_x18) && DiagnoseErrors) {
683 D.
Diag(diag::err_drv_argument_only_allowed_with)
692 if (~Supported & SanitizerKind::Vptr) {
698 if (KindsToDiagnose) {
700 S.
Mask = KindsToDiagnose;
702 D.
Diag(diag::err_drv_unsupported_opt_for_target)
704 Kinds &= ~KindsToDiagnose;
709 for (
auto G : IncompatibleGroups) {
714 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
730 options::OPT_fno_sanitize_recover_EQ);
731 RecoverableKinds &= Kinds;
733 TrappingKinds &= Kinds;
734 RecoverableKinds &= ~TrappingKinds;
739 options::OPT_fsanitize_merge_handlers_EQ,
740 options::OPT_fno_sanitize_merge_handlers_EQ);
749 {}, options::OPT_fsanitize_annotate_debug_info_EQ,
750 options::OPT_fno_sanitize_annotate_debug_info_EQ);
751 AnnotateDebugInfoKinds &= Kinds;
756 if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_ignorelist))
762 D, Args, UserIgnorelistFiles, options::OPT_fsanitize_ignorelist_EQ,
763 options::OPT_fno_sanitize_ignorelist,
764 clang::diag::err_drv_malformed_sanitizer_ignorelist, DiagnoseErrors);
767 if (Arg *A = Args.getLastArg(
768 options::OPT_fsanitize_coverage_stack_depth_callback_min_EQ)) {
769 StringRef S = A->getValue();
770 if (S.getAsInteger(0, CoverageStackDepthCallbackMin) ||
771 CoverageStackDepthCallbackMin < 0) {
773 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
778 if (AllAddedKinds & SanitizerKind::Memory) {
780 Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
781 options::OPT_fno_sanitize_memory_track_origins)) {
782 if (!A->getOption().matches(
783 options::OPT_fno_sanitize_memory_track_origins)) {
784 StringRef S = A->getValue();
785 if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
786 MsanTrackOrigins > 2) {
788 D.
Diag(clang::diag::err_drv_invalid_value)
789 << A->getAsString(Args) << S;
793 MsanUseAfterDtor = Args.hasFlag(
794 options::OPT_fsanitize_memory_use_after_dtor,
795 options::OPT_fno_sanitize_memory_use_after_dtor, MsanUseAfterDtor);
796 MsanParamRetval = Args.hasFlag(
797 options::OPT_fsanitize_memory_param_retval,
798 options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
799 }
else if (AllAddedKinds & SanitizerKind::KernelMemory) {
800 MsanUseAfterDtor =
false;
801 MsanParamRetval = Args.hasFlag(
802 options::OPT_fsanitize_memory_param_retval,
803 options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
805 MsanUseAfterDtor =
false;
806 MsanParamRetval =
false;
809 if (AllAddedKinds & SanitizerKind::MemTag) {
811 Args.getLastArgValue(options::OPT_fsanitize_memtag_mode_EQ,
"sync");
812 if (S ==
"async" || S ==
"sync") {
813 MemtagMode = S.str();
815 D.
Diag(clang::diag::err_drv_invalid_value_with_suggestion)
816 <<
"-fsanitize-memtag-mode=" << S <<
"{async, sync}";
821 if (AllAddedKinds & SanitizerKind::Thread) {
822 TsanMemoryAccess = Args.hasFlag(
823 options::OPT_fsanitize_thread_memory_access,
824 options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
825 TsanFuncEntryExit = Args.hasFlag(
826 options::OPT_fsanitize_thread_func_entry_exit,
827 options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
829 Args.hasFlag(options::OPT_fsanitize_thread_atomics,
830 options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
833 if (AllAddedKinds & SanitizerKind::CFI) {
836 NeedPIE |= CfiCrossDso;
837 CfiICallGeneralizePointers =
838 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
840 CfiICallNormalizeIntegers =
841 Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
843 if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors)
844 D.
Diag(diag::err_drv_argument_not_allowed_with)
845 <<
"-fsanitize-cfi-cross-dso"
846 <<
"-fsanitize-cfi-icall-generalize-pointers";
848 CfiCanonicalJumpTables =
849 Args.hasFlag(options::OPT_fsanitize_cfi_canonical_jump_tables,
850 options::OPT_fno_sanitize_cfi_canonical_jump_tables,
true);
853 if (AllAddedKinds & SanitizerKind::KCFI) {
854 CfiICallGeneralizePointers =
855 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
856 CfiICallNormalizeIntegers =
857 Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
859 KcfiArity = Args.hasArg(options::OPT_fsanitize_kcfi_arity);
861 if (AllAddedKinds & SanitizerKind::CFI && DiagnoseErrors)
862 D.
Diag(diag::err_drv_argument_not_allowed_with)
867 Stats = Args.hasFlag(options::OPT_fsanitize_stats,
868 options::OPT_fno_sanitize_stats,
false);
870 if (MinimalRuntime) {
873 if (IncompatibleMask && DiagnoseErrors)
874 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
875 <<
"-fsanitize-minimal-runtime"
879 for (
const auto *Arg : Args.filtered(
880 options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
882 OverflowPatternExclusions |=
888 for (
const auto *Arg : Args) {
889 if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
890 int LegacySanitizeCoverage;
891 if (Arg->getNumValues() == 1 &&
892 !StringRef(Arg->getValue(0))
893 .getAsInteger(0, LegacySanitizeCoverage)) {
894 CoverageFeatures = 0;
896 if (LegacySanitizeCoverage != 0 && DiagnoseErrors) {
897 D.
Diag(diag::warn_drv_deprecated_arg)
898 << Arg->getAsString(Args) <<
true
899 <<
"-fsanitize-coverage=trace-pc-guard";
910 CoverageFeatures = 0;
912 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
918 if (DiagnoseErrors) {
920 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
921 <<
"-fsanitize-coverage=func"
922 <<
"-fsanitize-coverage=bb";
924 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
925 <<
"-fsanitize-coverage=func"
926 <<
"-fsanitize-coverage=edge";
928 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
929 <<
"-fsanitize-coverage=bb"
930 <<
"-fsanitize-coverage=edge";
934 D.
Diag(clang::diag::warn_drv_deprecated_arg)
935 <<
"-fsanitize-coverage=trace-bb" <<
true
936 <<
"-fsanitize-coverage=trace-pc-guard";
938 D.
Diag(clang::diag::warn_drv_deprecated_arg)
939 <<
"-fsanitize-coverage=8bit-counters" <<
true
940 <<
"-fsanitize-coverage=trace-pc-guard";
948 if ((CoverageFeatures & InsertionPointTypes) &&
949 !(CoverageFeatures & InstrumentationTypes) && DiagnoseErrors) {
950 D.
Diag(clang::diag::warn_drv_deprecated_arg)
951 <<
"-fsanitize-coverage=[func|bb|edge]" <<
true
952 <<
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc],["
957 if (!(CoverageFeatures & InsertionPointTypes)) {
958 if (CoverageFeatures &
971 if (CoverageFeatures) {
973 D, Args, CoverageAllowlistFiles,
974 options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
975 clang::diag::err_drv_malformed_sanitizer_coverage_allowlist,
978 D, Args, CoverageIgnorelistFiles,
979 options::OPT_fsanitize_coverage_ignorelist, OptSpecifier(),
980 clang::diag::err_drv_malformed_sanitizer_coverage_ignorelist,
985 for (
const auto *Arg :
986 Args.filtered(options::OPT_fexperimental_sanitize_metadata_EQ,
987 options::OPT_fno_experimental_sanitize_metadata_EQ)) {
988 if (Arg->getOption().matches(
989 options::OPT_fexperimental_sanitize_metadata_EQ)) {
991 BinaryMetadataFeatures |=
995 BinaryMetadataFeatures &=
1001 if (BinaryMetadataFeatures) {
1003 D, Args, BinaryMetadataIgnorelistFiles,
1004 options::OPT_fexperimental_sanitize_metadata_ignorelist_EQ,
1006 clang::diag::err_drv_malformed_sanitizer_metadata_ignorelist,
1010 SharedRuntime = Args.hasFlag(
1011 options::OPT_shared_libsan, options::OPT_static_libsan,
1014 if (!SharedRuntime && TC.
getTriple().isOSWindows()) {
1016 Args.getLastArg(options::OPT_shared_libsan, options::OPT_static_libsan);
1017 D.
Diag(clang::diag::err_drv_unsupported_opt_for_target)
1018 << A->getSpelling() << TC.
getTriple().str();
1021 ImplicitCfiRuntime = TC.
getTriple().isAndroid();
1023 if (AllAddedKinds & SanitizerKind::Address) {
1024 NeedPIE |= TC.
getTriple().isOSFuchsia();
1026 Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
1027 StringRef S = A->getValue();
1029 if ((S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
1030 AsanFieldPadding > 2) &&
1032 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
1036 if (Arg *WindowsDebugRTArg =
1037 Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
1038 options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
1039 options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
1040 switch (WindowsDebugRTArg->getOption().getID()) {
1041 case options::OPT__SLASH_MTd:
1042 case options::OPT__SLASH_MDd:
1043 case options::OPT__SLASH_LDd:
1044 if (DiagnoseErrors) {
1045 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
1046 << WindowsDebugRTArg->getAsString(Args)
1048 D.
Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
1053 StableABI = Args.hasFlag(options::OPT_fsanitize_stable_abi,
1054 options::OPT_fno_sanitize_stable_abi,
false);
1056 AsanPoisonCustomArrayCookie = Args.hasFlag(
1057 options::OPT_fsanitize_address_poison_custom_array_cookie,
1058 options::OPT_fno_sanitize_address_poison_custom_array_cookie,
1059 AsanPoisonCustomArrayCookie);
1061 AsanOutlineInstrumentation =
1062 Args.hasFlag(options::OPT_fsanitize_address_outline_instrumentation,
1063 options::OPT_fno_sanitize_address_outline_instrumentation,
1064 AsanOutlineInstrumentation);
1066 AsanGlobalsDeadStripping = Args.hasFlag(
1067 options::OPT_fsanitize_address_globals_dead_stripping,
1068 options::OPT_fno_sanitize_address_globals_dead_stripping,
true);
1074 AsanUseOdrIndicator =
1075 Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
1076 options::OPT_fno_sanitize_address_use_odr_indicator,
1079 if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
1080 AsanInvalidPointerCmp =
true;
1083 if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
1084 AsanInvalidPointerSub =
true;
1088 (Args.hasArg(options::OPT_mkernel) ||
1089 Args.hasArg(options::OPT_fapple_kext))) {
1090 AsanDtorKind = llvm::AsanDtorKind::None;
1093 if (
const auto *Arg =
1094 Args.getLastArg(options::OPT_sanitize_address_destructor_EQ)) {
1096 if (parsedAsanDtorKind == llvm::AsanDtorKind::Invalid && DiagnoseErrors) {
1097 TC.
getDriver().
Diag(clang::diag::err_drv_unsupported_option_argument)
1098 << Arg->getSpelling() << Arg->getValue();
1100 AsanDtorKind = parsedAsanDtorKind;
1103 if (
const auto *Arg = Args.getLastArg(
1104 options::OPT_sanitize_address_use_after_return_EQ)) {
1105 auto parsedAsanUseAfterReturn =
1107 if (parsedAsanUseAfterReturn ==
1108 llvm::AsanDetectStackUseAfterReturnMode::Invalid &&
1110 TC.
getDriver().
Diag(clang::diag::err_drv_unsupported_option_argument)
1111 << Arg->getSpelling() << Arg->getValue();
1113 AsanUseAfterReturn = parsedAsanUseAfterReturn;
1119 SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
1120 if ((AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) &&
1122 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
1124 SanitizerKind::PointerCompare |
1125 SanitizerKind::PointerSubtract)
1126 <<
"-fsanitize=address";
1130 if (AllAddedKinds & (SanitizerKind::Address | SanitizerKind::KernelAddress)) {
1131 AsanUseAfterScope = Args.hasFlag(
1132 options::OPT_fsanitize_address_use_after_scope,
1133 options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
1135 AsanUseAfterScope =
false;
1138 if (AllAddedKinds & SanitizerKind::HWAddress) {
1139 if (Arg *HwasanAbiArg =
1140 Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
1141 HwasanAbi = HwasanAbiArg->getValue();
1142 if (HwasanAbi !=
"platform" && HwasanAbi !=
"interceptor" &&
1144 D.
Diag(clang::diag::err_drv_invalid_value)
1145 << HwasanAbiArg->getAsString(Args) << HwasanAbi;
1147 HwasanAbi =
"interceptor";
1149 if (TC.
getTriple().getArch() == llvm::Triple::x86_64)
1150 HwasanUseAliases = Args.hasFlag(
1151 options::OPT_fsanitize_hwaddress_experimental_aliasing,
1152 options::OPT_fno_sanitize_hwaddress_experimental_aliasing,
1156 if (AllAddedKinds & SanitizerKind::SafeStack) {
1162 LinkRuntimes = Args.hasFlag(options::OPT_fsanitize_link_runtime,
1163 options::OPT_fno_sanitize_link_runtime,
1164 !Args.hasArg(options::OPT_r));
1169 Args.hasFlag(options::OPT_fsanitize_link_cxx_runtime,
1170 options::OPT_fno_sanitize_link_cxx_runtime, LinkCXXRuntimes);
1172 NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile,
1173 options::OPT_fmemory_profile_EQ,
1174 options::OPT_fno_memory_profile,
false);
1177 Sanitizers.Mask |= Kinds;
1178 RecoverableSanitizers.Mask |= RecoverableKinds;
1179 TrapSanitizers.Mask |= TrappingKinds;
1180 assert(!(RecoverableKinds & TrappingKinds) &&
1181 "Overlap between recoverable and trapping sanitizers");
1183 MergeHandlers.Mask |= MergeKinds;
1185 AnnotateDebugInfo.Mask |= AnnotateDebugInfoKinds;
1188 SkipHotCutoffs.clear(~Sanitizers.Mask);