From 40ad3d2aa4b037587c3aba1aee87626830838564 Mon Sep 17 00:00:00 2001 From: Pierre Gousseau Date: Tue, 26 Feb 2019 13:50:29 +0000 Subject: [PATCH] revert r354873 as this breaks lldb builds. llvm-svn: 354875 --- clang/include/clang/Basic/Attr.td | 2 +- clang/include/clang/Basic/Sanitizers.def | 2 +- clang/include/clang/Basic/Sanitizers.h | 165 +++--------------- clang/include/clang/Driver/ToolChain.h | 4 +- clang/lib/Basic/SanitizerSpecialCaseList.cpp | 2 +- clang/lib/Basic/Sanitizers.cpp | 15 +- clang/lib/CodeGen/CGExpr.cpp | 11 +- clang/lib/Driver/SanitizerArgs.cpp | 248 +++++++++++---------------- clang/lib/Driver/ToolChain.cpp | 16 +- clang/lib/Frontend/CompilerInvocation.cpp | 2 +- clang/lib/Sema/SemaDeclAttr.cpp | 3 +- 11 files changed, 145 insertions(+), 325 deletions(-) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index bf226c8..faad45d 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2366,7 +2366,7 @@ def NoSanitize : InheritableAttr { let Documentation = [NoSanitizeDocs]; let AdditionalMembers = [{ SanitizerMask getMask() const { - SanitizerMask Mask; + SanitizerMask Mask = 0; for (auto SanitizerName : sanitizers()) { SanitizerMask ParsedMask = parseSanitizerValue(SanitizerName, /*AllowGroups=*/true); diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def index 98e9aaa..34bd6fc 100644 --- a/clang/include/clang/Basic/Sanitizers.def +++ b/clang/include/clang/Basic/Sanitizers.def @@ -177,7 +177,7 @@ SANITIZER("scudo", Scudo) // Magic group, containing all sanitizers. For example, "-fno-sanitize=all" // can be used to disable all the sanitizers. -SANITIZER_GROUP("all", All, ~SanitizerMask()) +SANITIZER_GROUP("all", All, ~0ULL) #undef SANITIZER #undef SANITIZER_GROUP diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h index afbdf63..f2cfadb 100644 --- a/clang/include/clang/Basic/Sanitizers.h +++ b/clang/include/clang/Basic/Sanitizers.h @@ -21,167 +21,44 @@ #include namespace clang { -class SanitizerMask; -} - -namespace llvm { -class hashcode; -hash_code hash_value(const clang::SanitizerMask &Arg); -} // namespace llvm - -namespace clang { - -class SanitizerMask { - /// Number of array elements. - static constexpr unsigned kNumElem = 2; - /// Mask value initialized to 0. - uint64_t maskLoToHigh[kNumElem]{}; - /// Number of bits in a mask. - static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8; - /// Number of bits in a mask element. - static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8; - -public: - static constexpr bool checkBitPos(const unsigned Pos) { - return Pos < kNumBits; - } - - /// Create a mask with a bit enabled at position Pos. - static SanitizerMask bitPosToMask(const unsigned Pos) { - assert(Pos < kNumBits && "Bit position too big."); - SanitizerMask mask; - mask.maskLoToHigh[Pos / kNumBitElem] = 1ULL << Pos % kNumBitElem; - return mask; - } - - unsigned countPopulation() const { - unsigned total = 0; - for (const auto &Val : maskLoToHigh) - total += llvm::countPopulation(Val); - return total; - } - - void flipAllBits() { - for (auto &Val : maskLoToHigh) - Val = ~Val; - } - - bool isPowerOf2() const { - return countPopulation() == 1; - } - - llvm::hash_code hash_value() const; - - explicit operator bool() const { - for (const auto &Val : maskLoToHigh) - if (Val) - return true; - return false; - }; - - bool operator==(const SanitizerMask &V) const { - for (unsigned k = 0; k < kNumElem; k++) { - if (maskLoToHigh[k] != V.maskLoToHigh[k]) - return false; - } - return true; - } - - SanitizerMask &operator&=(const SanitizerMask &RHS) { - for (unsigned k = 0; k < kNumElem; k++) - maskLoToHigh[k] &= RHS.maskLoToHigh[k]; - return *this; - } - SanitizerMask &operator|=(const SanitizerMask &RHS) { - for (unsigned k = 0; k < kNumElem; k++) - maskLoToHigh[k] |= RHS.maskLoToHigh[k]; - return *this; - } +using SanitizerMask = uint64_t; - bool operator!() const { - for (const auto &Val : maskLoToHigh) - if (Val) - return false; - return true; - } +namespace SanitizerKind { - bool operator!=(const SanitizerMask &RHS) const { return !((*this) == RHS); } +// Assign ordinals to possible values of -fsanitize= flag, which we will use as +// bit positions. +enum SanitizerOrdinal : uint64_t { +#define SANITIZER(NAME, ID) SO_##ID, +#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group, +#include "clang/Basic/Sanitizers.def" + SO_Count }; -inline SanitizerMask operator~(SanitizerMask v) { - v.flipAllBits(); - return v; -} - -inline SanitizerMask operator&(SanitizerMask a, const SanitizerMask &b) { - a &= b; - return a; -} - -inline SanitizerMask operator|(SanitizerMask a, const SanitizerMask &b) { - a |= b; - return a; -} - // Define the set of sanitizer kinds, as well as the set of sanitizers each // sanitizer group expands into. -// Uses static data member of a class template as recommended in second -// workaround from n4424 to avoid odr issues. -// FIXME: Can be marked as constexpr once c++14 can be used in llvm. -// FIXME: n4424 workaround can be replaced by c++17 inline variable. -template struct SanitizerMasks { - - // Assign ordinals to possible values of -fsanitize= flag, which we will use - // as bit positions. - enum SanitizerOrdinal : uint64_t { -#define SANITIZER(NAME, ID) SO_##ID, -#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group, -#include "clang/Basic/Sanitizers.def" - SO_Count - }; - -#define SANITIZER(NAME, ID) \ - static const SanitizerMask ID; \ - static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big."); -#define SANITIZER_GROUP(NAME, ID, ALIAS) \ - static const SanitizerMask ID; \ - static const SanitizerMask ID##Group; \ - static_assert(SanitizerMask::checkBitPos(SO_##ID##Group), \ - "Bit position too big."); +#define SANITIZER(NAME, ID) \ + const SanitizerMask ID = 1ULL << SO_##ID; +#define SANITIZER_GROUP(NAME, ID, ALIAS) \ + const SanitizerMask ID = ALIAS; \ + const SanitizerMask ID##Group = 1ULL << SO_##ID##Group; #include "clang/Basic/Sanitizers.def" -}; // SanitizerMasks - -#define SANITIZER(NAME, ID) \ - template \ - const SanitizerMask SanitizerMasks::ID = \ - SanitizerMask::bitPosToMask(SO_##ID); -#define SANITIZER_GROUP(NAME, ID, ALIAS) \ - template \ - const SanitizerMask SanitizerMasks::ID = SanitizerMask(ALIAS); \ - template \ - const SanitizerMask SanitizerMasks::ID##Group = \ - SanitizerMask::bitPosToMask(SO_##ID##Group); -#include "clang/Basic/Sanitizers.def" - -// Explicit instantiation here to ensure correct initialization order. -template struct SanitizerMasks<>; -using SanitizerKind = SanitizerMasks<>; +} // namespace SanitizerKind struct SanitizerSet { /// Check if a certain (single) sanitizer is enabled. bool has(SanitizerMask K) const { - assert(K.isPowerOf2() && "Has to be a single sanitizer."); - return static_cast(Mask & K); + assert(llvm::isPowerOf2_64(K)); + return Mask & K; } /// Check if one or more sanitizers are enabled. - bool hasOneOf(SanitizerMask K) const { return static_cast(Mask & K); } + bool hasOneOf(SanitizerMask K) const { return Mask & K; } /// Enable or disable a certain (single) sanitizer. void set(SanitizerMask K, bool Value) { - assert(K.isPowerOf2() && "Has to be a single sanitizer."); + assert(llvm::isPowerOf2_64(K)); Mask = Value ? (Mask | K) : (Mask & ~K); } @@ -189,10 +66,10 @@ struct SanitizerSet { void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; } /// Returns true if no sanitizers are enabled. - bool empty() const { return !Mask; } + bool empty() const { return Mask == 0; } /// Bitmask of enabled sanitizers. - SanitizerMask Mask; + SanitizerMask Mask = 0; }; /// Parse a single value from a -fsanitize= or -fno-sanitize= value list. diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 014b238..e82675d 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -565,9 +565,7 @@ public: virtual SanitizerMask getSupportedSanitizers() const; /// Return sanitizers which are enabled by default. - virtual SanitizerMask getDefaultSanitizers() const { - return SanitizerMask(); - } + virtual SanitizerMask getDefaultSanitizers() const { return 0; } }; /// Set a ToolChain's effective triple. Reset it when the registration object diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp index 5fb0f96..e042db9 100644 --- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -36,7 +36,7 @@ SanitizerSpecialCaseList::createOrDie(const std::vector &Paths) { void SanitizerSpecialCaseList::createSanitizerSections() { for (auto &S : Sections) { - SanitizerMask Mask; + SanitizerMask Mask = 0; #define SANITIZER(NAME, ID) \ if (S.SectionMatcher->match(NAME)) \ diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp index 6203c1a..dd0fddb 100644 --- a/clang/lib/Basic/Sanitizers.cpp +++ b/clang/lib/Basic/Sanitizers.cpp @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "clang/Basic/Sanitizers.h" -#include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringSwitch.h" using namespace clang; @@ -20,9 +19,9 @@ SanitizerMask clang::parseSanitizerValue(StringRef Value, bool AllowGroups) { SanitizerMask ParsedKind = llvm::StringSwitch(Value) #define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID) #define SANITIZER_GROUP(NAME, ID, ALIAS) \ - .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : SanitizerMask()) + .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : 0) #include "clang/Basic/Sanitizers.def" - .Default(SanitizerMask()); + .Default(0); return ParsedKind; } @@ -34,13 +33,3 @@ SanitizerMask clang::expandSanitizerGroups(SanitizerMask Kinds) { #include "clang/Basic/Sanitizers.def" return Kinds; } - -llvm::hash_code SanitizerMask::hash_value() const { - return llvm::hash_combine_range(&maskLoToHigh[0], &maskLoToHigh[kNumElem]); -} - -namespace llvm { -hash_code hash_value(const clang::SanitizerMask &Arg) { - return Arg.hash_value(); -} -} // namespace llvm diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 09ba2a0..5ee0378 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2855,13 +2855,16 @@ enum class CheckRecoverableKind { } static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) { - assert(Kind.countPopulation() == 1); - if (Kind == SanitizerKind::Vptr) + assert(llvm::countPopulation(Kind) == 1); + switch (Kind) { + case SanitizerKind::Vptr: return CheckRecoverableKind::AlwaysRecoverable; - else if (Kind == SanitizerKind::Return || Kind == SanitizerKind::Unreachable) + case SanitizerKind::Return: + case SanitizerKind::Unreachable: return CheckRecoverableKind::Unrecoverable; - else + default: return CheckRecoverableKind::Recoverable; + } } namespace { diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index e84933b..0112416 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -21,52 +21,33 @@ #include using namespace clang; +using namespace clang::SanitizerKind; using namespace clang::driver; using namespace llvm::opt; -static const SanitizerMask NeedsUbsanRt = - SanitizerKind::Undefined | SanitizerKind::Integer | - SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | - SanitizerKind::CFI; -static const SanitizerMask NeedsUbsanCxxRt = - SanitizerKind::Vptr | SanitizerKind::CFI; -static const SanitizerMask NotAllowedWithTrap = SanitizerKind::Vptr; -static const SanitizerMask NotAllowedWithMinimalRuntime = SanitizerKind::Vptr; -static const SanitizerMask RequiresPIE = - SanitizerKind::DataFlow | SanitizerKind::HWAddress | SanitizerKind::Scudo; -static const SanitizerMask NeedsUnwindTables = - SanitizerKind::Address | SanitizerKind::HWAddress | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::DataFlow; -static const SanitizerMask SupportsCoverage = - SanitizerKind::Address | SanitizerKind::HWAddress | - SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress | - SanitizerKind::Memory | SanitizerKind::KernelMemory | SanitizerKind::Leak | - SanitizerKind::Undefined | SanitizerKind::Integer | - SanitizerKind::ImplicitConversion | SanitizerKind::Nullability | - SanitizerKind::DataFlow | SanitizerKind::Fuzzer | - SanitizerKind::FuzzerNoLink; -static const SanitizerMask RecoverableByDefault = - SanitizerKind::Undefined | SanitizerKind::Integer | - SanitizerKind::ImplicitConversion | SanitizerKind::Nullability; -static const SanitizerMask Unrecoverable = - SanitizerKind::Unreachable | SanitizerKind::Return; -static const SanitizerMask AlwaysRecoverable = - SanitizerKind::KernelAddress | SanitizerKind::KernelHWAddress; -static const SanitizerMask LegacyFsanitizeRecoverMask = - SanitizerKind::Undefined | SanitizerKind::Integer; -static const SanitizerMask NeedsLTO = SanitizerKind::CFI; -static const SanitizerMask TrappingSupported = - (SanitizerKind::Undefined & ~SanitizerKind::Vptr) | - SanitizerKind::UnsignedIntegerOverflow | SanitizerKind::ImplicitConversion | - SanitizerKind::Nullability | SanitizerKind::LocalBounds | - SanitizerKind::CFI; -static const SanitizerMask TrappingDefault = SanitizerKind::CFI; -static const SanitizerMask CFIClasses = - SanitizerKind::CFIVCall | SanitizerKind::CFINVCall | - SanitizerKind::CFIMFCall | SanitizerKind::CFIDerivedCast | - SanitizerKind::CFIUnrelatedCast; -static const SanitizerMask CompatibleWithMinimalRuntime = - TrappingSupported | SanitizerKind::Scudo | SanitizerKind::ShadowCallStack; +enum : SanitizerMask { + NeedsUbsanRt = Undefined | Integer | ImplicitConversion | Nullability | CFI, + NeedsUbsanCxxRt = Vptr | CFI, + NotAllowedWithTrap = Vptr, + NotAllowedWithMinimalRuntime = Vptr, + RequiresPIE = DataFlow | HWAddress | Scudo, + NeedsUnwindTables = Address | HWAddress | Thread | Memory | DataFlow, + SupportsCoverage = Address | HWAddress | KernelAddress | KernelHWAddress | + Memory | KernelMemory | Leak | Undefined | Integer | + ImplicitConversion | Nullability | DataFlow | Fuzzer | + FuzzerNoLink, + RecoverableByDefault = Undefined | Integer | ImplicitConversion | Nullability, + Unrecoverable = Unreachable | Return, + AlwaysRecoverable = KernelAddress | KernelHWAddress, + LegacyFsanitizeRecoverMask = Undefined | Integer, + NeedsLTO = CFI, + TrappingSupported = (Undefined & ~Vptr) | UnsignedIntegerOverflow | + ImplicitConversion | Nullability | LocalBounds | CFI, + TrappingDefault = CFI, + CFIClasses = + CFIVCall | CFINVCall | CFIMFCall | CFIDerivedCast | CFIUnrelatedCast, + CompatibleWithMinimalRuntime = TrappingSupported | Scudo | ShadowCallStack, +}; enum CoverageFeature { CoverageFunc = 1 << 0, @@ -119,15 +100,13 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, struct Blacklist { const char *File; SanitizerMask Mask; - } Blacklists[] = {{"asan_blacklist.txt", SanitizerKind::Address}, - {"hwasan_blacklist.txt", SanitizerKind::HWAddress}, - {"msan_blacklist.txt", SanitizerKind::Memory}, - {"tsan_blacklist.txt", SanitizerKind::Thread}, - {"dfsan_abilist.txt", SanitizerKind::DataFlow}, - {"cfi_blacklist.txt", SanitizerKind::CFI}, - {"ubsan_blacklist.txt", SanitizerKind::Undefined | - SanitizerKind::Integer | - SanitizerKind::Nullability}}; + } Blacklists[] = {{"asan_blacklist.txt", Address}, + {"hwasan_blacklist.txt", HWAddress}, + {"msan_blacklist.txt", Memory}, + {"tsan_blacklist.txt", Thread}, + {"dfsan_abilist.txt", DataFlow}, + {"cfi_blacklist.txt", CFI}, + {"ubsan_blacklist.txt", Undefined | Integer | Nullability}}; for (auto BL : Blacklists) { if (!(Kinds & BL.Mask)) @@ -137,7 +116,7 @@ static void addDefaultBlacklists(const Driver &D, SanitizerMask Kinds, llvm::sys::path::append(Path, "share", BL.File); if (llvm::sys::fs::exists(Path)) BlacklistFiles.push_back(Path.str()); - else if (BL.Mask == SanitizerKind::CFI) + else if (BL.Mask == CFI) // If cfi_blacklist.txt cannot be found in the resource dir, driver // should fail. D.Diag(clang::diag::err_drv_no_such_file) << Path; @@ -157,10 +136,10 @@ static SanitizerMask setGroupBits(SanitizerMask Kinds) { static SanitizerMask parseSanitizeTrapArgs(const Driver &D, const llvm::opt::ArgList &Args) { - SanitizerMask TrapRemove; // During the loop below, the accumulated set of + SanitizerMask TrapRemove = 0; // During the loop below, the accumulated set of // sanitizers disabled by the current sanitizer // argument or any argument after it. - SanitizerMask TrappingKinds; + SanitizerMask TrappingKinds = 0; SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported); for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend(); @@ -184,12 +163,11 @@ static SanitizerMask parseSanitizeTrapArgs(const Driver &D, options::OPT_fsanitize_undefined_trap_on_error)) { Arg->claim(); TrappingKinds |= - expandSanitizerGroups(SanitizerKind::UndefinedGroup & ~TrapRemove) & - ~TrapRemove; + expandSanitizerGroups(UndefinedGroup & ~TrapRemove) & ~TrapRemove; } else if (Arg->getOption().matches( options::OPT_fno_sanitize_undefined_trap_on_error)) { Arg->claim(); - TrapRemove |= expandSanitizerGroups(SanitizerKind::UndefinedGroup); + TrapRemove |= expandSanitizerGroups(UndefinedGroup); } } @@ -211,13 +189,13 @@ bool SanitizerArgs::needsUbsanRt() const { } bool SanitizerArgs::needsCfiRt() const { - return !(Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) && - CfiCrossDso && !ImplicitCfiRuntime; + return !(Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && + !ImplicitCfiRuntime; } bool SanitizerArgs::needsCfiDiagRt() const { - return (Sanitizers.Mask & SanitizerKind::CFI & ~TrapSanitizers.Mask) && - CfiCrossDso && !ImplicitCfiRuntime; + return (Sanitizers.Mask & CFI & ~TrapSanitizers.Mask) && CfiCrossDso && + !ImplicitCfiRuntime; } bool SanitizerArgs::requiresPIE() const { @@ -225,26 +203,24 @@ bool SanitizerArgs::requiresPIE() const { } bool SanitizerArgs::needsUnwindTables() const { - return static_cast(Sanitizers.Mask & NeedsUnwindTables); + return Sanitizers.Mask & NeedsUnwindTables; } -bool SanitizerArgs::needsLTO() const { - return static_cast(Sanitizers.Mask & NeedsLTO); -} +bool SanitizerArgs::needsLTO() const { return Sanitizers.Mask & NeedsLTO; } SanitizerArgs::SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args) { - SanitizerMask AllRemove; // During the loop below, the accumulated set of + SanitizerMask AllRemove = 0; // During the loop below, the accumulated set of // sanitizers disabled by the current sanitizer // argument or any argument after it. - SanitizerMask AllAddedKinds; // Mask of all sanitizers ever enabled by + SanitizerMask AllAddedKinds = 0; // Mask of all sanitizers ever enabled by // -fsanitize= flags (directly or via group // expansion), some of which may be disabled // later. Used to carefully prune // unused-argument diagnostics. - SanitizerMask DiagnosedKinds; // All Kinds we have diagnosed up to now. + SanitizerMask DiagnosedKinds = 0; // All Kinds we have diagnosed up to now. // Used to deduplicate diagnostics. - SanitizerMask Kinds; + SanitizerMask Kinds = 0; const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers()); CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso, @@ -319,12 +295,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // identifiers. // Fixing both of those may require changes to the cross-DSO CFI // interface. - if (CfiCrossDso && (Add & SanitizerKind::CFIMFCall & ~DiagnosedKinds)) { + if (CfiCrossDso && (Add & CFIMFCall & ~DiagnosedKinds)) { D.Diag(diag::err_drv_argument_not_allowed_with) << "-fsanitize=cfi-mfcall" << "-fsanitize-cfi-cross-dso"; - Add &= ~SanitizerKind::CFIMFCall; - DiagnosedKinds |= SanitizerKind::CFIMFCall; + Add &= ~CFIMFCall; + DiagnosedKinds |= CFIMFCall; } if (SanitizerMask KindsToDiagnose = Add & ~Supported & ~DiagnosedKinds) { @@ -338,7 +314,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // Test for -fno-rtti + explicit -fsanitizer=vptr before expanding groups // so we don't error out if -fno-rtti and -fsanitize=undefined were // passed. - if ((Add & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { + if ((Add & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { if (const llvm::opt::Arg *NoRTTIArg = TC.getRTTIArg()) { assert(NoRTTIArg->getOption().matches(options::OPT_fno_rtti) && "RTTI disabled without -fno-rtti option?"); @@ -353,7 +329,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } // Take out the Vptr sanitizer from the enabled sanitizers - AllRemove |= SanitizerKind::Vptr; + AllRemove |= Vptr; } Add = expandSanitizerGroups(Add); @@ -366,14 +342,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Add &= ~NotAllowedWithMinimalRuntime; } if (CfiCrossDso) - Add &= ~SanitizerKind::CFIMFCall; + Add &= ~CFIMFCall; Add &= Supported; - if (Add & SanitizerKind::Fuzzer) - Add |= SanitizerKind::FuzzerNoLink; + if (Add & Fuzzer) + Add |= FuzzerNoLink; // Enable coverage if the fuzzing flag is set. - if (Add & SanitizerKind::FuzzerNoLink) { + if (Add & FuzzerNoLink) { CoverageFeatures |= CoverageInline8bitCounters | CoverageIndirCall | CoverageTraceCmp | CoveragePCTable; // Due to TLS differences, stack depth tracking is only enabled on Linux @@ -390,42 +366,23 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } std::pair IncompatibleGroups[] = { - std::make_pair(SanitizerKind::Address, - SanitizerKind::Thread | SanitizerKind::Memory), - std::make_pair(SanitizerKind::Thread, SanitizerKind::Memory), - std::make_pair(SanitizerKind::Leak, - SanitizerKind::Thread | SanitizerKind::Memory), - std::make_pair(SanitizerKind::KernelAddress, - SanitizerKind::Address | SanitizerKind::Leak | - SanitizerKind::Thread | SanitizerKind::Memory), - std::make_pair(SanitizerKind::HWAddress, - SanitizerKind::Address | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::KernelAddress), - std::make_pair(SanitizerKind::Efficiency, - SanitizerKind::Address | SanitizerKind::HWAddress | - SanitizerKind::Leak | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::KernelAddress), - std::make_pair(SanitizerKind::Scudo, - SanitizerKind::Address | SanitizerKind::HWAddress | - SanitizerKind::Leak | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::KernelAddress | - SanitizerKind::Efficiency), - std::make_pair(SanitizerKind::SafeStack, - SanitizerKind::Address | SanitizerKind::HWAddress | - SanitizerKind::Leak | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::KernelAddress | - SanitizerKind::Efficiency), - std::make_pair(SanitizerKind::KernelHWAddress, - SanitizerKind::Address | SanitizerKind::HWAddress | - SanitizerKind::Leak | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::KernelAddress | - SanitizerKind::Efficiency | SanitizerKind::SafeStack), - std::make_pair(SanitizerKind::KernelMemory, - SanitizerKind::Address | SanitizerKind::HWAddress | - SanitizerKind::Leak | SanitizerKind::Thread | - SanitizerKind::Memory | SanitizerKind::KernelAddress | - SanitizerKind::Efficiency | SanitizerKind::Scudo | - SanitizerKind::SafeStack)}; + std::make_pair(Address, Thread | Memory), + std::make_pair(Thread, Memory), + std::make_pair(Leak, Thread | Memory), + std::make_pair(KernelAddress, Address | Leak | Thread | Memory), + std::make_pair(HWAddress, Address | Thread | Memory | KernelAddress), + std::make_pair(Efficiency, Address | HWAddress | Leak | Thread | Memory | + KernelAddress), + std::make_pair(Scudo, Address | HWAddress | Leak | Thread | Memory | + KernelAddress | Efficiency), + std::make_pair(SafeStack, Address | HWAddress | Leak | Thread | Memory | + KernelAddress | Efficiency), + std::make_pair(KernelHWAddress, Address | HWAddress | Leak | Thread | + Memory | KernelAddress | Efficiency | + SafeStack), + std::make_pair(KernelMemory, Address | HWAddress | Leak | Thread | + Memory | KernelAddress | Efficiency | + Scudo | SafeStack)}; // Enable toolchain specific default sanitizers if not explicitly disabled. SanitizerMask Default = TC.getDefaultSanitizers() & ~AllRemove; @@ -441,8 +398,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // We disable the vptr sanitizer if it was enabled by group expansion but RTTI // is disabled. - if ((Kinds & SanitizerKind::Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { - Kinds &= ~SanitizerKind::Vptr; + if ((Kinds & Vptr) && (RTTIMode == ToolChain::RM_Disabled)) { + Kinds &= ~Vptr; } // Check that LTO is enabled if we need it. @@ -451,12 +408,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << lastArgumentForMask(D, Args, Kinds & NeedsLTO) << "-flto"; } - if ((Kinds & SanitizerKind::ShadowCallStack) && + if ((Kinds & ShadowCallStack) && TC.getTriple().getArch() == llvm::Triple::aarch64 && !llvm::AArch64::isX18ReservedByDefault(TC.getTriple()) && !Args.hasArg(options::OPT_ffixed_x18)) { D.Diag(diag::err_drv_argument_only_allowed_with) - << lastArgumentForMask(D, Args, Kinds & SanitizerKind::ShadowCallStack) + << lastArgumentForMask(D, Args, Kinds & ShadowCallStack) << "-ffixed-x18"; } @@ -464,12 +421,12 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // c++abi-specific parts of UBSan runtime, and they are not provided by the // toolchain. We don't have a good way to check the latter, so we just // check if the toolchan supports vptr. - if (~Supported & SanitizerKind::Vptr) { + if (~Supported & Vptr) { SanitizerMask KindsToDiagnose = Kinds & ~TrappingKinds & NeedsUbsanCxxRt; // The runtime library supports the Microsoft C++ ABI, but only well enough // for CFI. FIXME: Remove this once we support vptr on Windows. if (TC.getTriple().isOSWindows()) - KindsToDiagnose &= ~SanitizerKind::CFI; + KindsToDiagnose &= ~CFI; if (KindsToDiagnose) { SanitizerSet S; S.Mask = KindsToDiagnose; @@ -498,8 +455,8 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // Parse -f(no-)?sanitize-recover flags. SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable; - SanitizerMask DiagnosedUnrecoverableKinds; - SanitizerMask DiagnosedAlwaysRecoverableKinds; + SanitizerMask DiagnosedUnrecoverableKinds = 0; + SanitizerMask DiagnosedAlwaysRecoverableKinds = 0; for (const auto *Arg : Args) { const char *DeprecatedReplacement = nullptr; if (Arg->getOption().matches(options::OPT_fsanitize_recover)) { @@ -582,7 +539,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } // Parse -f[no-]sanitize-memory-track-origins[=level] options. - if (AllAddedKinds & SanitizerKind::Memory) { + if (AllAddedKinds & Memory) { if (Arg *A = Args.getLastArg(options::OPT_fsanitize_memory_track_origins_EQ, options::OPT_fsanitize_memory_track_origins, @@ -610,19 +567,19 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, MsanUseAfterDtor = false; } - if (AllAddedKinds & SanitizerKind::Thread) { - TsanMemoryAccess = Args.hasFlag( - options::OPT_fsanitize_thread_memory_access, - options::OPT_fno_sanitize_thread_memory_access, TsanMemoryAccess); - TsanFuncEntryExit = Args.hasFlag( - options::OPT_fsanitize_thread_func_entry_exit, - options::OPT_fno_sanitize_thread_func_entry_exit, TsanFuncEntryExit); - TsanAtomics = - Args.hasFlag(options::OPT_fsanitize_thread_atomics, - options::OPT_fno_sanitize_thread_atomics, TsanAtomics); + if (AllAddedKinds & Thread) { + TsanMemoryAccess = Args.hasFlag(options::OPT_fsanitize_thread_memory_access, + options::OPT_fno_sanitize_thread_memory_access, + TsanMemoryAccess); + TsanFuncEntryExit = Args.hasFlag(options::OPT_fsanitize_thread_func_entry_exit, + options::OPT_fno_sanitize_thread_func_entry_exit, + TsanFuncEntryExit); + TsanAtomics = Args.hasFlag(options::OPT_fsanitize_thread_atomics, + options::OPT_fno_sanitize_thread_atomics, + TsanAtomics); } - if (AllAddedKinds & SanitizerKind::CFI) { + if (AllAddedKinds & CFI) { // Without PIE, external function address may resolve to a PLT record, which // can not be verified by the target module. NeedPIE |= CfiCrossDso; @@ -646,7 +603,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, << "-fsanitize-minimal-runtime" << lastArgumentForMask(D, Args, IncompatibleMask); - SanitizerMask NonTrappingCfi = Kinds & SanitizerKind::CFI & ~TrappingKinds; + SanitizerMask NonTrappingCfi = Kinds & CFI & ~TrappingKinds; if (NonTrappingCfi) D.Diag(clang::diag::err_drv_argument_only_allowed_with) << "fsanitize-minimal-runtime" @@ -734,7 +691,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, ImplicitCfiRuntime = TC.getTriple().isAndroid(); - if (AllAddedKinds & SanitizerKind::Address) { + if (AllAddedKinds & Address) { NeedPIE |= TC.getTriple().isOSFuchsia(); if (Arg *A = Args.getLastArg(options::OPT_fsanitize_address_field_padding)) { @@ -756,7 +713,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, case options::OPT__SLASH_LDd: D.Diag(clang::diag::err_drv_argument_not_allowed_with) << WindowsDebugRTArg->getAsString(Args) - << lastArgumentForMask(D, Args, SanitizerKind::Address); + << lastArgumentForMask(D, Args, Address); D.Diag(clang::diag::note_drv_address_sanitizer_debug_runtime); } } @@ -785,7 +742,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, AsanUseAfterScope = false; } - if (AllAddedKinds & SanitizerKind::HWAddress) { + if (AllAddedKinds & HWAddress) { if (Arg *HwasanAbiArg = Args.getLastArg(options::OPT_fsanitize_hwaddress_abi_EQ)) { HwasanAbi = HwasanAbiArg->getValue(); @@ -797,7 +754,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, } } - if (AllAddedKinds & SanitizerKind::SafeStack) { + if (AllAddedKinds & SafeStack) { // SafeStack runtime is built into the system on Fuchsia. SafeStackRuntime = !TC.getTriple().isOSFuchsia(); } @@ -817,7 +774,7 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, static std::string toString(const clang::SanitizerSet &Sanitizers) { std::string Res; #define SANITIZER(NAME, ID) \ - if (Sanitizers.has(SanitizerKind::ID)) { \ + if (Sanitizers.has(ID)) { \ if (!Res.empty()) \ Res += ","; \ Res += NAME; \ @@ -979,8 +936,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, // https://github.com/google/sanitizers/issues/373 // We can't make this conditional on -fsanitize=leak, as that flag shouldn't // affect compilation. - if (Sanitizers.has(SanitizerKind::Memory) || - Sanitizers.has(SanitizerKind::Address)) + if (Sanitizers.has(Memory) || Sanitizers.has(Address)) CmdArgs.push_back("-fno-assume-sane-operator-new"); // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is @@ -1003,18 +959,18 @@ SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A, A->getOption().matches(options::OPT_fsanitize_trap_EQ) || A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) && "Invalid argument in parseArgValues!"); - SanitizerMask Kinds; + SanitizerMask Kinds = 0; for (int i = 0, n = A->getNumValues(); i != n; ++i) { const char *Value = A->getValue(i); SanitizerMask Kind; // Special case: don't accept -fsanitize=all. if (A->getOption().matches(options::OPT_fsanitize_EQ) && 0 == strcmp("all", Value)) - Kind = SanitizerMask(); + Kind = 0; // Similarly, don't accept -fsanitize=efficiency-all. else if (A->getOption().matches(options::OPT_fsanitize_EQ) && 0 == strcmp("efficiency-all", Value)) - Kind = SanitizerMask(); + Kind = 0; else Kind = parseSanitizerValue(Value, /*AllowGroups=*/true); diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 289d47d..fcf373e 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -818,23 +818,21 @@ SanitizerMask ToolChain::getSupportedSanitizers() const { // Return sanitizers which don't require runtime support and are not // platform dependent. - SanitizerMask Res = (SanitizerKind::Undefined & ~SanitizerKind::Vptr & - ~SanitizerKind::Function) | - (SanitizerKind::CFI & ~SanitizerKind::CFIICall) | - SanitizerKind::CFICastStrict | - SanitizerKind::UnsignedIntegerOverflow | - SanitizerKind::ImplicitConversion | - SanitizerKind::Nullability | SanitizerKind::LocalBounds; + using namespace SanitizerKind; + + SanitizerMask Res = (Undefined & ~Vptr & ~Function) | (CFI & ~CFIICall) | + CFICastStrict | UnsignedIntegerOverflow | + ImplicitConversion | Nullability | LocalBounds; if (getTriple().getArch() == llvm::Triple::x86 || getTriple().getArch() == llvm::Triple::x86_64 || getTriple().getArch() == llvm::Triple::arm || getTriple().getArch() == llvm::Triple::aarch64 || getTriple().getArch() == llvm::Triple::wasm32 || getTriple().getArch() == llvm::Triple::wasm64) - Res |= SanitizerKind::CFIICall; + Res |= CFIICall; if (getTriple().getArch() == llvm::Triple::x86_64 || getTriple().getArch() == llvm::Triple::aarch64) - Res |= SanitizerKind::ShadowCallStack; + Res |= ShadowCallStack; return Res; } diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 4d061c6..b1a8862 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -551,7 +551,7 @@ static void parseSanitizerKinds(StringRef FlagName, DiagnosticsEngine &Diags, SanitizerSet &S) { for (const auto &Sanitizer : Sanitizers) { SanitizerMask K = parseSanitizerValue(Sanitizer, /*AllowGroups=*/false); - if (K == SanitizerMask()) + if (K == 0) Diags.Report(diag::err_drv_invalid_value) << FlagName << Sanitizer; else S.set(K, true); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index d312936..bf11ae9 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6211,8 +6211,7 @@ static void handleNoSanitizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { if (!S.checkStringLiteralArgumentAttr(AL, I, SanitizerName, &LiteralLoc)) return; - if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) == - SanitizerMask()) + if (parseSanitizerValue(SanitizerName, /*AllowGroups=*/true) == 0) S.Diag(LiteralLoc, diag::warn_unknown_sanitizer_ignored) << SanitizerName; else if (isGlobalVar(D) && SanitizerName != "address") S.Diag(D->getLocation(), diag::err_attribute_wrong_decl_type) -- 2.7.4