13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/Support/Path.h"
16#include "llvm/Support/SpecialCaseList.h"
17#include "llvm/Support/VirtualFileSystem.h"
18#include "llvm/TargetParser/AArch64TargetParser.h"
19#include "llvm/TargetParser/RISCVTargetParser.h"
20#include "llvm/TargetParser/TargetParser.h"
21#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
29 SanitizerKind::Undefined | SanitizerKind::Integer |
30 SanitizerKind::LocalBounds | SanitizerKind::ImplicitConversion |
31 SanitizerKind::Nullability | SanitizerKind::CFI |
32 SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
34 SanitizerKind::Vptr | SanitizerKind::CFI;
38 SanitizerKind::Function | SanitizerKind::KCFI;
40 SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Type |
41 SanitizerKind::Thread | SanitizerKind::Memory | SanitizerKind::DataFlow |
42 SanitizerKind::NumericalStability;
44 SanitizerKind::Address | SanitizerKind::HWAddress |
45 SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress |
46 SanitizerKind::Type | SanitizerKind::MemtagStack |
47 SanitizerKind::MemtagHeap | SanitizerKind::MemtagGlobals |
48 SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak |
49 SanitizerKind::Undefined | SanitizerKind::Integer | SanitizerKind::Bounds |
50 SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
51 SanitizerKind::DataFlow | SanitizerKind::Fuzzer |
52 SanitizerKind::FuzzerNoLink | SanitizerKind::FloatDivideByZero |
53 SanitizerKind::SafeStack | SanitizerKind::ShadowCallStack |
54 SanitizerKind::Thread | SanitizerKind::ObjCCast | SanitizerKind::KCFI |
55 SanitizerKind::NumericalStability;
57 SanitizerKind::Undefined | SanitizerKind::Integer |
58 SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
59 SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
61 SanitizerKind::Unreachable | SanitizerKind::Return;
63 SanitizerKind::KernelHWAddress |
67 (SanitizerKind::Undefined &
~SanitizerKind::Vptr) | SanitizerKind::Integer |
68 SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
69 SanitizerKind::LocalBounds | SanitizerKind::CFI |
70 SanitizerKind::FloatDivideByZero | SanitizerKind::ObjCCast;
73 SanitizerKind::CFI | SanitizerKind::LocalBounds;
75 SanitizerKind::CFIVCall | SanitizerKind::CFINVCall |
76 SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast |
77 SanitizerKind::CFIUnrelatedCast;
80 SanitizerKind::MemtagStack | SanitizerKind::MemtagHeap |
81 SanitizerKind::MemtagGlobals | SanitizerKind::KCFI;
114 bool DiagnoseErrors);
119 bool DiagnoseErrors);
124 const llvm::opt::Arg *A,
125 bool DiagnoseErrors);
130 bool DiagnoseErrors);
137 const llvm::opt::ArgList &Args,
154 const llvm::opt::ArgList &Args) {
157 return Args.hasFlagNoClaim(options::OPT_mexecute_only,
158 options::OPT_mno_execute_only,
false);
162 std::vector<std::string> &SCLFiles,
163 unsigned MalformedSCLErrorDiagID,
164 bool DiagnoseErrors) {
165 if (SCLFiles.empty())
169 std::unique_ptr<llvm::SpecialCaseList> SCL(
170 llvm::SpecialCaseList::create(SCLFiles,
D.getVFS(), BLError));
171 if (!SCL.get() && DiagnoseErrors)
172 D.Diag(MalformedSCLErrorDiagID) << BLError;
176 std::vector<std::string> &IgnorelistFiles,
177 bool DiagnoseErrors) {
181 } Ignorelists[] = {{
"asan_ignorelist.txt", SanitizerKind::Address},
182 {
"hwasan_ignorelist.txt", SanitizerKind::HWAddress},
183 {
"memtag_ignorelist.txt", SanitizerKind::MemTag},
184 {
"msan_ignorelist.txt", SanitizerKind::Memory},
185 {
"nsan_ignorelist.txt", SanitizerKind::NumericalStability},
186 {
"tsan_ignorelist.txt", SanitizerKind::Thread},
187 {
"tysan_blacklist.txt", SanitizerKind::Type},
188 {
"dfsan_abilist.txt", SanitizerKind::DataFlow},
189 {
"cfi_ignorelist.txt", SanitizerKind::CFI},
190 {
"ubsan_ignorelist.txt",
191 SanitizerKind::Undefined | SanitizerKind::Integer |
192 SanitizerKind::Nullability |
193 SanitizerKind::FloatDivideByZero}};
195 for (
auto BL : Ignorelists) {
196 if (!(Kinds & BL.Mask))
200 llvm::sys::path::append(
Path,
"share", BL.File);
201 if (
D.getVFS().exists(
Path))
202 IgnorelistFiles.push_back(std::string(
Path));
203 else if (BL.Mask == SanitizerKind::CFI && DiagnoseErrors)
206 D.Diag(clang::diag::err_drv_missing_sanitizer_ignorelist) <<
Path;
209 D, IgnorelistFiles, clang::diag::err_drv_malformed_sanitizer_ignorelist,
216 const llvm::opt::ArgList &Args,
217 std::vector<std::string> &SCLFiles,
218 llvm::opt::OptSpecifier SCLOptionID,
219 llvm::opt::OptSpecifier NoSCLOptionID,
220 unsigned MalformedSCLErrorDiagID,
221 bool DiagnoseErrors) {
222 for (
const auto *Arg : Args) {
224 if (Arg->getOption().matches(SCLOptionID)) {
226 std::string SCLPath = Arg->getValue();
227 if (
D.getVFS().exists(SCLPath)) {
228 SCLFiles.push_back(SCLPath);
229 }
else if (DiagnoseErrors) {
230 D.Diag(clang::diag::err_drv_no_such_file) << SCLPath;
233 }
else if (Arg->getOption().matches(NoSCLOptionID)) {
245#define SANITIZER(NAME, ID)
246#define SANITIZER_GROUP(NAME, ID, ALIAS) \
247 if (Kinds & SanitizerKind::ID) \
248 Kinds |= SanitizerKind::ID##Group;
249#include "clang/Basic/Sanitizers.def"
264 assert(!(AlwaysIn & AlwaysOut) &&
265 "parseSanitizeArgs called with contradictory in/out requirements");
272 for (
const auto *Arg : Args) {
273 if (Arg->getOption().matches(OptInID)) {
278 Add & AlwaysOut & ~DiagnosedAlwaysOutViolations) {
279 if (DiagnoseErrors) {
281 SetToDiagnose.
Mask |= KindsToDiagnose;
282 D.Diag(diag::err_drv_unsupported_option_argument)
283 << Arg->getSpelling() <<
toString(SetToDiagnose);
284 DiagnosedAlwaysOutViolations |= KindsToDiagnose;
289 }
else if (Arg->getOption().matches(OptOutID)) {
294 Remove & AlwaysIn & ~DiagnosedAlwaysInViolations) {
295 if (DiagnoseErrors) {
297 SetToDiagnose.
Mask |= KindsToDiagnose;
298 D.Diag(diag::err_drv_unsupported_option_argument)
299 << Arg->getSpelling() <<
toString(SetToDiagnose);
300 DiagnosedAlwaysInViolations |= KindsToDiagnose;
303 Output &= ~expandSanitizerGroups(Remove);
312 const llvm::opt::ArgList &Args,
313 bool DiagnoseErrors) {
322 NeverTrap, options::OPT_fsanitize_trap_EQ,
323 options::OPT_fno_sanitize_trap_EQ);
346 ~TrapSanitizers.Mask);
350 return !(Sanitizers.
Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) &&
351 CfiCrossDso && !ImplicitCfiRuntime;
355 return (Sanitizers.
Mask & SanitizerKind::CFI & ~TrapSanitizers.
Mask) &&
356 CfiCrossDso && !ImplicitCfiRuntime;
370 const llvm::opt::ArgList &Args,
371 bool DiagnoseErrors) {
385 CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
386 options::OPT_fno_sanitize_cfi_cross_dso,
false);
395 Args.hasFlag(options::OPT_fsanitize_minimal_runtime,
396 options::OPT_fno_sanitize_minimal_runtime, MinimalRuntime);
399 Arg *OptLevel = Args.getLastArg(options::OPT_O_Group);
400 bool RemoveObjectSizeAtO0 =
401 !OptLevel || OptLevel->getOption().matches(options::OPT_O0);
403 for (
const llvm::opt::Arg *Arg : llvm::reverse(Args)) {
404 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
408 if (RemoveObjectSizeAtO0) {
409 AllRemove |= SanitizerKind::ObjectSize;
413 if ((Add & SanitizerKind::ObjectSize) && DiagnoseErrors)
414 D.Diag(diag::warn_drv_object_size_disabled_O0)
415 << Arg->getAsString(Args);
426 Add & InvalidTrappingKinds & ~DiagnosedKinds) {
427 if (DiagnoseErrors) {
429 D.Diag(diag::err_drv_argument_not_allowed_with)
430 << Desc <<
"-fsanitize-trap=undefined";
432 DiagnosedKinds |= KindsToDiagnose;
434 Add &= ~InvalidTrappingKinds;
436 if (MinimalRuntime) {
439 if (DiagnoseErrors) {
441 D.Diag(diag::err_drv_argument_not_allowed_with)
442 << Desc <<
"-fsanitize-minimal-runtime";
444 DiagnosedKinds |= KindsToDiagnose;
446 Add &= ~NotAllowedWithMinimalRuntime;
449 if (llvm::opt::Arg *A = Args.getLastArg(options::OPT_mcmodel_EQ)) {
450 StringRef CM = A->getValue();
452 (Add & SanitizerKind::Function & ~DiagnosedKinds)) {
454 D.Diag(diag::err_drv_argument_only_allowed_with)
455 <<
"-fsanitize=function"
458 DiagnosedKinds |= SanitizerKind::Function;
464 const llvm::Triple &Triple = TC.
getTriple();
468 if (DiagnoseErrors) {
470 llvm::opt::Arg *A = Args.getLastArgNoClaim(
471 options::OPT_mexecute_only, options::OPT_mno_execute_only);
472 if (A && A->getOption().matches(options::OPT_mexecute_only))
473 D.Diag(diag::err_drv_argument_not_allowed_with)
474 << Desc << A->getAsString(Args);
476 D.Diag(diag::err_drv_unsupported_opt_for_target)
477 << Desc << Triple.str();
479 DiagnosedKinds |= KindsToDiagnose;
481 Add &= ~NotAllowedWithExecuteOnly;
494 if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) {
496 D.Diag(diag::err_drv_argument_not_allowed_with)
497 <<
"-fsanitize=cfi-mfcall"
498 <<
"-fsanitize-cfi-cross-dso";
500 DiagnosedKinds |= SanitizerKind::CFIMFCall;
503 if (
SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) {
504 if (DiagnoseErrors) {
506 D.Diag(diag::err_drv_unsupported_opt_for_target)
509 DiagnosedKinds |= KindsToDiagnose;
517 if (
const llvm::opt::Arg *NoRTTIArg = TC.
getRTTIArg()) {
518 assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) &&
519 "RTTI disabled without -fno-rtti option?");
523 D.Diag(diag::err_drv_argument_not_allowed_with)
524 <<
"-fsanitize=vptr" << NoRTTIArg->getAsString(Args);
529 D.Diag(diag::warn_drv_disabling_vptr_no_rtti_default);
533 AllRemove |= SanitizerKind::Vptr;
541 Add &= ~InvalidTrappingKinds;
542 if (MinimalRuntime) {
543 Add &= ~NotAllowedWithMinimalRuntime;
548 Add &= ~NotAllowedWithExecuteOnly;
553 if (Add & SanitizerKind::UndefinedGroup) {
554 bool S = Args.hasFlagNoClaim(options::OPT_fno_strict_overflow,
555 options::OPT_fstrict_overflow,
false);
556 if (Args.hasFlagNoClaim(options::OPT_fwrapv, options::OPT_fno_wrapv, S))
561 if (Add & SanitizerKind::Fuzzer)
562 Add |= SanitizerKind::FuzzerNoLink;
565 if (Add & SanitizerKind::FuzzerNoLink) {
574 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
581 std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
582 std::make_pair(SanitizerKind::Address,
583 SanitizerKind::Thread | SanitizerKind::Memory),
584 std::make_pair(SanitizerKind::Type,
585 SanitizerKind::Address | SanitizerKind::KernelAddress |
586 SanitizerKind::Memory | SanitizerKind::Leak |
587 SanitizerKind::Thread | SanitizerKind::KernelAddress),
588 std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory),
589 std::make_pair(SanitizerKind::Leak,
590 SanitizerKind::Thread | SanitizerKind::Memory),
591 std::make_pair(SanitizerKind::KernelAddress,
592 SanitizerKind::Address | SanitizerKind::Leak |
593 SanitizerKind::Thread | SanitizerKind::Memory),
594 std::make_pair(SanitizerKind::HWAddress,
595 SanitizerKind::Address | SanitizerKind::Thread |
596 SanitizerKind::Memory | SanitizerKind::KernelAddress),
597 std::make_pair(SanitizerKind::Scudo,
598 SanitizerKind::Address | SanitizerKind::HWAddress |
599 SanitizerKind::Leak | SanitizerKind::Thread |
600 SanitizerKind::Memory | SanitizerKind::KernelAddress),
601 std::make_pair(SanitizerKind::SafeStack,
603 : SanitizerKind::Leak) |
604 SanitizerKind::Address | SanitizerKind::HWAddress |
605 SanitizerKind::Thread | SanitizerKind::Memory |
606 SanitizerKind::KernelAddress),
607 std::make_pair(SanitizerKind::KernelHWAddress,
608 SanitizerKind::Address | SanitizerKind::HWAddress |
609 SanitizerKind::Leak | SanitizerKind::Thread |
610 SanitizerKind::Memory | SanitizerKind::KernelAddress |
611 SanitizerKind::SafeStack),
612 std::make_pair(SanitizerKind::KernelMemory,
613 SanitizerKind::Address | SanitizerKind::HWAddress |
614 SanitizerKind::Leak | SanitizerKind::Thread |
615 SanitizerKind::Memory | SanitizerKind::KernelAddress |
616 SanitizerKind::Scudo | SanitizerKind::SafeStack),
617 std::make_pair(SanitizerKind::MemTag, SanitizerKind::Address |
618 SanitizerKind::KernelAddress |
619 SanitizerKind::HWAddress |
620 SanitizerKind::KernelHWAddress),
621 std::make_pair(SanitizerKind::KCFI, SanitizerKind::Function),
622 std::make_pair(SanitizerKind::Realtime,
623 SanitizerKind::Address | SanitizerKind::Thread |
624 SanitizerKind::Undefined | SanitizerKind::Memory)};
631 for (
auto G : IncompatibleGroups) {
633 if ((
Default & Group) && (Kinds & G.second))
646 if ((Kinds &
NeedsLTO) && !
D.isUsingLTO() && DiagnoseErrors) {
647 D.Diag(diag::err_drv_argument_only_allowed_with)
651 if ((Kinds & SanitizerKind::ShadowCallStack) && TC.
getTriple().isAArch64() &&
652 !llvm::AArch64::isX18ReservedByDefault(TC.
getTriple()) &&
653 !Args.hasArg(options::OPT_ffixed_x18) && DiagnoseErrors) {
654 D.Diag(diag::err_drv_argument_only_allowed_with)
663 if (~Supported & SanitizerKind::Vptr) {
669 if (KindsToDiagnose) {
671 S.Mask = KindsToDiagnose;
673 D.Diag(diag::err_drv_unsupported_opt_for_target)
675 Kinds &= ~KindsToDiagnose;
680 for (
auto G : IncompatibleGroups) {
685 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
688 Kinds &= ~Incompatible;
701 options::OPT_fno_sanitize_recover_EQ);
703 RecoverableKinds &= ~Unrecoverable;
704 RecoverableKinds &= Kinds;
706 TrappingKinds &= Kinds;
707 RecoverableKinds &= ~TrappingKinds;
712 options::OPT_fsanitize_merge_handlers_EQ,
713 options::OPT_fno_sanitize_merge_handlers_EQ);
719 if (!Args.hasArgNoClaim(options::OPT_fno_sanitize_ignorelist))
725 D, Args, UserIgnorelistFiles, options::OPT_fsanitize_ignorelist_EQ,
726 options::OPT_fno_sanitize_ignorelist,
727 clang::diag::err_drv_malformed_sanitizer_ignorelist, DiagnoseErrors);
730 if (AllAddedKinds & SanitizerKind::Memory) {
732 Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ,
733 options::OPT_fno_sanitize_memory_track_origins)) {
734 if (!A->getOption().matches(
735 options::OPT_fno_sanitize_memory_track_origins)) {
736 StringRef S = A->getValue();
737 if (S.getAsInteger(0, MsanTrackOrigins) || MsanTrackOrigins < 0 ||
738 MsanTrackOrigins > 2) {
740 D.Diag(clang::diag::err_drv_invalid_value)
741 << A->getAsString(Args) << S;
745 MsanUseAfterDtor = Args.hasFlag(
746 options::OPT_fsanitize_memory_use_after_dtor,
747 options::OPT_fno_sanitize_memory_use_after_dtor, MsanUseAfterDtor);
748 MsanParamRetval = Args.hasFlag(
749 options::OPT_fsanitize_memory_param_retval,
750 options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
751 }
else if (AllAddedKinds & SanitizerKind::KernelMemory) {
752 MsanUseAfterDtor =
false;
753 MsanParamRetval = Args.hasFlag(
754 options::OPT_fsanitize_memory_param_retval,
755 options::OPT_fno_sanitize_memory_param_retval, MsanParamRetval);
757 MsanUseAfterDtor =
false;
758 MsanParamRetval =
false;
761 if (AllAddedKinds & SanitizerKind::MemTag) {
763 Args.getLastArgValue(options::OPT_fsanitize_memtag_mode_EQ,
"sync");
764 if (S ==
"async" || S ==
"sync") {
765 MemtagMode = S.str();
767 D.Diag(clang::diag::err_drv_invalid_value_with_suggestion)
768 <<
"-fsanitize-memtag-mode=" << S <<
"{async, sync}";
773 if (AllAddedKinds & SanitizerKind::Thread) {
774 TsanMemoryAccess = Args.hasFlag(
775 options::OPT_fsanitize_thread_memory_access,
776 options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess);
777 TsanFuncEntryExit = Args.hasFlag(
778 options::OPT_fsanitize_thread_func_entry_exit,
779 options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit);
781 Args.hasFlag(options::OPT_fsanitize_thread_atomics,
782 options::OPT_fno_sanitize_thread_atomics, TsanAtomics);
785 if (AllAddedKinds & SanitizerKind::CFI) {
788 NeedPIE |= CfiCrossDso;
789 CfiICallGeneralizePointers =
790 Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
792 CfiICallNormalizeIntegers =
793 Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
795 if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors)
796 D.Diag(diag::err_drv_argument_not_allowed_with)
797 <<
"-fsanitize-cfi-cross-dso"
798 <<
"-fsanitize-cfi-icall-generalize-pointers";
800 CfiCanonicalJumpTables =
801 Args.hasFlag(options::OPT_fsanitize_cfi_canonical_jump_tables,
802 options::OPT_fno_sanitize_cfi_canonical_jump_tables,
true);
805 if (AllAddedKinds & SanitizerKind::KCFI) {
806 CfiICallNormalizeIntegers =
807 Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
809 if (AllAddedKinds & SanitizerKind::CFI && DiagnoseErrors)
810 D.Diag(diag::err_drv_argument_not_allowed_with)
815 Stats = Args.hasFlag(options::OPT_fsanitize_stats,
816 options::OPT_fno_sanitize_stats,
false);
818 if (MinimalRuntime) {
821 if (IncompatibleMask && DiagnoseErrors)
822 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
823 <<
"-fsanitize-minimal-runtime"
826 SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds;
827 if (NonTrappingCfi && DiagnoseErrors)
828 D.Diag(clang::diag::err_drv_argument_only_allowed_with)
829 <<
"fsanitize-minimal-runtime"
830 <<
"fsanitize-trap=cfi";
833 for (
const auto *Arg : Args.filtered(
834 options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ)) {
836 OverflowPatternExclusions |=
842 for (
const auto *Arg : Args) {
843 if (Arg->getOption().matches(options::OPT_fsanitize_coverage)) {
844 int LegacySanitizeCoverage;
845 if (Arg->getNumValues() == 1 &&
846 !StringRef(Arg->getValue(0))
847 .getAsInteger(0, LegacySanitizeCoverage)) {
848 CoverageFeatures = 0;
850 if (LegacySanitizeCoverage != 0 && DiagnoseErrors) {
851 D.Diag(diag::warn_drv_deprecated_arg)
852 << Arg->getAsString(Args) <<
true
853 <<
"-fsanitize-coverage=trace-pc-guard";
864 CoverageFeatures = 0;
866 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_coverage)) {
868 CoverageFeatures &= ~parseCoverageFeatures(
D, Arg, DiagnoseErrors);
872 if (DiagnoseErrors) {
874 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
875 <<
"-fsanitize-coverage=func"
876 <<
"-fsanitize-coverage=bb";
878 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
879 <<
"-fsanitize-coverage=func"
880 <<
"-fsanitize-coverage=edge";
882 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
883 <<
"-fsanitize-coverage=bb"
884 <<
"-fsanitize-coverage=edge";
888 D.Diag(clang::diag::warn_drv_deprecated_arg)
889 <<
"-fsanitize-coverage=trace-bb" <<
true
890 <<
"-fsanitize-coverage=trace-pc-guard";
892 D.Diag(clang::diag::warn_drv_deprecated_arg)
893 <<
"-fsanitize-coverage=8bit-counters" <<
true
894 <<
"-fsanitize-coverage=trace-pc-guard";
902 if ((CoverageFeatures & InsertionPointTypes) &&
903 !(CoverageFeatures & InstrumentationTypes) && DiagnoseErrors) {
904 D.Diag(clang::diag::warn_drv_deprecated_arg)
905 <<
"-fsanitize-coverage=[func|bb|edge]" <<
true
906 <<
"-fsanitize-coverage=[func|bb|edge],[trace-pc-guard|trace-pc],["
911 if (!(CoverageFeatures & InsertionPointTypes)) {
912 if (CoverageFeatures &
925 if (CoverageFeatures) {
927 D, Args, CoverageAllowlistFiles,
928 options::OPT_fsanitize_coverage_allowlist, OptSpecifier(),
929 clang::diag::err_drv_malformed_sanitizer_coverage_allowlist,
932 D, Args, CoverageIgnorelistFiles,
933 options::OPT_fsanitize_coverage_ignorelist, OptSpecifier(),
934 clang::diag::err_drv_malformed_sanitizer_coverage_ignorelist,
939 for (
const auto *Arg :
940 Args.filtered(options::OPT_fexperimental_sanitize_metadata_EQ,
941 options::OPT_fno_experimental_sanitize_metadata_EQ)) {
942 if (Arg->getOption().matches(
943 options::OPT_fexperimental_sanitize_metadata_EQ)) {
945 BinaryMetadataFeatures |=
949 BinaryMetadataFeatures &=
950 ~parseBinaryMetadataFeatures(
D, Arg, DiagnoseErrors);
955 if (BinaryMetadataFeatures) {
957 D, Args, BinaryMetadataIgnorelistFiles,
958 options::OPT_fexperimental_sanitize_metadata_ignorelist_EQ,
960 clang::diag::err_drv_malformed_sanitizer_metadata_ignorelist,
964 SharedRuntime = Args.hasFlag(
965 options::OPT_shared_libsan, options::OPT_static_libsan,
968 if (!SharedRuntime && TC.
getTriple().isOSWindows()) {
970 Args.getLastArg(options::OPT_shared_libsan, options::OPT_static_libsan);
971 D.Diag(clang::diag::err_drv_unsupported_opt_for_target)
972 << A->getSpelling() << TC.
getTriple().str();
975 ImplicitCfiRuntime = TC.
getTriple().isAndroid();
977 if (AllAddedKinds & SanitizerKind::Address) {
980 Args.getLastArg(options::OPT_fsanitize_address_field_padding)) {
981 StringRef S = A->getValue();
983 if ((S.getAsInteger(0, AsanFieldPadding) || AsanFieldPadding < 0 ||
984 AsanFieldPadding > 2) &&
986 D.Diag(clang::diag::err_drv_invalid_value) << A->getAsString(Args) << S;
990 if (Arg *WindowsDebugRTArg =
991 Args.getLastArg(options::OPT__SLASH_MTd, options::OPT__SLASH_MT,
992 options::OPT__SLASH_MDd, options::OPT__SLASH_MD,
993 options::OPT__SLASH_LDd, options::OPT__SLASH_LD)) {
994 switch (WindowsDebugRTArg->getOption().getID()) {
995 case options::OPT__SLASH_MTd:
996 case options::OPT__SLASH_MDd:
997 case options::OPT__SLASH_LDd:
998 if (DiagnoseErrors) {
999 D.Diag(clang::diag::err_drv_argument_not_allowed_with)
1000 << WindowsDebugRTArg->getAsString(Args)
1002 D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime);
1007 StableABI = Args.hasFlag(options::OPT_fsanitize_stable_abi,
1008 options::OPT_fno_sanitize_stable_abi,
false);
1010 AsanUseAfterScope = Args.hasFlag(
1011 options::OPT_fsanitize_address_use_after_scope,
1012 options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
1014 AsanPoisonCustomArrayCookie = Args.hasFlag(
1015 options::OPT_fsanitize_address_poison_custom_array_cookie,
1016 options::OPT_fno_sanitize_address_poison_custom_array_cookie,
1017 AsanPoisonCustomArrayCookie);
1019 AsanOutlineInstrumentation =
1020 Args.hasFlag(options::OPT_fsanitize_address_outline_instrumentation,
1021 options::OPT_fno_sanitize_address_outline_instrumentation,
1022 AsanOutlineInstrumentation);
1024 AsanGlobalsDeadStripping = Args.hasFlag(
1025 options::OPT_fsanitize_address_globals_dead_stripping,
1026 options::OPT_fno_sanitize_address_globals_dead_stripping,
true);
1032 AsanUseOdrIndicator =
1033 Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator,
1034 options::OPT_fno_sanitize_address_use_odr_indicator,
1037 if (AllAddedKinds & SanitizerKind::PointerCompare & ~AllRemove) {
1038 AsanInvalidPointerCmp =
true;
1041 if (AllAddedKinds & SanitizerKind::PointerSubtract & ~AllRemove) {
1042 AsanInvalidPointerSub =
true;
1046 (Args.hasArg(options::OPT_mkernel) ||
1047 Args.hasArg(options::OPT_fapple_kext))) {
1048 AsanDtorKind = llvm::AsanDtorKind::None;
1051 if (
const auto *Arg =
1052 Args.getLastArg(options::OPT_sanitize_address_destructor_EQ)) {
1054 if (parsedAsanDtorKind == llvm::AsanDtorKind::Invalid && DiagnoseErrors) {
1055 TC.
getDriver().
Diag(clang::diag::err_drv_unsupported_option_argument)
1056 << Arg->getSpelling() << Arg->getValue();
1058 AsanDtorKind = parsedAsanDtorKind;
1061 if (
const auto *Arg = Args.getLastArg(
1062 options::OPT_sanitize_address_use_after_return_EQ)) {
1063 auto parsedAsanUseAfterReturn =
1065 if (parsedAsanUseAfterReturn ==
1066 llvm::AsanDetectStackUseAfterReturnMode::Invalid &&
1068 TC.
getDriver().
Diag(clang::diag::err_drv_unsupported_option_argument)
1069 << Arg->getSpelling() << Arg->getValue();
1071 AsanUseAfterReturn = parsedAsanUseAfterReturn;
1075 AsanUseAfterScope =
false;
1078 SanitizerKind::PointerCompare | SanitizerKind::PointerSubtract;
1079 if ((AllAddedKinds & DetectInvalidPointerPairs & ~AllRemove) &&
1081 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
1083 SanitizerKind::PointerCompare |
1084 SanitizerKind::PointerSubtract)
1085 <<
"-fsanitize=address";
1089 if (AllAddedKinds & SanitizerKind::HWAddress) {
1090 if (Arg *HwasanAbiArg =
1091 Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) {
1092 HwasanAbi = HwasanAbiArg->getValue();
1093 if (HwasanAbi !=
"platform" && HwasanAbi !=
"interceptor" &&
1095 D.Diag(clang::diag::err_drv_invalid_value)
1096 << HwasanAbiArg->getAsString(Args) << HwasanAbi;
1098 HwasanAbi =
"interceptor";
1100 if (TC.
getTriple().getArch() == llvm::Triple::x86_64)
1101 HwasanUseAliases = Args.hasFlag(
1102 options::OPT_fsanitize_hwaddress_experimental_aliasing,
1103 options::OPT_fno_sanitize_hwaddress_experimental_aliasing,
1107 if (AllAddedKinds & SanitizerKind::SafeStack) {
1114 Args.hasFlag(options::OPT_fsanitize_link_runtime,
1115 options::OPT_fno_sanitize_link_runtime, LinkRuntimes);
1118 LinkCXXRuntimes =
D.CCCIsCXX();
1120 Args.hasFlag(options::OPT_fsanitize_link_cxx_runtime,
1121 options::OPT_fno_sanitize_link_cxx_runtime, LinkCXXRuntimes);
1123 NeedsMemProfRt = Args.hasFlag(options::OPT_fmemory_profile,
1124 options::OPT_fmemory_profile_EQ,
1125 options::OPT_fno_memory_profile,
false);
1128 Sanitizers.
Mask |= Kinds;
1129 RecoverableSanitizers.
Mask |= RecoverableKinds;
1130 TrapSanitizers.
Mask |= TrappingKinds;
1131 assert(!(RecoverableKinds & TrappingKinds) &&
1132 "Overlap between recoverable and trapping sanitizers");
1134 MergeHandlers.
Mask |= MergeKinds;
1139#define SANITIZER(NAME, ID) \
1140 if (Sanitizers.has(SanitizerKind::ID)) { \
1145#include "clang/Basic/Sanitizers.def"
1150 llvm::opt::ArgStringList &CmdArgs,
1151 const char *SCLOptFlag,
1152 const std::vector<std::string> &SCLFiles) {
1153 for (
const auto &SCLPath : SCLFiles) {
1156 CmdArgs.push_back(Args.MakeArgString(SCLOpt));
1161 const llvm::opt::ArgList &Args,
1162 llvm::opt::ArgStringList &CmdArgs,
1163 StringRef SymbolName) {
1165 LinkerOptionFlag =
"--linker-option=/include:";
1166 if (TC.
getTriple().getArch() == llvm::Triple::x86) {
1168 LinkerOptionFlag +=
'_';
1170 LinkerOptionFlag += SymbolName;
1171 CmdArgs.push_back(Args.MakeArgString(LinkerOptionFlag));
1175 for (
auto Start = CmdArgs.begin(), End = CmdArgs.end(); Start != End;
1177 auto It = std::find(Start, End, StringRef(
"+mte"));
1180 if (It > Start && *std::prev(It) == StringRef(
"-target-feature"))
1188 llvm::opt::ArgStringList &CmdArgs,
1196 bool GPUSanitize =
false;
1198 if (!Args.hasFlag(options::OPT_fgpu_sanitize, options::OPT_fno_gpu_sanitize,
1207 std::pair<int, const char *> CoverageFlags[] = {
1208 std::make_pair(
CoverageFunc,
"-fsanitize-coverage-type=1"),
1209 std::make_pair(
CoverageBB,
"-fsanitize-coverage-type=2"),
1210 std::make_pair(
CoverageEdge,
"-fsanitize-coverage-type=3"),
1219 "-fsanitize-coverage-trace-pc-guard"),
1221 "-fsanitize-coverage-inline-8bit-counters"),
1223 "-fsanitize-coverage-inline-bool-flag"),
1230 for (
auto F : CoverageFlags) {
1231 if (CoverageFeatures & F.first)
1232 CmdArgs.push_back(F.second);
1235 Args, CmdArgs,
"-fsanitize-coverage-allowlist=", CoverageAllowlistFiles);
1237 CoverageIgnorelistFiles);
1242 const std::pair<int, std::string> BinaryMetadataFlags[] = {
1246 for (
const auto &F : BinaryMetadataFlags) {
1247 if (BinaryMetadataFeatures & F.first)
1249 Args.MakeArgString(
"-fexperimental-sanitize-metadata=" + F.second));
1252 "-fexperimental-sanitize-metadata-ignorelist=",
1253 BinaryMetadataIgnorelistFiles);
1257 Args.hasFlag(options::OPT_frtlib_defaultlib,
1258 options::OPT_fno_rtlib_defaultlib,
true)) {
1262 Args.MakeArgString(
"--dependent-lib=" +
1265 CmdArgs.push_back(Args.MakeArgString(
1266 "--dependent-lib=" +
1270 Args.hasFlag(options::OPT_frtlib_defaultlib,
1271 options::OPT_fno_rtlib_defaultlib,
true)) {
1272 CmdArgs.push_back(Args.MakeArgString(
1279 CmdArgs.push_back(Args.MakeArgString(
1284 if (Sanitizers.
empty())
1286 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize=" +
toString(Sanitizers)));
1288 if (!RecoverableSanitizers.
empty())
1289 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-recover=" +
1292 if (!TrapSanitizers.
empty())
1294 Args.MakeArgString(
"-fsanitize-trap=" +
toString(TrapSanitizers)));
1296 if (!MergeHandlers.
empty())
1298 Args.MakeArgString(
"-fsanitize-merge=" +
toString(MergeHandlers)));
1301 "-fsanitize-ignorelist=", UserIgnorelistFiles);
1303 "-fsanitize-system-ignorelist=", SystemIgnorelistFiles);
1305 if (OverflowPatternExclusions)
1307 CmdArgs, options::OPT_fsanitize_undefined_ignore_overflow_pattern_EQ);
1309 if (MsanTrackOrigins)
1310 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-memory-track-origins=" +
1311 Twine(MsanTrackOrigins)));
1313 if (MsanUseAfterDtor)
1314 CmdArgs.push_back(
"-fsanitize-memory-use-after-dtor");
1316 if (!MsanParamRetval)
1317 CmdArgs.push_back(
"-fno-sanitize-memory-param-retval");
1320 if (!TsanMemoryAccess) {
1321 CmdArgs.push_back(
"-mllvm");
1322 CmdArgs.push_back(
"-tsan-instrument-memory-accesses=0");
1323 CmdArgs.push_back(
"-mllvm");
1324 CmdArgs.push_back(
"-tsan-instrument-memintrinsics=0");
1326 if (!TsanFuncEntryExit) {
1327 CmdArgs.push_back(
"-mllvm");
1328 CmdArgs.push_back(
"-tsan-instrument-func-entry-exit=0");
1331 CmdArgs.push_back(
"-mllvm");
1332 CmdArgs.push_back(
"-tsan-instrument-atomics=0");
1335 if (HwasanUseAliases) {
1336 CmdArgs.push_back(
"-mllvm");
1337 CmdArgs.push_back(
"-hwasan-experimental-use-page-aliases=1");
1341 CmdArgs.push_back(
"-fsanitize-cfi-cross-dso");
1343 if (CfiICallGeneralizePointers)
1344 CmdArgs.push_back(
"-fsanitize-cfi-icall-generalize-pointers");
1346 if (CfiICallNormalizeIntegers)
1347 CmdArgs.push_back(
"-fsanitize-cfi-icall-experimental-normalize-integers");
1349 if (CfiCanonicalJumpTables)
1350 CmdArgs.push_back(
"-fsanitize-cfi-canonical-jump-tables");
1353 CmdArgs.push_back(
"-fsanitize-stats");
1356 CmdArgs.push_back(
"-fsanitize-minimal-runtime");
1358 if (AsanFieldPadding)
1359 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-address-field-padding=" +
1360 Twine(AsanFieldPadding)));
1362 if (AsanUseAfterScope)
1363 CmdArgs.push_back(
"-fsanitize-address-use-after-scope");
1365 if (AsanPoisonCustomArrayCookie)
1366 CmdArgs.push_back(
"-fsanitize-address-poison-custom-array-cookie");
1368 if (AsanGlobalsDeadStripping)
1369 CmdArgs.push_back(
"-fsanitize-address-globals-dead-stripping");
1371 if (!AsanUseOdrIndicator)
1372 CmdArgs.push_back(
"-fno-sanitize-address-use-odr-indicator");
1374 if (AsanInvalidPointerCmp) {
1375 CmdArgs.push_back(
"-mllvm");
1376 CmdArgs.push_back(
"-asan-detect-invalid-pointer-cmp");
1379 if (AsanInvalidPointerSub) {
1380 CmdArgs.push_back(
"-mllvm");
1381 CmdArgs.push_back(
"-asan-detect-invalid-pointer-sub");
1384 if (AsanOutlineInstrumentation) {
1385 CmdArgs.push_back(
"-mllvm");
1386 CmdArgs.push_back(
"-asan-instrumentation-with-call-threshold=0");
1393 CmdArgs.push_back(
"-mllvm");
1394 CmdArgs.push_back(
"-asan-instrumentation-with-call-threshold=0");
1395 CmdArgs.push_back(
"-mllvm");
1396 CmdArgs.push_back(
"-asan-max-inline-poisoning-size=0");
1397 CmdArgs.push_back(
"-mllvm");
1398 CmdArgs.push_back(
"-asan-guard-against-version-mismatch=0");
1403 if (AsanDtorKind != llvm::AsanDtorKind::Invalid) {
1404 CmdArgs.push_back(Args.MakeArgString(
"-fsanitize-address-destructor=" +
1408 if (AsanUseAfterReturn != llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
1409 CmdArgs.push_back(Args.MakeArgString(
1410 "-fsanitize-address-use-after-return=" +
1414 if (!HwasanAbi.empty()) {
1415 CmdArgs.push_back(
"-default-function-attr");
1416 CmdArgs.push_back(Args.MakeArgString(
"hwasan-abi=" + HwasanAbi));
1419 if (Sanitizers.
has(SanitizerKind::HWAddress) && !HwasanUseAliases) {
1420 CmdArgs.push_back(
"-target-feature");
1421 CmdArgs.push_back(
"+tagged-globals");
1429 if (Sanitizers.
has(SanitizerKind::Memory) ||
1430 Sanitizers.
has(SanitizerKind::Address))
1431 CmdArgs.push_back(
"-fno-assume-sane-operator-new");
1438 if (Sanitizers.
has(SanitizerKind::FuzzerNoLink)) {
1439 CmdArgs.push_back(
"-fno-builtin-bcmp");
1440 CmdArgs.push_back(
"-fno-builtin-memcmp");
1441 CmdArgs.push_back(
"-fno-builtin-strncmp");
1442 CmdArgs.push_back(
"-fno-builtin-strcmp");
1443 CmdArgs.push_back(
"-fno-builtin-strncasecmp");
1444 CmdArgs.push_back(
"-fno-builtin-strcasecmp");
1445 CmdArgs.push_back(
"-fno-builtin-strstr");
1446 CmdArgs.push_back(
"-fno-builtin-strcasestr");
1447 CmdArgs.push_back(
"-fno-builtin-memmem");
1453 !Args.hasArg(options::OPT_fvisibility_EQ)) {
1454 TC.
getDriver().
Diag(clang::diag::err_drv_argument_only_allowed_with)
1460 if (Sanitizers.
has(SanitizerKind::MemtagStack) &&
1462 TC.
getDriver().
Diag(diag::err_stack_tagging_requires_hardware_feature);
1466 bool DiagnoseErrors) {
1468 (A->getOption().matches(options::OPT_fsanitize_EQ) ||
1469 A->getOption().matches(options::OPT_fno_sanitize_EQ) ||
1470 A->getOption().matches(options::OPT_fsanitize_recover_EQ) ||
1471 A->getOption().matches(options::OPT_fno_sanitize_recover_EQ) ||
1472 A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
1473 A->getOption().matches(options::OPT_fno_sanitize_trap_EQ) ||
1474 A->getOption().matches(options::OPT_fsanitize_merge_handlers_EQ) ||
1475 A->getOption().matches(options::OPT_fno_sanitize_merge_handlers_EQ)) &&
1476 "Invalid argument in parseArgValues!");
1478 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1479 const char *
Value = A->getValue(i);
1482 if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
1483 0 == strcmp(
"all",
Value))
1490 else if (DiagnoseErrors)
1491 D.Diag(clang::diag::err_drv_unsupported_option_argument)
1492 << A->getSpelling() <<
Value;
1498 const llvm::opt::Arg *A,
1499 bool DiagnoseErrors) {
1501 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1502 const char *
Value = A->getValue(i);
1504 llvm::StringSwitch<int>(
Value)
1507 .Case(
"add-unsigned-overflow-test",
1509 .Case(
"add-signed-overflow-test",
1515 D.Diag(clang::diag::err_drv_unsupported_option_argument)
1516 << A->getSpelling() <<
Value;
1523 bool DiagnoseErrors) {
1524 assert(A->getOption().matches(options::OPT_fsanitize_coverage) ||
1525 A->getOption().matches(options::OPT_fno_sanitize_coverage));
1527 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1528 const char *
Value = A->getValue(i);
1529 int F = llvm::StringSwitch<int>(
Value)
1550 if (F == 0 && DiagnoseErrors)
1551 D.Diag(clang::diag::err_drv_unsupported_option_argument)
1552 << A->getSpelling() <<
Value;
1559 bool DiagnoseErrors) {
1561 A->getOption().matches(options::OPT_fexperimental_sanitize_metadata_EQ) ||
1562 A->getOption().matches(
1563 options::OPT_fno_experimental_sanitize_metadata_EQ));
1565 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1566 const char *
Value = A->getValue(i);
1567 int F = llvm::StringSwitch<int>(
Value)
1573 if (F == 0 && DiagnoseErrors)
1574 D.Diag(clang::diag::err_drv_unsupported_option_argument)
1575 << A->getSpelling() <<
Value;
1583 for (llvm::opt::ArgList::const_reverse_iterator I = Args.rbegin(),
1586 const auto *Arg = *I;
1587 if (Arg->getOption().matches(options::OPT_fsanitize_EQ)) {
1590 if (AddKinds & Mask)
1592 }
else if (Arg->getOption().matches(options::OPT_fno_sanitize_EQ)) {
1595 Mask &= ~RemoveKinds;
1598 llvm_unreachable(
"arg list didn't provide expected value");
1602 assert(A->getOption().matches(options::OPT_fsanitize_EQ) &&
1603 "Invalid argument in describeSanitizerArg!");
1605 std::string Sanitizers;
1606 for (
int i = 0, n = A->getNumValues(); i != n; ++i) {
1610 if (!Sanitizers.empty())
1612 Sanitizers += A->getValue(i);
1616 assert(!Sanitizers.empty() &&
"arg didn't provide expected value");
1617 return "-fsanitize=" + Sanitizers;
static void addDefaultIgnorelists(const Driver &D, SanitizerMask Kinds, std::vector< std::string > &IgnorelistFiles, bool DiagnoseErrors)
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 SanitizerMask parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args, bool DiagnoseErrors)
static SanitizerMask parseSanitizeArgs(const Driver &D, const llvm::opt::ArgList &Args, bool DiagnoseErrors, SanitizerMask Default, SanitizerMask AlwaysIn, SanitizerMask AlwaysOut, int OptInID, int OptOutID)
static void addIncludeLinkerOption(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, StringRef SymbolName)
static bool isExecuteOnlyTarget(const llvm::Triple &Triple, const llvm::opt::ArgList &Args)
Return true if an execute-only target disallows data access to code sections.
static bool hasTargetFeatureMTE(const llvm::opt::ArgStringList &CmdArgs)
static const SanitizerMask SupportsCoverage
static const SanitizerMask CFIClasses
static int parseBinaryMetadataFeatures(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors)
Parse -f(no-)?sanitize-metadata= flag values, diagnosing any invalid components.
static const SanitizerMask TrappingSupported
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 const SanitizerMask NeedsUnwindTables
static const SanitizerMask MergeDefault
static void addSpecialCaseListOpt(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const char *SCLOptFlag, const std::vector< std::string > &SCLFiles)
static const SanitizerMask NotAllowedWithMinimalRuntime
static const SanitizerMask AlwaysRecoverable
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...
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
static const SanitizerMask NeedsUbsanCxxRt
static const SanitizerMask TrappingDefault
static const SanitizerMask CompatibleWithMinimalRuntime
static const SanitizerMask Unrecoverable
static const SanitizerMask RecoverableByDefault
static const SanitizerMask NeedsLTO
static SanitizerMask setGroupBits(SanitizerMask Kinds)
Sets group bits for every group that has at least one representative already enabled in Kinds.
static const SanitizerMask NeedsUbsanRt
static int parseCoverageFeatures(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors)
Parse -f(no-)?sanitize-coverage= flag values, diagnosing any invalid components.
static void validateSpecialCaseListFormat(const Driver &D, std::vector< std::string > &SCLFiles, unsigned MalformedSCLErrorDiagID, bool DiagnoseErrors)
static const SanitizerMask NotAllowedWithTrap
static void parseSpecialCaseListArg(const Driver &D, const llvm::opt::ArgList &Args, std::vector< std::string > &SCLFiles, llvm::opt::OptSpecifier SCLOptionID, llvm::opt::OptSpecifier NoSCLOptionID, unsigned MalformedSCLErrorDiagID, bool DiagnoseErrors)
Parse -f(no-)?sanitize-(coverage-)?(allow|ignore)list argument's values, diagnosing any invalid file ...
static int parseOverflowPatternExclusionValues(const Driver &D, const llvm::opt::Arg *A, bool DiagnoseErrors)
Parse -fsanitize-undefined-ignore-overflow-pattern= flag values, diagnosing any invalid values.
static const SanitizerMask NotAllowedWithExecuteOnly
@ CoverageInline8bitCounters
Defines the clang::SanitizerKind enum.
@ None
Don't exclude any overflow patterns from sanitizers.
@ AddUnsignedOverflowTest
if (a + b < a)
@ All
Exclude all overflow patterns (below)
@ AddSignedOverflowTest
if (a + b < a)
@ PostDecrInWhile
while (count–)
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
DiagnosticBuilder Diag(unsigned DiagID) const
bool needsFuzzerInterceptors() const
bool needsStatsRt() const
bool needsCfiDiagRt() const
bool needsUbsanRt() const
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, bool DiagnoseErrors=true)
Parses the sanitizer arguments from an argument list.
bool needsHwasanRt() const
bool requiresMinimalRuntime() const
bool needsUnwindTables() const
bool needsDfsanRt() const
bool needsScudoRt() const
bool needsUbsanCXXRt() const
void addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, types::ID InputType) const
bool isCXX(ID Id)
isCXX - Is this a "C++" input (C++ and Obj-C++ sources and headers).
The JSON file list parser is used to communicate input to InstallAPI.
StringRef AsanDtorKindToString(llvm::AsanDtorKind kind)
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables.
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind)
llvm::AsanDetectStackUseAfterReturnMode AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr)
StringRef AsanDetectStackUseAfterReturnModeToString(llvm::AsanDetectStackUseAfterReturnMode mode)
bool empty() const
Returns true if no sanitizers are enabled.
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
SanitizerMask Mask
Bitmask of enabled sanitizers.
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.