blob: 2ce3c7b2eafd4f5ccb2cb699c7499922c318fcce [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]f1ea2fa2008-08-21 22:26:064
5#ifndef BASE_COMPILER_SPECIFIC_H_
6#define BASE_COMPILER_SPECIFIC_H_
7
8#include "build/build_config.h"
9
Nico Weberfb053cc2020-03-03 13:33:0510#if defined(COMPILER_MSVC) && !defined(__clang__)
Nico Weber59791812019-07-27 04:02:1111#error "Only clang-cl is supported on Windows, see https://crbug.com/988071"
12#endif
13
Peter Kastingc3dadb022024-09-17 22:44:5414// A wrapper around `__has_attribute`, which can be used to test for
Jan Wilken Dörrief8d479d2020-11-23 12:21:1315// the presence of an attribute. In case the compiler does not support this
16// macro it will simply evaluate to 0.
Peter Kasting64c67dd2022-05-12 18:11:5117#if defined(__has_attribute)
18#define HAS_ATTRIBUTE(x) __has_attribute(x)
19#else
20#define HAS_ATTRIBUTE(x) 0
21#endif
22
Jann Horn9e4b48552021-03-04 14:34:2723// A wrapper around `__has_builtin`, similar to HAS_CPP_ATTRIBUTE.
24#if defined(__has_builtin)
25#define HAS_BUILTIN(x) __has_builtin(x)
26#else
27#define HAS_BUILTIN(x) 0
28#endif
29
[email protected]2149cc622012-02-14 01:12:1230// Annotate a function indicating it should not be inlined.
31// Use like:
32// NOINLINE void DoStuff() { ... }
Peter Kastingc3dadb022024-09-17 22:44:5433#if __has_cpp_attribute(gnu::noinline)
34#define NOINLINE [[gnu::noinline]]
35#elif __has_cpp_attribute(msvc::noinline)
36#define NOINLINE [[msvc::noinline]]
[email protected]2149cc622012-02-14 01:12:1237#else
[email protected]50795a02011-05-09 20:11:0138#define NOINLINE
[email protected]f50595102010-10-08 16:20:3239#endif
40
Jose Dapena Paz7cc1b1d42023-11-08 18:37:2841// Annotate a function indicating it should not be optimized.
Peter Kastingc3dadb022024-09-17 22:44:5442#if __has_cpp_attribute(clang::optnone)
Jose Dapena Paz7cc1b1d42023-11-08 18:37:2843#define NOOPT [[clang::optnone]]
Peter Kastingc3dadb022024-09-17 22:44:5444#elif __has_cpp_attribute(gnu::optimize)
45#define NOOPT [[gnu::optimize(0)]]
Jose Dapena Paz7cc1b1d42023-11-08 18:37:2846#else
47#define NOOPT
48#endif
49
Peter Kastingc3dadb022024-09-17 22:44:5450#if defined(NDEBUG)
51#if __has_cpp_attribute(gnu::always_inline)
52#define ALWAYS_INLINE [[gnu::always_inline]] inline
53#elif defined(COMPILER_MSVC)
palmer58184a8282016-11-08 19:15:3954#define ALWAYS_INLINE __forceinline
Peter Kastingc3dadb022024-09-17 22:44:5455#endif
56#endif
57#if !defined(ALWAYS_INLINE)
palmer58184a8282016-11-08 19:15:3958#define ALWAYS_INLINE inline
59#endif
60
Olivier Li19d89252020-05-13 17:57:5561// Annotate a function indicating it should never be tail called. Useful to make
62// sure callers of the annotated function are never omitted from call-stacks.
63// To provide the complementary behavior (prevent the annotated function from
64// being omitted) look at NOINLINE. Also note that this doesn't prevent code
65// folding of multiple identical caller functions into a single signature. To
Bruce Dawson7915efd2021-01-27 18:07:5866// prevent code folding, see NO_CODE_FOLDING() in base/debug/alias.h.
Olivier Li19d89252020-05-13 17:57:5567// Use like:
Daniel Chengddf1b222023-02-02 02:41:5268// NOT_TAIL_CALLED void FooBar();
Peter Kastingc3dadb022024-09-17 22:44:5469#if __has_cpp_attribute(clang::not_tail_called)
Peter Kastingf541f7782023-03-10 23:44:4670#define NOT_TAIL_CALLED [[clang::not_tail_called]]
Olivier Li19d89252020-05-13 17:57:5571#else
72#define NOT_TAIL_CALLED
73#endif
74
mikt2a4fdf02024-07-09 18:47:5775// Annotate a function indicating it must be tail called.
76// Can be used only on return statements, even for functions returning void.
77// Caller and callee must have the same number of arguments and its types must
78// be "similar".
Peter Kastingc3dadb022024-09-17 22:44:5479#if __has_cpp_attribute(clang::musttail)
mikt2a4fdf02024-07-09 18:47:5780#define MUSTTAIL [[clang::musttail]]
81#else
82#define MUSTTAIL
83#endif
84
Jan Wilken Dörrief8d479d2020-11-23 12:21:1385// In case the compiler supports it NO_UNIQUE_ADDRESS evaluates to the C++20
86// attribute [[no_unique_address]]. This allows annotating data members so that
87// they need not have an address distinct from all other non-static data members
88// of its class.
89//
90// References:
91// * https://en.cppreference.com/w/cpp/language/attributes/no_unique_address
92// * https://wg21.link/dcl.attr.nouniqueaddr
Peter Kastingc3dadb022024-09-17 22:44:5493//
Peter Kasting8bc046d22023-11-14 00:38:0394// Unfortunately MSVC ignores [[no_unique_address]] (see
95// https://devblogs.microsoft.com/cppblog/msvc-cpp20-and-the-std-cpp20-switch/#msvc-extensions-and-abi),
96// and clang-cl matches it for ABI compatibility reasons. We need to prefer
97// [[msvc::no_unique_address]] when available if we actually want any effect.
Peter Kastingc3dadb022024-09-17 22:44:5498#if __has_cpp_attribute(msvc::no_unique_address)
Helmut Januschka13cd38b2023-12-22 03:31:4799#define NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
Peter Kastingc3dadb022024-09-17 22:44:54100#elif __has_cpp_attribute(no_unique_address)
Jan Wilken Dörrief8d479d2020-11-23 12:21:13101#define NO_UNIQUE_ADDRESS [[no_unique_address]]
102#else
103#define NO_UNIQUE_ADDRESS
104#endif
105
Peter Kastingf541f7782023-03-10 23:44:46106// Tells the compiler a function is using a printf-style format string.
[email protected]34b2b002009-11-20 06:53:28107// |format_param| is the one-based index of the format string parameter;
108// |dots_param| is the one-based index of the "..." parameter.
109// For v*printf functions (which take a va_list), pass 0 for dots_param.
110// (This is undocumented but matches what the system C headers do.)
Nico Weberfc7c8dd2019-02-28 21:28:44111// For member functions, the implicit this parameter counts as index 1.
Peter Kastingc3dadb022024-09-17 22:44:54112#if __has_cpp_attribute(gnu::format)
[email protected]34b2b002009-11-20 06:53:28113#define PRINTF_FORMAT(format_param, dots_param) \
Peter Kastingc3dadb022024-09-17 22:44:54114 [[gnu::format(printf, format_param, dots_param)]]
[email protected]f50595102010-10-08 16:20:32115#else
116#define PRINTF_FORMAT(format_param, dots_param)
117#endif
[email protected]34b2b002009-11-20 06:53:28118
etienneb4e9250a2016-11-18 18:47:53119// Sanitizers annotations.
Peter Kastingc3dadb022024-09-17 22:44:54120#if __has_cpp_attribute(clang::no_sanitize)
121#define NO_SANITIZE(sanitizer) [[clang::no_sanitize(sanitizer)]]
122#else
123#define NO_SANITIZE(sanitizer)
etienneb4e9250a2016-11-18 18:47:53124#endif
125
[email protected]75086be2013-03-20 21:18:22126// MemorySanitizer annotations.
Xiaohan Wang38e4ebb2022-01-19 06:57:43127#if defined(MEMORY_SANITIZER) && !BUILDFLAG(IS_NACL)
[email protected]eb82dfb2014-02-03 19:51:17128#include <sanitizer/msan_interface.h>
[email protected]75086be2013-03-20 21:18:22129
130// Mark a memory region fully initialized.
131// Use this to annotate code that deliberately reads uninitialized data, for
132// example a GC scavenging root set pointers from the stack.
Vitaly Buka2b790762019-12-20 21:11:48133#define MSAN_UNPOISON(p, size) __msan_unpoison(p, size)
thestig1a42b4072015-03-16 22:36:55134
135// Check a memory region for initializedness, as if it was being used here.
136// If any bits are uninitialized, crash with an MSan report.
137// Use this to sanitize data which MSan won't be able to track, e.g. before
138// passing data to another process via shared memory.
139#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \
Vitaly Buka2b790762019-12-20 21:11:48140 __msan_check_mem_is_initialized(p, size)
[email protected]75086be2013-03-20 21:18:22141#else // MEMORY_SANITIZER
thestig1a42b4072015-03-16 22:36:55142#define MSAN_UNPOISON(p, size)
143#define MSAN_CHECK_MEM_IS_INITIALIZED(p, size)
[email protected]75086be2013-03-20 21:18:22144#endif // MEMORY_SANITIZER
145
krasin825ce482016-08-27 11:01:11146// DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons.
147#if !defined(DISABLE_CFI_PERF)
krasin40f7c782016-09-22 19:04:27148#if defined(__clang__) && defined(OFFICIAL_BUILD)
Peter Kastingf541f7782023-03-10 23:44:46149#define DISABLE_CFI_PERF NO_SANITIZE("cfi")
krasin825ce482016-08-27 11:01:11150#else
151#define DISABLE_CFI_PERF
152#endif
153#endif
154
Will Harris9a033b02020-07-11 01:26:54155// DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks.
Alex Gough36579802022-07-25 20:20:46156// Security Note: if you just need to allow calling of dlsym functions use
157// DISABLE_CFI_DLSYM.
Will Harris9a033b02020-07-11 01:26:54158#if !defined(DISABLE_CFI_ICALL)
Xiaohan Wang38e4ebb2022-01-19 06:57:43159#if BUILDFLAG(IS_WIN)
Will Harris9a033b02020-07-11 01:26:54160// Windows also needs __declspec(guard(nocf)).
161#define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") __declspec(guard(nocf))
162#else
163#define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall")
164#endif
165#endif
Will Harris9a033b02020-07-11 01:26:54166
Alex Gough36579802022-07-25 20:20:46167// DISABLE_CFI_DLSYM -- applies DISABLE_CFI_ICALL on platforms where dlsym
168// functions must be called. Retains CFI checks on platforms where loaded
169// modules participate in CFI (e.g. Windows).
170#if !defined(DISABLE_CFI_DLSYM)
171#if BUILDFLAG(IS_WIN)
172// Windows modules register functions when loaded so can be checked by CFG.
173#define DISABLE_CFI_DLSYM
174#else
175#define DISABLE_CFI_DLSYM DISABLE_CFI_ICALL
176#endif
177#endif
Alex Gough36579802022-07-25 20:20:46178
jfbd81c1ce2016-04-05 20:50:35179// Compiler feature-detection.
jfba8dc9dd82016-04-06 20:20:31180// clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension
181#if defined(__has_feature)
182#define HAS_FEATURE(FEATURE) __has_feature(FEATURE)
183#else
184#define HAS_FEATURE(FEATURE) 0
jfbd81c1ce2016-04-05 20:50:35185#endif
186
Alex Clarke23c6cf72018-11-21 13:22:27187#if defined(COMPILER_GCC)
188#define PRETTY_FUNCTION __PRETTY_FUNCTION__
189#elif defined(COMPILER_MSVC)
190#define PRETTY_FUNCTION __FUNCSIG__
191#else
192// See https://en.cppreference.com/w/c/language/function_definition#func
193#define PRETTY_FUNCTION __func__
194#endif
195
Vitaly Buka2b790762019-12-20 21:11:48196// Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for
197// the specified variable.
198// Library-wide alternative is
199// 'configs -= [ "//build/config/compiler:default_init_stack_vars" ]' in .gn
200// file.
201//
202// See "init_stack_vars" in build/config/compiler/BUILD.gn and
203// http://crbug.com/977230
204// "init_stack_vars" is enabled for non-official builds and we hope to enable it
205// in official build in 2020 as well. The flag writes fixed pattern into
206// uninitialized parts of all local variables. In rare cases such initialization
207// is undesirable and attribute can be used:
208// 1. Degraded performance
209// In most cases compiler is able to remove additional stores. E.g. if memory is
210// never accessed or properly initialized later. Preserved stores mostly will
211// not affect program performance. However if compiler failed on some
212// performance critical code we can get a visible regression in a benchmark.
213// 2. memset, memcpy calls
214// Compiler may replaces some memory writes with memset or memcpy calls. This is
215// not -ftrivial-auto-var-init specific, but it can happen more likely with the
216// flag. It can be a problem if code is not linked with C run-time library.
217//
218// Note: The flag is security risk mitigation feature. So in future the
219// attribute uses should be avoided when possible. However to enable this
220// mitigation on the most of the code we need to be less strict now and minimize
221// number of exceptions later. So if in doubt feel free to use attribute, but
222// please document the problem for someone who is going to cleanup it later.
223// E.g. platform, bot, benchmark or test name in patch description or next to
224// the attribute.
Peter Kastingc3dadb022024-09-17 22:44:54225#if __has_cpp_attribute(clang::uninitialized)
Peter Kastingf541f7782023-03-10 23:44:46226#define STACK_UNINITIALIZED [[clang::uninitialized]]
Peter Kastingc3dadb022024-09-17 22:44:54227#elif __has_cpp_attribute(gnu::uninitialized)
228#define STACK_UNINITIALIZED [[gnu::uninitialized]]
Vitaly Buka2b790762019-12-20 21:11:48229#else
230#define STACK_UNINITIALIZED
231#endif
232
Matthew Dentonbb0b03e2021-07-22 16:18:13233// Attribute "no_stack_protector" disables -fstack-protector for the specified
234// function.
235//
236// "stack_protector" is enabled on most POSIX builds. The flag adds a canary
237// to each stack frame, which on function return is checked against a reference
238// canary. If the canaries do not match, it's likely that a stack buffer
239// overflow has occurred, so immediately crashing will prevent exploitation in
240// many cases.
241//
242// In some cases it's desirable to remove this, e.g. on hot functions, or if
243// we have purposely changed the reference canary.
Peter Kastingc3dadb022024-09-17 22:44:54244#if __has_cpp_attribute(gnu::no_stack_protector)
245#define NO_STACK_PROTECTOR [[gnu::no_stack_protector]]
246#elif __has_cpp_attribute(gnu::optimize)
247#define NO_STACK_PROTECTOR [[gnu::optimize("-fno-stack-protector")]]
Matthew Dentonbb0b03e2021-07-22 16:18:13248#else
249#define NO_STACK_PROTECTOR
250#endif
251
Peter Kastingc3dadb022024-09-17 22:44:54252// ANALYZER_SKIP_THIS_PATH() suppresses static analysis for the current
253// codepath and any other branching codepaths that might follow.
254#if defined(__clang_analyzer__)
255inline constexpr bool AnalyzerNoReturn()
256#if HAS_ATTRIBUTE(analyzer_noreturn)
257 __attribute__((analyzer_noreturn))
258#endif
259{
260 return false;
261}
262#define ANALYZER_SKIP_THIS_PATH() static_cast<void>(::AnalyzerNoReturn())
263#else
264// The above definition would be safe even outside the analyzer, but defining
265// the macro away entirely avoids the need for the optimizer to eliminate it.
266#define ANALYZER_SKIP_THIS_PATH()
267#endif
268
Hans Wennborg12aea3e2020-04-14 15:29:00269// The ANALYZER_ASSUME_TRUE(bool arg) macro adds compiler-specific hints
270// to Clang which control what code paths are statically analyzed,
271// and is meant to be used in conjunction with assert & assert-like functions.
272// The expression is passed straight through if analysis isn't enabled.
Hans Wennborg12aea3e2020-04-14 15:29:00273#if defined(__clang_analyzer__)
Hans Wennborg12aea3e2020-04-14 15:29:00274inline constexpr bool AnalyzerAssumeTrue(bool arg) {
275 // AnalyzerNoReturn() is invoked and analysis is terminated if |arg| is
276 // false.
277 return arg || AnalyzerNoReturn();
278}
George Burgess IVa09d235d2020-04-17 13:32:50279#define ANALYZER_ASSUME_TRUE(arg) ::AnalyzerAssumeTrue(!!(arg))
Peter Kastingc3dadb022024-09-17 22:44:54280#else
281// Again, the above definition is safe, this is just simpler for the optimizer.
Hans Wennborg12aea3e2020-04-14 15:29:00282#define ANALYZER_ASSUME_TRUE(arg) (arg)
Peter Kastingc3dadb022024-09-17 22:44:54283#endif
Hans Wennborg12aea3e2020-04-14 15:29:00284
Zequan Wu9909f142021-02-10 03:26:00285// Use nomerge attribute to disable optimization of merging multiple same calls.
Peter Kastingc3dadb022024-09-17 22:44:54286#if __has_cpp_attribute(clang::nomerge)
Zequan Wu9909f142021-02-10 03:26:00287#define NOMERGE [[clang::nomerge]]
288#else
289#define NOMERGE
290#endif
291
Jeremy Roman810d98d2021-04-06 16:46:07292// Marks a type as being eligible for the "trivial" ABI despite having a
293// non-trivial destructor or copy/move constructor. Such types can be relocated
294// after construction by simply copying their memory, which makes them eligible
295// to be passed in registers. The canonical example is std::unique_ptr.
296//
297// Use with caution; this has some subtle effects on constructor/destructor
298// ordering and will be very incorrect if the type relies on its address
299// remaining constant. When used as a function argument (by value), the value
300// may be constructed in the caller's stack frame, passed in a register, and
301// then used and destructed in the callee's stack frame. A similar thing can
302// occur when values are returned.
303//
304// TRIVIAL_ABI is not needed for types which have a trivial destructor and
305// copy/move constructors, such as base::TimeTicks and other POD.
306//
307// It is also not likely to be effective on types too large to be passed in one
308// or two registers on typical target ABIs.
309//
310// See also:
311// https://clang.llvm.org/docs/AttributeReference.html#trivial-abi
312// https://libcxx.llvm.org/docs/DesignDocs/UniquePtrTrivialAbi.html
Peter Kastingc3dadb022024-09-17 22:44:54313#if __has_cpp_attribute(clang::trivial_abi)
Jeremy Roman810d98d2021-04-06 16:46:07314#define TRIVIAL_ABI [[clang::trivial_abi]]
315#else
316#define TRIVIAL_ABI
317#endif
318
Adam Ricefb288d02023-10-13 08:36:21319// Detect whether a type is trivially relocatable, ie. a move-and-destroy
320// sequence can replaced with memmove(). This can be used to optimise the
321// implementation of containers. This is automatically true for types that were
322// defined with TRIVIAL_ABI such as scoped_refptr.
323//
324// See also:
325// https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p1144r8.html
326// https://clang.llvm.org/docs/LanguageExtensions.html#:~:text=__is_trivially_relocatable
Peter Kastingc3dadb022024-09-17 22:44:54327#if HAS_BUILTIN(__is_trivially_relocatable)
Adam Ricefb288d02023-10-13 08:36:21328#define IS_TRIVIALLY_RELOCATABLE(t) __is_trivially_relocatable(t)
329#else
330#define IS_TRIVIALLY_RELOCATABLE(t) false
331#endif
332
Lukasz Anforowicz3be38fbb2021-04-14 20:29:29333// Marks a member function as reinitializing a moved-from variable.
334// See also
Lei Zhangdd1e6fe2024-02-01 08:51:35335// https://clang.llvm.org/extra/clang-tidy/checks/bugprone/use-after-move.html#reinitialization
Peter Kastingc3dadb022024-09-17 22:44:54336#if __has_cpp_attribute(clang::reinitializes)
Lukasz Anforowicz3be38fbb2021-04-14 20:29:29337#define REINITIALIZES_AFTER_MOVE [[clang::reinitializes]]
338#else
339#define REINITIALIZES_AFTER_MOVE
340#endif
341
Peter Kastingc3dadb022024-09-17 22:44:54342#if __has_cpp_attribute(gsl::Owner)
Daniel Cheng8ac305b2022-02-17 00:05:11343#define GSL_OWNER [[gsl::Owner]]
danakjceb17022022-02-11 23:52:01344#else
Jose Dapena Paz1183b142022-02-18 16:28:25345#define GSL_OWNER
Peter Kastingc3dadb022024-09-17 22:44:54346#endif
347
348#if __has_cpp_attribute(gsl::Pointer)
349#define GSL_POINTER [[gsl::Pointer]]
350#else
danakjceb17022022-02-11 23:52:01351#define GSL_POINTER
352#endif
353
Daniel Chengf2c05382022-09-16 02:51:42354// Adds the "logically_const" tag to a symbol's mangled name. The "Mutable
355// Constants" check [1] detects instances of constants that aren't in .rodata,
356// e.g. due to a missing `const`. Using this tag suppresses the check for this
357// symbol, allowing it to live outside .rodata without a warning.
358//
359// [1]:
360// https://crsrc.org/c/docs/speed/binary_size/android_binary_size_trybot.md#Mutable-Constants
Peter Kastingc3dadb022024-09-17 22:44:54361#if __has_cpp_attribute(gnu::abi_tag)
Anthony Vallee-Dubois9dbbbda32022-08-26 01:25:31362#define LOGICALLY_CONST [[gnu::abi_tag("logically_const")]]
363#else
364#define LOGICALLY_CONST
365#endif
366
Peter Kastingc3dadb022024-09-17 22:44:54367// Disable `PRESERVE_MOST` outside AArch64/x64, where it's currently unsupported
368// and thus may trigger warnings.
369//
370// Disable in component builds, since `_dl_runtime_resolve()` clobbers registers
371// on platforms where it's used, and the component build is not perf-critical
372// anyway; see https://github.com/llvm/llvm-project/issues/105588.
373//
374// Disable for Win ARM64 due to as-yet-uninvestigated crashes.
375// TODO(crbug.com/42204008): Investigate, fix, and re-enable.
376#if __has_cpp_attribute(clang::preserve_most) && \
377 (defined(ARCH_CPU_ARM64) || defined(ARCH_CPU_X86_64)) && \
378 !defined(COMPONENT_BUILD) && \
379 !(BUILDFLAG(IS_WIN) && defined(ARCH_CPU_ARM64))
Anton Bikineev4d23e842023-06-14 10:46:19380// preserve_most clang's calling convention. Reduces register pressure for the
Peter Kastingc3dadb022024-09-17 22:44:54381// caller and as such can be used for cold calls.
kxxt120045d2024-02-13 04:22:39382// Clang only supports preserve_most on X86-64 and AArch64 for now.
Anton Bikineev4d23e842023-06-14 10:46:19383// See https://clang.llvm.org/docs/AttributeReference.html#preserve-most for
384// more details.
Peter Kastingc3dadb022024-09-17 22:44:54385#define PRESERVE_MOST [[clang::preserve_most]]
Anton Bikineev4d23e842023-06-14 10:46:19386#else
387#define PRESERVE_MOST
388#endif
389
danakjc077a30e2024-03-22 19:25:36390// Mark parameters or return types as having a lifetime attached to the class.
391//
392// When used to mark a method's pointer/reference parameter, the compiler is
393// made aware that it will be stored internally in the class and the pointee
394// must outlive the class. Typically used on constructor arguments. It should
395// appear to the right of the parameter's variable name.
396//
397// Example:
398// ```
399// struct S {
400// S(int* p LIFETIME_BOUND) : ptr_(p) {}
401//
402// int* ptr_;
403// };
404// ```
405//
406// When used on a method with a return value, the compiler is made aware that
407// the returned type is/has a pointer to the internals of the class, and must
408// not outlive the class object. It should appear after any method qualifiers.
409//
410// Example:
411// ```
412// struct S {
413// int* GetPtr() const LIFETIME_BOUND { return i_; };
414//
415// int i_;
416// };
417// ```
418//
419// This allows the compiler to warn in (a limited set of) cases where the
420// pointer would otherwise be left dangling, especially in cases where the
421// pointee would be a destroyed temporary.
422//
423// Docs: https://clang.llvm.org/docs/AttributeReference.html#lifetimebound
Peter Kastingc3dadb022024-09-17 22:44:54424#if __has_cpp_attribute(clang::lifetimebound)
danakjc077a30e2024-03-22 19:25:36425#define LIFETIME_BOUND [[clang::lifetimebound]]
426#else
427#define LIFETIME_BOUND
428#endif
429
430// Mark a function as pure, meaning that it does not have side effects, meaning
431// that it does not write anything external to the function's local variables
432// and return value.
433//
434// WARNING: If this attribute is mis-used it will result in UB and
435// miscompilation, as the optimizator may fold multiple calls into one and
436// reorder them inappropriately. This shouldn't appear outside of key vocabulary
437// types. It allows callers to work with the vocab type directly, and call its
438// methods without having to worry about caching things into local variables in
439// hot code.
440//
441// This attribute must not appear on functions that make use of function
442// pointers, virtual methods, or methods of templates (including operators like
443// comparison), as the "pure" function can not know what those functions do and
444// can not guarantee there will never be sideeffects.
Peter Kastingc3dadb022024-09-17 22:44:54445#if __has_cpp_attribute(gnu::pure)
danakjc077a30e2024-03-22 19:25:36446#define PURE_FUNCTION [[gnu::pure]]
447#else
448#define PURE_FUNCTION
449#endif
450
danakj59f56d92024-02-01 15:31:35451// Functions should be marked with UNSAFE_BUFFER_USAGE when they lead to
452// out-of-bounds bugs when called with incorrect inputs.
453//
454// Ideally such functions should be paired with a safer version that works with
455// safe primitives like `base::span`. Otherwise, another safer coding pattern
456// should be documented along side the use of `UNSAFE_BUFFER_USAGE`.
457//
458// All functions marked with UNSAFE_BUFFER_USAGE should come with a safety
David Benjamin34f6c2d02024-04-16 17:43:54459// comment that explains the requirements of the function to prevent an
460// out-of-bounds bug. For example:
danakj59f56d92024-02-01 15:31:35461// ```
462// // Function to do things between `input` and `end`.
463// //
464// // # Safety
465// // The `input` must point to an array with size at least 5. The `end` must
466// // point within the same allocation of `input` and not come before `input`.
467// ```
David Benjamin34f6c2d02024-04-16 17:43:54468//
469// The requirements described in the safety comment must be sufficient to
470// guarantee that the function never goes out of bounds. Annotating a function
471// in this way means that all callers will be required to wrap the call in an
472// `UNSAFE_BUFFERS()` macro (see below), with a comment justifying how it meets
473// the requirements.
Peter Kastingc3dadb022024-09-17 22:44:54474#if __has_cpp_attribute(clang::unsafe_buffer_usage)
danakj59f56d92024-02-01 15:31:35475#define UNSAFE_BUFFER_USAGE [[clang::unsafe_buffer_usage]]
476#else
477#define UNSAFE_BUFFER_USAGE
478#endif
479
Peter Kastingc3dadb022024-09-17 22:44:54480// Test for `__clang__` directly, as there's no `__has_pragma` or similar (see
481// https://github.com/llvm/llvm-project/issues/51887).
482#if defined(__clang__)
danakj59f56d92024-02-01 15:31:35483// UNSAFE_BUFFERS() wraps code that violates the -Wunsafe-buffer-usage warning,
484// such as:
485// - pointer arithmetic,
486// - pointer subscripting, and
487// - calls to functions annotated with UNSAFE_BUFFER_USAGE.
488//
David Benjamin34f6c2d02024-04-16 17:43:54489// This indicates code whose bounds correctness cannot be ensured
490// systematically, and thus requires manual review.
491//
492// ** USE OF THIS MACRO SHOULD BE VERY RARE.** This should only be used when
493// strictly necessary. Prefer to use `base::span` instead of pointers, or other
494// safer coding patterns (like std containers) that avoid the opportunity for
495// out-of-bounds bugs to creep into the code. Any use of UNSAFE_BUFFERS() can
496// lead to a critical security bug if any assumptions are wrong, or ever become
497// wrong in the future.
danakj59f56d92024-02-01 15:31:35498//
499// The macro should be used to wrap the minimum necessary code, to make it clear
500// what is unsafe, and prevent accidentally opting extra things out of the
501// warning.
502//
Tom Sepezea67b6e2024-08-08 18:17:27503// All usage of UNSAFE_BUFFERS() *must* come with a `// SAFETY: ...` comment
David Benjamin34f6c2d02024-04-16 17:43:54504// that explains how we have guaranteed that the pointer usage can never go
505// out-of-bounds, or that the requirements of the UNSAFE_BUFFER_USAGE function
Tom Sepezea67b6e2024-08-08 18:17:27506// are met. The safety comment should allow the chrome security team to check
507// that all requirements have been met, using only local invariants. Contact
508// [email protected] to schedule such a review.
509//
510// Examples of local invariants include:
David Benjamin34f6c2d02024-04-16 17:43:54511// - Runtime conditions or CHECKs near the UNSAFE_BUFFERS macros
512// - Invariants guaranteed by types in the surrounding code
513// - Invariants guaranteed by function calls in the surrounding code
514// - Caller requirements, if the containing function is itself marked with
515// UNSAFE_BUFFER_USAGE
516//
517// The last case should be an option of last resort. It is less safe and will
518// require the caller also use the UNSAFE_BUFFERS() macro. Prefer directly
519// capturing such invariants in types like `base::span`.
520//
521// Safety explanations may not rely on invariants that are not fully
522// encapsulated close to the UNSAFE_BUFFERS() usage. Instead, use safer coding
523// patterns or stronger invariants.
Peter Kastingc3dadb022024-09-17 22:44:54524//
danakj59f56d92024-02-01 15:31:35525// Formatting is off so that we can put each _Pragma on its own line, as
526// recommended by the gcc docs.
Peter Kastingc3dadb022024-09-17 22:44:54527// clang-format off
danakj59f56d92024-02-01 15:31:35528#define UNSAFE_BUFFERS(...) \
529 _Pragma("clang unsafe_buffer_usage begin") \
530 __VA_ARGS__ \
531 _Pragma("clang unsafe_buffer_usage end")
532// clang-format on
533#else
534#define UNSAFE_BUFFERS(...) __VA_ARGS__
535#endif
536
Tom Sepezea67b6e2024-08-08 18:17:27537// Line-level suppression of unsafe buffers warnings. This gives finer-grained
538// control over opting out portions of code from buffer safety checks than the
539// file-level pragma. It is used to indicate code that should be re-written for
540// safety and makes such sections easy-to-find (contrast this with the
541// UNSAFE_BUFFERS macro that indicates code that is expected to remain present
542// and has been manually evaluated for safety). Use of this macro can increase
543// the number of non-exempt files, and hence prevent new unsafe code from
544// being written in them.
545#define UNSAFE_TODO(...) UNSAFE_BUFFERS(__VA_ARGS__)
546
danakjc077a30e2024-03-22 19:25:36547// Defines a condition for a function to be checked at compile time if the
548// parameter's value is known at compile time. If the condition is failed, the
549// function is omitted from the overload set resolution, much like `requires`.
550//
551// If the parameter is a runtime value, then the condition is unable to be
552// checked and the function will be omitted from the overload set resolution.
553// This ensures the function can only be called with values known at compile
554// time. This is a clang extension.
555//
556// Example:
557// ```
558// void f(int a) ENABLE_IF_ATTR(a > 0) {}
559// f(1); // Ok.
560// f(0); // Error: no valid f() found.
561// ```
562//
563// The `ENABLE_IF_ATTR` annotation is preferred over `consteval` with a check
564// that breaks compile because metaprogramming does not observe such checks. So
565// with `consteval`, the function looks callable to concepts/type_traits but is
566// not and will fail to compile even though it reports it's usable. Whereas
567// `ENABLE_IF_ATTR` interacts correctly with metaprogramming. This is especially
568// painful for constructors. See also
569// https://github.com/chromium/subspace/issues/266.
Peter Kastingc3dadb022024-09-17 22:44:54570#if HAS_ATTRIBUTE(enable_if)
danakjc077a30e2024-03-22 19:25:36571#define ENABLE_IF_ATTR(cond, msg) __attribute__((enable_if(cond, msg)))
572#else
573#define ENABLE_IF_ATTR(cond, msg)
574#endif
575
[email protected]dd9afc0b2008-11-21 23:58:09576#endif // BASE_COMPILER_SPECIFIC_H_