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