pgousseau updated this revision to Diff 186201.
pgousseau added a comment.

Move num bits constant inside class.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57914/new/

https://reviews.llvm.org/D57914

Files:
  include/clang/Basic/Attr.td
  include/clang/Basic/Sanitizers.h
  include/clang/Driver/ToolChain.h
  lib/Basic/SanitizerSpecialCaseList.cpp
  lib/Basic/Sanitizers.cpp
  lib/CodeGen/CGExpr.cpp
  lib/Driver/SanitizerArgs.cpp

Index: lib/Driver/SanitizerArgs.cpp
===================================================================
--- lib/Driver/SanitizerArgs.cpp
+++ lib/Driver/SanitizerArgs.cpp
@@ -25,29 +25,32 @@
 using namespace clang::driver;
 using namespace llvm::opt;
 
-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,
-};
+SanitizerMask NeedsUbsanRt =
+    Undefined | Integer | ImplicitConversion | Nullability | CFI;
+SanitizerMask NeedsUbsanCxxRt = Vptr | CFI;
+SanitizerMask NotAllowedWithTrap = Vptr;
+SanitizerMask NotAllowedWithMinimalRuntime = Vptr;
+SanitizerMask RequiresPIE = DataFlow | HWAddress | Scudo;
+SanitizerMask NeedsUnwindTables =
+    Address | HWAddress | Thread | Memory | DataFlow;
+SanitizerMask SupportsCoverage =
+    Address | HWAddress | KernelAddress | KernelHWAddress | Memory |
+    KernelMemory | Leak | Undefined | Integer | ImplicitConversion |
+    Nullability | DataFlow | Fuzzer | FuzzerNoLink;
+SanitizerMask RecoverableByDefault =
+    Undefined | Integer | ImplicitConversion | Nullability;
+SanitizerMask Unrecoverable = Unreachable | Return;
+SanitizerMask AlwaysRecoverable = KernelAddress | KernelHWAddress;
+SanitizerMask LegacyFsanitizeRecoverMask = Undefined | Integer;
+SanitizerMask NeedsLTO = CFI;
+SanitizerMask TrappingSupported = (Undefined & ~Vptr) |
+                                  UnsignedIntegerOverflow | ImplicitConversion |
+                                  Nullability | LocalBounds | CFI;
+SanitizerMask TrappingDefault = CFI;
+SanitizerMask CFIClasses =
+    CFIVCall | CFINVCall | CFIMFCall | CFIDerivedCast | CFIUnrelatedCast;
+SanitizerMask CompatibleWithMinimalRuntime =
+    TrappingSupported | Scudo | ShadowCallStack;
 
 enum CoverageFeature {
   CoverageFunc = 1 << 0,
@@ -136,10 +139,10 @@
 
 static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
                                            const llvm::opt::ArgList &Args) {
-  SanitizerMask TrapRemove = 0; // 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 = 0;
+  SanitizerMask TrappingKinds(0);
   SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported);
 
   for (ArgList::const_reverse_iterator I = Args.rbegin(), E = Args.rend();
@@ -203,24 +206,26 @@
 }
 
 bool SanitizerArgs::needsUnwindTables() const {
-  return Sanitizers.Mask & NeedsUnwindTables;
+  return static_cast<bool>(Sanitizers.Mask & NeedsUnwindTables);
 }
 
-bool SanitizerArgs::needsLTO() const { return Sanitizers.Mask & NeedsLTO; }
+bool SanitizerArgs::needsLTO() const {
+  return static_cast<bool>(Sanitizers.Mask & NeedsLTO);
+}
 
 SanitizerArgs::SanitizerArgs(const ToolChain &TC,
                              const llvm::opt::ArgList &Args) {
-  SanitizerMask AllRemove = 0;  // 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 = 0;  // 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 = 0;  // 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 = 0;
+  SanitizerMask Kinds(0);
   const SanitizerMask Supported = setGroupBits(TC.getSupportedSanitizers());
 
   CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
@@ -455,8 +460,8 @@
 
   // Parse -f(no-)?sanitize-recover flags.
   SanitizerMask RecoverableKinds = RecoverableByDefault | AlwaysRecoverable;
-  SanitizerMask DiagnosedUnrecoverableKinds = 0;
-  SanitizerMask DiagnosedAlwaysRecoverableKinds = 0;
+  SanitizerMask DiagnosedUnrecoverableKinds(0);
+  SanitizerMask DiagnosedAlwaysRecoverableKinds(0);
   for (const auto *Arg : Args) {
     const char *DeprecatedReplacement = nullptr;
     if (Arg->getOption().matches(options::OPT_fsanitize_recover)) {
@@ -959,18 +964,18 @@
           A->getOption().matches(options::OPT_fsanitize_trap_EQ) ||
           A->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) &&
          "Invalid argument in parseArgValues!");
-  SanitizerMask Kinds = 0;
+  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 = 0;
+      Kind = SanitizerMask(0);
     // Similarly, don't accept -fsanitize=efficiency-all.
     else if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
         0 == strcmp("efficiency-all", Value))
-      Kind = 0;
+      Kind = SanitizerMask(0);
     else
       Kind = parseSanitizerValue(Value, /*AllowGroups=*/true);
 
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -2856,16 +2856,13 @@
 }
 
 static CheckRecoverableKind getRecoverableKind(SanitizerMask Kind) {
-  assert(llvm::countPopulation(Kind) == 1);
-  switch (Kind) {
-  case SanitizerKind::Vptr:
+  assert(Kind.countPopulation() == 1);
+  if (Kind == SanitizerKind::Vptr)
     return CheckRecoverableKind::AlwaysRecoverable;
-  case SanitizerKind::Return:
-  case SanitizerKind::Unreachable:
+  else if (Kind == SanitizerKind::Return || Kind == SanitizerKind::Unreachable)
     return CheckRecoverableKind::Unrecoverable;
-  default:
+  else
     return CheckRecoverableKind::Recoverable;
-  }
 }
 
 namespace {
Index: lib/Basic/Sanitizers.cpp
===================================================================
--- lib/Basic/Sanitizers.cpp
+++ lib/Basic/Sanitizers.cpp
@@ -11,6 +11,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Basic/Sanitizers.h"
+#include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/StringSwitch.h"
 
 using namespace clang;
@@ -19,9 +20,9 @@
   SanitizerMask ParsedKind = llvm::StringSwitch<SanitizerMask>(Value)
 #define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID)
 #define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
-  .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : 0)
+  .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : SanitizerMask(0))
 #include "clang/Basic/Sanitizers.def"
-    .Default(0);
+    .Default(SanitizerMask(0));
   return ParsedKind;
 }
 
@@ -33,3 +34,13 @@
 #include "clang/Basic/Sanitizers.def"
   return Kinds;
 }
+
+llvm::hash_code SanitizerMask::hash_value() const {
+  return llvm::hash_value(mask);
+}
+
+namespace llvm {
+hash_code hash_value(const clang::SanitizerMask &Arg) {
+  return Arg.hash_value();
+}
+} // namespace llvm
Index: lib/Basic/SanitizerSpecialCaseList.cpp
===================================================================
--- lib/Basic/SanitizerSpecialCaseList.cpp
+++ lib/Basic/SanitizerSpecialCaseList.cpp
@@ -36,7 +36,7 @@
 
 void SanitizerSpecialCaseList::createSanitizerSections() {
   for (auto &S : Sections) {
-    SanitizerMask Mask = 0;
+    SanitizerMask Mask(0);
 
 #define SANITIZER(NAME, ID)                                                    \
   if (S.SectionMatcher->match(NAME))                                           \
Index: include/clang/Driver/ToolChain.h
===================================================================
--- include/clang/Driver/ToolChain.h
+++ include/clang/Driver/ToolChain.h
@@ -563,7 +563,9 @@
   virtual SanitizerMask getSupportedSanitizers() const;
 
   /// Return sanitizers which are enabled by default.
-  virtual SanitizerMask getDefaultSanitizers() const { return 0; }
+  virtual SanitizerMask getDefaultSanitizers() const {
+    return SanitizerMask(0);
+  }
 };
 
 /// Set a ToolChain's effective triple. Reset it when the registration object
Index: include/clang/Basic/Sanitizers.h
===================================================================
--- include/clang/Basic/Sanitizers.h
+++ include/clang/Basic/Sanitizers.h
@@ -15,14 +15,89 @@
 #define LLVM_CLANG_BASIC_SANITIZERS_H
 
 #include "clang/Basic/LLVM.h"
+#include "llvm/ADT/APInt.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/MathExtras.h"
 #include <cassert>
 #include <cstdint>
 
 namespace clang {
+struct SanitizerMask;
+}
+
+namespace llvm {
+class hashcode;
+hash_code hash_value(const clang::SanitizerMask &Arg);
+} // namespace llvm
+
+namespace clang {
+
+namespace SanitizerKind {
+enum SanitizerOrdinal : uint64_t;
+}
+
+struct SanitizerMask {
+private:
+  llvm::APInt mask;
+
+public:
+  // Size of SanitizerMask's bit mask in bits.
+  static const int kNumBits = 128;
+
+  SanitizerMask() : mask(kNumBits, 0) {}
+
+  explicit SanitizerMask(uint64_t val) : mask(kNumBits, val) {}
+
+  explicit SanitizerMask(const llvm::APInt &v) : mask(v) {}
+
+  void flipAllBits() { mask.flipAllBits(); }
+
+  bool isPowerOf2() const { return mask.isPowerOf2(); }
+
+  unsigned countPopulation() const { return mask.countPopulation(); }
+
+  llvm::hash_code hash_value() const;
+
+  explicit operator bool() { return mask.getBoolValue(); };
 
-using SanitizerMask = uint64_t;
+  SanitizerMask operator<<(const SanitizerKind::SanitizerOrdinal &Bits) const {
+    assert(Bits < kNumBits && "Bit shift too big.");
+    return SanitizerMask(mask << Bits);
+  }
+
+  bool operator==(const SanitizerMask &V) const { return mask == V.mask; }
+
+  bool operator==(uint64_t Val) const { return mask == Val; }
+
+  SanitizerMask &operator&=(const SanitizerMask &RHS) {
+    mask &= RHS.mask;
+    return *this;
+  }
+
+  SanitizerMask &operator|=(const SanitizerMask &RHS) {
+    mask |= RHS.mask;
+    return *this;
+  }
+
+  bool operator!() const { return !mask; }
+
+  bool operator!=(const SanitizerMask &RHS) const { return !((*this) == RHS); }
+};
+
+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 SanitizerMask(a);
+}
 
 namespace SanitizerKind {
 
@@ -37,11 +112,15 @@
 
 // Define the set of sanitizer kinds, as well as the set of sanitizers each
 // sanitizer group expands into.
-#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;
+#define SANITIZER(NAME, ID)                                                    \
+  static_assert(SO_##ID < SanitizerMask::kNumBits,                             \
+                "Bit shift value too big.");                                   \
+  const SanitizerMask ID = SanitizerMask(1ULL) << SO_##ID;
+#define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
+  static_assert(SO_##ID##Group < SanitizerMask::kNumBits,                      \
+                "Bit shift value too big.");                                   \
+  const SanitizerMask ID = SanitizerMask(ALIAS);                               \
+  const SanitizerMask ID##Group = SanitizerMask(1ULL) << SO_##ID##Group;
 #include "clang/Basic/Sanitizers.def"
 
 } // namespace SanitizerKind
@@ -49,16 +128,16 @@
 struct SanitizerSet {
   /// Check if a certain (single) sanitizer is enabled.
   bool has(SanitizerMask K) const {
-    assert(llvm::isPowerOf2_64(K));
-    return Mask & K;
+    assert(K.isPowerOf2());
+    return static_cast<bool>(Mask & K);
   }
 
   /// Check if one or more sanitizers are enabled.
-  bool hasOneOf(SanitizerMask K) const { return Mask & K; }
+  bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }
 
   /// Enable or disable a certain (single) sanitizer.
   void set(SanitizerMask K, bool Value) {
-    assert(llvm::isPowerOf2_64(K));
+    assert(K.isPowerOf2());
     Mask = Value ? (Mask | K) : (Mask & ~K);
   }
 
@@ -69,7 +148,7 @@
   bool empty() const { return Mask == 0; }
 
   /// Bitmask of enabled sanitizers.
-  SanitizerMask Mask = 0;
+  SanitizerMask Mask = SanitizerMask(0);
 };
 
 /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Index: include/clang/Basic/Attr.td
===================================================================
--- include/clang/Basic/Attr.td
+++ include/clang/Basic/Attr.td
@@ -2360,7 +2360,7 @@
   let Documentation = [NoSanitizeDocs];
   let AdditionalMembers = [{
     SanitizerMask getMask() const {
-      SanitizerMask Mask = 0;
+      SanitizerMask Mask(0);
       for (auto SanitizerName : sanitizers()) {
         SanitizerMask ParsedMask =
             parseSanitizerValue(SanitizerName, /*AllowGroups=*/true);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to