1/*
2 * Copyright (c) Facebook, Inc. and its affiliates.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#pragma once
18
19/* These definitions are in a separate file so that they
20 * may be included from C- as well as C++-based projects. */
21
22#include <folly/portability/Config.h>
23
24/**
25 * Portable version check.
26 */
27#ifndef __GNUC_PREREQ
28#if defined __GNUC__ && defined __GNUC_MINOR__
29/* nolint */
30#define __GNUC_PREREQ(maj, min) \
31 ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
32#else
33/* nolint */
34#define __GNUC_PREREQ(maj, min) 0
35#endif
36#endif
37
38// portable version check for clang
39#ifndef __CLANG_PREREQ
40#if defined __clang__ && defined __clang_major__ && defined __clang_minor__
41/* nolint */
42#define __CLANG_PREREQ(maj, min) \
43 ((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
44#else
45/* nolint */
46#define __CLANG_PREREQ(maj, min) 0
47#endif
48#endif
49
50#if defined(__has_builtin)
51#define FOLLY_HAS_BUILTIN(...) __has_builtin(__VA_ARGS__)
52#else
53#define FOLLY_HAS_BUILTIN(...) 0
54#endif
55
56#if defined(__has_feature)
57#define FOLLY_HAS_FEATURE(...) __has_feature(__VA_ARGS__)
58#else
59#define FOLLY_HAS_FEATURE(...) 0
60#endif
61
62/* FOLLY_SANITIZE_ADDRESS is defined to 1 if the current compilation unit
63 * is being compiled with ASAN enabled.
64 *
65 * Beware when using this macro in a header file: this macro may change values
66 * across compilation units if some libraries are built with ASAN enabled
67 * and some built with ASAN disabled. For instance, this may occur, if folly
68 * itself was compiled without ASAN but a downstream project that uses folly is
69 * compiling with ASAN enabled.
70 *
71 * Use FOLLY_LIBRARY_SANITIZE_ADDRESS (defined in folly-config.h) to check if
72 * folly itself was compiled with ASAN enabled.
73 */
74#ifndef FOLLY_SANITIZE_ADDRESS
75#if FOLLY_HAS_FEATURE(address_sanitizer) || __SANITIZE_ADDRESS__
76#define FOLLY_SANITIZE_ADDRESS 1
77#endif
78#endif
79
80/* Define attribute wrapper for function attribute used to disable
81 * address sanitizer instrumentation. Unfortunately, this attribute
82 * has issues when inlining is used, so disable that as well. */
83#ifdef FOLLY_SANITIZE_ADDRESS
84#if defined(__clang__)
85#if __has_attribute(__no_sanitize__)
86#define FOLLY_DISABLE_ADDRESS_SANITIZER \
87 __attribute__((__no_sanitize__("address"), __noinline__))
88#elif __has_attribute(__no_address_safety_analysis__)
89#define FOLLY_DISABLE_ADDRESS_SANITIZER \
90 __attribute__((__no_address_safety_analysis__, __noinline__))
91#elif __has_attribute(__no_sanitize_address__)
92#define FOLLY_DISABLE_ADDRESS_SANITIZER \
93 __attribute__((__no_sanitize_address__, __noinline__))
94#endif
95#elif defined(__GNUC__)
96#define FOLLY_DISABLE_ADDRESS_SANITIZER \
97 __attribute__((__no_address_safety_analysis__, __noinline__))
98#endif
99#endif
100#ifndef FOLLY_DISABLE_ADDRESS_SANITIZER
101#define FOLLY_DISABLE_ADDRESS_SANITIZER
102#endif
103
104/* Define a convenience macro to test when thread sanitizer is being used
105 * across the different compilers (e.g. clang, gcc) */
106#ifndef FOLLY_SANITIZE_THREAD
107#if FOLLY_HAS_FEATURE(thread_sanitizer) || __SANITIZE_THREAD__
108#define FOLLY_SANITIZE_THREAD 1
109#endif
110#endif
111
112#if FOLLY_SANITIZE_THREAD
113#define FOLLY_DISABLE_THREAD_SANITIZER \
114 __attribute__((no_sanitize_thread, noinline))
115#else
116#define FOLLY_DISABLE_THREAD_SANITIZER
117#endif
118
119/**
120 * Define a convenience macro to test when memory sanitizer is being used
121 * across the different compilers (e.g. clang, gcc)
122 */
123#ifndef FOLLY_SANITIZE_MEMORY
124#if FOLLY_HAS_FEATURE(memory_sanitizer) || __SANITIZE_MEMORY__
125#define FOLLY_SANITIZE_MEMORY 1
126#endif
127#endif
128
129#if FOLLY_SANITIZE_MEMORY
130#define FOLLY_DISABLE_MEMORY_SANITIZER \
131 __attribute__((no_sanitize_memory, noinline))
132#else
133#define FOLLY_DISABLE_MEMORY_SANITIZER
134#endif
135
136/**
137 * Define a convenience macro to test when ASAN, UBSAN, TSAN or MSAN sanitizer
138 * are being used
139 */
140#ifndef FOLLY_SANITIZE
141#if defined(FOLLY_SANITIZE_ADDRESS) || defined(FOLLY_SANITIZE_THREAD) || \
142 defined(FOLLY_SANITIZE_MEMORY)
143#define FOLLY_SANITIZE 1
144#endif
145#endif
146
147#if FOLLY_SANITIZE
148#define FOLLY_DISABLE_UNDEFINED_BEHAVIOR_SANITIZER(...) \
149 __attribute__((no_sanitize(__VA_ARGS__)))
150#else
151#define FOLLY_DISABLE_UNDEFINED_BEHAVIOR_SANITIZER(...)
152#endif // FOLLY_SANITIZE
153
154#define FOLLY_DISABLE_SANITIZERS \
155 FOLLY_DISABLE_ADDRESS_SANITIZER FOLLY_DISABLE_THREAD_SANITIZER \
156 FOLLY_DISABLE_UNDEFINED_BEHAVIOR_SANITIZER("undefined")
157
158/**
159 * Macro for marking functions as having public visibility.
160 */
161#if defined(__GNUC__)
162#define FOLLY_EXPORT __attribute__((__visibility__("default")))
163#else
164#define FOLLY_EXPORT
165#endif
166
167// noinline
168#ifdef _MSC_VER
169#define FOLLY_NOINLINE __declspec(noinline)
170#elif defined(__GNUC__)
171#define FOLLY_NOINLINE __attribute__((__noinline__))
172#else
173#define FOLLY_NOINLINE
174#endif
175
176// always inline
177#ifdef _MSC_VER
178#define FOLLY_ALWAYS_INLINE __forceinline
179#elif defined(__GNUC__)
180#define FOLLY_ALWAYS_INLINE inline __attribute__((__always_inline__))
181#else
182#define FOLLY_ALWAYS_INLINE inline
183#endif
184
185// attribute hidden
186#if defined(_MSC_VER)
187#define FOLLY_ATTR_VISIBILITY_HIDDEN
188#elif defined(__GNUC__)
189#define FOLLY_ATTR_VISIBILITY_HIDDEN __attribute__((__visibility__("hidden")))
190#else
191#define FOLLY_ATTR_VISIBILITY_HIDDEN
192#endif
193
194// An attribute for marking symbols as weak, if supported
195#if FOLLY_HAVE_WEAK_SYMBOLS
196#define FOLLY_ATTR_WEAK __attribute__((__weak__))
197#else
198#define FOLLY_ATTR_WEAK
199#endif
200
201// Microsoft ABI version (can be overridden manually if necessary)
202#ifndef FOLLY_MICROSOFT_ABI_VER
203#ifdef _MSC_VER
204#define FOLLY_MICROSOFT_ABI_VER _MSC_VER
205#endif
206#endif
207
208// FOLLY_ERASE
209//
210// A conceptual attribute/syntax combo for erasing a function from the build
211// artifacts and forcing all call-sites to inline the callee, at least as far
212// as each compiler supports.
213//
214// Semantically includes the inline specifier.
215#define FOLLY_ERASE FOLLY_ALWAYS_INLINE FOLLY_ATTR_VISIBILITY_HIDDEN
216
217// FOLLY_ERASE_HACK_GCC
218//
219// Equivalent to FOLLY_ERASE, but without hiding under gcc. Useful when applied
220// to a function which may sometimes be hidden separately, for example by being
221// declared in an anonymous namespace, since in such cases with -Wattributes
222// enabled, gcc would emit: 'visibility' attribute ignored.
223//
224// Semantically includes the inline specifier.
225#if defined(__GNUC__) && !defined(__clang__)
226#define FOLLY_ERASE_HACK_GCC FOLLY_ALWAYS_INLINE
227#else
228#define FOLLY_ERASE_HACK_GCC FOLLY_ERASE
229#endif
230
231// FOLLY_ERASE_TRYCATCH
232//
233// Equivalent to FOLLY_ERASE, but for code which might contain explicit
234// exception handling. Has the effect of FOLLY_ERASE, except under MSVC which
235// warns about __forceinline when functions contain exception handling.
236//
237// Semantically includes the inline specifier.
238#ifdef _MSC_VER
239#define FOLLY_ERASE_TRYCATCH inline
240#else
241#define FOLLY_ERASE_TRYCATCH FOLLY_ERASE
242#endif
243