//===- Sanitizers.h - C Language Family Language Options --------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines the clang::SanitizerKind enum.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_BASIC_SANITIZERS_H
#define LLVM_CLANG_BASIC_SANITIZERS_H

#include "clang/Basic/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/HashBuilder.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include <cassert>
#include <cstdint>

namespace llvm {
class hash_code;
}

namespace clang {

class SanitizerMask {
  // NOTE: this class assumes kNumElem == 2 in most of the constexpr functions,
  // in order to work within the C++11 constexpr function constraints. If you
  // change kNumElem, you'll need to update those member functions as well.

  /// Number of array elements.
  static constexpr unsigned kNumElem = 2;
  /// Mask value initialized to 0.
  uint64_t maskLoToHigh[kNumElem]{};
  /// Number of bits in a mask.
  static constexpr unsigned kNumBits = sizeof(decltype(maskLoToHigh)) * 8;
  /// Number of bits in a mask element.
  static constexpr unsigned kNumBitElem = sizeof(decltype(maskLoToHigh[0])) * 8;

  constexpr SanitizerMask(uint64_t mask1, uint64_t mask2)
      : maskLoToHigh{mask1, mask2} {}

public:
  SanitizerMask() = default;

  static constexpr bool checkBitPos(const unsigned Pos) {
    return Pos < kNumBits;
  }

  /// Create a mask with a bit enabled at position Pos.
  static constexpr SanitizerMask bitPosToMask(const unsigned Pos) {
    uint64_t mask1 = (Pos < kNumBitElem) ? 1ULL << (Pos % kNumBitElem) : 0;
    uint64_t mask2 = (Pos >= kNumBitElem && Pos < (kNumBitElem * 2))
                         ? 1ULL << (Pos % kNumBitElem)
                         : 0;
    return SanitizerMask(mask1, mask2);
  }

  unsigned countPopulation() const;

  void flipAllBits() {
    for (auto &Val : maskLoToHigh)
      Val = ~Val;
  }

  bool isPowerOf2() const {
    return countPopulation() == 1;
  }

  llvm::hash_code hash_value() const;

  template <typename HasherT, llvm::support::endianness Endianness>
  friend void addHash(llvm::HashBuilderImpl<HasherT, Endianness> &HBuilder,
                      const SanitizerMask &SM) {
    HBuilder.addRange(&SM.maskLoToHigh[0], &SM.maskLoToHigh[kNumElem]);
  }

  constexpr explicit operator bool() const {
    return maskLoToHigh[0] || maskLoToHigh[1];
  }

  constexpr bool operator==(const SanitizerMask &V) const {
    return maskLoToHigh[0] == V.maskLoToHigh[0] &&
           maskLoToHigh[1] == V.maskLoToHigh[1];
  }

  SanitizerMask &operator&=(const SanitizerMask &RHS) {
    for (unsigned k = 0; k < kNumElem; k++)
      maskLoToHigh[k] &= RHS.maskLoToHigh[k];
    return *this;
  }

  SanitizerMask &operator|=(const SanitizerMask &RHS) {
    for (unsigned k = 0; k < kNumElem; k++)
      maskLoToHigh[k] |= RHS.maskLoToHigh[k];
    return *this;
  }

  constexpr bool operator!() const { return !bool(*this); }

  constexpr bool operator!=(const SanitizerMask &RHS) const {
    return !((*this) == RHS);
  }

  friend constexpr inline SanitizerMask operator~(SanitizerMask v) {
    return SanitizerMask(~v.maskLoToHigh[0], ~v.maskLoToHigh[1]);
  }

  friend constexpr inline SanitizerMask operator&(SanitizerMask a,
                                                  const SanitizerMask &b) {
    return SanitizerMask(a.maskLoToHigh[0] & b.maskLoToHigh[0],
                         a.maskLoToHigh[1] & b.maskLoToHigh[1]);
  }

  friend constexpr inline SanitizerMask operator|(SanitizerMask a,
                                                  const SanitizerMask &b) {
    return SanitizerMask(a.maskLoToHigh[0] | b.maskLoToHigh[0],
                         a.maskLoToHigh[1] | b.maskLoToHigh[1]);
  }
};

// Declaring in clang namespace so that it can be found by ADL.
llvm::hash_code hash_value(const clang::SanitizerMask &Arg);

// Define the set of sanitizer kinds, as well as the set of sanitizers each
// sanitizer group expands into.
struct SanitizerKind {
  // Assign ordinals to possible values of -fsanitize= flag, which we will use
  // as bit positions.
  enum SanitizerOrdinal : uint64_t {
#define SANITIZER(NAME, ID) SO_##ID,
#define SANITIZER_GROUP(NAME, ID, ALIAS) SO_##ID##Group,
#include "clang/Basic/Sanitizers.def"
    SO_Count
  };

#define SANITIZER(NAME, ID)                                                    \
  static constexpr SanitizerMask ID = SanitizerMask::bitPosToMask(SO_##ID);    \
  static_assert(SanitizerMask::checkBitPos(SO_##ID), "Bit position too big.");
#define SANITIZER_GROUP(NAME, ID, ALIAS)                                       \
  static constexpr SanitizerMask ID = SanitizerMask(ALIAS);                    \
  static constexpr SanitizerMask ID##Group =                                   \
      SanitizerMask::bitPosToMask(SO_##ID##Group);                             \
  static_assert(SanitizerMask::checkBitPos(SO_##ID##Group),                    \
                "Bit position too big.");
#include "clang/Basic/Sanitizers.def"
}; // SanitizerKind

struct SanitizerSet {
  /// Check if a certain (single) sanitizer is enabled.
  bool has(SanitizerMask K) const {
    assert(K.isPowerOf2() && "Has to be a single sanitizer.");
    return static_cast<bool>(Mask & K);
  }

  /// Check if one or more sanitizers are enabled.
  bool hasOneOf(SanitizerMask K) const { return static_cast<bool>(Mask & K); }

  /// Enable or disable a certain (single) sanitizer.
  void set(SanitizerMask K, bool Value) {
    assert(K.isPowerOf2() && "Has to be a single sanitizer.");
    Mask = Value ? (Mask | K) : (Mask & ~K);
  }

  /// Disable the sanitizers specified in \p K.
  void clear(SanitizerMask K = SanitizerKind::All) { Mask &= ~K; }

  /// Returns true if no sanitizers are enabled.
  bool empty() const { return !Mask; }

  /// Bitmask of enabled sanitizers.
  SanitizerMask Mask;
};

/// Parse a single value from a -fsanitize= or -fno-sanitize= value list.
/// Returns a non-zero SanitizerMask, or \c 0 if \p Value is not known.
SanitizerMask parseSanitizerValue(StringRef Value, bool AllowGroups);

/// Serialize a SanitizerSet into values for -fsanitize= or -fno-sanitize=.
void serializeSanitizerSet(SanitizerSet Set,
                           SmallVectorImpl<StringRef> &Values);

/// For each sanitizer group bit set in \p Kinds, set the bits for sanitizers
/// this group enables.
SanitizerMask expandSanitizerGroups(SanitizerMask Kinds);

/// Return the sanitizers which do not affect preprocessing.
inline SanitizerMask getPPTransparentSanitizers() {
  return SanitizerKind::CFI | SanitizerKind::Integer |
         SanitizerKind::ImplicitConversion | SanitizerKind::Nullability |
         SanitizerKind::Undefined | SanitizerKind::FloatDivideByZero;
}

StringRef AsanDtorKindToString(llvm::AsanDtorKind kind);

llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind);

StringRef AsanDetectStackUseAfterReturnModeToString(
    llvm::AsanDetectStackUseAfterReturnMode mode);

llvm::AsanDetectStackUseAfterReturnMode
AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr);

} // namespace clang

#endif // LLVM_CLANG_BASIC_SANITIZERS_H
