1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// This file provides macros for unifying differences in C/C++ compiler
// extensions, and providing backwards-compatibility for older C++ standards.
//
// May be included by C, C++, and assembly files.
#ifndef ZIRCON_COMPILER_H_
#define ZIRCON_COMPILER_H_
// Ensure we are using a known compiler.
#if !defined(__GNUC__) && !defined(__clang__)
#error "Unrecognized compiler!"
#endif
// Feature checking macros.
//
// If feature checking macros are not provided by the compiler, we assume that the
// checked features are unavailable.
// C++11 attribute checking.
#ifndef __has_cpp_attribute
#define __has_cpp_attribute(x) 0
#endif
// clang feature checking.
#ifndef __has_feature
#define __has_feature(x) 0
#endif
#if !defined(__ASSEMBLER__)
// C++ header guards.
#ifdef __cplusplus
#define __BEGIN_CDECLS extern "C" {
#define __END_CDECLS }
#else
#define __BEGIN_CDECLS
#define __END_CDECLS
#endif
//
// Function and data attributes.
//
// Function inlining directives.
#define __NO_INLINE __attribute__((__noinline__))
#define __ALWAYS_INLINE __attribute__((__always_inline__))
// Avoid issuing a warning if the given variable/function is unused.
#ifndef __cplusplus
#define __UNUSED __attribute__((__unused__))
#endif
// Pack the given structure or class, omitting padding between fields.
#define __PACKED __attribute__((packed))
// Place the variable in thread-local storage.
#define __THREAD __thread
// Align the variable or type to at least `x` bytes. `x` must be a power of two.
#define __ALIGNED(x) __attribute__((aligned(x)))
// Declare the given function will never return. (such as `exit`, `abort`, etc).
#define __NO_RETURN __attribute__((__noreturn__))
// Warn if the result of this function is ignored by the caller.
#define __WARN_UNUSED_RESULT __attribute__((__warn_unused_result__))
// Declare that the given stack variable may be left uninitialized if it does
// not have a specified initial value.
#if defined(__clang__)
#define __UNINITIALIZED __attribute__((uninitialized))
#else
#define __UNINITIALIZED
#endif
// Warn if a constructed objected is not used by the caller.
//
// Generates a warning on code like this:
//
// {
// AutoLock(&mutex); // error: the AutoLock goes out of scope immediately.
// locked_variable = 42;
// }
//
// C++17 defines [[nodiscard]] to do this, but some older but supported
// versions of GCC support [[nodiscard]] on functions but not constructors.
// Having a separate __WARN_UNUSED_CONSTRUCTOR allows us to hide the attribute
// only on constructors on old versions of GCC.
#if defined(__cplusplus)
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 10))
#define __WARN_UNUSED_CONSTRUCTOR [[nodiscard]]
#else
#define __WARN_UNUSED_CONSTRUCTOR
#endif
#endif
// Mark a function or variable as deprecated, warning about any callers.
#if !defined(__DEPRECATE)
#define __DEPRECATE __attribute__((__deprecated__))
#endif
// Mark a function as having no visible side-effects: It may read memory, but
// will not modify it.
//
// Multiple calls to the function may be optimized away by the compiler.
#define __PURE __attribute__((__pure__))
// Mark a function has having an output determined solely on its input
// parameters (but not memory).
//
// Multiple calls to the function may be optimized away by the compiler, even
// if memory is modified between calls.
#define __CONST __attribute__((__const__))
// The given function is malloc-like, returning a pointer to new, unused
// memory.
//
// The compiler can assume that the returned pointer does not alias any other
// pointer, which may help the compiler optimize the program.
#define __MALLOC __attribute__((__malloc__))
// The given function allocates memory of size argument |x| or |x| * |y| and returns
// a pointer to that memory. Argument indexes are one-based. The compiler can use this
// information to support compile-time __builtin_object_size checks.
#if defined(__clang__)
#define __ALLOC_SIZE(x, ...) __attribute__((__alloc_size__(x, ##__VA_ARGS__)))
#else
// TODO(fxrev.dev/571541): GCC warns incorrectly on constructs that could result in
// large allocations for type reasons but cannot for other (checked) reasons. Disable
// the attribute there.
#define __ALLOC_SIZE(x, ...)
#endif
// Indicate that the given function takes a printf/scanf-style format string.
//
// "__fmt" is the argument number of the format string, indexed from 1.
// "__varargs" is the argument number of the variable args "..." argument
// counting from 1.
//
// If applied to a class method, the implicit "this" parameter counts as the
// first argument.
#define __PRINTFLIKE(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
#define __SCANFLIKE(__fmt, __varargs) __attribute__((__format__(__scanf__, __fmt, __varargs)))
// Indicate that the `n`th argument to a function is non-null.
//
// The compiler will emit warnings if it can prove an argument is null, and
// may optimise assuming that the values are non-null.
#define __NONNULL(n) __attribute__((__nonnull__ n))
// The given function is a "leaf", and won't call further functions.
//
// Leaf functions must only return directly, and not call back into the
// current compilation unit (either via direct calls, or function pointers).
//
// May help the compiler optimize calls to the function in some cases.
#define __LEAF_FN __attribute__((__leaf__))
// Mark the given function or variable as `constexpr`.
//
// Used in code included by both C and C++. Code that is pure C++ should use
// `constexpr` directly.
#ifdef __cplusplus
#define __CONSTEXPR constexpr
#else
#define __CONSTEXPR
#endif
// Optimize the given function using custom flags.
//
// For example,
//
// __OPTIMIZE("O3") int myfunction() { ... }
//
// will cause GCC to optimize the function at the O3 level, independent
// of what the compiler optimization flags are.
#if !defined(__clang__)
#define __OPTIMIZE(x) __attribute__((__optimize__(x)))
#else
#define __OPTIMIZE(x)
#endif
// Indicate the given function should not use LLVM's stack hardening features,
// but instead put all local variables on the standard stack.
//
// c.f. https://clang.llvm.org/docs/SafeStack.html
#if defined(__clang__)
#define __NO_SAFESTACK __attribute__((__no_sanitize__("safe-stack", "shadow-call-stack")))
#else
#define __NO_SAFESTACK
#endif
// The given C++ class or struct need not have a unique address when part of
// a larger struct or class, but can be safely collapsed into a zero-byte
// object by the compiler.
#if __has_cpp_attribute(no_unique_address)
#define __NO_UNIQUE_ADDRESS [[no_unique_address]]
#elif __has_cpp_attribute(msvc::no_unique_address)
// msvc targets, as used by efi, have a different attribute name, even when
// targeting C++20.
#define __NO_UNIQUE_ADDRESS [[msvc::no_unique_address]]
#else
#define __NO_UNIQUE_ADDRESS
#endif
// Indicate that the given function should be treated by the Clang static
// analyzer as if it doesn't return.
//
// A workaround to help static analyzer identify assertion failures
#if defined(__clang__)
#define __ANALYZER_CREATE_SINK __attribute__((analyzer_noreturn))
#else
#define __ANALYZER_CREATE_SINK
#endif
// Mark the given function as externally visible, and shouldn't be optimized
// away by link-time optimizations or whole-program optimizations.
#if !defined(__clang__)
#define __EXTERNALLY_VISIBLE __attribute__((__externally_visible__))
#else
#define __EXTERNALLY_VISIBLE
#endif
// Declare that this function declaration should be emitted as an alias for
// another function.
#define __ALIAS(x) __attribute__((__alias__(x)))
// Place the given global into a particular linker section.
#define __SECTION(x) __attribute__((__section__(x)))
// The given function or global should be given a weak symbol, or a weak
// alias to another symbol.
#define __WEAK __attribute__((__weak__))
#define __WEAK_ALIAS(x) __attribute__((__weak__, __alias__(x)))
// The given static variable should still be emitted by the compiler, even if it
// appears unused to the compiler.
//
// Rarely needed. Not to be confused with "__UNUSED", which avoids the
// compiler warning if a variable appears unused.
#define __ALWAYS_EMIT __attribute__((__used__))
// Declare this object's ELF symbol visibility.
#define __EXPORT __attribute__((__visibility__("default")))
#define __LOCAL __attribute__((__visibility__("hidden")))
//
// Builtin functions.
//
// Provide a hint to the compiler that the given expression is likely/unlikely
// to be true.
//
// if (unlikely(status != ZX_OK)) {
// error(...);
// }
//
#ifndef likely
#define likely(x) __builtin_expect(!!(x), 1)
#endif
#ifndef unlikely
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
// Return the program counter of the calling function.
#define __GET_CALLER(x) __builtin_return_address(0)
// Return the address of the current stack frame.
#define __GET_FRAME(x) __builtin_frame_address(0)
// Return true if the given expression is a known compile-time constant.
#define __ISCONSTANT(x) __builtin_constant_p(x)
// Assume this branch of code cannot be reached.
#define __UNREACHABLE __builtin_unreachable()
// Get the offset of `field` from the beginning of the struct or class `type`.
#define __offsetof(type, field) __builtin_offsetof(type, field)
// Perform an arithmetic operation, returning "true" if the operation overflowed.
//
// Equivalent to: { *result = a + b; return _overflow_occurred; }
#define add_overflow(a, b, result) __builtin_add_overflow(a, b, result)
#define sub_overflow(a, b, result) __builtin_sub_overflow(a, b, result)
#define mul_overflow(a, b, result) __builtin_mul_overflow(a, b, result)
// Indicate the given case of a switch statement is intended to fall through
// to the next case, and avoid generating a compiler warning.
//
// switch (n) {
// case 0:
// case 1:
// handle_zero_and_one_case();
// __FALLTHROUGH;
// default:
// handle_all_cases();
// break;
// }
//
#if defined(__cplusplus)
#define __FALLTHROUGH [[fallthrough]]
#elif defined(__cplusplus) && defined(__clang__)
#define __FALLTHROUGH [[clang::fallthrough]]
// The GNU style attribute is supported by Clang for C code, but __GNUC__ for
// clang right now is 4.
#elif __GNUC__ >= 7 || (!defined(__cplusplus) && defined(__clang__))
#define __FALLTHROUGH __attribute__((__fallthrough__))
#else
#define __FALLTHROUGH \
do { \
} while (0)
#endif
// Locking annotations.
//
// The following annotations allow compile-time checking that annotated data
// is only accessed while holding the correct locks.
//
// The annotations are only supported by Clang, and frequently used with C++
// standard library types in userspace, so only enable in Clang when we know
// that the C++ standard library types are annotated or if we're in kernel
// code.
#if defined(__clang__) && (defined(_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS) || defined(_KERNEL))
#define __THREAD_ANNOTATION(x) __attribute__((x))
#else
#define __THREAD_ANNOTATION(x)
#endif
#define __TA_CAPABILITY(x) __THREAD_ANNOTATION(__capability__(x))
#define __TA_GUARDED(x) __THREAD_ANNOTATION(__guarded_by__(x))
#define __TA_ACQUIRE(...) __THREAD_ANNOTATION(__acquire_capability__(__VA_ARGS__))
#define __TA_ACQUIRE_SHARED(...) __THREAD_ANNOTATION(__acquire_shared_capability__(__VA_ARGS__))
#define __TA_TRY_ACQUIRE(...) __THREAD_ANNOTATION(__try_acquire_capability__(__VA_ARGS__))
#define __TA_TRY_ACQUIRE_SHARED(...) \
__THREAD_ANNOTATION(__try_acquire_shared_capability__(__VA_ARGS__))
// Neither ACQUIRED_BEFORE nor ACQUIRED_AFTER are implemented in clang. Users of these macros must
// not rely upon them to catch lock ordering bugs, and must treat them as documentation only.
// See:
// https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#acquired-before-and-acquired-after-are-currently-unimplemented
#define __TA_ACQUIRED_BEFORE(...) __THREAD_ANNOTATION(__acquired_before__(__VA_ARGS__))
#define __TA_ACQUIRED_AFTER(...) __THREAD_ANNOTATION(__acquired_after__(__VA_ARGS__))
#define __TA_RELEASE(...) __THREAD_ANNOTATION(__release_capability__(__VA_ARGS__))
#define __TA_RELEASE_SHARED(...) __THREAD_ANNOTATION(__release_shared_capability__(__VA_ARGS__))
#define __TA_REQUIRES(...) __THREAD_ANNOTATION(__requires_capability__(__VA_ARGS__))
#define __TA_REQUIRES_SHARED(...) __THREAD_ANNOTATION(__requires_shared_capability__(__VA_ARGS__))
#define __TA_EXCLUDES(...) __THREAD_ANNOTATION(__locks_excluded__(__VA_ARGS__))
#define __TA_ASSERT(...) __THREAD_ANNOTATION(__assert_capability__(__VA_ARGS__))
#define __TA_ASSERT_SHARED(...) __THREAD_ANNOTATION(__assert_shared_capability__(__VA_ARGS__))
#define __TA_RETURN_CAPABILITY(x) __THREAD_ANNOTATION(__lock_returned__(x))
#define __TA_SCOPED_CAPABILITY __THREAD_ANNOTATION(__scoped_lockable__)
#define __TA_NO_THREAD_SAFETY_ANALYSIS __THREAD_ANNOTATION(__no_thread_safety_analysis__)
// Experimental lifetime analysis annotations.
#ifndef __OWNER
#ifdef __clang__
#define __OWNER(x) [[gsl::Owner(x)]]
#define __POINTER(x) [[gsl::Pointer(x)]]
#else
#define __OWNER(x)
#define __POINTER(x)
#endif
#endif
#if defined(__cpp_constinit) && __cpp_constinit >= 201907L
#define __CONSTINIT constinit
#elif defined(__clang__)
#define __CONSTINIT [[clang::require_constant_initialization]]
#elif defined(__GNUC__) && __GNUC__ >= 13
#define __CONSTINIT __constinit
#else
#define __CONSTINIT
#endif
#endif // !defined(__ASSEMBLER__)
#endif // ZIRCON_COMPILER_H_
|