clang  10.0.0svn
Sanitizers.h
Go to the documentation of this file.
1 //===- Sanitizers.h - C Language Family Language Options --------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 /// \file
10 /// Defines the clang::SanitizerKind enum.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_BASIC_SANITIZERS_H
15 #define LLVM_CLANG_BASIC_SANITIZERS_H
16 
17 #include "clang/Basic/LLVM.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/MathExtras.h"
20 #include <cassert>
21 #include <cstdint>
22 
23 namespace llvm {
24 class hash_code;
25 }
26 
27 namespace clang {
28 
30  // NOTE: this class assumes kNumElem == 2 in most of the constexpr functions,
31  // in order to work within the C++11 constexpr function constraints. If you
32  // change kNumElem, you'll need to update those member functions as well.
33 
34  /// Number of array elements.
35  static constexpr unsigned kNumElem = 2;
36  /// Mask value initialized to 0.
37  uint64_t maskLoToHigh[kNumElem]{};
38  /// Number of bits in a mask.
39  static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8;
40  /// Number of bits in a mask element.
41  static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8;
42 
43  constexpr SanitizerMask(uint64_t mask1, uint64_t mask2)
44  : maskLoToHigh{mask1, mask2} {}
45 
46 public:
47  SanitizerMask() = default;
48 
49  static constexpr bool checkBitPos(const unsigned Pos) {
50  return Pos < kNumBits;
51  }
52 
53  /// Create a mask with a bit enabled at position Pos.
54  static constexpr SanitizerMask bitPosToMask(const unsigned Pos) {
55  return SanitizerMask((Pos < kNumBitElem) ? 1ULL << Pos % kNumBitElem : 0,
56  (Pos >= kNumBitElem && Pos < kNumBitElem * 2)
57  ? 1ULL << Pos % kNumBitElem
58  : 0);
59  }
60 
61  unsigned countPopulation() const {
62  unsigned total = 0;
63  for (const auto &Val : maskLoToHigh)
64  total += llvm::countPopulation(Val);
65  return total;
66  }
67 
68  void flipAllBits() {
69  for (auto &Val : maskLoToHigh)
70  Val = ~Val;
71  }
72 
73  bool isPowerOf2() const {
74  return countPopulation() == 1;
75  }
76 
77  llvm::hash_code hash_value() const;
78 
79  constexpr explicit operator bool() const {
80  return maskLoToHigh[0] || maskLoToHigh[1];
81  }
82 
83  constexpr bool operator==(const SanitizerMask &V) const {
84  return maskLoToHigh[0] == V.maskLoToHigh[0] &&
85  maskLoToHigh[1] == V.maskLoToHigh[1];
86  }
87 
88  SanitizerMask &operator&=(const SanitizerMask &RHS) {
89  for (unsigned k = 0; k < kNumElem; k++)
90  maskLoToHigh[k] &= RHS.maskLoToHigh[k];
91  return *this;
92  }
93 
94  SanitizerMask &operator|=(const SanitizerMask &RHS) {
95  for (unsigned k = 0; k < kNumElem; k++)
96  maskLoToHigh[k] |= RHS.maskLoToHigh[k];
97  return *this;
98  }
99 
100  constexpr bool operator!() const { return !bool(*this); }
101 
102  constexpr bool operator!=(const SanitizerMask &RHS) const {
103  return !((*this) == RHS);
104  }
105 
106  friend constexpr inline SanitizerMask operator~(SanitizerMask v) {
107  return SanitizerMask(~v.maskLoToHigh[0], ~v.maskLoToHigh[1]);
108  }
109 
110  friend constexpr inline SanitizerMask operator&(SanitizerMask a,
111  const SanitizerMask &b) {
112  return SanitizerMask(a.maskLoToHigh[0] & b.maskLoToHigh[0],
113  a.maskLoToHigh[1] & b.maskLoToHigh[1]);
114  }
115 
116  friend constexpr inline SanitizerMask operator|(SanitizerMask a,
117  const SanitizerMask &b) {
118  return SanitizerMask(a.maskLoToHigh[0] | b.maskLoToHigh[0],
119  a.maskLoToHigh[1] | b.maskLoToHigh[1]);
120  }
121 };
122 
123 // Declaring in clang namespace so that it can be found by ADL.
124 llvm::hash_code hash_value(const clang::SanitizerMask &Arg);
125 
126 // Define the set of sanitizer kinds, as well as the set of sanitizers each
127 // sanitizer group expands into.
129  // Assign ordinals to possible values of -fsanitize= flag, which we will use
130  // as bit positions.
131  enum SanitizerOrdinal : uint64_t {
132 #define SANITIZER(NAME, ID) SO_##ID,
133 #define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
134 #include "clang/Basic/Sanitizers.def"
135  SO_Count
136  };
137 
138 #define SANITIZER(NAME, ID) \
139  static constexpr SanitizerMask ID = SanitizerMask::bitPosToMask(SO_##ID); \
140  static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big.");
141 #define SANITIZER_GROUP(NAME, ID, ALIAS) \
142  static constexpr SanitizerMask ID = SanitizerMask(ALIAS); \
143  static constexpr SanitizerMask ID##Group = \
144  SanitizerMask::bitPosToMask(SO_##ID##Group); \
145  static_assert(SanitizerMask::checkBitPos(SO_##ID##Group), \
146  "Bit position too big.");
147 #include "clang/Basic/Sanitizers.def"
148 }; // SanitizerKind
149 
150 struct SanitizerSet {
151  /// Check if a certain (single) sanitizer is enabled.
152  bool has(SanitizerMask K) const {
153  assert(K.isPowerOf2() && "Has to be a single sanitizer.");
154  return static_cast<bool>(Mask & K);
155  }
156 
157  /// Check if one or more sanitizers are enabled.
158  bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }
159 
160  /// Enable or disable a certain (single) sanitizer.
161  void set(SanitizerMask K, bool Value) {
162  assert(K.isPowerOf2() && "Has to be a single sanitizer.");
163  Mask = Value ? (Mask | K) : (Mask & ~K);
164  }
165 
166  /// Disable the sanitizers specified in \p K.
167  void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
168 
169  /// Returns true if no sanitizers are enabled.
170  bool empty() const { return !Mask; }
171 
172  /// Bitmask of enabled sanitizers.
174 };
175 
176 /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
177 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
178 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
179 
180 /// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
181 /// this group enables.
183 
184 /// Return the sanitizers which do not affect preprocessing.
186  return SanitizerKind::CFI | SanitizerKind::Integer |
187  SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
188  SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero;
189 }
190 
191 } // namespace clang
192 
193 #endif // LLVM_CLANG_BASIC_SANITIZERS_H
unsigned countPopulation() const
Definition: Sanitizers.h:61
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
Definition: Dominators.h:30
constexpr bool operator==(const SanitizerMask &V) const
Definition: Sanitizers.h:83
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
Definition: Sanitizers.h:158
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:173
bool isPowerOf2() const
Definition: Sanitizers.h:73
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
constexpr XRayInstrMask All
Definition: XRayInstr.h:41
DiagnosticLevelMask operator &(DiagnosticLevelMask LHS, DiagnosticLevelMask RHS)
#define V(N, I)
Definition: ASTContext.h:2913
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
Definition: Sanitizers.cpp:51
#define bool
Definition: stdbool.h:15
friend constexpr SanitizerMask operator~(SanitizerMask v)
Definition: Sanitizers.h:106
void clear(SanitizerMask K=SanitizerKind::All)
Disable the sanitizers specified in K.
Definition: Sanitizers.h:167
constexpr bool operator!() const
Definition: Sanitizers.h:100
do v
Definition: arm_acle.h:64
SanitizerMask getPPTransparentSanitizers()
Return the sanitizers which do not affect preprocessing.
Definition: Sanitizers.h:185
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
Definition: Sanitizers.h:54
constexpr bool operator!=(const SanitizerMask &RHS) const
Definition: Sanitizers.h:102
Dataflow Directional Tag Classes.
static constexpr bool checkBitPos(const unsigned Pos)
Definition: Sanitizers.h:49
SanitizerMask & operator|=(const SanitizerMask &RHS)
Definition: Sanitizers.h:94
bool empty() const
Returns true if no sanitizers are enabled.
Definition: Sanitizers.h:170
friend constexpr SanitizerMask operator|(SanitizerMask a, const SanitizerMask &b)
Definition: Sanitizers.h:116
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Definition: Sanitizers.cpp:27
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables...
Definition: Sanitizers.cpp:37
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition: Sanitizers.h:152