1 //===- Sanitizers.cpp - C Language Family Language Options ----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the classes from Sanitizers.h
11 //===----------------------------------------------------------------------===//
13 #include "clang/Basic/Sanitizers.h"
14 #include "llvm/ADT/Hashing.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/Support/MathExtras.h"
19 using namespace clang
;
21 // Once LLVM switches to C++17, the constexpr variables can be inline and we
23 #define SANITIZER(NAME, ID) constexpr SanitizerMask SanitizerKind::ID;
24 #define SANITIZER_GROUP(NAME, ID, ALIAS) \
25 constexpr SanitizerMask SanitizerKind::ID; \
26 constexpr SanitizerMask SanitizerKind::ID##Group;
27 #include "clang/Basic/Sanitizers.def"
29 SanitizerMask
clang::parseSanitizerValue(StringRef Value
, bool AllowGroups
) {
30 SanitizerMask ParsedKind
= llvm::StringSwitch
<SanitizerMask
>(Value
)
31 #define SANITIZER(NAME, ID) .Case(NAME, SanitizerKind::ID)
32 #define SANITIZER_GROUP(NAME, ID, ALIAS) \
33 .Case(NAME, AllowGroups ? SanitizerKind::ID##Group : SanitizerMask())
34 #include "clang/Basic/Sanitizers.def"
35 .Default(SanitizerMask());
39 void clang::serializeSanitizerSet(SanitizerSet Set
,
40 SmallVectorImpl
<StringRef
> &Values
) {
41 #define SANITIZER(NAME, ID) \
42 if (Set.has(SanitizerKind::ID)) \
43 Values.push_back(NAME);
44 #include "clang/Basic/Sanitizers.def"
47 SanitizerMask
clang::expandSanitizerGroups(SanitizerMask Kinds
) {
48 #define SANITIZER(NAME, ID)
49 #define SANITIZER_GROUP(NAME, ID, ALIAS) \
50 if (Kinds & SanitizerKind::ID##Group) \
51 Kinds |= SanitizerKind::ID;
52 #include "clang/Basic/Sanitizers.def"
56 llvm::hash_code
SanitizerMask::hash_value() const {
57 return llvm::hash_combine_range(&maskLoToHigh
[0], &maskLoToHigh
[kNumElem
]);
61 unsigned SanitizerMask::countPopulation() const {
63 for (const auto &Val
: maskLoToHigh
)
64 total
+= llvm::popcount(Val
);
68 llvm::hash_code
hash_value(const clang::SanitizerMask
&Arg
) {
69 return Arg
.hash_value();
72 StringRef
AsanDtorKindToString(llvm::AsanDtorKind kind
) {
74 case llvm::AsanDtorKind::None
:
76 case llvm::AsanDtorKind::Global
:
78 case llvm::AsanDtorKind::Invalid
:
84 llvm::AsanDtorKind
AsanDtorKindFromString(StringRef kindStr
) {
85 return llvm::StringSwitch
<llvm::AsanDtorKind
>(kindStr
)
86 .Case("none", llvm::AsanDtorKind::None
)
87 .Case("global", llvm::AsanDtorKind::Global
)
88 .Default(llvm::AsanDtorKind::Invalid
);
91 StringRef
AsanDetectStackUseAfterReturnModeToString(
92 llvm::AsanDetectStackUseAfterReturnMode mode
) {
94 case llvm::AsanDetectStackUseAfterReturnMode::Always
:
96 case llvm::AsanDetectStackUseAfterReturnMode::Runtime
:
98 case llvm::AsanDetectStackUseAfterReturnMode::Never
:
100 case llvm::AsanDetectStackUseAfterReturnMode::Invalid
:
106 llvm::AsanDetectStackUseAfterReturnMode
107 AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr
) {
108 return llvm::StringSwitch
<llvm::AsanDetectStackUseAfterReturnMode
>(modeStr
)
109 .Case("always", llvm::AsanDetectStackUseAfterReturnMode::Always
)
110 .Case("runtime", llvm::AsanDetectStackUseAfterReturnMode::Runtime
)
111 .Case("never", llvm::AsanDetectStackUseAfterReturnMode::Never
)
112 .Default(llvm::AsanDetectStackUseAfterReturnMode::Invalid
);