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