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 #include <assert.h> 20 21 // Marks a struct or class as packed. 22 #define PW_PACKED(declaration) declaration __attribute__((packed)) 23 24 // Marks a function or object as used, ensuring code for it is generated. 25 #define PW_USED __attribute__((used)) 26 27 // Prevents generation of a prologue or epilogue for a function. This is 28 // helpful when implementing the function in assembly. 29 #define PW_NO_PROLOGUE __attribute__((naked)) 30 31 // Marks that a function declaration takes a printf-style format string and 32 // variadic arguments. This allows the compiler to perform check the validity of 33 // the format string and arguments. This macro must only be on the function 34 // declaration, not the definition. 35 // 36 // The format_index is index of the format string parameter and parameter_index 37 // is the starting index of the variadic arguments. Indices start at 1. For C++ 38 // class member functions, add one to the index to account for the implicit this 39 // parameter. 40 // 41 // This example shows a function where the format string is argument 2 and the 42 // varargs start at argument 3. 43 // 44 // int PrintfStyleFunction(char* buffer, 45 // const char* fmt, ...) PW_PRINTF_FORMAT(2,3); 46 // 47 // int PrintfStyleFunction(char* buffer, const char* fmt, ...) { 48 // ... implementation here ... 49 // } 50 // 51 52 // When compiling for host using MinGW, use gnu_printf() rather than printf() 53 // to support %z format specifiers. 54 #ifdef __USE_MINGW_ANSI_STDIO 55 #define _PW_PRINTF_FORMAT_TYPE gnu_printf 56 #else 57 #define _PW_PRINTF_FORMAT_TYPE printf 58 #endif // __USE_MINGW_ANSI_STDIO 59 60 #define PW_PRINTF_FORMAT(format_index, parameter_index) \ 61 __attribute__((format(_PW_PRINTF_FORMAT_TYPE, format_index, parameter_index))) 62 63 // Places a variable in the specified linker section and directs the compiler 64 // to keep the variable, even if it is not used. Depending on the linker 65 // options, the linker may still remove this section if it is not declared in 66 // the linker script and marked KEEP. 67 #ifdef __APPLE__ 68 #define PW_KEEP_IN_SECTION(name) __attribute__((section("__DATA," name), used)) 69 #else 70 #define PW_KEEP_IN_SECTION(name) __attribute__((section(name), used)) 71 #endif // __APPLE__ 72 73 // Indicate to the compiler that the annotated function won't return. Example: 74 // 75 // PW_NO_RETURN void HandleAssertFailure(ErrorCode error_code); 76 // 77 #define PW_NO_RETURN __attribute__((noreturn)) 78 79 // Prevents the compiler from inlining a fuction. 80 #define PW_NO_INLINE __attribute__((noinline)) 81 82 // Indicate to the compiler that the given section of code will not be reached. 83 // Example: 84 // 85 // int main() { 86 // InitializeBoard(); 87 // vendor_StartScheduler(); // Note: vendor forgot noreturn attribute. 88 // PW_UNREACHABLE; 89 // } 90 // 91 #define PW_UNREACHABLE __builtin_unreachable() 92 93 // Indicate to a sanitizer compiler runtime to skip the named check in the 94 // associated function. 95 // Example: 96 // 97 // uint32_t djb2(const void* buf, size_t len) 98 // PW_NO_SANITIZE("unsigned-integer-overflow"){ 99 // uint32_t hash = 5381; 100 // const uint8_t* u8 = static_cast<const uint8_t*>(buf); 101 // for (size_t i = 0; i < len; ++i) { 102 // hash = (hash * 33) + u8[i]; /* hash * 33 + c */ 103 // } 104 // return hash; 105 // } 106 #ifdef __clang__ 107 #define PW_NO_SANITIZE(check) __attribute__((no_sanitize(check))) 108 #else 109 #define PW_NO_SANITIZE(check) 110 #endif // __clang__ 111 112 // Wrapper around `__has_attribute`, which is defined by GCC 5+ and Clang and 113 // evaluates to a non zero constant integer if the attribute is supported or 0 114 // if not. 115 #ifdef __has_attribute 116 #define PW_HAVE_ATTRIBUTE(x) __has_attribute(x) 117 #else 118 #define PW_HAVE_ATTRIBUTE(x) 0 119 #endif 120 121 #define _PW_REQUIRE_SEMICOLON \ 122 static_assert(1, "This macro must be terminated with a semicolon") 123 124 // PW_MODIFY_DIAGNOSTICS_PUSH and PW_MODIFY_DIAGNOSTICS_POP are used to turn off 125 // or on diagnostics (warnings or errors) for a section of code. Use 126 // PW_MODIFY_DIAGNOSTICS_PUSH, use PW_MODIFY_DIAGNOSTIC as many times as needed, 127 // then use PW_MODIFY_DIAGNOSTICS_POP to restore the previous settings. 128 #define PW_MODIFY_DIAGNOSTICS_PUSH() \ 129 _Pragma("GCC diagnostic push") _PW_REQUIRE_SEMICOLON 130 #define PW_MODIFY_DIAGNOSTICS_POP() \ 131 _Pragma("GCC diagnostic pop") _PW_REQUIRE_SEMICOLON 132 133 // Changes how a diagnostic (warning or error) is handled. Most commonly used to 134 // disable warnings. PW_MODIFY_DIAGNOSTIC should be used between 135 // PW_MODIFY_DIAGNOSTICS_PUSH and PW_MODIFY_DIAGNOSTICS_POP statements to avoid 136 // applying the modifications too broadly. 137 // 138 // 'kind' must be one of warning, error, or ignored. 139 #define PW_MODIFY_DIAGNOSTIC(kind, option) \ 140 PW_PRAGMA(GCC diagnostic kind option) _PW_REQUIRE_SEMICOLON 141 142 // Applies PW_MODIFY_DIAGNOSTIC only for GCC. This is useful for warnings that 143 // aren't supported by or don't need to be changed in other compilers. 144 #ifdef __clang__ 145 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) _PW_REQUIRE_SEMICOLON 146 #else 147 #define PW_MODIFY_DIAGNOSTIC_GCC(kind, option) \ 148 PW_MODIFY_DIAGNOSTIC(kind, option) 149 #endif // __clang__ 150 151 // Expands to a _Pragma with the contents as a string. _Pragma must take a 152 // single string literal; this can be used to construct a _Pragma argument. 153 #define PW_PRAGMA(contents) _Pragma(#contents) 154