1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_ 6 #define THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_ 7 8 #include "build/build_config.h" 9 10 // Annotate a variable indicating it's ok if the variable is not used. 11 // (Typically used to silence a compiler warning when the assignment 12 // is important for some other reason.) 13 // Use like: 14 // int x = ...; 15 // ALLOW_UNUSED_LOCAL(x); 16 #define ALLOW_UNUSED_LOCAL(x) (void)x 17 18 // Annotate a typedef or function indicating it's ok if it's not used. 19 // Use like: 20 // typedef Foo Bar ALLOW_UNUSED_TYPE; 21 #if defined(COMPILER_GCC) || defined(__clang__) 22 #define ALLOW_UNUSED_TYPE __attribute__((unused)) 23 #else 24 #define ALLOW_UNUSED_TYPE 25 #endif 26 27 // Annotate a function indicating it should not be inlined. 28 // Use like: 29 // NOINLINE void DoStuff() { ... } 30 #if defined(COMPILER_GCC) 31 #define NOINLINE __attribute__((noinline)) 32 #elif defined(COMPILER_MSVC) 33 #define NOINLINE __declspec(noinline) 34 #else 35 #define NOINLINE 36 #endif 37 38 #if defined(COMPILER_GCC) && defined(NDEBUG) 39 #define ALWAYS_INLINE inline __attribute__((__always_inline__)) 40 #elif defined(COMPILER_MSVC) && defined(NDEBUG) 41 #define ALWAYS_INLINE __forceinline 42 #else 43 #define ALWAYS_INLINE inline 44 #endif 45 46 // Specify memory alignment for structs, classes, etc. 47 // Use like: 48 // class ALIGNAS(16) MyClass { ... } 49 // ALIGNAS(16) int array[4]; 50 // 51 // In most places you can use the C++11 keyword "alignas", which is preferred. 52 // 53 // But compilers have trouble mixing __attribute__((...)) syntax with 54 // alignas(...) syntax. 55 // 56 // Doesn't work in clang or gcc: 57 // struct alignas(16) __attribute__((packed)) S { char c; }; 58 // Works in clang but not gcc: 59 // struct __attribute__((packed)) alignas(16) S2 { char c; }; 60 // Works in clang and gcc: 61 // struct alignas(16) S3 { char c; } __attribute__((packed)); 62 // 63 // There are also some attributes that must be specified *before* a class 64 // definition: visibility (used for exporting functions/classes) is one of 65 // these attributes. This means that it is not possible to use alignas() with a 66 // class that is marked as exported. 67 #if defined(COMPILER_MSVC) 68 #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) 69 #elif defined(COMPILER_GCC) 70 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) 71 #endif 72 73 // Annotate a function indicating the caller must examine the return value. 74 // Use like: 75 // int foo() WARN_UNUSED_RESULT; 76 // To explicitly ignore a result, see |ignore_result()| in base/macros.h. 77 #undef WARN_UNUSED_RESULT 78 #if defined(COMPILER_GCC) || defined(__clang__) 79 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 80 #else 81 #define WARN_UNUSED_RESULT 82 #endif 83 84 // Tell the compiler a function is using a printf-style format string. 85 // |format_param| is the one-based index of the format string parameter; 86 // |dots_param| is the one-based index of the "..." parameter. 87 // For v*printf functions (which take a va_list), pass 0 for dots_param. 88 // (This is undocumented but matches what the system C headers do.) 89 #if defined(COMPILER_GCC) || defined(__clang__) 90 #define PRINTF_FORMAT(format_param, dots_param) \ 91 __attribute__((format(printf, format_param, dots_param))) 92 #else 93 #define PRINTF_FORMAT(format_param, dots_param) 94 #endif 95 96 // WPRINTF_FORMAT is the same, but for wide format strings. 97 // This doesn't appear to yet be implemented in any compiler. 98 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 . 99 #define WPRINTF_FORMAT(format_param, dots_param) 100 // If available, it would look like: 101 // __attribute__((format(wprintf, format_param, dots_param))) 102 103 // Sanitizers annotations. 104 #if defined(__has_attribute) 105 #if __has_attribute(no_sanitize) 106 #define NO_SANITIZE(what) __attribute__((no_sanitize(what))) 107 #endif 108 #endif 109 #if !defined(NO_SANITIZE) 110 #define NO_SANITIZE(what) 111 #endif 112 113 // MemorySanitizer annotations. 114 #if defined(MEMORY_SANITIZER) && !defined(OS_NACL) 115 #include <sanitizer/msan_interface.h> 116 117 // Mark a memory region fully initialized. 118 // Use this to annotate code that deliberately reads uninitialized data, for 119 // example a GC scavenging root set pointers from the stack. 120 #define MSAN_UNPOISON(p, size) __msan_unpoison(p, size) 121 122 // Check a memory region for initializedness, as if it was being used here. 123 // If any bits are uninitialized, crash with an MSan report. 124 // Use this to sanitize data which MSan won't be able to track, e.g. before 125 // passing data to another process via shared memory. 126 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \ 127 __msan_check_mem_is_initialized(p, size) 128 #else // MEMORY_SANITIZER 129 #define MSAN_UNPOISON(p, size) 130 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) 131 #endif // MEMORY_SANITIZER 132 133 // DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons. 134 #if !defined(DISABLE_CFI_PERF) 135 #if defined(__clang__) && defined(OFFICIAL_BUILD) 136 #define DISABLE_CFI_PERF __attribute__((no_sanitize("cfi"))) 137 #else 138 #define DISABLE_CFI_PERF 139 #endif 140 #endif 141 142 // Macro useful for writing cross-platform function pointers. 143 #if !defined(CDECL) 144 #if defined(OS_WIN) 145 #define CDECL __cdecl 146 #else // defined(OS_WIN) 147 #define CDECL 148 #endif // defined(OS_WIN) 149 #endif // !defined(CDECL) 150 151 // Macro for hinting that an expression is likely to be false. 152 #if !defined(UNLIKELY) 153 #if defined(COMPILER_GCC) || defined(__clang__) 154 #define UNLIKELY(x) __builtin_expect(!!(x), 0) 155 #else 156 #define UNLIKELY(x) (x) 157 #endif // defined(COMPILER_GCC) 158 #endif // !defined(UNLIKELY) 159 160 #if !defined(LIKELY) 161 #if defined(COMPILER_GCC) || defined(__clang__) 162 #define LIKELY(x) __builtin_expect(!!(x), 1) 163 #else 164 #define LIKELY(x) (x) 165 #endif // defined(COMPILER_GCC) 166 #endif // !defined(LIKELY) 167 168 // Compiler feature-detection. 169 // clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension 170 #if defined(__has_feature) 171 #define HAS_FEATURE(FEATURE) __has_feature(FEATURE) 172 #else 173 #define HAS_FEATURE(FEATURE) 0 174 #endif 175 176 // Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional. 177 #if defined(__clang__) 178 #define FALLTHROUGH [[clang::fallthrough]] 179 #else 180 #define FALLTHROUGH 181 #endif 182 183 #endif // THIRD_PARTY_BASE_COMPILER_SPECIFIC_H_ 184