folly/folly/lang/SafeAssert.h

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <cstdint>
#include <utility>

#include <folly/CppAttributes.h>
#include <folly/Portability.h>
#include <folly/Preprocessor.h>
#include <folly/lang/CArray.h>

#define FOLLY_DETAIL_SAFE_CHECK_IMPL(d, p, u, expr, ...)

//  FOLLY_SAFE_CHECK
//
//  If expr evaluates to false after explicit conversion to bool, prints context
//  information to stderr and aborts. Context information includes the remaining
//  variadic arguments.
//
//  When the remaining variadic arguments are printed to stderr, there are two
//  supported types after implicit conversions: char const* and uint64_t. This
//  facility is intentionally not extensible to custom types.
//
//  multi-thread-safe
//  async-signal-safe
#define FOLLY_SAFE_CHECK(expr, ...)

//  FOLLY_SAFE_DCHECK
//
//  Equivalent to FOLLY_SAFE_CHECK when in debug or instrumented builds, where
//  debug builds are signalled by NDEBUG being undefined and instrumented builds
//  include sanitizer builds.
//
//  multi-thread-safe
//  async-signal-safe
#define FOLLY_SAFE_DCHECK(expr, ...)

//  FOLLY_SAFE_PCHECK
//
//  Equivalent to FOLLY_SAFE_CHECK but includes errno in the contextual
//  information printed to stderr.
//
//  multi-thread-safe
//  async-signal-safe
#define FOLLY_SAFE_PCHECK(expr, ...)

//  FOLLY_SAFE_DPCHECK
//
//  Equivalent to FOLLY_SAFE_DCHECK but includes errno in the contextual
//  information printed to stderr.
//
//  multi-thread-safe
//  async-signal-safe
#define FOLLY_SAFE_DPCHECK(expr, ...)

//  FOLLY_SAFE_FATAL
//
//  Equivalent to FOLLY_SAFE_CHECK(false, ...) but excludes any failing
//  expression from the contextual information printed to stderr.
//
//  multi-thread-safe
//  async-signal-safe
#define FOLLY_SAFE_FATAL(...)

//  FOLLY_SAFE_DFATAL
//
//  Equivalent to FOLLY_SAFE_DCHECK(false, ...) but excludes any failing
//  expression from the contextual information printed to stderr.
//
//  multi-thread-safe
//  async-signal-safe
#define FOLLY_SAFE_DFATAL(...)

namespace folly {
namespace detail {

enum class safe_assert_msg_type : char {};

template <safe_assert_msg_type... A>
struct safe_assert_msg_type_s {};

struct safe_assert_msg_types_one_fn {};
inline constexpr safe_assert_msg_types_one_fn
    safe_assert_msg_types_one{}; // a function object to prevent extensions

template <typename... A>
safe_assert_msg_type_s<decltype(safe_assert_msg_types_one((A)A{}; // only used in unevaluated contexts

template <typename>
struct safe_assert_msg_types;
safe_assert_msg_types<safe_assert_msg_type_s<A...>>;

struct safe_assert_arg {};

struct safe_assert_msg_cast_one_fn {};
inline constexpr safe_assert_msg_cast_one_fn
    safe_assert_msg_cast_one{}; // a function object to prevent extensions

template <bool P>
[[noreturn, FOLLY_ATTR_GNU_COLD]] FOLLY_NOINLINE void safe_assert_terminate(
    safe_assert_arg const* arg, ...) noexcept; // the true backing function

template <bool P>
struct safe_assert_terminate_w {};

} // namespace detail
} // namespace folly