clang  14.0.0git
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/HashBuilder.h"
20 #include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
21 #include <cassert>
22 #include <cstdint>
23 
24 namespace llvm {
25 class hash_code;
26 }
27 
28 namespace clang {
29 
31  // NOTE: this class assumes kNumElem == 2 in most of the constexpr functions,
32  // in order to work within the C++11 constexpr function constraints. If you
33  // change kNumElem, you'll need to update those member functions as well.
34 
35  /// Number of array elements.
36  static constexpr unsigned kNumElem = 2;
37  /// Mask value initialized to 0.
38  uint64_t maskLoToHigh[kNumElem]{};
39  /// Number of bits in a mask.
40  static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8;
41  /// Number of bits in a mask element.
42  static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8;
43 
44  constexpr SanitizerMask(uint64_t mask1, uint64_t mask2)
45  : maskLoToHigh{mask1, mask2} {}
46 
47 public:
48  SanitizerMask() = default;
49 
50  static constexpr bool checkBitPos(const unsigned Pos) {
51  return Pos < kNumBits;
52  }
53 
54  /// Create a mask with a bit enabled at position Pos.
55  static constexpr SanitizerMask bitPosToMask(const unsigned Pos) {
56  uint64_t mask1 = (Pos < kNumBitElem) ? 1ULL << (Pos % kNumBitElem) : 0;
57  uint64_t mask2 = (Pos >= kNumBitElem && Pos < (kNumBitElem * 2))
58  ? 1ULL << (Pos % kNumBitElem)
59  : 0;
60  return SanitizerMask(mask1, mask2);
61  }
62 
63  unsigned countPopulation() const;
64 
65  void flipAllBits() {
66  for (auto &Val : maskLoToHigh)
67  Val = ~Val;
68  }
69 
70  bool isPowerOf2() const {
71  return countPopulation() == 1;
72  }
73 
74  llvm::hash_code hash_value() const;
75 
76  template <typename HasherT, llvm::support::endianness Endianness>
77  friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
78  const SanitizerMask &SM) {
79  HBuilder.addRange(&SM.maskLoToHigh[0], &SM.maskLoToHigh[kNumElem]);
80  }
81 
82  constexpr explicit operator bool() const {
83  return maskLoToHigh[0] || maskLoToHigh[1];
84  }
85 
86  constexpr bool operator==(const SanitizerMask &V) const {
87  return maskLoToHigh[0] == V.maskLoToHigh[0] &&
88  maskLoToHigh[1] == V.maskLoToHigh[1];
89  }
90 
92  for (unsigned k = 0; k < kNumElem; k++)
93  maskLoToHigh[k] &= RHS.maskLoToHigh[k];
94  return *this;
95  }
96 
98  for (unsigned k = 0; k < kNumElem; k++)
99  maskLoToHigh[k] |= RHS.maskLoToHigh[k];
100  return *this;
101  }
102 
103  constexpr bool operator!() const { return !bool(*this); }
104 
105  constexpr bool operator!=(const SanitizerMask &RHS) const {
106  return !((*this) == RHS);
107  }
108 
109  friend constexpr inline SanitizerMask operator~(SanitizerMask v) {
110  return SanitizerMask(~v.maskLoToHigh[0], ~v.maskLoToHigh[1]);
111  }
112 
113  friend constexpr inline SanitizerMask operator&(SanitizerMask a,
114  const SanitizerMask &b) {
115  return SanitizerMask(a.maskLoToHigh[0] & b.maskLoToHigh[0],
116  a.maskLoToHigh[1] & b.maskLoToHigh[1]);
117  }
118 
119  friend constexpr inline SanitizerMask operator|(SanitizerMask a,
120  const SanitizerMask &b) {
121  return SanitizerMask(a.maskLoToHigh[0] | b.maskLoToHigh[0],
122  a.maskLoToHigh[1] | b.maskLoToHigh[1]);
123  }
124 };
125 
126 // Declaring in clang namespace so that it can be found by ADL.
127 llvm::hash_code hash_value(const clang::SanitizerMask &Arg);
128 
129 // Define the set of sanitizer kinds, as well as the set of sanitizers each
130 // sanitizer group expands into.
132  // Assign ordinals to possible values of -fsanitize= flag, which we will use
133  // as bit positions.
134  enum SanitizerOrdinal : uint64_t {
135 #define SANITIZER(NAME, ID) SO_##ID,
136 #define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
137 #include "clang/Basic/Sanitizers.def"
139  };
140 
141 #define SANITIZER(NAME, ID) \
142  static constexpr SanitizerMask ID = SanitizerMask::bitPosToMask(SO_##ID); \
143  static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big.");
144 #define SANITIZER_GROUP(NAME, ID, ALIAS) \
145  static constexpr SanitizerMask ID = SanitizerMask(ALIAS); \
146  static constexpr SanitizerMask ID##Group = \
147  SanitizerMask::bitPosToMask(SO_##ID##Group); \
148  static_assert(SanitizerMask::checkBitPos(SO_##ID##Group), \
149  "Bit position too big.");
150 #include "clang/Basic/Sanitizers.def"
151 }; // SanitizerKind
152 
153 struct SanitizerSet {
154  /// Check if a certain (single) sanitizer is enabled.
155  bool has(SanitizerMask K) const {
156  assert(K.isPowerOf2() && "Has to be a single sanitizer.");
157  return static_cast<bool>(Mask & K);
158  }
159 
160  /// Check if one or more sanitizers are enabled.
161  bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }
162 
163  /// Enable or disable a certain (single) sanitizer.
164  void set(SanitizerMask K, bool Value) {
165  assert(K.isPowerOf2() && "Has to be a single sanitizer.");
166  Mask = Value ? (Mask | K) : (Mask & ~K);
167  }
168 
169  /// Disable the sanitizers specified in \p K.
171 
172  /// Returns true if no sanitizers are enabled.
173  bool empty() const { return !Mask; }
174 
175  /// Bitmask of enabled sanitizers.
177 };
178 
179 /// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
180 /// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
181 SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
182 
183 /// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
186 
187 /// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
188 /// this group enables.
190 
191 /// Return the sanitizers which do not affect preprocessing.
193  return SanitizerKind::CFI | SanitizerKind::Integer |
194  SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
195  SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero;
196 }
197 
198 StringRef AsanDtorKindToString(llvm::AsanDtorKind kind);
199 
200 llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind);
201 
203  llvm::AsanDetectStackUseAfterReturnMode mode);
204 
205 llvm::AsanDetectStackUseAfterReturnMode
207 
208 } // namespace clang
209 
210 #endif // LLVM_CLANG_BASIC_SANITIZERS_H
llvm
Definition: Dominators.h:30
clang::ento::Nullability
Nullability
Definition: CheckerHelpers.h:56
clang::SanitizerMask::operator==
constexpr bool operator==(const SanitizerMask &V) const
Definition: Sanitizers.h:86
clang::SanitizerKind::SanitizerOrdinal
SanitizerOrdinal
Definition: Sanitizers.h:134
clang::SanitizerSet::has
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition: Sanitizers.h:155
clang::SanitizerSet::hasOneOf
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
Definition: Sanitizers.h:161
clang::SanitizerMask::operator&
constexpr friend SanitizerMask operator&(SanitizerMask a, const SanitizerMask &b)
Definition: Sanitizers.h:113
clang::SanitizerMask::isPowerOf2
bool isPowerOf2() const
Definition: Sanitizers.h:70
b
__device__ __2f16 b
Definition: __clang_hip_libdevice_declares.h:314
clang::SanitizerMask::operator&=
SanitizerMask & operator&=(const SanitizerMask &RHS)
Definition: Sanitizers.h:91
clang::SanitizerSet::Mask
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:176
clang::SanitizerMask::countPopulation
unsigned countPopulation() const
Definition: Sanitizers.cpp:61
clang::getPPTransparentSanitizers
SanitizerMask getPPTransparentSanitizers()
Return the sanitizers which do not affect preprocessing.
Definition: Sanitizers.h:192
clang::hash_value
llvm::hash_code hash_value(const clang::SanitizerMask &Arg)
Definition: Sanitizers.cpp:68
clang::XRayInstrKind::All
constexpr XRayInstrMask All
Definition: XRayInstr.h:43
clang::SanitizerMask::hash_value
llvm::hash_code hash_value() const
Definition: Sanitizers.cpp:56
clang::AsanDtorKindFromString
llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind)
Definition: Sanitizers.cpp:84
clang::SanitizerMask::operator|
constexpr friend SanitizerMask operator|(SanitizerMask a, const SanitizerMask &b)
Definition: Sanitizers.h:119
V
#define V(N, I)
Definition: ASTContext.h:3113
clang::SanitizerMask::operator!
constexpr bool operator!() const
Definition: Sanitizers.h:103
clang::SanitizerSet
Definition: Sanitizers.h:153
clang::SanitizerKind::SO_Count
@ SO_Count
Definition: Sanitizers.h:138
clang::AsanDetectStackUseAfterReturnModeFromString
llvm::AsanDetectStackUseAfterReturnMode AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr)
Definition: Sanitizers.cpp:107
clang::SanitizerMask::operator!=
constexpr bool operator!=(const SanitizerMask &RHS) const
Definition: Sanitizers.h:105
bool
#define bool
Definition: stdbool.h:15
clang::expandSanitizerGroups
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables.
Definition: Sanitizers.cpp:47
clang::serializeSanitizerSet
void serializeSanitizerSet(SanitizerSet Set, SmallVectorImpl< StringRef > &Values)
Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
Definition: Sanitizers.cpp:39
Value
Value
Definition: UninitializedValues.cpp:102
clang::SanitizerKind
Definition: Sanitizers.h:131
LLVM.h
clang::SanitizerMask::operator~
constexpr friend SanitizerMask operator~(SanitizerMask v)
Definition: Sanitizers.h:109
clang::SanitizerSet::empty
bool empty() const
Returns true if no sanitizers are enabled.
Definition: Sanitizers.h:173
clang::AsanDtorKindToString
StringRef AsanDtorKindToString(llvm::AsanDtorKind kind)
Definition: Sanitizers.cpp:72
clang::SanitizerMask::bitPosToMask
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
Definition: Sanitizers.h:55
clang::SanitizerSet::clear
void clear(SanitizerMask K=SanitizerKind::All)
Disable the sanitizers specified in K.
Definition: Sanitizers.h:170
clang::SanitizerMask::addHash
friend void addHash(llvm::HashBuilderImpl< HasherT, Endianness > &HBuilder, const SanitizerMask &SM)
Definition: Sanitizers.h:77
clang
Definition: CalledOnceCheck.h:17
clang::SanitizerMask::operator|=
SanitizerMask & operator|=(const SanitizerMask &RHS)
Definition: Sanitizers.h:97
clang::AsanDetectStackUseAfterReturnModeToString
StringRef AsanDetectStackUseAfterReturnModeToString(llvm::AsanDetectStackUseAfterReturnMode mode)
Definition: Sanitizers.cpp:91
clang::SanitizerSet::set
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
Definition: Sanitizers.h:164
v
do v
Definition: arm_acle.h:76
llvm::SmallVectorImpl
Definition: LLVM.h:39
clang::SanitizerMask::checkBitPos
static constexpr bool checkBitPos(const unsigned Pos)
Definition: Sanitizers.h:50
clang::SanitizerMask::SanitizerMask
SanitizerMask()=default
clang::SanitizerMask::flipAllBits
void flipAllBits()
Definition: Sanitizers.h:65
SM
#define SM(sm)
Definition: Cuda.cpp:78
clang::parseSanitizerValue
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Definition: Sanitizers.cpp:29
clang::diag::kind
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Definition: DiagnosticIDs.h:60
clang::SanitizerMask
Definition: Sanitizers.h:30