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