15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/Support/AArch64TargetParser.h"
18 #include "llvm/Support/Path.h"
19 #include "llvm/Support/SpecialCaseList.h"
20 #include "llvm/Support/TargetParser.h"
21 #include "llvm/Support/VirtualFileSystem.h"
22 #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
25 using namespace clang;
30 SanitizerKind::Undefined | SanitizerKind::Integer |
32 SanitizerKind::CFI | SanitizerKind::FloatDivideByZero |
33 SanitizerKind::ObjCCast;
35 SanitizerKind::Vptr | SanitizerKind::CFI;
38 SanitizerKind::Function | SanitizerKind::Vptr;
40 SanitizerKind::DataFlow | SanitizerKind::HWAddress | SanitizerKind::Scudo;
42 SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread |
43 SanitizerKind::Memory | SanitizerKind::DataFlow;
45 SanitizerKind::Address | SanitizerKind::HWAddress |
46 SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
47 SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap |
48 SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak |
49 SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::Bounds |
51 SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
52 SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero |
53 SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack |
54 SanitizerKind::Thread | SanitizerKind::ObjCCast;
56 SanitizerKind::Undefined | SanitizerKind::Integer |
58 SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
60 SanitizerKind::Unreachable | SanitizerKind::Return;
62 SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress;
65 (SanitizerKind::Undefined & ~
SanitizerKind::Vptr) | SanitizerKind::Integer |
67 SanitizerKind::CFI | SanitizerKind::FloatDivideByZero |
68 SanitizerKind::ObjCCast;
71 SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
72 SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
73 SanitizerKind::CFIUnrelatedCast;
76 SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap;
102 bool DiagnoseErrors);
107 bool DiagnoseErrors);
114 const llvm::opt::ArgList &Args,
129 std::vector<std::string> &SCLFiles,
130 unsigned MalformedSCLErrorDiagID,
131 bool DiagnoseErrors) {
132 if (SCLFiles.empty())
136 std::unique_ptr<llvm::SpecialCaseList> SCL(
138 if (!SCL.get() && DiagnoseErrors)
139 D.
Diag(MalformedSCLErrorDiagID) << BLError;
143 std::vector<std::string> &IgnorelistFiles,
144 bool DiagnoseErrors) {
148 } Ignorelists[] = {{
"asan_ignorelist.txt", SanitizerKind::Address},
149 {
"hwasan_ignorelist.txt", SanitizerKind::HWAddress},
150 {
"memtag_ignorelist.txt", SanitizerKind::MemTag},
151 {
"msan_ignorelist.txt", SanitizerKind::Memory},
152 {
"tsan_ignorelist.txt", SanitizerKind::Thread},
153 {
"dfsan_abilist.txt", SanitizerKind::DataFlow},
154 {
"cfi_ignorelist.txt", SanitizerKind::CFI},
155 {
"ubsan_ignorelist.txt",
156 SanitizerKind::Undefined | SanitizerKind::Integer |
158 SanitizerKind::FloatDivideByZero}};
160 for (
auto BL : Ignorelists) {
161 if (!(Kinds & BL.Mask))
165 llvm::sys::path::append(Path,
"share", BL.File);
166 if (D.
getVFS().exists(Path))
167 IgnorelistFiles.push_back(
std::string(Path.str()));
168 else if (BL.Mask == SanitizerKind::CFI && DiagnoseErrors)
171 D.
Diag(clang::diag::err_drv_no_such_file) << Path;
174 D, IgnorelistFiles, clang::diag::err_drv_malformed_sanitizer_ignorelist,
181 const llvm::opt::ArgList &Args,
182 std::vector<std::string> &SCLFiles,
183 llvm::opt::OptSpecifier SCLOptionID,
184 llvm::opt::OptSpecifier NoSCLOptionID,
185 unsigned MalformedSCLErrorDiagID,
186 bool DiagnoseErrors) {
187 for (
const auto *Arg : Args) {
189 if (Arg->getOption().matches(SCLOptionID)) {
192 if (D.
getVFS().exists(SCLPath)) {
193 SCLFiles.push_back(SCLPath);
194 }
else if (DiagnoseErrors) {
195 D.
Diag(clang::diag::err_drv_no_such_file) << SCLPath;
198 }
else if (Arg->getOption().matches(NoSCLOptionID)) {
210 #define SANITIZER(NAME, ID)
211 #define SANITIZER_GROUP(NAME, ID, ALIAS) \
212 if (Kinds & SanitizerKind::ID) \
213 Kinds |= SanitizerKind::ID##Group;
214 #include "clang/Basic/Sanitizers.def"
219 const llvm::opt::ArgList &Args,
220 bool DiagnoseErrors) {
227 for (
const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
228 if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) {
233 if (InvalidValues && DiagnoseErrors) {
235 S.Mask = InvalidValues;
236 D.
Diag(diag::err_drv_unsupported_option_argument)
237 << Arg->getOption().getName() <<
toString(S);
240 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) {
250 return TrappingKinds;
254 return needsFuzzer() && !needsAsanRt() && !needsTsanRt() && !needsMsanRt();
259 if (needsAsanRt() || needsMsanRt() || needsHwasanRt() || needsTsanRt() ||
260 needsDfsanRt() || needsLsanRt() || needsCfiDiagRt() ||
261 (needsScudoRt() && !requiresMinimalRuntime()))
264 return (Sanitizers.Mask &
NeedsUbsanRt & ~TrapSanitizers.Mask) ||
269 return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
270 CfiCrossDso && !ImplicitCfiRuntime;
274 return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
275 CfiCrossDso && !ImplicitCfiRuntime;
287 return static_cast<bool>(Sanitizers.Mask &
NeedsLTO);
291 const llvm::opt::ArgList &Args,
292 bool DiagnoseErrors) {
306 CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
307 options::OPT_fno_sanitize_cfi_cross_dso,
false);
316 Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
317 options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
320 Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
321 bool RemoveObjectSizeAtO0 =
322 !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
324 for (
const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
325 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
329 if (RemoveObjectSizeAtO0) {
330 AllRemove |= SanitizerKind::ObjectSize;
334 if ((
Add & SanitizerKind::ObjectSize) && DiagnoseErrors)
335 D.
Diag(diag::warn_drv_object_size_disabled_O0)
336 << Arg->getAsString(Args);
347 Add & InvalidTrappingKinds & ~DiagnosedKinds) {
348 if (DiagnoseErrors) {
350 D.
Diag(diag::err_drv_argument_not_allowed_with)
351 << Desc <<
"-fsanitize-trap=undefined";
353 DiagnosedKinds |= KindsToDiagnose;
355 Add &= ~InvalidTrappingKinds;
357 if (MinimalRuntime) {
360 if (DiagnoseErrors) {
362 D.
Diag(diag::err_drv_argument_not_allowed_with)
363 << Desc <<
"-fsanitize-minimal-runtime";
365 DiagnosedKinds |= KindsToDiagnose;
380 if (CfiCrossDso && (
Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
382 D.
Diag(diag::err_drv_argument_not_allowed_with)
383 <<
"-fsanitize=cfi-mfcall"
384 <<
"-fsanitize-cfi-cross-dso";
386 DiagnosedKinds |= SanitizerKind::CFIMFCall;
390 if (DiagnoseErrors) {
392 D.
Diag(diag::err_drv_unsupported_opt_for_target)
395 DiagnosedKinds |= KindsToDiagnose;
403 if (
const llvm::opt::Arg *NoRTTIArg = TC.
getRTTIArg()) {
404 assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
405 "RTTI disabled without -fno-rtti option?");
409 D.
Diag(diag::err_drv_argument_not_allowed_with)
410 <<
"-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
415 D.
Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
419 AllRemove |= SanitizerKind::Vptr;
427 Add &= ~InvalidTrappingKinds;
428 if (MinimalRuntime) {
435 if (
Add & SanitizerKind::Fuzzer)
436 Add |= SanitizerKind::FuzzerNoLink;
439 if (
Add & SanitizerKind::FuzzerNoLink) {
448 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
455 std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
456 std::make_pair(SanitizerKind::Address,
457 SanitizerKind::Thread | SanitizerKind::Memory),
458 std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
459 std::make_pair(SanitizerKind::Leak,
460 SanitizerKind::Thread | SanitizerKind::Memory),
461 std::make_pair(SanitizerKind::KernelAddress,
462 SanitizerKind::Address | SanitizerKind::Leak |
463 SanitizerKind::Thread | SanitizerKind::Memory),
464 std::make_pair(SanitizerKind::HWAddress,
465 SanitizerKind::Address | SanitizerKind::Thread |
466 SanitizerKind::Memory | SanitizerKind::KernelAddress),
467 std::make_pair(SanitizerKind::Scudo,
468 SanitizerKind::Address | SanitizerKind::HWAddress |
469 SanitizerKind::Leak | SanitizerKind::Thread |
470 SanitizerKind::Memory | SanitizerKind::KernelAddress),
471 std::make_pair(SanitizerKind::SafeStack,
473 : SanitizerKind::Leak) |
474 SanitizerKind::Address | SanitizerKind::HWAddress |
475 SanitizerKind::Thread | SanitizerKind::Memory |
476 SanitizerKind::KernelAddress),
477 std::make_pair(SanitizerKind::KernelHWAddress,
478 SanitizerKind::Address | SanitizerKind::HWAddress |
479 SanitizerKind::Leak | SanitizerKind::Thread |
480 SanitizerKind::Memory | SanitizerKind::KernelAddress |
481 SanitizerKind::SafeStack),
482 std::make_pair(SanitizerKind::KernelMemory,
483 SanitizerKind::Address | SanitizerKind::HWAddress |
484 SanitizerKind::Leak | SanitizerKind::Thread |
485 SanitizerKind::Memory | SanitizerKind::KernelAddress |
486 SanitizerKind::Scudo | SanitizerKind::SafeStack),
487 std::make_pair(SanitizerKind::MemTag,
488 SanitizerKind::Address | SanitizerKind::KernelAddress |
489 SanitizerKind::HWAddress |
490 SanitizerKind::KernelHWAddress)};
496 for (
auto G : IncompatibleGroups) {
512 D.
Diag(diag::err_drv_argument_only_allowed_with)
516 if ((Kinds & SanitizerKind::ShadowCallStack) &&
518 !llvm::AArch64::isX18ReservedByDefault(TC.
getTriple())) ||
520 !Args.hasArg(options::OPT_ffixed_x18) && DiagnoseErrors) {
521 D.
Diag(diag::err_drv_argument_only_allowed_with)
530 if (~Supported & SanitizerKind::Vptr) {
536 if (KindsToDiagnose) {
538 S.Mask = KindsToDiagnose;
540 D.
Diag(diag::err_drv_unsupported_opt_for_target)
542 Kinds &= ~KindsToDiagnose;
547 for (
auto G : IncompatibleGroups) {
552 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
555 Kinds &= ~Incompatible;
568 for (
const auto *Arg : Args) {
569 if (Arg->getOption().matches(options::OPT_fsanitize_recover_EQ)) {
576 SetToDiagnose.
Mask |= KindsToDiagnose;
578 D.
Diag(diag::err_drv_unsupported_option_argument)
579 << Arg->getOption().getName() <<
toString(SetToDiagnose);
580 DiagnosedUnrecoverableKinds |= KindsToDiagnose;
584 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_recover_EQ)) {
591 SetToDiagnose.
Mask |= KindsToDiagnose;
593 D.
Diag(diag::err_drv_unsupported_option_argument)
594 << Arg->getOption().getName() <<
toString(SetToDiagnose);
595 DiagnosedAlwaysRecoverableKinds |= KindsToDiagnose;
601 RecoverableKinds &= Kinds;
604 TrappingKinds &= Kinds;
605 RecoverableKinds &= ~TrappingKinds;
610 if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_ignorelist))
616 D, Args, UserIgnorelistFiles, options::OPT_fsanitize_ignorelist_EQ,
617 options::OPT_fno_sanitize_ignorelist,
618 clang::diag::err_drv_malformed_sanitizer_ignorelist, DiagnoseErrors);
621 if (AllAddedKinds & SanitizerKind::Memory) {
623 Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
624 options::OPT_fsanitize_memory_track_origins,
625 options::OPT_fno_sanitize_memory_track_origins)) {
626 if (A->getOption().matches(options::OPT_fsanitize_memory_track_origins)) {
627 MsanTrackOrigins = 2;
628 }
else if (A->getOption().matches(
629 options::OPT_fno_sanitize_memory_track_origins)) {
630 MsanTrackOrigins = 0;
632 StringRef S = A->getValue();
633 if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
634 MsanTrackOrigins > 2) {
636 D.
Diag(clang::diag::err_drv_invalid_value)
637 << A->getAsString(Args) << S;
641 MsanUseAfterDtor = Args.hasFlag(
642 options::OPT_fsanitize_memory_use_after_dtor,
643 options::OPT_fno_sanitize_memory_use_after_dtor, MsanUseAfterDtor);
644 MsanParamRetval = Args.hasFlag(
645 options::OPT_fsanitize_memory_param_retval,
646 options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
647 NeedPIE |= !(TC.
getTriple().isOSLinux() &&
648 TC.
getTriple().getArch() == llvm::Triple::x86_64);
650 MsanUseAfterDtor =
false;
651 MsanParamRetval =
false;
654 if (AllAddedKinds & SanitizerKind::MemTag) {
656 Args.getLastArgValue(options::OPT_fsanitize_memtag_mode_EQ,
"sync");
657 if (S ==
"async" || S ==
"sync") {
658 MemtagMode = S.str();
660 D.
Diag(clang::diag::err_drv_invalid_value_with_suggestion)
661 <<
"-fsanitize-memtag-mode=" << S <<
"{async, sync}";
666 if (AllAddedKinds & SanitizerKind::Thread) {
667 TsanMemoryAccess = Args.hasFlag(
668 options::OPT_fsanitize_thread_memory_access,
669 options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
670 TsanFuncEntryExit = Args.hasFlag(
671 options::OPT_fsanitize_thread_func_entry_exit,
672 options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
674 Args.hasFlag(options::OPT_fsanitize_thread_atomics,
675 options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
678 if (AllAddedKinds & SanitizerKind::CFI) {
681 NeedPIE |= CfiCrossDso;
682 CfiICallGeneralizePointers =
683 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
685 if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors)
686 D.
Diag(diag::err_drv_argument_not_allowed_with)
687 <<
"-fsanitize-cfi-cross-dso"
688 <<
"-fsanitize-cfi-icall-generalize-pointers";
690 CfiCanonicalJumpTables =
691 Args.hasFlag(options::OPT_fsanitize_cfi_canonical_jump_tables,
692 options::OPT_fno_sanitize_cfi_canonical_jump_tables,
true);
695 Stats = Args.hasFlag(options::OPT_fsanitize_stats,
696 options::OPT_fno_sanitize_stats,
false);
698 if (MinimalRuntime) {
701 if (IncompatibleMask && DiagnoseErrors)
702 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
703 <<
"-fsanitize-minimal-runtime"
706 SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
707 if (NonTrappingCfi && DiagnoseErrors)
708 D.
Diag(clang::diag::err_drv_argument_only_allowed_with)
709 <<
"fsanitize-minimal-runtime"
710 <<
"fsanitize-trap=cfi";
715 for (
const auto *Arg : Args) {
716 if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
717 int LegacySanitizeCoverage;
718 if (Arg->getNumValues() == 1 &&
719 !StringRef(Arg->getValue(0))
720 .getAsInteger(0, LegacySanitizeCoverage)) {
721 CoverageFeatures = 0;
723 if (LegacySanitizeCoverage != 0 && DiagnoseErrors) {
724 D.
Diag(diag::warn_drv_deprecated_arg)
725 << Arg->getAsString(Args) <<
"-fsanitize-coverage=trace-pc-guard";
736 CoverageFeatures = 0;
738 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
744 if (DiagnoseErrors) {
746 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
747 <<
"-fsanitize-coverage=func"
748 <<
"-fsanitize-coverage=bb";
750 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
751 <<
"-fsanitize-coverage=func"
752 <<
"-fsanitize-coverage=edge";
754 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
755 <<
"-fsanitize-coverage=bb"
756 <<
"-fsanitize-coverage=edge";
760 D.
Diag(clang::diag::warn_drv_deprecated_arg)
761 <<
"-fsanitize-coverage=trace-bb"
762 <<
"-fsanitize-coverage=trace-pc-guard";
764 D.
Diag(clang::diag::warn_drv_deprecated_arg)
765 <<
"-fsanitize-coverage=8bit-counters"
766 <<
"-fsanitize-coverage=trace-pc-guard";
773 if ((CoverageFeatures & InsertionPointTypes) &&
774 !(CoverageFeatures & InstrumentationTypes) && DiagnoseErrors) {
775 D.
Diag(clang::diag::warn_drv_deprecated_arg)
776 <<
"-fsanitize-coverage=[func|bb|edge]"
777 <<
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc]";
781 if (!(CoverageFeatures & InsertionPointTypes)) {
782 if (CoverageFeatures &
795 if (CoverageFeatures) {
797 D, Args, CoverageAllowlistFiles,
798 options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
799 clang::diag::err_drv_malformed_sanitizer_coverage_allowlist,
802 D, Args, CoverageIgnorelistFiles,
803 options::OPT_fsanitize_coverage_ignorelist, OptSpecifier(),
804 clang::diag::err_drv_malformed_sanitizer_coverage_ignorelist,
809 Args.hasFlag(options::OPT_shared_libsan, options::OPT_static_libsan,
813 ImplicitCfiRuntime = TC.
getTriple().isAndroid();
815 if (AllAddedKinds & SanitizerKind::Address) {
818 Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
819 StringRef S = A->getValue();
821 if ((S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
822 AsanFieldPadding > 2) &&
824 D.
Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
828 if (Arg *WindowsDebugRTArg =
829 Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
830 options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
831 options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
832 switch (WindowsDebugRTArg->getOption().getID()) {
833 case options::OPT__SLASH_MTd:
834 case options::OPT__SLASH_MDd:
835 case options::OPT__SLASH_LDd:
836 if (DiagnoseErrors) {
837 D.
Diag(clang::diag::err_drv_argument_not_allowed_with)
838 << WindowsDebugRTArg->getAsString(Args)
840 D.
Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
845 AsanUseAfterScope = Args.hasFlag(
846 options::OPT_fsanitize_address_use_after_scope,
847 options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
849 AsanPoisonCustomArrayCookie = Args.hasFlag(
850 options::OPT_fsanitize_address_poison_custom_array_cookie,
851 options::OPT_fno_sanitize_address_poison_custom_array_cookie,
852 AsanPoisonCustomArrayCookie);
854 AsanOutlineInstrumentation =
855 Args.hasFlag(options::OPT_fsanitize_address_outline_instrumentation,
856 options::OPT_fno_sanitize_address_outline_instrumentation,
857 AsanOutlineInstrumentation);
862 AsanGlobalsDeadStripping = Args.hasFlag(
863 options::OPT_fsanitize_address_globals_dead_stripping,
864 options::OPT_fno_sanitize_address_globals_dead_stripping,
868 AsanUseOdrIndicator =
869 Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
870 options::OPT_fno_sanitize_address_use_odr_indicator,
871 AsanUseOdrIndicator);
873 if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
874 AsanInvalidPointerCmp =
true;
877 if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
878 AsanInvalidPointerSub =
true;
882 (Args.hasArg(options::OPT_mkernel) ||
883 Args.hasArg(options::OPT_fapple_kext))) {
887 if (
const auto *Arg =
888 Args.getLastArg(options::OPT_sanitize_address_destructor_EQ)) {
891 TC.
getDriver().
Diag(clang::diag::err_drv_unsupported_option_argument)
892 << Arg->getOption().getName() << Arg->getValue();
894 AsanDtorKind = parsedAsanDtorKind;
897 if (
const auto *Arg = Args.getLastArg(
898 options::OPT_sanitize_address_use_after_return_EQ)) {
899 auto parsedAsanUseAfterReturn =
901 if (parsedAsanUseAfterReturn ==
904 TC.
getDriver().
Diag(clang::diag::err_drv_unsupported_option_argument)
905 << Arg->getOption().getName() << Arg->getValue();
907 AsanUseAfterReturn = parsedAsanUseAfterReturn;
911 AsanUseAfterScope =
false;
914 SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
915 if ((AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) &&
917 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
919 SanitizerKind::PointerCompare |
920 SanitizerKind::PointerSubtract)
921 <<
"-fsanitize=address";
925 if (AllAddedKinds & SanitizerKind::HWAddress) {
926 if (Arg *HwasanAbiArg =
927 Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
928 HwasanAbi = HwasanAbiArg->getValue();
929 if (HwasanAbi !=
"platform" && HwasanAbi !=
"interceptor" &&
931 D.
Diag(clang::diag::err_drv_invalid_value)
932 << HwasanAbiArg->getAsString(Args) << HwasanAbi;
934 HwasanAbi =
"interceptor";
936 if (TC.
getTriple().getArch() == llvm::Triple::x86_64)
937 HwasanUseAliases = Args.hasFlag(
938 options::OPT_fsanitize_hwaddress_experimental_aliasing,
939 options::OPT_fno_sanitize_hwaddress_experimental_aliasing,
943 if (AllAddedKinds & SanitizerKind::SafeStack) {
950 Args.hasFlag(options::OPT_fsanitize_link_runtime,
951 options::OPT_fno_sanitize_link_runtime, LinkRuntimes);
954 LinkCXXRuntimes = Args.hasArg(options::OPT_fsanitize_link_cxx_runtime,
955 options::OPT_fno_sanitize_link_cxx_runtime,
959 NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile,
960 options::OPT_fmemory_profile_EQ,
961 options::OPT_fno_memory_profile,
false);
964 Sanitizers.Mask |= Kinds;
965 RecoverableSanitizers.Mask |= RecoverableKinds;
966 TrapSanitizers.Mask |= TrappingKinds;
967 assert(!(RecoverableKinds & TrappingKinds) &&
968 "Overlap between recoverable and trapping sanitizers");
973 #define SANITIZER(NAME, ID) \
974 if (Sanitizers.has(SanitizerKind::ID)) { \
979 #include "clang/Basic/Sanitizers.def"
984 llvm::opt::ArgStringList &CmdArgs,
985 const char *SCLOptFlag,
986 const std::vector<std::string> &SCLFiles) {
987 for (
const auto &SCLPath : SCLFiles) {
990 CmdArgs.push_back(Args.MakeArgString(SCLOpt));
995 const llvm::opt::ArgList &Args,
996 llvm::opt::ArgStringList &CmdArgs,
997 StringRef SymbolName) {
999 LinkerOptionFlag =
"--linker-option=/include:";
1000 if (TC.
getTriple().getArch() == llvm::Triple::x86) {
1002 LinkerOptionFlag +=
'_';
1004 LinkerOptionFlag += SymbolName;
1005 CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
1009 for (
auto Start = CmdArgs.begin(),
End = CmdArgs.end(); Start !=
End;
1011 auto It = std::find(Start,
End, StringRef(
"+mte"));
1014 if (It > Start && *std::prev(It) == StringRef(
"-target-feature"))
1022 llvm::opt::ArgStringList &CmdArgs,
1031 !Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
1038 std::pair<int, const char *> CoverageFlags[] = {
1039 std::make_pair(
CoverageFunc,
"-fsanitize-coverage-type=1"),
1040 std::make_pair(
CoverageBB,
"-fsanitize-coverage-type=2"),
1041 std::make_pair(
CoverageEdge,
"-fsanitize-coverage-type=3"),
1050 "-fsanitize-coverage-trace-pc-guard"),
1052 "-fsanitize-coverage-inline-8bit-counters"),
1054 "-fsanitize-coverage-inline-bool-flag"),
1060 for (
auto F : CoverageFlags) {
1061 if (CoverageFeatures & F.first)
1062 CmdArgs.push_back(F.second);
1065 Args, CmdArgs,
"-fsanitize-coverage-allowlist=", CoverageAllowlistFiles);
1067 CoverageIgnorelistFiles);
1069 if (TC.
getTriple().isOSWindows() && needsUbsanRt()) {
1073 Args.MakeArgString(
"--dependent-lib=" +
1076 CmdArgs.push_back(Args.MakeArgString(
1077 "--dependent-lib=" +
1080 if (TC.
getTriple().isOSWindows() && needsStatsRt()) {
1081 CmdArgs.push_back(Args.MakeArgString(
1088 CmdArgs.push_back(Args.MakeArgString(
1093 if (Sanitizers.empty())
1095 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize=" +
toString(Sanitizers)));
1097 if (!RecoverableSanitizers.empty())
1098 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-recover=" +
1101 if (!TrapSanitizers.empty())
1103 Args.MakeArgString(
"-fsanitize-trap=" +
toString(TrapSanitizers)));
1106 "-fsanitize-ignorelist=", UserIgnorelistFiles);
1108 "-fsanitize-system-ignorelist=", SystemIgnorelistFiles);
1110 if (MsanTrackOrigins)
1111 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-memory-track-origins=" +
1112 Twine(MsanTrackOrigins)));
1114 if (MsanUseAfterDtor)
1115 CmdArgs.push_back(
"-fsanitize-memory-use-after-dtor");
1117 if (MsanParamRetval)
1118 CmdArgs.push_back(
"-fsanitize-memory-param-retval");
1121 if (!TsanMemoryAccess) {
1122 CmdArgs.push_back(
"-mllvm");
1123 CmdArgs.push_back(
"-tsan-instrument-memory-accesses=0");
1124 CmdArgs.push_back(
"-mllvm");
1125 CmdArgs.push_back(
"-tsan-instrument-memintrinsics=0");
1127 if (!TsanFuncEntryExit) {
1128 CmdArgs.push_back(
"-mllvm");
1129 CmdArgs.push_back(
"-tsan-instrument-func-entry-exit=0");
1132 CmdArgs.push_back(
"-mllvm");
1133 CmdArgs.push_back(
"-tsan-instrument-atomics=0");
1136 if (HwasanUseAliases) {
1137 CmdArgs.push_back(
"-mllvm");
1138 CmdArgs.push_back(
"-hwasan-experimental-use-page-aliases=1");
1142 CmdArgs.push_back(
"-fsanitize-cfi-cross-dso");
1144 if (CfiICallGeneralizePointers)
1145 CmdArgs.push_back(
"-fsanitize-cfi-icall-generalize-pointers");
1147 if (CfiCanonicalJumpTables)
1148 CmdArgs.push_back(
"-fsanitize-cfi-canonical-jump-tables");
1151 CmdArgs.push_back(
"-fsanitize-stats");
1154 CmdArgs.push_back(
"-fsanitize-minimal-runtime");
1156 if (AsanFieldPadding)
1157 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-address-field-padding=" +
1158 Twine(AsanFieldPadding)));
1160 if (AsanUseAfterScope)
1161 CmdArgs.push_back(
"-fsanitize-address-use-after-scope");
1163 if (AsanPoisonCustomArrayCookie)
1164 CmdArgs.push_back(
"-fsanitize-address-poison-custom-array-cookie");
1166 if (AsanGlobalsDeadStripping)
1167 CmdArgs.push_back(
"-fsanitize-address-globals-dead-stripping");
1169 if (AsanUseOdrIndicator)
1170 CmdArgs.push_back(
"-fsanitize-address-use-odr-indicator");
1172 if (AsanInvalidPointerCmp) {
1173 CmdArgs.push_back(
"-mllvm");
1174 CmdArgs.push_back(
"-asan-detect-invalid-pointer-cmp");
1177 if (AsanInvalidPointerSub) {
1178 CmdArgs.push_back(
"-mllvm");
1179 CmdArgs.push_back(
"-asan-detect-invalid-pointer-sub");
1182 if (AsanOutlineInstrumentation) {
1183 CmdArgs.push_back(
"-mllvm");
1184 CmdArgs.push_back(
"-asan-instrumentation-with-call-threshold=0");
1190 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-address-destructor=" +
1195 CmdArgs.push_back(Args.MakeArgString(
1196 "-fsanitize-address-use-after-return=" +
1200 if (!HwasanAbi.empty()) {
1201 CmdArgs.push_back(
"-default-function-attr");
1202 CmdArgs.push_back(Args.MakeArgString(
"hwasan-abi=" + HwasanAbi));
1205 if (Sanitizers.has(SanitizerKind::HWAddress) && !HwasanUseAliases) {
1206 CmdArgs.push_back(
"-target-feature");
1207 CmdArgs.push_back(
"+tagged-globals");
1215 if (Sanitizers.has(SanitizerKind::Memory) ||
1216 Sanitizers.has(SanitizerKind::Address))
1217 CmdArgs.push_back(
"-fno-assume-sane-operator-new");
1224 if (Sanitizers.has(SanitizerKind::FuzzerNoLink)) {
1225 CmdArgs.push_back(
"-fno-builtin-bcmp");
1226 CmdArgs.push_back(
"-fno-builtin-memcmp");
1227 CmdArgs.push_back(
"-fno-builtin-strncmp");
1228 CmdArgs.push_back(
"-fno-builtin-strcmp");
1229 CmdArgs.push_back(
"-fno-builtin-strncasecmp");
1230 CmdArgs.push_back(
"-fno-builtin-strcasecmp");
1231 CmdArgs.push_back(
"-fno-builtin-strstr");
1232 CmdArgs.push_back(
"-fno-builtin-strcasestr");
1233 CmdArgs.push_back(
"-fno-builtin-memmem");
1239 !Args.hasArg(options::OPT_fvisibility_EQ)) {
1240 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
1246 if (Sanitizers.has(SanitizerKind::MemtagStack) &&
1248 TC.
getDriver().
Diag(diag::err_stack_tagging_requires_hardware_feature);
1252 bool DiagnoseErrors) {
1253 assert((A->getOption().matches(options::OPT_fsanitize_EQ) ||
1254 A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1255 A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1256 A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1257 A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1258 A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
1259 "Invalid argument in parseArgValues!");
1261 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1262 const char *
Value = A->getValue(i);
1265 if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
1266 0 == strcmp(
"all",
Value))
1273 else if (DiagnoseErrors)
1274 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
1275 << A->getOption().getName() <<
Value;
1281 bool DiagnoseErrors) {
1282 assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
1283 A->getOption().matches(options::OPT_fno_sanitize_coverage));
1285 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1286 const char *
Value = A->getValue(i);
1287 int F = llvm::StringSwitch<int>(
Value)
1307 if (F == 0 && DiagnoseErrors)
1308 D.
Diag(clang::diag::err_drv_unsupported_option_argument)
1309 << A->getOption().getName() <<
Value;
1317 for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1320 const auto *Arg = *I;
1321 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1324 if (AddKinds & Mask)
1326 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1329 Mask &= ~RemoveKinds;
1332 llvm_unreachable(
"arg list didn't provide expected value");
1336 assert(A->getOption().matches(options::OPT_fsanitize_EQ) &&
1337 "Invalid argument in describeSanitizerArg!");
1340 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1344 if (!Sanitizers.empty())
1346 Sanitizers += A->getValue(i);
1350 assert(!Sanitizers.empty() &&
"arg didn't provide expected value");
1351 return "-fsanitize=" + Sanitizers;