mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-12-16 19:32:07 +00:00
125 lines
3.9 KiB
C++
125 lines
3.9 KiB
C++
#pragma once
|
|
|
|
/// __has_feature supported only by clang.
|
|
///
|
|
/// But libcxx/libcxxabi overrides it to 0,
|
|
/// thus the checks for __has_feature will be wrong.
|
|
///
|
|
/// NOTE:
|
|
/// - __has_feature cannot be simply undefined,
|
|
/// since this will be broken if some C++ header will be included after
|
|
/// including <common/defines.h>
|
|
/// - it should not have fallback to 0,
|
|
/// since this may create false-positive detection (common problem)
|
|
#if defined(__clang__) && defined(__has_feature)
|
|
# define ch_has_feature __has_feature
|
|
#endif
|
|
|
|
#if defined(_MSC_VER)
|
|
# if !defined(likely)
|
|
# define likely(x) (x)
|
|
# endif
|
|
# if !defined(unlikely)
|
|
# define unlikely(x) (x)
|
|
# endif
|
|
#else
|
|
# if !defined(likely)
|
|
# define likely(x) (__builtin_expect(!!(x), 1))
|
|
# endif
|
|
# if !defined(unlikely)
|
|
# define unlikely(x) (__builtin_expect(!!(x), 0))
|
|
# endif
|
|
#endif
|
|
|
|
#if defined(_MSC_VER)
|
|
# define ALWAYS_INLINE __forceinline
|
|
# define NO_INLINE static __declspec(noinline)
|
|
# define MAY_ALIAS
|
|
#else
|
|
# define ALWAYS_INLINE __attribute__((__always_inline__))
|
|
# define NO_INLINE __attribute__((__noinline__))
|
|
# define MAY_ALIAS __attribute__((__may_alias__))
|
|
#endif
|
|
|
|
#if !defined(__x86_64__) && !defined(__aarch64__) && !defined(__PPC__)
|
|
# error "The only supported platforms are x86_64 and AArch64, PowerPC (work in progress)"
|
|
#endif
|
|
|
|
/// Check for presence of address sanitizer
|
|
#if !defined(ADDRESS_SANITIZER)
|
|
# if defined(ch_has_feature)
|
|
# if ch_has_feature(address_sanitizer)
|
|
# define ADDRESS_SANITIZER 1
|
|
# endif
|
|
# elif defined(__SANITIZE_ADDRESS__)
|
|
# define ADDRESS_SANITIZER 1
|
|
# endif
|
|
#endif
|
|
|
|
#if !defined(THREAD_SANITIZER)
|
|
# if defined(ch_has_feature)
|
|
# if ch_has_feature(thread_sanitizer)
|
|
# define THREAD_SANITIZER 1
|
|
# endif
|
|
# elif defined(__SANITIZE_THREAD__)
|
|
# define THREAD_SANITIZER 1
|
|
# endif
|
|
#endif
|
|
|
|
#if !defined(MEMORY_SANITIZER)
|
|
# if defined(ch_has_feature)
|
|
# if ch_has_feature(memory_sanitizer)
|
|
# define MEMORY_SANITIZER 1
|
|
# endif
|
|
# elif defined(__MEMORY_SANITIZER__)
|
|
# define MEMORY_SANITIZER 1
|
|
# endif
|
|
#endif
|
|
|
|
#if !defined(UNDEFINED_BEHAVIOR_SANITIZER)
|
|
# if defined(__has_feature)
|
|
# if __has_feature(undefined_behavior_sanitizer)
|
|
# define UNDEFINED_BEHAVIOR_SANITIZER 1
|
|
# endif
|
|
# elif defined(__UNDEFINED_BEHAVIOR_SANITIZER__)
|
|
# define UNDEFINED_BEHAVIOR_SANITIZER 1
|
|
# endif
|
|
#endif
|
|
|
|
#if defined(ADDRESS_SANITIZER)
|
|
# define BOOST_USE_ASAN 1
|
|
# define BOOST_USE_UCONTEXT 1
|
|
#endif
|
|
|
|
#if defined(THREAD_SANITIZER)
|
|
# define BOOST_USE_TSAN 1
|
|
# define BOOST_USE_UCONTEXT 1
|
|
#endif
|
|
|
|
#if defined(ARCADIA_BUILD) && defined(BOOST_USE_UCONTEXT)
|
|
# undef BOOST_USE_UCONTEXT
|
|
#endif
|
|
|
|
/// TODO: Strange enough, there is no way to detect UB sanitizer.
|
|
|
|
/// Explicitly allow undefined behaviour for certain functions. Use it as a function attribute.
|
|
/// It is useful in case when compiler cannot see (and exploit) it, but UBSan can.
|
|
/// Example: multiplication of signed integers with possibility of overflow when both sides are from user input.
|
|
#if defined(__clang__)
|
|
# define NO_SANITIZE_UNDEFINED __attribute__((__no_sanitize__("undefined")))
|
|
# define NO_SANITIZE_ADDRESS __attribute__((__no_sanitize__("address")))
|
|
# define NO_SANITIZE_THREAD __attribute__((__no_sanitize__("thread")))
|
|
# define ALWAYS_INLINE_NO_SANITIZE_UNDEFINED __attribute__((__always_inline__, __no_sanitize__("undefined")))
|
|
#else /// It does not work in GCC. GCC 7 cannot recognize this attribute and GCC 8 simply ignores it.
|
|
# define NO_SANITIZE_UNDEFINED
|
|
# define NO_SANITIZE_ADDRESS
|
|
# define NO_SANITIZE_THREAD
|
|
# define ALWAYS_INLINE_NO_SANITIZE_UNDEFINED ALWAYS_INLINE
|
|
#endif
|
|
|
|
/// A template function for suppressing warnings about unused variables or function results.
|
|
template <typename... Args>
|
|
constexpr void UNUSED(Args &&... args [[maybe_unused]])
|
|
{
|
|
}
|