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 BASE_COMPILER_SPECIFIC_H_ 6 #define BASE_COMPILER_SPECIFIC_H_ 7 8 #include "build/build_config.h" 9 10 #if defined(ANDROID) 11 // Prefer Android's libbase definitions to our own. 12 #include <android-base/macros.h> 13 #endif // defined(ANDROID) 14 15 #if defined(COMPILER_MSVC) 16 17 // For _Printf_format_string_. 18 #include <sal.h> 19 20 // Macros for suppressing and disabling warnings on MSVC. 21 // 22 // Warning numbers are enumerated at: 23 // http://msdn.microsoft.com/en-us/library/8x5x43k7(VS.80).aspx 24 // 25 // The warning pragma: 26 // http://msdn.microsoft.com/en-us/library/2c8f766e(VS.80).aspx 27 // 28 // Using __pragma instead of #pragma inside macros: 29 // http://msdn.microsoft.com/en-us/library/d9x1s805.aspx 30 31 // MSVC_SUPPRESS_WARNING disables warning |n| for the remainder of the line and 32 // for the next line of the source file. 33 #define MSVC_SUPPRESS_WARNING(n) __pragma(warning(suppress:n)) 34 35 // MSVC_PUSH_DISABLE_WARNING pushes |n| onto a stack of warnings to be disabled. 36 // The warning remains disabled until popped by MSVC_POP_WARNING. 37 #define MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ 38 __pragma(warning(disable:n)) 39 40 // MSVC_PUSH_WARNING_LEVEL pushes |n| as the global warning level. The level 41 // remains in effect until popped by MSVC_POP_WARNING(). Use 0 to disable all 42 // warnings. 43 #define MSVC_PUSH_WARNING_LEVEL(n) __pragma(warning(push, n)) 44 45 // Pop effects of innermost MSVC_PUSH_* macro. 46 #define MSVC_POP_WARNING() __pragma(warning(pop)) 47 48 #define MSVC_DISABLE_OPTIMIZE() __pragma(optimize("", off)) 49 #define MSVC_ENABLE_OPTIMIZE() __pragma(optimize("", on)) 50 51 #else // Not MSVC 52 53 #define _Printf_format_string_ 54 #define MSVC_SUPPRESS_WARNING(n) 55 #define MSVC_PUSH_DISABLE_WARNING(n) 56 #define MSVC_PUSH_WARNING_LEVEL(n) 57 #define MSVC_POP_WARNING() 58 #define MSVC_DISABLE_OPTIMIZE() 59 #define MSVC_ENABLE_OPTIMIZE() 60 61 #endif // COMPILER_MSVC 62 63 // Annotate a variable indicating it's ok if the variable is not used. 64 // (Typically used to silence a compiler warning when the assignment 65 // is important for some other reason.) 66 // Use like: 67 // int x = ...; 68 // ALLOW_UNUSED_LOCAL(x); 69 #define ALLOW_UNUSED_LOCAL(x) (void)x 70 71 // Annotate a typedef or function indicating it's ok if it's not used. 72 // Use like: 73 // typedef Foo Bar ALLOW_UNUSED_TYPE; 74 #if defined(COMPILER_GCC) || defined(__clang__) 75 #define ALLOW_UNUSED_TYPE __attribute__((unused)) 76 #else 77 #define ALLOW_UNUSED_TYPE 78 #endif 79 80 // Annotate a function indicating it should not be inlined. 81 // Use like: 82 // NOINLINE void DoStuff() { ... } 83 #if defined(COMPILER_GCC) 84 #define NOINLINE __attribute__((noinline)) 85 #elif defined(COMPILER_MSVC) 86 #define NOINLINE __declspec(noinline) 87 #else 88 #define NOINLINE 89 #endif 90 91 #if COMPILER_GCC && defined(NDEBUG) 92 #define ALWAYS_INLINE inline __attribute__((__always_inline__)) 93 #elif COMPILER_MSVC && defined(NDEBUG) 94 #define ALWAYS_INLINE __forceinline 95 #else 96 #define ALWAYS_INLINE inline 97 #endif 98 99 // Specify memory alignment for structs, classes, etc. 100 // Use like: 101 // class ALIGNAS(16) MyClass { ... } 102 // ALIGNAS(16) int array[4]; 103 // 104 // In most places you can use the C++11 keyword "alignas", which is preferred. 105 // 106 // But compilers have trouble mixing __attribute__((...)) syntax with 107 // alignas(...) syntax. 108 // 109 // Doesn't work in clang or gcc: 110 // struct alignas(16) __attribute__((packed)) S { char c; }; 111 // Works in clang but not gcc: 112 // struct __attribute__((packed)) alignas(16) S2 { char c; }; 113 // Works in clang and gcc: 114 // struct alignas(16) S3 { char c; } __attribute__((packed)); 115 // 116 // There are also some attributes that must be specified *before* a class 117 // definition: visibility (used for exporting functions/classes) is one of 118 // these attributes. This means that it is not possible to use alignas() with a 119 // class that is marked as exported. 120 #if defined(COMPILER_MSVC) 121 #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) 122 #elif defined(COMPILER_GCC) 123 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) 124 #endif 125 126 // Annotate a function indicating the caller must examine the return value. 127 // Use like: 128 // int foo() WARN_UNUSED_RESULT; 129 // To explicitly ignore a result, see |ignore_result()| in base/macros.h. 130 #undef WARN_UNUSED_RESULT 131 #if defined(COMPILER_GCC) || defined(__clang__) 132 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) 133 #else 134 #define WARN_UNUSED_RESULT 135 #endif 136 137 // Tell the compiler a function is using a printf-style format string. 138 // |format_param| is the one-based index of the format string parameter; 139 // |dots_param| is the one-based index of the "..." parameter. 140 // For v*printf functions (which take a va_list), pass 0 for dots_param. 141 // (This is undocumented but matches what the system C headers do.) 142 #if defined(COMPILER_GCC) || defined(__clang__) 143 #define PRINTF_FORMAT(format_param, dots_param) \ 144 __attribute__((format(printf, format_param, dots_param))) 145 #else 146 #define PRINTF_FORMAT(format_param, dots_param) 147 #endif 148 149 // WPRINTF_FORMAT is the same, but for wide format strings. 150 // This doesn't appear to yet be implemented in any compiler. 151 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 . 152 #define WPRINTF_FORMAT(format_param, dots_param) 153 // If available, it would look like: 154 // __attribute__((format(wprintf, format_param, dots_param))) 155 156 // Sanitizers annotations. 157 #if defined(__has_attribute) 158 #if __has_attribute(no_sanitize) 159 #define NO_SANITIZE(what) __attribute__((no_sanitize(what))) 160 #endif 161 #endif 162 #if !defined(NO_SANITIZE) 163 #define NO_SANITIZE(what) 164 #endif 165 166 // MemorySanitizer annotations. 167 #if defined(MEMORY_SANITIZER) && !defined(OS_NACL) 168 #include <sanitizer/msan_interface.h> 169 170 // Mark a memory region fully initialized. 171 // Use this to annotate code that deliberately reads uninitialized data, for 172 // example a GC scavenging root set pointers from the stack. 173 #define MSAN_UNPOISON(p, size) __msan_unpoison(p, size) 174 175 // Check a memory region for initializedness, as if it was being used here. 176 // If any bits are uninitialized, crash with an MSan report. 177 // Use this to sanitize data which MSan won't be able to track, e.g. before 178 // passing data to another process via shared memory. 179 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \ 180 __msan_check_mem_is_initialized(p, size) 181 #else // MEMORY_SANITIZER 182 #define MSAN_UNPOISON(p, size) 183 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) 184 #endif // MEMORY_SANITIZER 185 186 // DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons. 187 #if !defined(DISABLE_CFI_PERF) 188 #if defined(__clang__) && defined(OFFICIAL_BUILD) 189 #define DISABLE_CFI_PERF __attribute__((no_sanitize("cfi"))) 190 #else 191 #define DISABLE_CFI_PERF 192 #endif 193 #endif 194 195 // Macro useful for writing cross-platform function pointers. 196 #if !defined(CDECL) 197 #if defined(OS_WIN) 198 #define CDECL __cdecl 199 #else // defined(OS_WIN) 200 #define CDECL 201 #endif // defined(OS_WIN) 202 #endif // !defined(CDECL) 203 204 // Macro for hinting that an expression is likely to be false. 205 #if !defined(UNLIKELY) 206 #if defined(COMPILER_GCC) || defined(__clang__) 207 #define UNLIKELY(x) __builtin_expect(!!(x), 0) 208 #else 209 #define UNLIKELY(x) (x) 210 #endif // defined(COMPILER_GCC) 211 #endif // !defined(UNLIKELY) 212 213 #if !defined(LIKELY) 214 #if defined(COMPILER_GCC) || defined(__clang__) 215 #define LIKELY(x) __builtin_expect(!!(x), 1) 216 #else 217 #define LIKELY(x) (x) 218 #endif // defined(COMPILER_GCC) 219 #endif // !defined(LIKELY) 220 221 // Compiler feature-detection. 222 // clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension 223 #if defined(__has_feature) 224 #define HAS_FEATURE(FEATURE) __has_feature(FEATURE) 225 #else 226 #define HAS_FEATURE(FEATURE) 0 227 #endif 228 229 // Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional. 230 #if defined(__clang__) 231 #define FALLTHROUGH [[clang::fallthrough]] 232 #else 233 #define FALLTHROUGH 234 #endif 235 236 #endif // BASE_COMPILER_SPECIFIC_H_ 237