xref: /DragonStub/inc/dragonstub/compiler_attributes.h (revision f412fd2a1a248b546b7085648dece8d908077fab)
1 #pragma once
2 /* SPDX-License-Identifier: GPL-2.0 */
3 #ifndef __LINUX_COMPILER_ATTRIBUTES_H
4 #define __LINUX_COMPILER_ATTRIBUTES_H
5 
6 /*
7  * The attributes in this file are unconditionally defined and they directly
8  * map to compiler attribute(s), unless one of the compilers does not support
9  * the attribute. In that case, __has_attribute is used to check for support
10  * and the reason is stated in its comment ("Optional: ...").
11  *
12  * Any other "attributes" (i.e. those that depend on a configuration option,
13  * on a compiler, on an architecture, on plugins, on other attributes...)
14  * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h).
15  * The intention is to keep this file as simple as possible, as well as
16  * compiler- and version-agnostic (e.g. avoiding GCC_VERSION checks).
17  *
18  * This file is meant to be sorted (by actual attribute name,
19  * not by #define identifier). Use the __attribute__((__name__)) syntax
20  * (i.e. with underscores) to avoid future collisions with other macros.
21  * Provide links to the documentation of each supported compiler, if it exists.
22  */
23 
24 /*
25  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alias-function-attribute
26  */
27 #define __alias(symbol) __attribute__((__alias__(#symbol)))
28 
29 /*
30  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-aligned-function-attribute
31  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-aligned-type-attribute
32  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-aligned-variable-attribute
33  */
34 #define __aligned(x) __attribute__((__aligned__(x)))
35 #define __aligned_largest __attribute__((__aligned__))
36 
37 /*
38  * Note: do not use this directly. Instead, use __alloc_size() since it is conditionally
39  * available and includes other attributes. For GCC < 9.1, __alloc_size__ gets undefined
40  * in compiler-gcc.h, due to misbehaviors.
41  *
42  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alloc_005fsize-function-attribute
43  * clang: https://clang.llvm.org/docs/AttributeReference.html#alloc-size
44  */
45 #define __alloc_size__(x, ...) __attribute__((__alloc_size__(x, ##__VA_ARGS__)))
46 
47 /*
48  * Note: users of __always_inline currently do not write "inline" themselves,
49  * which seems to be required by gcc to apply the attribute according
50  * to its docs (and also "warning: always_inline function might not be
51  * inlinable [-Wattributes]" is emitted).
52  *
53  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute
54  * clang: mentioned
55  */
56 #define __always_inline inline __attribute__((__always_inline__))
57 
58 /*
59  * The second argument is optional (default 0), so we use a variadic macro
60  * to make the shorthand.
61  *
62  * Beware: Do not apply this to functions which may return
63  * ERR_PTRs. Also, it is probably unwise to apply it to functions
64  * returning extra information in the low bits (but in that case the
65  * compiler should see some alignment anyway, when the return value is
66  * massaged by 'flags = ptr & 3; ptr &= ~3;').
67  *
68  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute
69  * clang: https://clang.llvm.org/docs/AttributeReference.html#assume-aligned
70  */
71 #define __assume_aligned(a, ...) \
72 	__attribute__((__assume_aligned__(a, ##__VA_ARGS__)))
73 
74 /*
75  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-cleanup-variable-attribute
76  * clang: https://clang.llvm.org/docs/AttributeReference.html#cleanup
77  */
78 #define __cleanup(func) __attribute__((__cleanup__(func)))
79 
80 /*
81  * Note the long name.
82  *
83  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute
84  */
85 #define __attribute_const__ __attribute__((__const__))
86 
87 /*
88  * Optional: only supported since gcc >= 9
89  * Optional: not supported by clang
90  *
91  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-copy-function-attribute
92  */
93 #if __has_attribute(__copy__)
94 #define __copy(symbol) __attribute__((__copy__(symbol)))
95 #else
96 #define __copy(symbol)
97 #endif
98 
99 /*
100  * Optional: only supported since gcc >= 14
101  * Optional: only supported since clang >= 18
102  *
103  *   gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108896
104  * clang: https://reviews.llvm.org/D148381
105  */
106 #if __has_attribute(__counted_by__)
107 #define __counted_by(member) __attribute__((__counted_by__(member)))
108 #else
109 #define __counted_by(member)
110 #endif
111 
112 /*
113  * Optional: not supported by gcc
114  * Optional: only supported since clang >= 14.0
115  *
116  * clang: https://clang.llvm.org/docs/AttributeReference.html#diagnose_as_builtin
117  */
118 #if __has_attribute(__diagnose_as_builtin__)
119 #define __diagnose_as(builtin...) \
120 	__attribute__((__diagnose_as_builtin__(builtin)))
121 #else
122 #define __diagnose_as(builtin...)
123 #endif
124 
125 /*
126  * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated'
127  * attribute warnings entirely and for good") for more information.
128  *
129  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-deprecated-function-attribute
130  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute
131  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute
132  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute
133  * clang: https://clang.llvm.org/docs/AttributeReference.html#deprecated
134  */
135 #define __deprecated
136 
137 /*
138  * Optional: not supported by clang
139  *
140  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-designated_005finit-type-attribute
141  */
142 #if __has_attribute(__designated_init__)
143 #define __designated_init __attribute__((__designated_init__))
144 #else
145 #define __designated_init
146 #endif
147 
148 /*
149  * Optional: only supported since clang >= 14.0
150  *
151  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-error-function-attribute
152  */
153 #if __has_attribute(__error__)
154 #define __compiletime_error(msg) __attribute__((__error__(msg)))
155 #else
156 #define __compiletime_error(msg)
157 #endif
158 
159 /*
160  * Optional: not supported by clang
161  *
162  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-externally_005fvisible-function-attribute
163  */
164 #if __has_attribute(__externally_visible__)
165 #define __visible __attribute__((__externally_visible__))
166 #else
167 #define __visible
168 #endif
169 
170 /*
171  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-format-function-attribute
172  * clang: https://clang.llvm.org/docs/AttributeReference.html#format
173  */
174 #define __printf(a, b) __attribute__((__format__(printf, a, b)))
175 #define __scanf(a, b) __attribute__((__format__(scanf, a, b)))
176 
177 /*
178  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-gnu_005finline-function-attribute
179  * clang: https://clang.llvm.org/docs/AttributeReference.html#gnu-inline
180  */
181 #define __gnu_inline __attribute__((__gnu_inline__))
182 
183 /*
184  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute
185  * clang: https://clang.llvm.org/docs/AttributeReference.html#malloc
186  */
187 #define __malloc __attribute__((__malloc__))
188 
189 /*
190  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-mode-type-attribute
191  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-mode-variable-attribute
192  */
193 #define __mode(x) __attribute__((__mode__(x)))
194 
195 /*
196  * Optional: only supported since gcc >= 7
197  *
198  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/x86-Function-Attributes.html#index-no_005fcaller_005fsaved_005fregisters-function-attribute_002c-x86
199  * clang: https://clang.llvm.org/docs/AttributeReference.html#no-caller-saved-registers
200  */
201 #if __has_attribute(__no_caller_saved_registers__)
202 #define __no_caller_saved_registers \
203 	__attribute__((__no_caller_saved_registers__))
204 #else
205 #define __no_caller_saved_registers
206 #endif
207 
208 /*
209  * Optional: not supported by clang
210  *
211  *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noclone-function-attribute
212  */
213 #if __has_attribute(__noclone__)
214 #define __noclone __attribute__((__noclone__))
215 #else
216 #define __noclone
217 #endif
218 
219 /*
220  * Add the pseudo keyword 'fallthrough' so case statement blocks
221  * must end with any of these keywords:
222  *   break;
223  *   fallthrough;
224  *   continue;
225  *   goto <label>;
226  *   return [expression];
227  *
228  *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
229  */
230 #if __has_attribute(__fallthrough__)
231 #define fallthrough __attribute__((__fallthrough__))
232 #else
233 #define fallthrough \
234 	do {        \
235 	} while (0) /* fallthrough */
236 #endif
237 
238 /*
239  * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
240  * clang: https://clang.llvm.org/docs/AttributeReference.html#flatten
241  */
242 #define __flatten __attribute__((flatten))
243 
244 /*
245  * Note the missing underscores.
246  *
247  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute
248  * clang: mentioned
249  */
250 #define noinline __attribute__((__noinline__))
251 
252 /*
253  * Optional: only supported since gcc >= 8
254  * Optional: not supported by clang
255  *
256  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-nonstring-variable-attribute
257  */
258 #if __has_attribute(__nonstring__)
259 #define __nonstring __attribute__((__nonstring__))
260 #else
261 #define __nonstring
262 #endif
263 
264 /*
265  * Optional: only supported since GCC >= 7.1, clang >= 13.0.
266  *
267  *      gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005fprofile_005finstrument_005ffunction-function-attribute
268  *    clang: https://clang.llvm.org/docs/AttributeReference.html#no-profile-instrument-function
269  */
270 #if __has_attribute(__no_profile_instrument_function__)
271 #define __no_profile __attribute__((__no_profile_instrument_function__))
272 #else
273 #define __no_profile
274 #endif
275 
276 /*
277  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noreturn-function-attribute
278  * clang: https://clang.llvm.org/docs/AttributeReference.html#noreturn
279  * clang: https://clang.llvm.org/docs/AttributeReference.html#id1
280  */
281 #define __noreturn __attribute__((__noreturn__))
282 
283 /*
284  * Optional: only supported since GCC >= 11.1, clang >= 7.0.
285  *
286  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005fstack_005fprotector-function-attribute
287  *   clang: https://clang.llvm.org/docs/AttributeReference.html#no-stack-protector-safebuffers
288  */
289 #if __has_attribute(__no_stack_protector__)
290 #define __no_stack_protector __attribute__((__no_stack_protector__))
291 #else
292 #define __no_stack_protector
293 #endif
294 
295 /*
296  * Optional: not supported by gcc.
297  *
298  * clang: https://clang.llvm.org/docs/AttributeReference.html#overloadable
299  */
300 #if __has_attribute(__overloadable__)
301 #define __overloadable __attribute__((__overloadable__))
302 #else
303 #define __overloadable
304 #endif
305 
306 /*
307  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute
308  * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute
309  */
310 #define __packed __attribute__((__packed__))
311 
312 /*
313  * Note: the "type" argument should match any __builtin_object_size(p, type) usage.
314  *
315  * Optional: not supported by gcc.
316  *
317  * clang: https://clang.llvm.org/docs/AttributeReference.html#pass-object-size-pass-dynamic-object-size
318  */
319 #if __has_attribute(__pass_dynamic_object_size__)
320 #define __pass_dynamic_object_size(type) \
321 	__attribute__((__pass_dynamic_object_size__(type)))
322 #else
323 #define __pass_dynamic_object_size(type)
324 #endif
325 #if __has_attribute(__pass_object_size__)
326 #define __pass_object_size(type) __attribute__((__pass_object_size__(type)))
327 #else
328 #define __pass_object_size(type)
329 #endif
330 
331 /*
332  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute
333  */
334 #define __pure __attribute__((__pure__))
335 
336 /*
337  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-section-function-attribute
338  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute
339  * clang: https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate
340  */
341 #define __section(section) __attribute__((__section__(section)))
342 
343 /*
344  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute
345  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-unused-type-attribute
346  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute
347  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-unused-label-attribute
348  * clang: https://clang.llvm.org/docs/AttributeReference.html#maybe-unused-unused
349  */
350 #define __always_unused __attribute__((__unused__))
351 #define __maybe_unused __attribute__((__unused__))
352 
353 /*
354  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-used-function-attribute
355  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-used-variable-attribute
356  */
357 #define __used __attribute__((__used__))
358 
359 /*
360  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-warn_005funused_005fresult-function-attribute
361  * clang: https://clang.llvm.org/docs/AttributeReference.html#nodiscard-warn-unused-result
362  */
363 #define __must_check __attribute__((__warn_unused_result__))
364 
365 /*
366  * Optional: only supported since clang >= 14.0
367  *
368  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-warning-function-attribute
369  */
370 #if __has_attribute(__warning__)
371 #define __compiletime_warning(msg) __attribute__((__warning__(msg)))
372 #else
373 #define __compiletime_warning(msg)
374 #endif
375 
376 /*
377  * Optional: only supported since clang >= 14.0
378  *
379  * clang: https://clang.llvm.org/docs/AttributeReference.html#disable-sanitizer-instrumentation
380  *
381  * disable_sanitizer_instrumentation is not always similar to
382  * no_sanitize((<sanitizer-name>)): the latter may still let specific sanitizers
383  * insert code into functions to prevent false positives. Unlike that,
384  * disable_sanitizer_instrumentation prevents all kinds of instrumentation to
385  * functions with the attribute.
386  */
387 #if __has_attribute(disable_sanitizer_instrumentation)
388 #define __disable_sanitizer_instrumentation \
389 	__attribute__((disable_sanitizer_instrumentation))
390 #else
391 #define __disable_sanitizer_instrumentation
392 #endif
393 
394 /*
395  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute
396  *   gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute
397  */
398 #define __weak __attribute__((__weak__))
399 
400 /*
401  * Used by functions that use '__builtin_return_address'. These function
402  * don't want to be splited or made inline, which can make
403  * the '__builtin_return_address' get unexpected address.
404  */
405 #define __fix_address noinline __noclone
406 
407 #endif /* __LINUX_COMPILER_ATTRIBUTES_H */
408