compiler_specific.h (17337B)
1 // Copyright 2012 The Chromium Authors 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(COMPILER_MSVC) && !defined(__clang__) 11 #error "Only clang-cl is supported on Windows, see https://crbug.com/988071" 12 #endif 13 14 // This is a wrapper around `__has_cpp_attribute`, which can be used to test for 15 // the presence of an attribute. In case the compiler does not support this 16 // macro it will simply evaluate to 0. 17 // 18 // References: 19 // https://wg21.link/sd6#testing-for-the-presence-of-an-attribute-__has_cpp_attribute 20 // https://wg21.link/cpp.cond#:__has_cpp_attribute 21 #if defined(__has_cpp_attribute) 22 #define HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) 23 #else 24 #define HAS_CPP_ATTRIBUTE(x) 0 25 #endif 26 27 // A wrapper around `__has_attribute`, similar to HAS_CPP_ATTRIBUTE. 28 #if defined(__has_attribute) 29 #define HAS_ATTRIBUTE(x) __has_attribute(x) 30 #else 31 #define HAS_ATTRIBUTE(x) 0 32 #endif 33 34 // A wrapper around `__has_builtin`, similar to HAS_CPP_ATTRIBUTE. 35 #if defined(__has_builtin) 36 #define HAS_BUILTIN(x) __has_builtin(x) 37 #else 38 #define HAS_BUILTIN(x) 0 39 #endif 40 41 // Annotate a function indicating it should not be inlined. 42 // Use like: 43 // NOINLINE void DoStuff() { ... } 44 #if defined(__clang__) && HAS_ATTRIBUTE(noinline) && __clang_major__ >= 15 45 #define NOINLINE [[clang::noinline]] 46 #elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(noinline) 47 #define NOINLINE __attribute__((noinline)) 48 #elif defined(COMPILER_MSVC) 49 #define NOINLINE __declspec(noinline) 50 #else 51 #define NOINLINE 52 #endif 53 54 #if defined(__clang__) && defined(NDEBUG) && HAS_ATTRIBUTE(always_inline) && \ 55 __clang_major__ >= 15 56 #define ALWAYS_INLINE [[clang::always_inline]] inline 57 #elif defined(COMPILER_GCC) && defined(NDEBUG) && HAS_ATTRIBUTE(always_inline) 58 #define ALWAYS_INLINE inline __attribute__((__always_inline__)) 59 #elif defined(COMPILER_MSVC) && defined(NDEBUG) 60 #define ALWAYS_INLINE __forceinline 61 #else 62 #define ALWAYS_INLINE inline 63 #endif 64 65 // Annotate a function indicating it should never be tail called. Useful to make 66 // sure callers of the annotated function are never omitted from call-stacks. 67 // To provide the complementary behavior (prevent the annotated function from 68 // being omitted) look at NOINLINE. Also note that this doesn't prevent code 69 // folding of multiple identical caller functions into a single signature. To 70 // prevent code folding, see NO_CODE_FOLDING() in base/debug/alias.h. 71 // Use like: 72 // NOT_TAIL_CALLED void FooBar(); 73 #if defined(__clang__) && HAS_ATTRIBUTE(not_tail_called) && \ 74 __clang_major__ >= 15 75 #define NOT_TAIL_CALLED [[clang::not_tail_called]] 76 #else 77 #define NOT_TAIL_CALLED 78 #endif 79 80 // Specify memory alignment for structs, classes, etc. 81 // Use like: 82 // class ALIGNAS(16) MyClass { ... } 83 // ALIGNAS(16) int array[4]; 84 // 85 // In most places you can use the C++11 keyword "alignas", which is preferred. 86 // 87 // Historically, compilers had trouble mixing __attribute__((...)) syntax with 88 // alignas(...) syntax. However, at least Clang is very accepting nowadays. It 89 // may be that this macro can be removed entirely. 90 #if defined(__clang__) 91 #define ALIGNAS(byte_alignment) alignas(byte_alignment) 92 #elif defined(COMPILER_MSVC) 93 #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment)) 94 #elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(aligned) 95 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment))) 96 #endif 97 98 // In case the compiler supports it NO_UNIQUE_ADDRESS evaluates to the C++20 99 // attribute [[no_unique_address]]. This allows annotating data members so that 100 // they need not have an address distinct from all other non-static data members 101 // of its class. 102 // 103 // References: 104 // * https://en.cppreference.com/w/cpp/language/attributes/no_unique_address 105 // * https://wg21.link/dcl.attr.nouniqueaddr 106 #if HAS_CPP_ATTRIBUTE(no_unique_address) 107 #define NO_UNIQUE_ADDRESS [[no_unique_address]] 108 #else 109 #define NO_UNIQUE_ADDRESS 110 #endif 111 112 // Tells the compiler a function is using a printf-style format string. 113 // |format_param| is the one-based index of the format string parameter; 114 // |dots_param| is the one-based index of the "..." parameter. 115 // For v*printf functions (which take a va_list), pass 0 for dots_param. 116 // (This is undocumented but matches what the system C headers do.) 117 // For member functions, the implicit this parameter counts as index 1. 118 #if (defined(COMPILER_GCC) || defined(__clang__)) && HAS_ATTRIBUTE(format) 119 #define PRINTF_FORMAT(format_param, dots_param) \ 120 __attribute__((format(printf, format_param, dots_param))) 121 #else 122 #define PRINTF_FORMAT(format_param, dots_param) 123 #endif 124 125 // WPRINTF_FORMAT is the same, but for wide format strings. 126 // This doesn't appear to yet be implemented in any compiler. 127 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 . 128 #define WPRINTF_FORMAT(format_param, dots_param) 129 // If available, it would look like: 130 // __attribute__((format(wprintf, format_param, dots_param))) 131 132 // Sanitizers annotations. 133 #if HAS_ATTRIBUTE(no_sanitize) 134 #define NO_SANITIZE(what) __attribute__((no_sanitize(what))) 135 #endif 136 #if !defined(NO_SANITIZE) 137 #define NO_SANITIZE(what) 138 #endif 139 140 // MemorySanitizer annotations. 141 #if defined(MEMORY_SANITIZER) && !BUILDFLAG(IS_NACL) 142 #include <sanitizer/msan_interface.h> 143 144 // Mark a memory region fully initialized. 145 // Use this to annotate code that deliberately reads uninitialized data, for 146 // example a GC scavenging root set pointers from the stack. 147 #define MSAN_UNPOISON(p, size) __msan_unpoison(p, size) 148 149 // Check a memory region for initializedness, as if it was being used here. 150 // If any bits are uninitialized, crash with an MSan report. 151 // Use this to sanitize data which MSan won't be able to track, e.g. before 152 // passing data to another process via shared memory. 153 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \ 154 __msan_check_mem_is_initialized(p, size) 155 #else // MEMORY_SANITIZER 156 #define MSAN_UNPOISON(p, size) 157 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) 158 #endif // MEMORY_SANITIZER 159 160 // DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons. 161 #if !defined(DISABLE_CFI_PERF) 162 #if defined(__clang__) && defined(OFFICIAL_BUILD) 163 #define DISABLE_CFI_PERF NO_SANITIZE("cfi") 164 #else 165 #define DISABLE_CFI_PERF 166 #endif 167 #endif 168 169 // DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks. 170 // Security Note: if you just need to allow calling of dlsym functions use 171 // DISABLE_CFI_DLSYM. 172 #if !defined(DISABLE_CFI_ICALL) 173 #if BUILDFLAG(IS_WIN) 174 // Windows also needs __declspec(guard(nocf)). 175 #define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") __declspec(guard(nocf)) 176 #else 177 #define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") 178 #endif 179 #endif 180 #if !defined(DISABLE_CFI_ICALL) 181 #define DISABLE_CFI_ICALL 182 #endif 183 184 // DISABLE_CFI_DLSYM -- applies DISABLE_CFI_ICALL on platforms where dlsym 185 // functions must be called. Retains CFI checks on platforms where loaded 186 // modules participate in CFI (e.g. Windows). 187 #if !defined(DISABLE_CFI_DLSYM) 188 #if BUILDFLAG(IS_WIN) 189 // Windows modules register functions when loaded so can be checked by CFG. 190 #define DISABLE_CFI_DLSYM 191 #else 192 #define DISABLE_CFI_DLSYM DISABLE_CFI_ICALL 193 #endif 194 #endif 195 #if !defined(DISABLE_CFI_DLSYM) 196 #define DISABLE_CFI_DLSYM 197 #endif 198 199 // Macro useful for writing cross-platform function pointers. 200 #if !defined(CDECL) 201 #if BUILDFLAG(IS_WIN) 202 #define CDECL __cdecl 203 #else // BUILDFLAG(IS_WIN) 204 #define CDECL 205 #endif // BUILDFLAG(IS_WIN) 206 #endif // !defined(CDECL) 207 208 // Macro for hinting that an expression is likely to be false. 209 #if !defined(UNLIKELY) 210 #if defined(COMPILER_GCC) || defined(__clang__) 211 #define UNLIKELY(x) __builtin_expect(!!(x), 0) 212 #else 213 #define UNLIKELY(x) (x) 214 #endif // defined(COMPILER_GCC) 215 #endif // !defined(UNLIKELY) 216 217 #if !defined(LIKELY) 218 #if defined(COMPILER_GCC) || defined(__clang__) 219 #define LIKELY(x) __builtin_expect(!!(x), 1) 220 #else 221 #define LIKELY(x) (x) 222 #endif // defined(COMPILER_GCC) 223 #endif // !defined(LIKELY) 224 225 // Compiler feature-detection. 226 // clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension 227 #if defined(__has_feature) 228 #define HAS_FEATURE(FEATURE) __has_feature(FEATURE) 229 #else 230 #define HAS_FEATURE(FEATURE) 0 231 #endif 232 233 #if defined(COMPILER_GCC) 234 #define PRETTY_FUNCTION __PRETTY_FUNCTION__ 235 #elif defined(COMPILER_MSVC) 236 #define PRETTY_FUNCTION __FUNCSIG__ 237 #else 238 // See https://en.cppreference.com/w/c/language/function_definition#func 239 #define PRETTY_FUNCTION __func__ 240 #endif 241 242 #if !defined(CPU_ARM_NEON) 243 #if defined(__arm__) 244 #if !defined(__ARMEB__) && !defined(__ARM_EABI__) && !defined(__EABI__) && \ 245 !defined(__VFP_FP__) && !defined(_WIN32_WCE) && !defined(ANDROID) 246 #error Chromium does not support middle endian architecture 247 #endif 248 #if defined(__ARM_NEON__) 249 #define CPU_ARM_NEON 1 250 #endif 251 #endif // defined(__arm__) 252 #endif // !defined(CPU_ARM_NEON) 253 254 #if !defined(HAVE_MIPS_MSA_INTRINSICS) 255 #if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5) 256 #define HAVE_MIPS_MSA_INTRINSICS 1 257 #endif 258 #endif 259 260 #if defined(__clang__) && HAS_ATTRIBUTE(uninitialized) 261 // Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for 262 // the specified variable. 263 // Library-wide alternative is 264 // 'configs -= [ "//build/config/compiler:default_init_stack_vars" ]' in .gn 265 // file. 266 // 267 // See "init_stack_vars" in build/config/compiler/BUILD.gn and 268 // http://crbug.com/977230 269 // "init_stack_vars" is enabled for non-official builds and we hope to enable it 270 // in official build in 2020 as well. The flag writes fixed pattern into 271 // uninitialized parts of all local variables. In rare cases such initialization 272 // is undesirable and attribute can be used: 273 // 1. Degraded performance 274 // In most cases compiler is able to remove additional stores. E.g. if memory is 275 // never accessed or properly initialized later. Preserved stores mostly will 276 // not affect program performance. However if compiler failed on some 277 // performance critical code we can get a visible regression in a benchmark. 278 // 2. memset, memcpy calls 279 // Compiler may replaces some memory writes with memset or memcpy calls. This is 280 // not -ftrivial-auto-var-init specific, but it can happen more likely with the 281 // flag. It can be a problem if code is not linked with C run-time library. 282 // 283 // Note: The flag is security risk mitigation feature. So in future the 284 // attribute uses should be avoided when possible. However to enable this 285 // mitigation on the most of the code we need to be less strict now and minimize 286 // number of exceptions later. So if in doubt feel free to use attribute, but 287 // please document the problem for someone who is going to cleanup it later. 288 // E.g. platform, bot, benchmark or test name in patch description or next to 289 // the attribute. 290 #define STACK_UNINITIALIZED [[clang::uninitialized]] 291 #else 292 #define STACK_UNINITIALIZED 293 #endif 294 295 // Attribute "no_stack_protector" disables -fstack-protector for the specified 296 // function. 297 // 298 // "stack_protector" is enabled on most POSIX builds. The flag adds a canary 299 // to each stack frame, which on function return is checked against a reference 300 // canary. If the canaries do not match, it's likely that a stack buffer 301 // overflow has occurred, so immediately crashing will prevent exploitation in 302 // many cases. 303 // 304 // In some cases it's desirable to remove this, e.g. on hot functions, or if 305 // we have purposely changed the reference canary. 306 #if defined(COMPILER_GCC) || defined(__clang__) 307 #if HAS_ATTRIBUTE(__no_stack_protector__) 308 #define NO_STACK_PROTECTOR __attribute__((__no_stack_protector__)) 309 #else 310 #define NO_STACK_PROTECTOR __attribute__((__optimize__("-fno-stack-protector"))) 311 #endif 312 #else 313 #define NO_STACK_PROTECTOR 314 #endif 315 316 // The ANALYZER_ASSUME_TRUE(bool arg) macro adds compiler-specific hints 317 // to Clang which control what code paths are statically analyzed, 318 // and is meant to be used in conjunction with assert & assert-like functions. 319 // The expression is passed straight through if analysis isn't enabled. 320 // 321 // ANALYZER_SKIP_THIS_PATH() suppresses static analysis for the current 322 // codepath and any other branching codepaths that might follow. 323 #if defined(__clang_analyzer__) 324 325 inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) { 326 return false; 327 } 328 329 inline constexpr bool AnalyzerAssumeTrue(bool arg) { 330 // AnalyzerNoReturn() is invoked and analysis is terminated if |arg| is 331 // false. 332 return arg || AnalyzerNoReturn(); 333 } 334 335 #define ANALYZER_ASSUME_TRUE(arg) ::AnalyzerAssumeTrue(!!(arg)) 336 #define ANALYZER_SKIP_THIS_PATH() static_cast<void>(::AnalyzerNoReturn()) 337 338 #else // !defined(__clang_analyzer__) 339 340 #define ANALYZER_ASSUME_TRUE(arg) (arg) 341 #define ANALYZER_SKIP_THIS_PATH() 342 343 #endif // defined(__clang_analyzer__) 344 345 // Use nomerge attribute to disable optimization of merging multiple same calls. 346 #if defined(__clang__) && HAS_ATTRIBUTE(nomerge) 347 #define NOMERGE [[clang::nomerge]] 348 #else 349 #define NOMERGE 350 #endif 351 352 // Marks a type as being eligible for the "trivial" ABI despite having a 353 // non-trivial destructor or copy/move constructor. Such types can be relocated 354 // after construction by simply copying their memory, which makes them eligible 355 // to be passed in registers. The canonical example is std::unique_ptr. 356 // 357 // Use with caution; this has some subtle effects on constructor/destructor 358 // ordering and will be very incorrect if the type relies on its address 359 // remaining constant. When used as a function argument (by value), the value 360 // may be constructed in the caller's stack frame, passed in a register, and 361 // then used and destructed in the callee's stack frame. A similar thing can 362 // occur when values are returned. 363 // 364 // TRIVIAL_ABI is not needed for types which have a trivial destructor and 365 // copy/move constructors, such as base::TimeTicks and other POD. 366 // 367 // It is also not likely to be effective on types too large to be passed in one 368 // or two registers on typical target ABIs. 369 // 370 // See also: 371 // https://clang.llvm.org/docs/AttributeReference.html#trivial-abi 372 // https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html 373 #if defined(__clang__) && HAS_ATTRIBUTE(trivial_abi) 374 #define TRIVIAL_ABI [[clang::trivial_abi]] 375 #else 376 #define TRIVIAL_ABI 377 #endif 378 379 // Detect whether a type is trivially relocatable, ie. a move-and-destroy 380 // sequence can replaced with memmove(). This can be used to optimise the 381 // implementation of containers. This is automatically true for types that were 382 // defined with TRIVIAL_ABI such as scoped_refptr. 383 // 384 // See also: 385 // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1144r8.html 386 // https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__is_trivially_relocatable 387 #if defined(__clang__) && HAS_BUILTIN(__is_trivially_relocatable) 388 #define IS_TRIVIALLY_RELOCATABLE(t) __is_trivially_relocatable(t) 389 #else 390 #define IS_TRIVIALLY_RELOCATABLE(t) false 391 #endif 392 393 // Marks a member function as reinitializing a moved-from variable. 394 // See also 395 // https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html#reinitialization 396 #if defined(__clang__) && HAS_ATTRIBUTE(reinitializes) 397 #define REINITIALIZES_AFTER_MOVE [[clang::reinitializes]] 398 #else 399 #define REINITIALIZES_AFTER_MOVE 400 #endif 401 402 // Requires constant initialization. See constinit in C++20. Allows to rely on a 403 // variable being initialized before execution, and not requiring a global 404 // constructor. 405 #if HAS_ATTRIBUTE(require_constant_initialization) 406 #define CONSTINIT __attribute__((require_constant_initialization)) 407 #endif 408 #if !defined(CONSTINIT) 409 #define CONSTINIT 410 #endif 411 412 #if defined(__clang__) && __clang_major__ >= 13 413 #define GSL_OWNER [[gsl::Owner]] 414 #define GSL_POINTER [[gsl::Pointer]] 415 #else 416 #define GSL_OWNER 417 #define GSL_POINTER 418 #endif 419 420 // Adds the "logically_const" tag to a symbol's mangled name. The "Mutable 421 // Constants" check [1] detects instances of constants that aren't in .rodata, 422 // e.g. due to a missing `const`. Using this tag suppresses the check for this 423 // symbol, allowing it to live outside .rodata without a warning. 424 // 425 // [1]: 426 // https://crsrc.org/c/docs/speed/binary_size/android_binary_size_trybot.md#Mutable-Constants 427 #if defined(COMPILER_GCC) || defined(__clang__) 428 #define LOGICALLY_CONST [[gnu::abi_tag("logically_const")]] 429 #else 430 #define LOGICALLY_CONST 431 #endif 432 433 // preserve_most clang's calling convention. Reduces register pressure for the 434 // caller and as such can be used for cold calls. Support for the 435 // "preserve_most" attribute is limited: 436 // - 32-bit platforms do not implement it, 437 // - component builds fail because _dl_runtime_resolve() clobbers registers, 438 // - there are crashes on arm64 on Windows (https://crbug.com/v8/14065), which 439 // can hopefully be fixed in the future. 440 // Additionally, the initial implementation in clang <= 16 overwrote the return 441 // register(s) in the epilogue of a preserve_most function, so we only use 442 // preserve_most in clang >= 17 (see https://reviews.llvm.org/D143425). 443 // See https://clang.llvm.org/docs/AttributeReference.html#preserve-most for 444 // more details. 445 #if defined(ARCH_CPU_64_BITS) && \ 446 !(BUILDFLAG(IS_WIN) && defined(ARCH_CPU_ARM64)) && \ 447 !defined(COMPONENT_BUILD) && defined(__clang__) && \ 448 __clang_major__ >= 17 && HAS_ATTRIBUTE(preserve_most) 449 #define PRESERVE_MOST __attribute__((preserve_most)) 450 #else 451 #define PRESERVE_MOST 452 #endif 453 454 #endif // BASE_COMPILER_SPECIFIC_H_