1 #ifndef MY_COMPILER_INCLUDED
2 #define MY_COMPILER_INCLUDED
3 
4 /* Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
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    Without limiting anything contained in the foregoing, this file,
18    which is part of C Driver for MySQL (Connector/C), is also subject to the
19    Universal FOSS Exception, version 1.0, a copy of which can be found at
20    http://oss.oracle.com/licenses/universal-foss-exception.
21 
22    This program is distributed in the hope that it will be useful,
23    but WITHOUT ANY WARRANTY; without even the implied warranty of
24    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25    GNU General Public License, version 2.0, for more details.
26 
27    You should have received a copy of the GNU General Public License
28    along with this program; if not, write to the Free Software
29    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
30 
31 /**
32   Header for compiler-dependent features.
33 
34   Intended to contain a set of reusable wrappers for preprocessor
35   macros, attributes, pragmas, and any other features that are
36   specific to a target compiler.
37 */
38 
39 #include <stddef.h> /* size_t */
40 
41 #if defined __GNUC__
42 /*
43   Convenience macro to test the minimum required GCC version.
44   These should be used with care as Clang also sets __GNUC__ and
45   __GNUC_MINOR__ (currently to 4.2). Prefer using feature specific
46   CMake checks in configure.cmake instead.
47 */
48 #  define MY_GNUC_PREREQ(maj, min) \
49     ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
50 #  define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
51 #else
52 #  define MY_GNUC_PREREQ(maj, min) (0)
53 #endif
54 
55 /*
56   The macros below are borrowed from include/linux/compiler.h in the
57   Linux kernel. Use them to indicate the likelyhood of the truthfulness
58   of a condition. This serves two purposes - newer versions of gcc will be
59   able to optimize for branch predication, which could yield siginficant
60   performance gains in frequently executed sections of the code, and the
61   other reason to use them is for documentation
62 */
63 #ifdef HAVE_BUILTIN_EXPECT
64 
65 // likely/unlikely are likely to clash with other symbols, do not #define
66 #if defined(__cplusplus)
likely(bool expr)67 inline bool likely(bool expr)
68 {
69   return __builtin_expect(expr, true);
70 }
unlikely(bool expr)71 inline bool unlikely(bool expr)
72 {
73   return __builtin_expect(expr, false);
74 }
75 #else
76 #  define likely(x)    __builtin_expect((x),1)
77 #  define unlikely(x)  __builtin_expect((x),0)
78 #endif
79 
80 #else  /* HAVE_BUILTIN_EXPECT */
81 
82 #if defined(__cplusplus)
likely(bool expr)83 inline bool likely(bool expr)
84 {
85   return expr;
86 }
unlikely(bool expr)87 inline bool unlikely(bool expr)
88 {
89   return expr;
90 }
91 #else
92 #  define likely(x)    (x)
93 #  define unlikely(x)  (x)
94 #endif
95 
96 #endif  /* HAVE_BUILTIN_EXPECT */
97 
98 /* Comunicate to the compiler the unreachability of the code. */
99 #ifdef HAVE_BUILTIN_UNREACHABLE
100 #  define MY_ASSERT_UNREACHABLE()   __builtin_unreachable()
101 #else
102 #  define MY_ASSERT_UNREACHABLE()  do { assert(0); } while (0)
103 #endif
104 
105 #if defined __GNUC__ || defined __SUNPRO_C || defined __SUNPRO_CC
106 /* Specifies the minimum alignment of a type. */
107 # define MY_ALIGNOF(type)   __alignof__(type)
108 /* Determine the alignment requirement of a type. */
109 # define MY_ALIGNED(n)      __attribute__((__aligned__((n))))
110 /* Microsoft Visual C++ */
111 #elif defined _MSC_VER
112 # define MY_ALIGNOF(type)   __alignof(type)
113 # define MY_ALIGNED(n)      __declspec(align(n))
114 #else /* Make sure they are defined for other compilers. */
115 # define MY_ALIGNOF(type)
116 # define MY_ALIGNED(size)
117 #endif
118 
119 /* Visual Studio requires '__inline' for C code */
120 #if !defined(__cplusplus) && defined(_MSC_VER)
121 # define inline __inline
122 #endif
123 
124 /* Provide __func__ macro definition for Visual Studio. */
125 #if defined(_MSC_VER)
126 #  define __func__ __FUNCTION__
127 #endif
128 
129 /**
130   C++ Type Traits
131 */
132 #ifdef __cplusplus
133 
134 /**
135   Opaque storage with a particular alignment.
136   Partial specialization used due to MSVC++.
137 */
138 template<size_t alignment> struct my_alignment_imp;
139 template<> struct MY_ALIGNED(1) my_alignment_imp<1> {};
140 template<> struct MY_ALIGNED(2) my_alignment_imp<2> {};
141 template<> struct MY_ALIGNED(4) my_alignment_imp<4> {};
142 template<> struct MY_ALIGNED(8) my_alignment_imp<8> {};
143 template<> struct MY_ALIGNED(16) my_alignment_imp<16> {};
144 
145 /**
146   A POD type with a given size and alignment.
147 
148   @remark If the compiler does not support a alignment attribute
149           (MY_ALIGN macro), the default alignment of a double is
150           used instead.
151 
152   @tparam size        The minimum size.
153   @tparam alignment   The desired alignment: 1, 2, 4, 8 or 16.
154 */
155 template <size_t size, size_t alignment>
156 struct my_aligned_storage
157 {
158   union
159   {
160     char data[size];
161     my_alignment_imp<alignment> align;
162   };
163 };
164 
165 #endif /* __cplusplus */
166 
167 /*
168   Disable MY_ATTRIBUTE for Sun Studio and Visual Studio.
169   Note that Sun Studio supports some __attribute__ variants,
170   but not format or unused which we use quite a lot.
171 */
172 #ifndef MY_ATTRIBUTE
173 #if defined(__GNUC__)
174 #  define MY_ATTRIBUTE(A) __attribute__(A)
175 #else
176 #  define MY_ATTRIBUTE(A)
177 #endif
178 #endif
179 
180 #ifndef __has_attribute
181 # define __has_attribute(x) 0
182 #endif
183 
184 #if __has_attribute(no_sanitize_undefined)
185 # define SUPPRESS_UBSAN __attribute__((no_sanitize_undefined))
186 #else
187 # define SUPPRESS_UBSAN
188 #endif
189 
190 #endif /* MY_COMPILER_INCLUDED */
191