MySQL 8.0.37
Source Code Documentation
my_compiler.h
Go to the documentation of this file.
1#ifndef MY_COMPILER_INCLUDED
2#define MY_COMPILER_INCLUDED
3
4/* Copyright (c) 2010, 2024, Oracle and/or its affiliates.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License, version 2.0,
8 as published by the Free Software Foundation.
9
10 This program is designed to work with certain software (including
11 but not limited to OpenSSL) that is licensed under separate terms,
12 as designated in a particular file or component or in included license
13 documentation. The authors of MySQL hereby grant you an additional
14 permission to link the program and your derivative works with the
15 separately licensed software that they have either included with
16 the program or referenced in the documentation.
17
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License, version 2.0, for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
26
27/**
28 @file include/my_compiler.h
29 Header for compiler-dependent features.
30
31 Intended to contain a set of reusable wrappers for preprocessor
32 macros, attributes, pragmas, and any other features that are
33 specific to a target compiler.
34*/
35
36#ifndef MYSQL_ABI_CHECK
37#include <assert.h>
38#include <stddef.h> /* size_t */
39#endif
40
41#include "my_config.h"
42
43/*
44 The macros below are borrowed from include/linux/compiler.h in the
45 Linux kernel. Use them to indicate the likelihood of the truthfulness
46 of a condition. This serves two purposes - newer versions of gcc will be
47 able to optimize for branch predication, which could yield significant
48 performance gains in frequently executed sections of the code, and the
49 other reason to use them is for documentation
50*/
51#ifdef HAVE_BUILTIN_EXPECT
52
53// likely/unlikely are likely to clash with other symbols, do not #define
54#if defined(__cplusplus)
55constexpr bool likely(bool expr) { return __builtin_expect(expr, true); }
56constexpr bool unlikely(bool expr) { return __builtin_expect(expr, false); }
57#else
58#define likely(x) __builtin_expect((x), 1)
59#define unlikely(x) __builtin_expect((x), 0)
60#endif
61
62#else /* HAVE_BUILTIN_EXPECT */
63
64#if defined(__cplusplus)
65constexpr bool likely(bool expr) { return expr; }
66constexpr bool unlikely(bool expr) { return expr; }
67#else
68#define likely(x) (x)
69#define unlikely(x) (x)
70#endif
71
72#endif /* HAVE_BUILTIN_EXPECT */
73
74/* Communicate to the compiler the unreachability of the code. */
75#ifdef HAVE_BUILTIN_UNREACHABLE
76#define MY_ASSERT_UNREACHABLE() __builtin_unreachable()
77#else
78#define MY_ASSERT_UNREACHABLE() \
79 do { \
80 assert(0); \
81 } while (0)
82#endif
83
84/* Visual Studio requires '__inline' for C code */
85#if !defined(__cplusplus) && defined(_MSC_VER)
86#define inline __inline
87#endif
88
89/* Provide __func__ macro definition for Visual Studio. */
90#if defined(_MSC_VER)
91#define __func__ __FUNCTION__
92#endif
93
94/*
95 Disable MY_ATTRIBUTE for Sun Studio and Visual Studio.
96 Note that Sun Studio supports some __attribute__ variants,
97 but not format or unused which we use quite a lot.
98*/
99#ifndef MY_ATTRIBUTE
100#if defined(__GNUC__) || defined(__clang__)
101#define MY_ATTRIBUTE(A) __attribute__(A)
102#else
103#define MY_ATTRIBUTE(A)
104#endif
105#endif
106
107#if defined(_MSC_VER)
108#define ALWAYS_INLINE __forceinline
109#else
110#define ALWAYS_INLINE __attribute__((always_inline)) inline
111#endif
112
113#if defined(_MSC_VER)
114#define NO_INLINE __declspec(noinline)
115#else
116#define NO_INLINE __attribute__((noinline))
117#endif
118
119#ifndef __has_attribute
120#define __has_attribute(x) 0
121#endif
122
123#ifndef SUPPRESS_UBSAN
124// clang -fsanitize=undefined
125#if defined(HAVE_UBSAN) && defined(__clang__)
126#define SUPPRESS_UBSAN MY_ATTRIBUTE((no_sanitize("undefined")))
127#if (__clang_major__ >= 10)
128#define SUPPRESS_UBSAN_CLANG10 MY_ATTRIBUTE((no_sanitize("undefined")))
129#endif
130// gcc -fsanitize=undefined
131#elif defined(HAVE_UBSAN) && __has_attribute(no_sanitize_undefined)
132#define SUPPRESS_UBSAN MY_ATTRIBUTE((no_sanitize_undefined))
133#else
134#define SUPPRESS_UBSAN
135#endif
136#endif /* SUPPRESS_UBSAN */
137
138// TODO(tdidriks) Fix new 'applying offset to null pointer' warnings.
139#ifndef SUPPRESS_UBSAN_CLANG10
140#define SUPPRESS_UBSAN_CLANG10
141#endif
142
143#ifndef SUPPRESS_TSAN
144#if defined(HAVE_TSAN) && defined(__clang__)
145#define SUPPRESS_TSAN MY_ATTRIBUTE((no_sanitize("thread")))
146#elif defined(HAVE_TSAN) && __has_attribute(no_sanitize_thread)
147#define SUPPRESS_TSAN MY_ATTRIBUTE((no_sanitize_thread))
148#else
149#define SUPPRESS_TSAN
150#endif
151#endif /* SUPPRESS_TSAN */
152
153#ifdef _WIN32
154#define STDCALL __stdcall
155#else
156#define STDCALL
157#endif
158
159/**
160 * stringify parameters for C99/C++11 _Pragma().
161 */
162#define MY_COMPILER_CPP11_PRAGMA(X) _Pragma(#X)
163/**
164 * pass parameters to MSVC's __pragma() as is.
165 */
166#define MY_COMPILER_MSVC_PRAGMA(X) __pragma(X)
167
168// enable compiler specified 'diagnostic' pragmas.
169//
170// 1. clang on windows defines both clang and msvc pragmas and generates the
171// same warnings
172// 2. clang defines both __clang__ and __GNUC__, but doesn't support all GCC
173// warnings with the same name
174//
175// +---------------------+
176// | enabled diagnostics |
177// +------+-------+------+
178// | gcc | clang | msvc |
179// +-------+------+-------+------+
180// | gcc | x | - | - |
181// | clang | - | x | x |
182// | msvc | - | - | x |
183// +-------+------+-------+------+
184// ^^^
185// +----- current compiler
186//
187// suppressions that aren't supported by the compiler are disabled to avoid
188// "unsupported pragmas" warnings:
189//
190// @code
191// // on GCC, clang-specific diagnostic pragmas are disabled
192// MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wdocumentation")
193// @endcode
194
195#if defined(__clang__)
196#define MY_COMPILER_CLANG_DIAGNOSTIC_PUSH() \
197 MY_COMPILER_CPP11_PRAGMA(clang diagnostic push)
198#define MY_COMPILER_CLANG_DIAGNOSTIC_POP() \
199 MY_COMPILER_CPP11_PRAGMA(clang diagnostic pop)
200/**
201 * ignore a compiler warning.
202 *
203 * @param X warning option to disable, must be quoted like "-Wdocumentation"
204 */
205#define MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE(X) \
206 MY_COMPILER_CPP11_PRAGMA(clang diagnostic ignored X)
207/**
208 * turn a compiler warning into an error.
209 *
210 * @param X warning option to turn into an error, must be a quoted string like
211 * "-Wdocumentation"
212 */
213#define MY_COMPILER_CLANG_DIAGNOSTIC_ERROR(X) \
214 MY_COMPILER_CPP11_PRAGMA(clang diagnostic error X)
215
216#elif defined(__GNUC__)
217#define MY_COMPILER_GCC_DIAGNOSTIC_PUSH() \
218 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic push)
219#define MY_COMPILER_GCC_DIAGNOSTIC_POP() \
220 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic pop)
221/**
222 * ignore a compiler warning.
223 *
224 * @param X warning option to disable, must be quoted like "-Wdocumentation"
225 */
226#define MY_COMPILER_GCC_DIAGNOSTIC_IGNORE(X) \
227 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic ignored X)
228/**
229 * turn a compiler warning into an error.
230 *
231 * @param X warning option to turn into an error, must be quoted like
232 * "-Wdocumentation"
233 */
234#define MY_COMPILER_GCC_DIAGNOSTIC_ERROR(X) \
235 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic error X)
236
237#endif // defined(__GNUC__)
238
239#if defined(_MSC_VER)
240#define MY_COMPILER_MSVC_DIAGNOSTIC_PUSH() \
241 MY_COMPILER_MSVC_PRAGMA(warning(push))
242#define MY_COMPILER_MSVC_DIAGNOSTIC_POP() MY_COMPILER_MSVC_PRAGMA(warning(pop))
243/**
244 * ignore a compiler warning.
245 *
246 * @param X warning number to disable
247 */
248#define MY_COMPILER_MSVC_DIAGNOSTIC_IGNORE(X) \
249 MY_COMPILER_MSVC_PRAGMA(warning(disable : X))
250#define MY_COMPILER_MSVC_DIAGNOSTIC_ERROR(X) \
251 MY_COMPILER_MSVC_PRAGMA(warning(error : X))
252
253#endif // defined(_MSC_VER)
254
255#if !defined(MY_COMPILER_CLANG_DIAGNOSTIC_ERROR)
256#define MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE(X)
257#define MY_COMPILER_CLANG_DIAGNOSTIC_ERROR(X)
258#endif
259
260#if !defined(MY_COMPILER_GCC_DIAGNOSTIC_ERROR)
261#define MY_COMPILER_GCC_DIAGNOSTIC_IGNORE(X)
262#define MY_COMPILER_GCC_DIAGNOSTIC_ERROR(X)
263#endif
264
265#if !defined(MY_COMPILER_MSVC_DIAGNOSTIC_ERROR)
266#define MY_COMPILER_MSVC_DIAGNOSTIC_IGNORE(X)
267#define MY_COMPILER_MSVC_DIAGNOSTIC_ERROR(X)
268#endif
269
270/**
271 * @def MY_COMPILER_DIAGNOSTIC_PUSH()
272 *
273 * save the compiler's diagnostic (enabled warnings, errors, ...) state
274 *
275 * @see MY_COMPILER_DIAGNOSTIC_POP()
276 */
277
278/**
279 * @def MY_COMPILER_DIAGNOSTIC_POP()
280 *
281 * restore the compiler's diagnostic (enabled warnings, errors, ...) state
282 *
283 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
284 */
285
286#if defined(__clang__)
287#define MY_COMPILER_DIAGNOSTIC_PUSH() MY_COMPILER_CLANG_DIAGNOSTIC_PUSH()
288#define MY_COMPILER_DIAGNOSTIC_POP() MY_COMPILER_CLANG_DIAGNOSTIC_POP()
289#elif defined(__GNUC__)
290#define MY_COMPILER_DIAGNOSTIC_PUSH() MY_COMPILER_GCC_DIAGNOSTIC_PUSH()
291#define MY_COMPILER_DIAGNOSTIC_POP() MY_COMPILER_GCC_DIAGNOSTIC_POP()
292#elif defined(_MSC_VER)
293#define MY_COMPILER_DIAGNOSTIC_PUSH() MY_COMPILER_MSVC_DIAGNOSTIC_PUSH()
294#define MY_COMPILER_DIAGNOSTIC_POP() MY_COMPILER_MSVC_DIAGNOSTIC_POP()
295#else
296#define MY_COMPILER_DIAGNOSTIC_PUSH()
297#define MY_COMPILER_DIAGNOSTIC_POP()
298#endif
299
300/**
301 * ignore -Wdocumentation compiler warnings for \@tparam.
302 *
303 * @code
304 * MY_COMPILER_DIAGNOSTIC_PUSH()
305 * MY_COMPILER_CLANG_WORKAROUND_TPARAM_DOCBUG()
306 * ...
307 * MY_COMPILER_DIAGNOSTIC_POP()
308 * @endcode
309 *
310 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
311 * @see MY_COMPILER_DIAGNOSTIC_POP()
312 *
313 * allows to work around false positives -Wdocumentation warnings like:
314 *
315 * - \@tparam and explicitly instantiated templates
316 * https://bugs.llvm.org/show_bug.cgi?id=35144
317 *
318 */
319#define MY_COMPILER_CLANG_WORKAROUND_TPARAM_DOCBUG() \
320 MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wdocumentation")
321
322/**
323 * ignore -Wdocumentation compiler warnings for \@see \@ref
324 *
325 * @code
326 * MY_COMPILER_DIAGNOSTIC_PUSH()
327 * MY_COMPILER_CLANG_WORKAROUND_REF_DOCBUG()
328 * ...
329 * MY_COMPILER_DIAGNOSTIC_POP()
330 * @endcode
331 *
332 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
333 * @see MY_COMPILER_DIAGNOSTIC_POP()
334 *
335 * allows to work around false positives -Wdocumentation warnings like:
336 *
337 * - \@sa \@ref
338 * - \@see \@ref
339 * - \@return \@ref
340 * https://bugs.llvm.org/show_bug.cgi?id=38905
341 *
342 */
343#define MY_COMPILER_CLANG_WORKAROUND_REF_DOCBUG() \
344 MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wdocumentation")
345
346/**
347 * ignore -Wunused-variable compiler warnings for \@see \@ref
348 *
349 * @code
350 * MY_COMPILER_DIAGNOSTIC_PUSH()
351 * MY_COMPILER_CLANG_WORKAROUND_FALSE_POSITIVE_UNUSED_VARIABLE_WARNING()
352 * ...
353 * MY_COMPILER_DIAGNOSTIC_POP()
354 * @endcode
355 *
356 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
357 * @see MY_COMPILER_DIAGNOSTIC_POP()
358 *
359 * allows to work around false positives -Wunused-variable warnings like:
360 *
361 * - \@sa \@ref
362 * - \@see \@ref
363 * - \@return \@ref
364 * https://bugs.llvm.org/show_bug.cgi?id=46035
365 *
366 */
367#define MY_COMPILER_CLANG_WORKAROUND_FALSE_POSITIVE_UNUSED_VARIABLE_WARNING() \
368 MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wunused-variable")
369
370#endif /* MY_COMPILER_INCLUDED */
constexpr bool likely(bool expr)
Definition: my_compiler.h:55
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:56