MySQL 9.0.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#if (__clang_major__ >= 10)
117#define SUPPRESS_UBSAN_CLANG10 MY_ATTRIBUTE((no_sanitize("undefined")))
118#endif
119// gcc -fsanitize=undefined
120#elif defined(HAVE_UBSAN) && __has_attribute(no_sanitize_undefined)
121#define SUPPRESS_UBSAN MY_ATTRIBUTE((no_sanitize_undefined))
122#else
123#define SUPPRESS_UBSAN
124#endif
125#endif /* SUPPRESS_UBSAN */
126
127// TODO(tdidriks) Fix new 'applying offset to null pointer' warnings.
128#ifndef SUPPRESS_UBSAN_CLANG10
129#define SUPPRESS_UBSAN_CLANG10
130#endif
131
132#ifndef SUPPRESS_TSAN
133#if defined(HAVE_TSAN) && defined(__clang__)
134#define SUPPRESS_TSAN MY_ATTRIBUTE((no_sanitize("thread")))
135#elif defined(HAVE_TSAN) && __has_attribute(no_sanitize_thread)
136#define SUPPRESS_TSAN MY_ATTRIBUTE((no_sanitize_thread))
137#else
138#define SUPPRESS_TSAN
139#endif
140#endif /* SUPPRESS_TSAN */
141
142#ifdef _WIN32
143#define STDCALL __stdcall
144#else
145#define STDCALL
146#endif
147
148/**
149 * stringify parameters for C99/C++11 _Pragma().
150 */
151#define MY_COMPILER_CPP11_PRAGMA(X) _Pragma(#X)
152/**
153 * pass parameters to MSVC's __pragma() as is.
154 */
155#define MY_COMPILER_MSVC_PRAGMA(X) __pragma(X)
156
157// enable compiler specified 'diagnostic' pragmas.
158//
159// 1. clang on windows defines both clang and msvc pragmas and generates the
160// same warnings
161// 2. clang defines both __clang__ and __GNUC__, but doesn't support all GCC
162// warnings with the same name
163//
164// +---------------------+
165// | enabled diagnostics |
166// +------+-------+------+
167// | gcc | clang | msvc |
168// +-------+------+-------+------+
169// | gcc | x | - | - |
170// | clang | - | x | x |
171// | msvc | - | - | x |
172// +-------+------+-------+------+
173// ^^^
174// +----- current compiler
175//
176// suppressions that aren't supported by the compiler are disabled to avoid
177// "unsupported pragmas" warnings:
178//
179// @code
180// // on GCC, clang-specific diagnostic pragmas are disabled
181// MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wdocumentation")
182// @endcode
183
184#if defined(__clang__)
185#define MY_COMPILER_CLANG_DIAGNOSTIC_PUSH() \
186 MY_COMPILER_CPP11_PRAGMA(clang diagnostic push)
187#define MY_COMPILER_CLANG_DIAGNOSTIC_POP() \
188 MY_COMPILER_CPP11_PRAGMA(clang diagnostic pop)
189/**
190 * ignore a compiler warning.
191 *
192 * @param X warning option to disable, must be quoted like "-Wdocumentation"
193 */
194#define MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE(X) \
195 MY_COMPILER_CPP11_PRAGMA(clang diagnostic ignored X)
196/**
197 * turn a compiler warning into an error.
198 *
199 * @param X warning option to turn into an error, must be a quoted string like
200 * "-Wdocumentation"
201 */
202#define MY_COMPILER_CLANG_DIAGNOSTIC_ERROR(X) \
203 MY_COMPILER_CPP11_PRAGMA(clang diagnostic error X)
204
205#elif defined(__GNUC__)
206#define MY_COMPILER_GCC_DIAGNOSTIC_PUSH() \
207 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic push)
208#define MY_COMPILER_GCC_DIAGNOSTIC_POP() \
209 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic pop)
210/**
211 * ignore a compiler warning.
212 *
213 * @param X warning option to disable, must be quoted like "-Wdocumentation"
214 */
215#define MY_COMPILER_GCC_DIAGNOSTIC_IGNORE(X) \
216 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic ignored X)
217/**
218 * turn a compiler warning into an error.
219 *
220 * @param X warning option to turn into an error, must be quoted like
221 * "-Wdocumentation"
222 */
223#define MY_COMPILER_GCC_DIAGNOSTIC_ERROR(X) \
224 MY_COMPILER_CPP11_PRAGMA(GCC diagnostic error X)
225
226#endif // defined(__GNUC__)
227
228#if defined(_MSC_VER)
229#define MY_COMPILER_MSVC_DIAGNOSTIC_PUSH() \
230 MY_COMPILER_MSVC_PRAGMA(warning(push))
231#define MY_COMPILER_MSVC_DIAGNOSTIC_POP() MY_COMPILER_MSVC_PRAGMA(warning(pop))
232/**
233 * ignore a compiler warning.
234 *
235 * @param X warning number to disable
236 */
237#define MY_COMPILER_MSVC_DIAGNOSTIC_IGNORE(X) \
238 MY_COMPILER_MSVC_PRAGMA(warning(disable : X))
239#define MY_COMPILER_MSVC_DIAGNOSTIC_ERROR(X) \
240 MY_COMPILER_MSVC_PRAGMA(warning(error : X))
241
242#endif // defined(_MSC_VER)
243
244#if !defined(MY_COMPILER_CLANG_DIAGNOSTIC_ERROR)
245#define MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE(X)
246#define MY_COMPILER_CLANG_DIAGNOSTIC_ERROR(X)
247#endif
248
249#if !defined(MY_COMPILER_GCC_DIAGNOSTIC_ERROR)
250#define MY_COMPILER_GCC_DIAGNOSTIC_IGNORE(X)
251#define MY_COMPILER_GCC_DIAGNOSTIC_ERROR(X)
252#endif
253
254#if !defined(MY_COMPILER_MSVC_DIAGNOSTIC_ERROR)
255#define MY_COMPILER_MSVC_DIAGNOSTIC_IGNORE(X)
256#define MY_COMPILER_MSVC_DIAGNOSTIC_ERROR(X)
257#endif
258
259/**
260 * @def MY_COMPILER_DIAGNOSTIC_PUSH()
261 *
262 * save the compiler's diagnostic (enabled warnings, errors, ...) state
263 *
264 * @see MY_COMPILER_DIAGNOSTIC_POP()
265 */
266
267/**
268 * @def MY_COMPILER_DIAGNOSTIC_POP()
269 *
270 * restore the compiler's diagnostic (enabled warnings, errors, ...) state
271 *
272 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
273 */
274
275#if defined(__clang__)
276#define MY_COMPILER_DIAGNOSTIC_PUSH() MY_COMPILER_CLANG_DIAGNOSTIC_PUSH()
277#define MY_COMPILER_DIAGNOSTIC_POP() MY_COMPILER_CLANG_DIAGNOSTIC_POP()
278#elif defined(__GNUC__)
279#define MY_COMPILER_DIAGNOSTIC_PUSH() MY_COMPILER_GCC_DIAGNOSTIC_PUSH()
280#define MY_COMPILER_DIAGNOSTIC_POP() MY_COMPILER_GCC_DIAGNOSTIC_POP()
281#elif defined(_MSC_VER)
282#define MY_COMPILER_DIAGNOSTIC_PUSH() MY_COMPILER_MSVC_DIAGNOSTIC_PUSH()
283#define MY_COMPILER_DIAGNOSTIC_POP() MY_COMPILER_MSVC_DIAGNOSTIC_POP()
284#else
285#define MY_COMPILER_DIAGNOSTIC_PUSH()
286#define MY_COMPILER_DIAGNOSTIC_POP()
287#endif
288
289/**
290 * ignore -Wdocumentation compiler warnings for \@tparam.
291 *
292 * @code
293 * MY_COMPILER_DIAGNOSTIC_PUSH()
294 * MY_COMPILER_CLANG_WORKAROUND_TPARAM_DOCBUG()
295 * ...
296 * MY_COMPILER_DIAGNOSTIC_POP()
297 * @endcode
298 *
299 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
300 * @see MY_COMPILER_DIAGNOSTIC_POP()
301 *
302 * allows to work around false positives -Wdocumentation warnings like:
303 *
304 * - \@tparam and explicitly instantiated templates
305 * https://bugs.llvm.org/show_bug.cgi?id=35144
306 *
307 */
308#define MY_COMPILER_CLANG_WORKAROUND_TPARAM_DOCBUG() \
309 MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wdocumentation")
310
311/**
312 * ignore -Wdocumentation compiler warnings for \@see \@ref
313 *
314 * @code
315 * MY_COMPILER_DIAGNOSTIC_PUSH()
316 * MY_COMPILER_CLANG_WORKAROUND_REF_DOCBUG()
317 * ...
318 * MY_COMPILER_DIAGNOSTIC_POP()
319 * @endcode
320 *
321 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
322 * @see MY_COMPILER_DIAGNOSTIC_POP()
323 *
324 * allows to work around false positives -Wdocumentation warnings like:
325 *
326 * - \@sa \@ref
327 * - \@see \@ref
328 * - \@return \@ref
329 * https://bugs.llvm.org/show_bug.cgi?id=38905
330 *
331 */
332#define MY_COMPILER_CLANG_WORKAROUND_REF_DOCBUG() \
333 MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wdocumentation")
334
335/**
336 * ignore -Wunused-variable compiler warnings for \@see \@ref
337 *
338 * @code
339 * MY_COMPILER_DIAGNOSTIC_PUSH()
340 * MY_COMPILER_CLANG_WORKAROUND_FALSE_POSITIVE_UNUSED_VARIABLE_WARNING()
341 * ...
342 * MY_COMPILER_DIAGNOSTIC_POP()
343 * @endcode
344 *
345 * @see MY_COMPILER_DIAGNOSTIC_PUSH()
346 * @see MY_COMPILER_DIAGNOSTIC_POP()
347 *
348 * allows to work around false positives -Wunused-variable warnings like:
349 *
350 * - \@sa \@ref
351 * - \@see \@ref
352 * - \@return \@ref
353 * https://bugs.llvm.org/show_bug.cgi?id=46035
354 *
355 */
356#define MY_COMPILER_CLANG_WORKAROUND_FALSE_POSITIVE_UNUSED_VARIABLE_WARNING() \
357 MY_COMPILER_CLANG_DIAGNOSTIC_IGNORE("-Wunused-variable")
358
359#endif /* MY_COMPILER_INCLUDED */
constexpr bool likely(bool expr)
Definition: my_compiler.h:57
constexpr bool unlikely(bool expr)
Definition: my_compiler.h:58