xref: /aosp_15_r20/external/pigweed/pw_preprocessor/public/pw_preprocessor/compiler.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2019 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 //
15 // Preprocessor macros that wrap compiler-specific features.
16 // This file is used by both C++ and C code.
17 #pragma once
18 
19 // TODO: b/234877280 - compiler.h should be refactored out of pw_preprocessor as
20 // the scope is outside of the module. Perhaps it should be split up and placed
21 // under pw_compiler, e.g. pw_compiler/attributes.h & pw_compiler/builtins.h.
22 
23 #include "pw_polyfill/static_assert.h"
24 
25 /// @defgroup pw_preprocessor_internal
26 
27 /// @defgroup pw_preprocessor_compiler
28 /// @{
29 
30 /// Marks a struct or class as packed.
31 ///
32 /// Use packed structs with extreme caution! Packed structs are rarely needed.
33 /// Instead, define the struct and `static_assert` to verify that the size and
34 /// alignement are as expected.
35 ///
36 /// Packed structs should only be used to avoid standard padding or to force
37 /// unaligned members when describing in-memory or wire format data structures.
38 /// Packed struct members should NOT be accessed directly because they may be
39 /// unaligned. Instead, `memcpy` the fields into variables. For example:
40 ///
41 /// @code{.cpp}
42 ///   PW_PACKED(struct) PackedStruct {
43 ///     uint8_t a;
44 ///     uint32_t b;
45 ///     uint16_t c;
46 ///   };
47 ///
48 ///   void UsePackedStruct(const PackedStruct& packed_struct) {
49 ///     uint8_t a;
50 ///     uint32_t b;
51 ///     uint16_t c;
52 ///     std::memcpy(&a, &packed_struct.a, sizeof(a));
53 ///     std::memcpy(&b, &packed_struct.b, sizeof(b));
54 ///     std::memcpy(&c, &packed_struct.c, sizeof(c));
55 ///   }
56 /// @endcode
57 #define PW_PACKED(declaration) declaration __attribute__((packed))
58 
59 /// Marks a function or object as used, ensuring code for it is generated.
60 #define PW_USED __attribute__((used))
61 
62 /// Prevents generation of a prologue or epilogue for a function. This is
63 /// helpful when implementing the function in assembly.
64 #define PW_NO_PROLOGUE __attribute__((naked))
65 
66 /// Marks that a function declaration takes a printf-style format string and
67 /// variadic arguments. This allows the compiler to perform check the validity
68 /// of the format string and arguments. This macro must only be on the function
69 /// declaration, not the definition.
70 ///
71 /// The format_index is index of the format string parameter and parameter_index
72 /// is the starting index of the variadic arguments. Indices start at 1. For C++
73 /// class member functions, add one to the index to account for the implicit
74 /// this parameter.
75 ///
76 /// This example shows a function where the format string is argument 2 and the
77 /// varargs start at argument 3.
78 ///
79 /// @code{.cpp}
80 ///   int PrintfStyleFunction(char* buffer, const char* fmt, ...)
81 ///   PW_PRINTF_FORMAT(2,3);
82 ///
83 ///   int PrintfStyleFunction(char* buffer, const char* fmt, ...) { ...
84 ///   implementation here ...  }
85 /// @endcode
86 #define PW_PRINTF_FORMAT(format_index, parameter_index) \
87   __attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index)))
88 
89 /// When compiling for host using MinGW, use gnu_printf() rather than printf()
90 /// to support %z format specifiers.
91 /// @ingroup pw_preprocessor_internal
92 #ifdef __USE_MINGW_ANSI_STDIO
93 #define _PW_PRINTF_FORMAT_TYPE gnu_printf
94 #else
95 #define _PW_PRINTF_FORMAT_TYPE printf
96 #endif  // __USE_MINGW_ANSI_STDIO
97 
98 /// Places a variable in the specified linker section.
99 #ifdef __APPLE__
100 #define PW_PLACE_IN_SECTION(name) __attribute__((section("__DATA," name)))
101 #else
102 #define PW_PLACE_IN_SECTION(name) __attribute__((section(name)))
103 #endif  // __APPLE__
104 
105 /// Places a variable in the specified linker section and directs the compiler
106 /// to keep the variable, even if it is not used. Depending on the linker
107 /// options, the linker may still remove this section if it is not declared in
108 /// the linker script and marked `KEEP`.
109 #ifdef __APPLE__
110 #define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA," name), used))
111 #else
112 #define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used))
113 #endif  // __APPLE__
114 
115 /// Indicate to the compiler that the annotated function won't return. Example:
116 ///
117 /// @code{.cpp}
118 ///   PW_NO_RETURN void HandleAssertFailure(ErrorCode error_code);
119 /// @endcode
120 #define PW_NO_RETURN __attribute__((noreturn))
121 
122 /// Prevents the compiler from inlining a fuction.
123 #define PW_NO_INLINE __attribute__((noinline))
124 
125 /// Indicate to the compiler that the given section of code will not be reached.
126 /// Example:
127 ///
128 /// @code{.cpp}
129 ///   int main() {
130 ///     InitializeBoard();
131 ///     vendor_StartScheduler();  // Note: vendor forgot noreturn attribute.
132 ///     PW_UNREACHABLE;
133 ///   }
134 /// @endcode
135 #define PW_UNREACHABLE __builtin_unreachable()
136 
137 /// Indicate to a sanitizer compiler runtime to skip the named check in the
138 /// associated function.
139 /// Example:
140 ///
141 /// @code{.cpp}
142 ///   uint32_t djb2(const void* buf, size_t len)
143 ///       PW_NO_SANITIZE("unsigned-integer-overflow") {
144 ///     uint32_t hash = 5381;
145 ///     const uint8_t* u8 = static_cast<const uint8_t*>(buf);
146 ///     for (size_t i = 0; i < len; ++i) {
147 ///       hash = (hash * 33) + u8[i]; /* hash * 33 + c */
148 ///     }
149 ///     return hash;
150 ///   }
151 /// @endcode
152 #ifdef __clang__
153 #define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
154 #else
155 #define PW_NO_SANITIZE(check)
156 #endif  // __clang__
157 
158 /// Wrapper around `__has_attribute`, which is defined by GCC 5+ and Clang and
159 /// evaluates to a non zero constant integer if the attribute is supported or 0
160 /// if not.
161 #ifdef __has_attribute
162 #define PW_HAVE_ATTRIBUTE(x) __has_attribute(x)
163 #else
164 #define PW_HAVE_ATTRIBUTE(x) 0
165 #endif  // __has_attribute
166 
167 /// A function-like feature checking macro that accepts C++11 style attributes.
168 /// It is a wrapper around `__has_cpp_attribute`, which was introduced in the <a
169 /// href="https://en.cppreference.com/w/cpp/feature_test">C++20 standard</a>. It
170 /// is supported by compilers even if C++20 is not in use. Evaluates to a
171 /// non-zero constant integer if the C++ attribute is supported or 0 if not.
172 ///
173 /// This is a copy of `ABSL_HAVE_CPP_ATTRIBUTE`.
174 #if defined(__cplusplus) && defined(__has_cpp_attribute)
175 #define PW_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
176 #else
177 #define PW_HAVE_CPP_ATTRIBUTE(x) 0
178 #endif  // defined(__cplusplus) && defined(__has_cpp_attribute)
179 
180 /// @ingroup pw_preprocessor_internal
181 #define _PW_REQUIRE_SEMICOLON \
182   static_assert(1, "This macro must be terminated with a semicolon")
183 
184 /// Starts a new group of @c_macro{PW_MODIFY_DIAGNOSTIC} statements. A
185 /// @c_macro{PW_MODIFY_DIAGNOSTICS_POP} statement must follow.
186 #define PW_MODIFY_DIAGNOSTICS_PUSH() \
187   _Pragma("GCC diagnostic push") _PW_REQUIRE_SEMICOLON
188 
189 /// @c_macro{PW_MODIFY_DIAGNOSTIC} statements since the most recent
190 /// @c_macro{PW_MODIFY_DIAGNOSTICS_PUSH} no longer apply after this statement.
191 #define PW_MODIFY_DIAGNOSTICS_POP() \
192   _Pragma("GCC diagnostic pop") _PW_REQUIRE_SEMICOLON
193 
194 /// Changes how a diagnostic (warning or error) is handled. Most commonly used
195 /// to disable warnings. ``PW_MODIFY_DIAGNOSTIC`` should be used between
196 /// @c_macro{PW_MODIFY_DIAGNOSTICS_PUSH} and @c_macro{PW_MODIFY_DIAGNOSTICS_POP}
197 /// statements to avoid applying the modifications too broadly.
198 ///
199 /// ``kind`` may be ``warning``, ``error``, or ``ignored``.
200 #define PW_MODIFY_DIAGNOSTIC(kind, option) \
201   PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON
202 
203 /// Applies ``PW_MODIFY_DIAGNOSTIC`` only for GCC. This is useful for warnings
204 /// that aren't supported by or don't need to be changed in other compilers.
205 #ifdef __clang__
206 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON
207 #else
208 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \
209   PW_MODIFY_DIAGNOSTIC(kind, option)
210 #endif  // __clang__
211 
212 /// Applies ``PW_MODIFY_DIAGNOSTIC`` only for Clang. This is useful for warnings
213 /// that aren't supported by or don't need to be changed in other compilers.
214 #ifdef __clang__
215 #define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) \
216   PW_MODIFY_DIAGNOSTIC(kind, option)
217 #else
218 #define PW_MODIFY_DIAGNOSTIC_CLANG(kind, option) _PW_REQUIRE_SEMICOLON
219 #endif  // __clang__
220 
221 /// Expands to a `_Pragma` with the contents as a string. `_Pragma` must take a
222 /// single string literal; this can be used to construct a `_Pragma` argument.
223 #define PW_PRAGMA(contents) _Pragma(#contents)
224 
225 /// Marks a function or object as weak, allowing the definition to be overriden.
226 ///
227 /// This can be useful when supporting third-party SDKs which may conditionally
228 /// compile in code, for example:
229 ///
230 /// @code{.cpp}
231 ///   PW_WEAK void SysTick_Handler(void) {
232 ///     // Default interrupt handler that might be overriden.
233 ///   }
234 /// @endcode
235 #define PW_WEAK __attribute__((weak))
236 
237 /// Marks a weak function as an alias to another, allowing the definition to
238 /// be given a default and overriden.
239 ///
240 /// This can be useful when supporting third-party SDKs which may conditionally
241 /// compile in code, for example:
242 ///
243 /// @code{.cpp}
244 ///   // Driver handler replaced with default unless overridden.
245 ///   void USART_DriverHandler(void) PW_ALIAS(DefaultDriverHandler);
246 /// @endcode
247 #define PW_ALIAS(aliased_to) __attribute__((weak, alias(#aliased_to)))
248 
249 /// `PW_ATTRIBUTE_LIFETIME_BOUND` indicates that a resource owned by a function
250 /// parameter or implicit object parameter is retained by the return value of
251 /// the annotated function (or, for a parameter of a constructor, in the value
252 /// of the constructed object). This attribute causes warnings to be produced if
253 /// a temporary object does not live long enough.
254 ///
255 /// When applied to a reference parameter, the referenced object is assumed to
256 /// be retained by the return value of the function. When applied to a
257 /// non-reference parameter (for example, a pointer or a class type), all
258 /// temporaries referenced by the parameter are assumed to be retained by the
259 /// return value of the function.
260 ///
261 /// See also the upstream documentation:
262 /// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
263 ///
264 /// This is a copy of `ABSL_ATTRIBUTE_LIFETIME_BOUND`.
265 #if PW_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
266 #define PW_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
267 #elif PW_HAVE_ATTRIBUTE(lifetimebound)
268 #define PW_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
269 #else
270 #define PW_ATTRIBUTE_LIFETIME_BOUND
271 #endif  // PW_ATTRIBUTE_LIFETIME_BOUND
272 
273 /// `PW_ADD_OVERFLOW` adds two integers while checking for overflow.
274 ///
275 /// Returns true if the result of `a + b` overflows the type of `out`; otherwise
276 /// stores the result in `out` and returns false.
277 ///
278 /// See also `PW_CHECK_ADD`.
279 #define PW_ADD_OVERFLOW(a, b, out) __builtin_add_overflow(a, b, out)
280 
281 /// `PW_SUB_OVERFLOW` subtracts an integer from another while checking for
282 /// overflow.
283 ///
284 /// Returns true if the result of `a - b` overflows the type of `out`; otherwise
285 /// stores the result in `out` and returns false.
286 ///
287 /// See also `PW_CHECK_SUB`.
288 #define PW_SUB_OVERFLOW(a, b, out) __builtin_sub_overflow(a, b, out)
289 
290 /// `PW_MUL_OVERFLOW` multiplies two integers while checking for overflow.
291 ///
292 /// Returns true if the result of `a * b` overflows the type of `out`; otherwise
293 /// stores the result in `out` and returns false.
294 ///
295 /// See also `PW_CHECK_MUL`.
296 #define PW_MUL_OVERFLOW(a, b, out) __builtin_mul_overflow(a, b, out)
297 
298 /// Evaluates to 1 if `__VA_OPT__` is supported, regardless of the C or C++
299 /// standard in use.
300 #if (defined(__clang_major__) && __clang_major__ < 9) || \
301     (defined(__GNUC__) && __GNUC__ < 12)
302 #define PW_VA_OPT_SUPPORTED() 0  // Don't bother checking on old compilers.
303 #else
304 #define PW_VA_OPT_SUPPORTED() _PW_VA_OPT_SUPPORTED()
305 /// @}
306 
307 #define _PW_VA_OPT_SUPPORTED(...) _PW_VA_OPT_SUPPORTED_##__VA_OPT__()
308 #define _PW_VA_OPT_SUPPORTED_ 1
309 #define _PW_VA_OPT_SUPPORTED___VA_OPT__() 0
310 
311 #endif  // __clang_major__ < 9 || __GNUC__ < 12
312 
313 /// `PW_NO_UNIQUE_ADDRESS` indicates that an object can have no unique
314 /// address. This is usually used to force empty member types to occupy
315 /// 0 bytes instead of 1 byte to have a unique address.
316 #if PW_HAVE_CPP_ATTRIBUTE(no_unique_address)
317 #define PW_NO_UNIQUE_ADDRESS [[no_unique_address]]
318 #else
319 #define PW_NO_UNIQUE_ADDRESS
320 #endif  // PW_NO_UNIQUE_ADDRESS
321