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