clang 20.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
24namespace llvm {
25class hash_code;
26class Triple;
27namespace opt {
28class ArgList;
29}
30} // namespace llvm
31
32namespace clang {
33
35 // NOTE: this class assumes kNumElem == 2 in most of the constexpr functions,
36 // in order to work within the C++11 constexpr function constraints. If you
37 // change kNumElem, you'll need to update those member functions as well.
38
39 /// Number of array elements.
40 static constexpr unsigned kNumElem = 2;
41 /// Mask value initialized to 0.
42 uint64_t maskLoToHigh[kNumElem]{};
43 /// Number of bits in a mask.
44 static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8;
45 /// Number of bits in a mask element.
46 static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8;
47
48 constexpr SanitizerMask(uint64_t mask1, uint64_t mask2)
49 : maskLoToHigh{mask1, mask2} {}
50
51public:
52 SanitizerMask() = default;
53
54 static constexpr bool checkBitPos(const unsigned Pos) {
55 return Pos < kNumBits;
56 }
57
58 /// Create a mask with a bit enabled at position Pos.
59 static constexpr SanitizerMask bitPosToMask(const unsigned Pos) {
60 uint64_t mask1 = (Pos < kNumBitElem) ? 1ULL << (Pos % kNumBitElem) : 0;
61 uint64_t mask2 = (Pos >= kNumBitElem && Pos < (kNumBitElem * 2))
62 ? 1ULL << (Pos % kNumBitElem)
63 : 0;
64 return SanitizerMask(mask1, mask2);
65 }
66
67 unsigned countPopulation() const;
68
69 void flipAllBits() {
70 for (auto &Val : maskLoToHigh)
71 Val = ~Val;
72 }
73
74 bool isPowerOf2() const {
75 return countPopulation() == 1;
76 }
77
78 llvm::hash_code hash_value() const;
79
80 template <typename HasherT, llvm::endianness Endianness>
81 friend void addHash(llvm::HashBuilder<HasherT, Endianness> &HBuilder,
82 const SanitizerMask &SM) {
83 HBuilder.addRange(&SM.maskLoToHigh[0], &SM.maskLoToHigh[kNumElem]);
84 }
85
86 constexpr explicit operator bool() const {
87 return maskLoToHigh[0] || maskLoToHigh[1];
88 }
89
90 constexpr bool operator==(const SanitizerMask &V) const {
91 return maskLoToHigh[0] == V.maskLoToHigh[0] &&
92 maskLoToHigh[1] == V.maskLoToHigh[1];
93 }
94
96 for (unsigned k = 0; k < kNumElem; k++)
97 maskLoToHigh[k] &= RHS.maskLoToHigh[k];
98 return *this;
99 }
100
102 for (unsigned k = 0; k < kNumElem; k++)
103 maskLoToHigh[k] |= RHS.maskLoToHigh[k];
104 return *this;
105 }
106
107 constexpr bool operator!() const { return !bool(*this); }
108
109 constexpr bool operator!=(const SanitizerMask &RHS) const {
110 return !((*this) == RHS);
111 }
112
113 friend constexpr inline SanitizerMask operator~(SanitizerMask v) {
114 return SanitizerMask(~v.maskLoToHigh[0], ~v.maskLoToHigh[1]);
115 }
116
117 friend constexpr inline SanitizerMask operator&(SanitizerMask a,
118 const SanitizerMask &b) {
119 return SanitizerMask(a.maskLoToHigh[0] & b.maskLoToHigh[0],
120 a.maskLoToHigh[1] & b.maskLoToHigh[1]);
121 }
122
123 friend constexpr inline SanitizerMask operator|(SanitizerMask a,
124 const SanitizerMask &b) {
125 return SanitizerMask(a.maskLoToHigh[0] | b.maskLoToHigh[0],
126 a.maskLoToHigh[1] | b.maskLoToHigh[1]);
127 }
128};
129
130// Declaring in clang namespace so that it can be found by ADL.
131llvm::hash_code hash_value(const clang::SanitizerMask &Arg);
132
133// Define the set of sanitizer kinds, as well as the set of sanitizers each
134// sanitizer group expands into.
136 // Assign ordinals to possible values of -fsanitize= flag, which we will use
137 // as bit positions.
138 enum SanitizerOrdinal : uint64_t {
139#define SANITIZER(NAME, ID) SO_##ID,
140#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
141#include "clang/Basic/Sanitizers.def"
143 };
144
145#define SANITIZER(NAME, ID) \
146 static constexpr SanitizerMask ID = SanitizerMask::bitPosToMask(SO_##ID); \
147 static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big.");
148#define SANITIZER_GROUP(NAME, ID, ALIAS) \
149 static constexpr SanitizerMask ID = SanitizerMask(ALIAS); \
150 static constexpr SanitizerMask ID##Group = \
151 SanitizerMask::bitPosToMask(SO_##ID##Group); \
152 static_assert(SanitizerMask::checkBitPos(SO_##ID##Group), \
153 "Bit position too big.");
154#include "clang/Basic/Sanitizers.def"
155}; // SanitizerKind
156
158 std::vector<double> Cutoffs;
159
160public:
161 std::optional<double> operator[](unsigned Kind) const;
162
163 void set(SanitizerMask K, double V);
164 void clear(SanitizerMask K = SanitizerKind::All);
165};
166
168 /// Check if a certain (single) sanitizer is enabled.
169 bool has(SanitizerMask K) const {
170 assert(K.isPowerOf2() && "Has to be a single sanitizer.");
171 return static_cast<bool>(Mask & K);
172 }
173
176 }
177
178 /// Check if one or more sanitizers are enabled.
179 bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }
180
181 /// Enable or disable a certain (single) sanitizer.
182 void set(SanitizerMask K, bool Value) {
183 assert(K.isPowerOf2() && "Has to be a single sanitizer.");
184 Mask = Value ? (Mask | K) : (Mask & ~K);
185 }
186
187 void set(SanitizerMask K) { Mask = K; }
188
189 /// Disable the sanitizers specified in \p K.
190 void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
191
192 /// Returns true if no sanitizers are enabled.
193 bool empty() const { return !Mask; }
194
195 /// Bitmask of enabled sanitizers.
197};
198
199/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
200/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
201SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
202
203/// Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= or
204/// -fno-sanitize= value list.
205/// The relevant weight(s) are updated in the passed Cutoffs parameter.
206/// Individual Cutoffs are never reset to zero unless explicitly set
207/// (e.g., 'null=0.0').
208/// Returns \c false if \p Value is not known or the weight is not valid.
209bool parseSanitizerWeightedValue(StringRef Value, bool AllowGroups,
210 SanitizerMaskCutoffs &Cutoffs);
211
212/// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
215
216/// Serialize a SanitizerMaskCutoffs into values for -fsanitize= or
217/// -fno-sanitize=.
220
221/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
222/// this group enables.
224
225/// Return the sanitizers which do not affect preprocessing.
227 return SanitizerKind::CFI | SanitizerKind::Integer |
228 SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
229 SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero;
230}
231
232StringRef AsanDtorKindToString(llvm::AsanDtorKind kind);
233
234llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind);
235
237 llvm::AsanDetectStackUseAfterReturnMode mode);
238
239llvm::AsanDetectStackUseAfterReturnMode
241
242} // namespace clang
243
244#endif // LLVM_CLANG_BASIC_SANITIZERS_H
#define V(N, I)
Definition: ASTContext.h:3453
#define SM(sm)
Definition: Cuda.cpp:84
enum clang::sema::@1724::IndirectLocalPathEntry::EntryKind Kind
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
__device__ __2f16 b
#define bool
Definition: amdgpuintrin.h:20
do v
Definition: arm_acle.h:91
void clear(SanitizerMask K=SanitizerKind::All)
Definition: Sanitizers.cpp:44
void set(SanitizerMask K, double V)
Definition: Sanitizers.cpp:27
std::optional< double > operator[](unsigned Kind) const
Definition: Sanitizers.cpp:37
friend void addHash(llvm::HashBuilder< HasherT, Endianness > &HBuilder, const SanitizerMask &SM)
Definition: Sanitizers.h:81
constexpr bool operator==(const SanitizerMask &V) const
Definition: Sanitizers.h:90
constexpr bool operator!() const
Definition: Sanitizers.h:107
SanitizerMask & operator|=(const SanitizerMask &RHS)
Definition: Sanitizers.h:101
bool isPowerOf2() const
Definition: Sanitizers.h:74
SanitizerMask & operator&=(const SanitizerMask &RHS)
Definition: Sanitizers.h:95
llvm::hash_code hash_value() const
Definition: Sanitizers.cpp:116
static constexpr bool checkBitPos(const unsigned Pos)
Definition: Sanitizers.h:54
unsigned countPopulation() const
Definition: Sanitizers.cpp:121
constexpr bool operator!=(const SanitizerMask &RHS) const
Definition: Sanitizers.h:109
friend constexpr SanitizerMask operator|(SanitizerMask a, const SanitizerMask &b)
Definition: Sanitizers.h:123
friend constexpr SanitizerMask operator~(SanitizerMask v)
Definition: Sanitizers.h:113
static constexpr SanitizerMask bitPosToMask(const unsigned Pos)
Create a mask with a bit enabled at position Pos.
Definition: Sanitizers.h:59
friend constexpr SanitizerMask operator&(SanitizerMask a, const SanitizerMask &b)
Definition: Sanitizers.h:117
const internal::ArgumentAdaptingMatcherFunc< internal::HasMatcher > has
Matches AST nodes that have child AST nodes that match the provided matcher.
The JSON file list parser is used to communicate input to InstallAPI.
SanitizerMask getPPTransparentSanitizers()
Return the sanitizers which do not affect preprocessing.
Definition: Sanitizers.h:226
StringRef AsanDtorKindToString(llvm::AsanDtorKind kind)
Definition: Sanitizers.cpp:132
void serializeSanitizerSet(SanitizerSet Set, SmallVectorImpl< StringRef > &Values)
Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
Definition: Sanitizers.cpp:87
bool parseSanitizerWeightedValue(StringRef Value, bool AllowGroups, SanitizerMaskCutoffs &Cutoffs)
Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= or -fno-sanitize= value lis...
Definition: Sanitizers.cpp:64
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables.
Definition: Sanitizers.cpp:107
void serializeSanitizerMaskCutoffs(const SanitizerMaskCutoffs &Cutoffs, SmallVectorImpl< std::string > &Values)
Serialize a SanitizerMaskCutoffs into values for -fsanitize= or -fno-sanitize=.
Definition: Sanitizers.cpp:95
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Definition: Sanitizers.cpp:54
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind)
Definition: Sanitizers.cpp:144
llvm::AsanDetectStackUseAfterReturnMode AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr)
Definition: Sanitizers.cpp:167
StringRef AsanDetectStackUseAfterReturnModeToString(llvm::AsanDetectStackUseAfterReturnMode mode)
Definition: Sanitizers.cpp:151
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
void set(SanitizerMask K)
Definition: Sanitizers.h:187
void clear(SanitizerMask K=SanitizerKind::All)
Disable the sanitizers specified in K.
Definition: Sanitizers.h:190
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
Definition: Sanitizers.h:182
bool empty() const
Returns true if no sanitizers are enabled.
Definition: Sanitizers.h:193
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition: Sanitizers.h:169
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:196
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
Definition: Sanitizers.h:179
bool has(SanitizerKind::SanitizerOrdinal O) const
Definition: Sanitizers.h:174