1//===--- Sanitizers.h - C Language Family Language Options ------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Defines the clang::SanitizerKind enum.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
16#define LLVM_CLANG_BASIC_SANITIZERS_H
17
18#include "clang/Basic/LLVM.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/MathExtras.h"
21
22namespace clang {
23
24typedef uint64_t SanitizerMask;
25
26namespace SanitizerKind {
27
28// Assign ordinals to possible values of -fsanitize= flag, which we will use as
29// bit positions.
30enum SanitizerOrdinal : uint64_t {
31#define SANITIZER(NAME, ID) SO_##ID,
32#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
33#include "clang/Basic/Sanitizers.def"
34  SO_Count
35};
36
37// Define the set of sanitizer kinds, as well as the set of sanitizers each
38// sanitizer group expands into.
39#define SANITIZER(NAME, ID) \
40  const SanitizerMask ID = 1ULL << SO_##ID;
41#define SANITIZER_GROUP(NAME, ID, ALIAS) \
42  const SanitizerMask ID = ALIAS; \
43  const SanitizerMask ID##Group = 1ULL << SO_##ID##Group;
44#include "clang/Basic/Sanitizers.def"
45
46}
47
48struct SanitizerSet {
49  /// \brief Check if a certain (single) sanitizer is enabled.
50  bool has(SanitizerMask K) const {
51    assert(llvm::isPowerOf2_64(K));
52    return Mask & K;
53  }
54
55  /// \brief Check if one or more sanitizers are enabled.
56  bool hasOneOf(SanitizerMask K) const { return Mask & K; }
57
58  /// \brief Enable or disable a certain (single) sanitizer.
59  void set(SanitizerMask K, bool Value) {
60    assert(llvm::isPowerOf2_64(K));
61    Mask = Value ? (Mask | K) : (Mask & ~K);
62  }
63
64  /// Disable the sanitizers specified in \p K.
65  void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }
66
67  /// \brief Returns true if at least one sanitizer is enabled.
68  bool empty() const { return Mask == 0; }
69
70  /// \brief Bitmask of enabled sanitizers.
71  SanitizerMask Mask = 0;
72};
73
74/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
75/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
76SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);
77
78/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
79/// this group enables.
80SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);
81
82/// Return the sanitizers which do not affect preprocessing.
83static inline SanitizerMask getPPTransparentSanitizers() {
84  return SanitizerKind::CFI | SanitizerKind::Integer |
85         SanitizerKind::Nullability | SanitizerKind::Undefined;
86}
87
88}  // end namespace clang
89
90#endif
91