clang 21.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 // Returns nullopt if all the values are zero.
167 // Otherwise, return value contains a vector of all the scaled values.
168 std::optional<std::vector<unsigned>>
169 getAllScaled(unsigned ScalingFactor) const;
170};
171
173 /// Check if a certain (single) sanitizer is enabled.
174 bool has(SanitizerMask K) const {
175 assert(K.isPowerOf2() && "Has to be a single sanitizer.");
176 return static_cast<bool>(Mask & K);
177 }
178
181 }
182
183 /// Check if one or more sanitizers are enabled.
184 bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }
185
186 /// Enable or disable a certain (single) sanitizer.
187 void set(SanitizerMask K, bool Value) {
188 assert(K.isPowerOf2() && "Has to be a single sanitizer.");
189 Mask = Value ? (Mask | K) : (Mask & ~K);
190 }
191
192 void set(SanitizerMask K) { Mask = K; }
193
194 /// Disable the sanitizers specified in \p K.
195 void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
196
197 /// Returns true if no sanitizers are enabled.
198 bool empty() const { return !Mask; }
199
200 /// Bitmask of enabled sanitizers.
202};
203
204/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
205/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
206SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
207
208/// Parse a single weighted value (e.g., 'undefined=0.05') from a -fsanitize= or
209/// -fno-sanitize= value list.
210/// The relevant weight(s) are updated in the passed Cutoffs parameter.
211/// Individual Cutoffs are never reset to zero unless explicitly set
212/// (e.g., 'null=0.0').
213/// Returns \c false if \p Value is not known or the weight is not valid.
214bool parseSanitizerWeightedValue(StringRef Value, bool AllowGroups,
215 SanitizerMaskCutoffs &Cutoffs);
216
217/// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
220
221/// Serialize a SanitizerMaskCutoffs into values for -fsanitize= or
222/// -fno-sanitize=.
225
226/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
227/// this group enables.
229
230/// Return the sanitizers which do not affect preprocessing.
232 return SanitizerKind::CFI | SanitizerKind::Integer |
233 SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
234 SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero;
235}
236
237StringRef AsanDtorKindToString(llvm::AsanDtorKind kind);
238
239llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind);
240
242 llvm::AsanDetectStackUseAfterReturnMode mode);
243
244llvm::AsanDetectStackUseAfterReturnMode
246
247} // namespace clang
248
249#endif // LLVM_CLANG_BASIC_SANITIZERS_H
#define V(N, I)
Definition: ASTContext.h:3460
#define SM(sm)
Definition: Cuda.cpp:85
enum clang::sema::@1704::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:45
void set(SanitizerMask K, double V)
Definition: Sanitizers.cpp:28
std::optional< double > operator[](unsigned Kind) const
Definition: Sanitizers.cpp:38
std::optional< std::vector< unsigned > > getAllScaled(unsigned ScalingFactor) const
Definition: Sanitizers.cpp:48
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:138
static constexpr bool checkBitPos(const unsigned Pos)
Definition: Sanitizers.h:54
unsigned countPopulation() const
Definition: Sanitizers.cpp:143
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:231
StringRef AsanDtorKindToString(llvm::AsanDtorKind kind)
Definition: Sanitizers.cpp:154
void serializeSanitizerSet(SanitizerSet Set, SmallVectorImpl< StringRef > &Values)
Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
Definition: Sanitizers.cpp:109
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:86
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds)
For each sanitizer group bit set in Kinds, set the bits for sanitizers this group enables.
Definition: Sanitizers.cpp:129
void serializeSanitizerMaskCutoffs(const SanitizerMaskCutoffs &Cutoffs, SmallVectorImpl< std::string > &Values)
Serialize a SanitizerMaskCutoffs into values for -fsanitize= or -fno-sanitize=.
Definition: Sanitizers.cpp:117
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups)
Parse a single value from a -fsanitize= or -fno-sanitize= value list.
Definition: Sanitizers.cpp:76
llvm::hash_code hash_value(const CustomizableOptional< T > &O)
llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind)
Definition: Sanitizers.cpp:166
llvm::AsanDetectStackUseAfterReturnMode AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr)
Definition: Sanitizers.cpp:189
StringRef AsanDetectStackUseAfterReturnModeToString(llvm::AsanDetectStackUseAfterReturnMode mode)
Definition: Sanitizers.cpp:173
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
void set(SanitizerMask K)
Definition: Sanitizers.h:192
void clear(SanitizerMask K=SanitizerKind::All)
Disable the sanitizers specified in K.
Definition: Sanitizers.h:195
void set(SanitizerMask K, bool Value)
Enable or disable a certain (single) sanitizer.
Definition: Sanitizers.h:187
bool empty() const
Returns true if no sanitizers are enabled.
Definition: Sanitizers.h:198
bool has(SanitizerMask K) const
Check if a certain (single) sanitizer is enabled.
Definition: Sanitizers.h:174
SanitizerMask Mask
Bitmask of enabled sanitizers.
Definition: Sanitizers.h:201
bool hasOneOf(SanitizerMask K) const
Check if one or more sanitizers are enabled.
Definition: Sanitizers.h:184
bool has(SanitizerKind::SanitizerOrdinal O) const
Definition: Sanitizers.h:179