• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #define PW_PACKED(declaration) declaration __attribute__((packed))
32 
33 /// Marks a function or object as used, ensuring code for it is generated.
34 #define PW_USED __attribute__((used))
35 
36 /// Prevents generation of a prologue or epilogue for a function. This is
37 /// helpful when implementing the function in assembly.
38 #define PW_NO_PROLOGUE __attribute__((naked))
39 
40 /// Marks that a function declaration takes a printf-style format string and
41 /// variadic arguments. This allows the compiler to perform check the validity
42 /// of the format string and arguments. This macro must only be on the function
43 /// declaration, not the definition.
44 ///
45 /// The format_index is index of the format string parameter and parameter_index
46 /// is the starting index of the variadic arguments. Indices start at 1. For C++
47 /// class member functions, add one to the index to account for the implicit
48 /// this parameter.
49 ///
50 /// This example shows a function where the format string is argument 2 and the
51 /// varargs start at argument 3.
52 ///
53 /// @code{.cpp}
54 ///   int PrintfStyleFunction(char* buffer, const char* fmt, ...)
55 ///   PW_PRINTF_FORMAT(2,3);
56 ///
57 ///   int PrintfStyleFunction(char* buffer, const char* fmt, ...) { ...
58 ///   implementation here ...  }
59 /// @endcode
60 #define PW_PRINTF_FORMAT(format_index, parameter_index) \
61   __attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index)))
62 
63 /// When compiling for host using MinGW, use gnu_printf() rather than printf()
64 /// to support %z format specifiers.
65 /// @ingroup pw_preprocessor_internal
66 #ifdef __USE_MINGW_ANSI_STDIO
67 #define _PW_PRINTF_FORMAT_TYPE gnu_printf
68 #else
69 #define _PW_PRINTF_FORMAT_TYPE printf
70 #endif  // __USE_MINGW_ANSI_STDIO
71 
72 /// Places a variable in the specified linker section.
73 #ifdef __APPLE__
74 #define PW_PLACE_IN_SECTION(name) __attribute__((section("__DATA," name)))
75 #else
76 #define PW_PLACE_IN_SECTION(name) __attribute__((section(name)))
77 #endif  // __APPLE__
78 
79 /// Places a variable in the specified linker section and directs the compiler
80 /// to keep the variable, even if it is not used. Depending on the linker
81 /// options, the linker may still remove this section if it is not declared in
82 /// the linker script and marked `KEEP`.
83 #ifdef __APPLE__
84 #define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA," name), used))
85 #else
86 #define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used))
87 #endif  // __APPLE__
88 
89 /// Indicate to the compiler that the annotated function won't return. Example:
90 ///
91 /// @code{.cpp}
92 ///   PW_NO_RETURN void HandleAssertFailure(ErrorCode error_code);
93 /// @endcode
94 #define PW_NO_RETURN __attribute__((noreturn))
95 
96 /// Prevents the compiler from inlining a fuction.
97 #define PW_NO_INLINE __attribute__((noinline))
98 
99 /// Indicate to the compiler that the given section of code will not be reached.
100 /// Example:
101 ///
102 /// @code{.cpp}
103 ///   int main() {
104 ///     InitializeBoard();
105 ///     vendor_StartScheduler();  // Note: vendor forgot noreturn attribute.
106 ///     PW_UNREACHABLE;
107 ///   }
108 /// @endcode
109 #define PW_UNREACHABLE __builtin_unreachable()
110 
111 /// Indicate to a sanitizer compiler runtime to skip the named check in the
112 /// associated function.
113 /// Example:
114 ///
115 /// @code{.cpp}
116 ///   uint32_t djb2(const void* buf, size_t len)
117 ///       PW_NO_SANITIZE("unsigned-integer-overflow") {
118 ///     uint32_t hash = 5381;
119 ///     const uint8_t* u8 = static_cast<const uint8_t*>(buf);
120 ///     for (size_t i = 0; i < len; ++i) {
121 ///       hash = (hash * 33) + u8[i]; /* hash * 33 + c */
122 ///     }
123 ///     return hash;
124 ///   }
125 /// @endcode
126 #ifdef __clang__
127 #define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check)))
128 #else
129 #define PW_NO_SANITIZE(check)
130 #endif  // __clang__
131 
132 /// Wrapper around `__has_attribute`, which is defined by GCC 5+ and Clang and
133 /// evaluates to a non zero constant integer if the attribute is supported or 0
134 /// if not.
135 #ifdef __has_attribute
136 #define PW_HAVE_ATTRIBUTE(x) __has_attribute(x)
137 #else
138 #define PW_HAVE_ATTRIBUTE(x) 0
139 #endif  // __has_attribute
140 
141 /// A function-like feature checking macro that accepts C++11 style attributes.
142 /// It is a wrapper around `__has_cpp_attribute`, which was introduced in the <a
143 /// href="https://en.cppreference.com/w/cpp/feature_test">C++20 standard</a>. It
144 /// is supported by compilers even if C++20 is not in use. Evaluates to a
145 /// non-zero constant integer if the C++ attribute is supported or 0 if not.
146 ///
147 /// This is a copy of `ABSL_HAVE_CPP_ATTRIBUTE`.
148 #if defined(__cplusplus) && defined(__has_cpp_attribute)
149 #define PW_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x)
150 #else
151 #define PW_HAVE_CPP_ATTRIBUTE(x) 0
152 #endif  // defined(__cplusplus) && defined(__has_cpp_attribute)
153 
154 /// @ingroup pw_preprocessor_internal
155 #define _PW_REQUIRE_SEMICOLON \
156   static_assert(1, "This macro must be terminated with a semicolon")
157 
158 /// Starts a new group of @c_macro{PW_MODIFY_DIAGNOSTIC} statements. A
159 /// @c_macro{PW_MODIFY_DIAGNOSTICS_POP} statement must follow.
160 #define PW_MODIFY_DIAGNOSTICS_PUSH() \
161   _Pragma("GCC diagnostic push") _PW_REQUIRE_SEMICOLON
162 
163 /// @c_macro{PW_MODIFY_DIAGNOSTIC} statements since the most recent
164 /// @c_macro{PW_MODIFY_DIAGNOSTICS_PUSH} no longer apply after this statement.
165 #define PW_MODIFY_DIAGNOSTICS_POP() \
166   _Pragma("GCC diagnostic pop") _PW_REQUIRE_SEMICOLON
167 
168 /// Changes how a diagnostic (warning or error) is handled. Most commonly used
169 /// to disable warnings. ``PW_MODIFY_DIAGNOSTIC`` should be used between
170 /// @c_macro{PW_MODIFY_DIAGNOSTICS_PUSH} and @c_macro{PW_MODIFY_DIAGNOSTICS_POP}
171 /// statements to avoid applying the modifications too broadly.
172 ///
173 /// ``kind`` may be ``warning``, ``error``, or ``ignored``.
174 #define PW_MODIFY_DIAGNOSTIC(kind, option) \
175   PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON
176 
177 /// Applies ``PW_MODIFY_DIAGNOSTIC`` only for GCC. This is useful for warnings
178 /// that aren't supported by or don't need to be changed in other compilers.
179 #ifdef __clang__
180 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON
181 #else
182 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \
183   PW_MODIFY_DIAGNOSTIC(kind, option)
184 #endif  // __clang__
185 
186 /// Expands to a `_Pragma` with the contents as a string. `_Pragma` must take a
187 /// single string literal; this can be used to construct a `_Pragma` argument.
188 #define PW_PRAGMA(contents) _Pragma(#contents)
189 
190 /// Marks a function or object as weak, allowing the definition to be overriden.
191 ///
192 /// This can be useful when supporting third-party SDKs which may conditionally
193 /// compile in code, for example:
194 ///
195 /// @code{.cpp}
196 ///   PW_WEAK void SysTick_Handler(void) {
197 ///     // Default interrupt handler that might be overriden.
198 ///   }
199 /// @endcode
200 #define PW_WEAK __attribute__((weak))
201 
202 /// Marks a weak function as an alias to another, allowing the definition to
203 /// be given a default and overriden.
204 ///
205 /// This can be useful when supporting third-party SDKs which may conditionally
206 /// compile in code, for example:
207 ///
208 /// @code{.cpp}
209 ///   // Driver handler replaced with default unless overridden.
210 ///   void USART_DriverHandler(void) PW_ALIAS(DefaultDriverHandler);
211 /// @endcode
212 #define PW_ALIAS(aliased_to) __attribute__((weak, alias(#aliased_to)))
213 
214 /// `PW_ATTRIBUTE_LIFETIME_BOUND` indicates that a resource owned by a function
215 /// parameter or implicit object parameter is retained by the return value of
216 /// the annotated function (or, for a parameter of a constructor, in the value
217 /// of the constructed object). This attribute causes warnings to be produced if
218 /// a temporary object does not live long enough.
219 ///
220 /// When applied to a reference parameter, the referenced object is assumed to
221 /// be retained by the return value of the function. When applied to a
222 /// non-reference parameter (for example, a pointer or a class type), all
223 /// temporaries referenced by the parameter are assumed to be retained by the
224 /// return value of the function.
225 ///
226 /// See also the upstream documentation:
227 /// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
228 ///
229 /// This is a copy of `ABSL_ATTRIBUTE_LIFETIME_BOUND`.
230 #if PW_HAVE_CPP_ATTRIBUTE(clang::lifetimebound)
231 #define PW_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]]
232 #elif PW_HAVE_ATTRIBUTE(lifetimebound)
233 #define PW_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound))
234 #else
235 #define PW_ATTRIBUTE_LIFETIME_BOUND
236 #endif  // PW_ATTRIBUTE_LIFETIME_BOUND
237 
238 /// `PW_ADD_OVERFLOW` adds two integers while checking for overflow.
239 ///
240 /// Returns true if the result of `a + b` overflows the type of `out`; otherwise
241 /// stores the result in `out` and returns false.
242 ///
243 /// See also `PW_CHECK_ADD`.
244 #define PW_ADD_OVERFLOW(a, b, out) __builtin_add_overflow(a, b, out)
245 
246 /// `PW_SUB_OVERFLOW` subtracts an integer from another while checking for
247 /// overflow.
248 ///
249 /// Returns true if the result of `a - b` overflows the type of `out`; otherwise
250 /// stores the result in `out` and returns false.
251 ///
252 /// See also `PW_CHECK_SUB`.
253 #define PW_SUB_OVERFLOW(a, b, out) __builtin_sub_overflow(a, b, out)
254 
255 /// `PW_MUL_OVERFLOW` multiplies two integers while checking for overflow.
256 ///
257 /// Returns true if the result of `a * b` overflows the type of `out`; otherwise
258 /// stores the result in `out` and returns false.
259 ///
260 /// See also `PW_CHECK_MUL`.
261 #define PW_MUL_OVERFLOW(a, b, out) __builtin_mul_overflow(a, b, out)
262 
263 /// Evaluates to 1 if `__VA_OPT__` is supported, regardless of the C or C++
264 /// standard in use.
265 #if (defined(__clang_major__) && __clang_major__ < 9) || \
266     (defined(__GNUC__) && __GNUC__ < 12)
267 #define PW_VA_OPT_SUPPORTED() 0  // Don't bother checking on old compilers.
268 #else
269 #define PW_VA_OPT_SUPPORTED() _PW_VA_OPT_SUPPORTED()
270 /// @}
271 
272 #define _PW_VA_OPT_SUPPORTED(...) _PW_VA_OPT_SUPPORTED_##__VA_OPT__()
273 #define _PW_VA_OPT_SUPPORTED_ 1
274 #define _PW_VA_OPT_SUPPORTED___VA_OPT__() 0
275 
276 #endif  // __clang_major__ < 9 || __GNUC__ < 12
277