Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Compiler Attributes: use feature checks instead of version checks

Instead of using version checks per-compiler to define (or not)
each attribute, use __has_attribute to test for them, following
the cleanup started with commit 815f0ddb346c
("include/linux/compiler*.h: make compiler-*.h mutually exclusive"),
which is supported on gcc >= 5, clang >= 2.9 and icc >= 17.
In the meantime, to support 4.6 <= gcc < 5, we implement
__has_attribute by hand.

All the attributes that can be unconditionally defined and directly
map to compiler attribute(s) (even if optional) have been moved
to a new file include/linux/compiler_attributes.h

In an effort to make the file as regular as possible, comments
stating the purpose of attributes have been removed. Instead,
links to the compiler docs have been added (i.e. to gcc and,
if available, to clang as well). In addition, they have been sorted.

Finally, if an attribute is optional (i.e. if it is guarded
by __has_attribute), the reason has been stated for future reference.

Tested-by: Sedat Dilek <sedat.dilek@gmail.com> # on top of v4.19-rc5, clang 7
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Reviewed-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Signed-off-by: Miguel Ojeda <miguel.ojeda.sandonis@gmail.com>

+254 -125
-4
include/linux/compiler-clang.h
··· 21 21 #define __SANITIZE_ADDRESS__ 22 22 #endif 23 23 24 - #define __no_sanitize_address __attribute__((__no_sanitize__("address"))) 25 - 26 24 /* 27 25 * Not all versions of clang implement the the type-generic versions 28 26 * of the builtin overflow checkers. Fortunately, clang implements ··· 39 41 * compilers, like ICC. 40 42 */ 41 43 #define barrier() __asm__ __volatile__("" : : : "memory") 42 - #define __assume_aligned(a, ...) \ 43 - __attribute__((__assume_aligned__(a, ## __VA_ARGS__)))
-51
include/linux/compiler-gcc.h
··· 108 108 __builtin_unreachable(); \ 109 109 } while (0) 110 110 111 - /* Mark a function definition as prohibited from being cloned. */ 112 - #define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) 113 - 114 111 #if defined(RANDSTRUCT_PLUGIN) && !defined(__CHECKER__) 115 112 #define __randomize_layout __attribute__((randomize_layout)) 116 113 #define __no_randomize_layout __attribute__((no_randomize_layout)) 117 114 /* This anon struct can add padding, so only enable it under randstruct. */ 118 115 #define randomized_struct_fields_start struct { 119 116 #define randomized_struct_fields_end } __randomize_layout; 120 - #endif 121 - 122 - /* 123 - * When used with Link Time Optimization, gcc can optimize away C functions or 124 - * variables which are referenced only from assembly code. __visible tells the 125 - * optimizer that something else uses this function or variable, thus preventing 126 - * this. 127 - */ 128 - #define __visible __attribute__((__externally_visible__)) 129 - 130 - /* gcc version specific checks */ 131 - 132 - #if GCC_VERSION >= 40900 133 - /* 134 - * __assume_aligned(n, k): Tell the optimizer that the returned 135 - * pointer can be assumed to be k modulo n. The second argument is 136 - * optional (default 0), so we use a variadic macro to make the 137 - * shorthand. 138 - * 139 - * Beware: Do not apply this to functions which may return 140 - * ERR_PTRs. Also, it is probably unwise to apply it to functions 141 - * returning extra information in the low bits (but in that case the 142 - * compiler should see some alignment anyway, when the return value is 143 - * massaged by 'flags = ptr & 3; ptr &= ~3;'). 144 - */ 145 - #define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) 146 117 #endif 147 118 148 119 /* ··· 147 176 #define KASAN_ABI_VERSION 3 148 177 #endif 149 178 150 - #if GCC_VERSION >= 40902 151 - /* 152 - * Tell the compiler that address safety instrumentation (KASAN) 153 - * should not be applied to that function. 154 - * Conflicts with inlining: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368 155 - */ 156 - #define __no_sanitize_address __attribute__((__no_sanitize_address__)) 157 - #endif 158 - 159 179 #if GCC_VERSION >= 50100 160 - /* 161 - * Mark structures as requiring designated initializers. 162 - * https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html 163 - */ 164 - #define __designated_init __attribute__((__designated_init__)) 165 180 #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 166 - #endif 167 - 168 - #if !defined(__noclone) 169 - #define __noclone /* not needed */ 170 - #endif 171 - 172 - #if !defined(__no_sanitize_address) 173 - #define __no_sanitize_address 174 181 #endif 175 182 176 183 /*
-6
include/linux/compiler-intel.h
··· 34 34 /* icc has this, but it's called _bswap16 */ 35 35 #define __HAVE_BUILTIN_BSWAP16__ 36 36 #define __builtin_bswap16 _bswap16 37 - 38 - /* The following are for compatibility with GCC, from compiler-gcc.h, 39 - * and may be redefined here because they should not be shared with other 40 - * compilers, like clang. 41 - */ 42 - #define __visible __attribute__((__externally_visible__))
+244
include/linux/compiler_attributes.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef __LINUX_COMPILER_ATTRIBUTES_H 3 + #define __LINUX_COMPILER_ATTRIBUTES_H 4 + 5 + /* 6 + * The attributes in this file are unconditionally defined and they directly 7 + * map to compiler attribute(s) -- except those that are optional. 8 + * 9 + * Any other "attributes" (i.e. those that depend on a configuration option, 10 + * on a compiler, on an architecture, on plugins, on other attributes...) 11 + * should be defined elsewhere (e.g. compiler_types.h or compiler-*.h). 12 + * 13 + * This file is meant to be sorted (by actual attribute name, 14 + * not by #define identifier). Use the __attribute__((__name__)) syntax 15 + * (i.e. with underscores) to avoid future collisions with other macros. 16 + * If an attribute is optional, state the reason in the comment. 17 + */ 18 + 19 + /* 20 + * To check for optional attributes, we use __has_attribute, which is supported 21 + * on gcc >= 5, clang >= 2.9 and icc >= 17. In the meantime, to support 22 + * 4.6 <= gcc < 5, we implement __has_attribute by hand. 23 + * 24 + * sparse does not support __has_attribute (yet) and defines __GNUC_MINOR__ 25 + * depending on the compiler used to build it; however, these attributes have 26 + * no semantic effects for sparse, so it does not matter. Also note that, 27 + * in order to avoid sparse's warnings, even the unsupported ones must be 28 + * defined to 0. 29 + */ 30 + #ifndef __has_attribute 31 + # define __has_attribute(x) __GCC4_has_attribute_##x 32 + # define __GCC4_has_attribute___assume_aligned__ (__GNUC_MINOR__ >= 9) 33 + # define __GCC4_has_attribute___designated_init__ 0 34 + # define __GCC4_has_attribute___externally_visible__ 1 35 + # define __GCC4_has_attribute___noclone__ 1 36 + # define __GCC4_has_attribute___optimize__ 1 37 + # define __GCC4_has_attribute___no_sanitize_address__ (__GNUC_MINOR__ >= 8) 38 + #endif 39 + 40 + /* 41 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-alias-function-attribute 42 + */ 43 + #define __alias(symbol) __attribute__((__alias__(#symbol))) 44 + 45 + /* 46 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-aligned-function-attribute 47 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-aligned-type-attribute 48 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-aligned-variable-attribute 49 + */ 50 + #define __aligned(x) __attribute__((__aligned__(x))) 51 + #define __aligned_largest __attribute__((__aligned__)) 52 + 53 + /* 54 + * Note: users of __always_inline currently do not write "inline" themselves, 55 + * which seems to be required by gcc to apply the attribute according 56 + * to its docs (and also "warning: always_inline function might not be 57 + * inlinable [-Wattributes]" is emitted). 58 + * 59 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-always_005finline-function-attribute 60 + * clang: mentioned 61 + */ 62 + #define __always_inline inline __attribute__((__always_inline__)) 63 + 64 + /* 65 + * The second argument is optional (default 0), so we use a variadic macro 66 + * to make the shorthand. 67 + * 68 + * Beware: Do not apply this to functions which may return 69 + * ERR_PTRs. Also, it is probably unwise to apply it to functions 70 + * returning extra information in the low bits (but in that case the 71 + * compiler should see some alignment anyway, when the return value is 72 + * massaged by 'flags = ptr & 3; ptr &= ~3;'). 73 + * 74 + * Optional: only supported since gcc >= 4.9 75 + * Optional: not supported by icc 76 + * 77 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-assume_005faligned-function-attribute 78 + * clang: https://clang.llvm.org/docs/AttributeReference.html#assume-aligned 79 + */ 80 + #if __has_attribute(__assume_aligned__) 81 + # define __assume_aligned(a, ...) __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) 82 + #else 83 + # define __assume_aligned(a, ...) 84 + #endif 85 + 86 + /* 87 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-cold-function-attribute 88 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute 89 + */ 90 + #define __cold __attribute__((__cold__)) 91 + 92 + /* 93 + * Note the long name. 94 + * 95 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-const-function-attribute 96 + */ 97 + #define __attribute_const__ __attribute__((__const__)) 98 + 99 + /* 100 + * Don't. Just don't. See commit 771c035372a0 ("deprecate the '__deprecated' 101 + * attribute warnings entirely and for good") for more information. 102 + * 103 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-deprecated-function-attribute 104 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute 105 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-deprecated-variable-attribute 106 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Enumerator-Attributes.html#index-deprecated-enumerator-attribute 107 + * clang: https://clang.llvm.org/docs/AttributeReference.html#deprecated 108 + */ 109 + #define __deprecated 110 + 111 + /* 112 + * Optional: only supported since gcc >= 5.1 113 + * Optional: not supported by clang 114 + * Optional: not supported by icc 115 + * 116 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-designated_005finit-type-attribute 117 + */ 118 + #if __has_attribute(__designated_init__) 119 + # define __designated_init __attribute__((__designated_init__)) 120 + #else 121 + # define __designated_init 122 + #endif 123 + 124 + /* 125 + * Optional: not supported by clang 126 + * 127 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-externally_005fvisible-function-attribute 128 + */ 129 + #if __has_attribute(__externally_visible__) 130 + # define __visible __attribute__((__externally_visible__)) 131 + #else 132 + # define __visible 133 + #endif 134 + 135 + /* 136 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-format-function-attribute 137 + * clang: https://clang.llvm.org/docs/AttributeReference.html#format 138 + */ 139 + #define __printf(a, b) __attribute__((__format__(printf, a, b))) 140 + #define __scanf(a, b) __attribute__((__format__(scanf, a, b))) 141 + 142 + /* 143 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-gnu_005finline-function-attribute 144 + * clang: https://clang.llvm.org/docs/AttributeReference.html#gnu-inline 145 + */ 146 + #define __gnu_inline __attribute__((__gnu_inline__)) 147 + 148 + /* 149 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-malloc-function-attribute 150 + */ 151 + #define __malloc __attribute__((__malloc__)) 152 + 153 + /* 154 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-mode-type-attribute 155 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-mode-variable-attribute 156 + */ 157 + #define __mode(x) __attribute__((__mode__(x))) 158 + 159 + /* 160 + * Optional: not supported by clang 161 + * Note: icc does not recognize gcc's no-tracer 162 + * 163 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noclone-function-attribute 164 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-optimize-function-attribute 165 + */ 166 + #if __has_attribute(__noclone__) 167 + # if __has_attribute(__optimize__) 168 + # define __noclone __attribute__((__noclone__, __optimize__("no-tracer"))) 169 + # else 170 + # define __noclone __attribute__((__noclone__)) 171 + # endif 172 + #else 173 + # define __noclone 174 + #endif 175 + 176 + /* 177 + * Note the missing underscores. 178 + * 179 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noinline-function-attribute 180 + * clang: mentioned 181 + */ 182 + #define noinline __attribute__((__noinline__)) 183 + 184 + /* 185 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-noreturn-function-attribute 186 + * clang: https://clang.llvm.org/docs/AttributeReference.html#noreturn 187 + * clang: https://clang.llvm.org/docs/AttributeReference.html#id1 188 + */ 189 + #define __noreturn __attribute__((__noreturn__)) 190 + 191 + /* 192 + * Optional: only supported since gcc >= 4.8 193 + * Optional: not supported by icc 194 + * 195 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-no_005fsanitize_005faddress-function-attribute 196 + * clang: https://clang.llvm.org/docs/AttributeReference.html#no-sanitize-address-no-address-safety-analysis 197 + */ 198 + #if __has_attribute(__no_sanitize_address__) 199 + # define __no_sanitize_address __attribute__((__no_sanitize_address__)) 200 + #else 201 + # define __no_sanitize_address 202 + #endif 203 + 204 + /* 205 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-packed-type-attribute 206 + * clang: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-packed-variable-attribute 207 + */ 208 + #define __packed __attribute__((__packed__)) 209 + 210 + /* 211 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-pure-function-attribute 212 + */ 213 + #define __pure __attribute__((__pure__)) 214 + 215 + /* 216 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-section-function-attribute 217 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute 218 + * clang: https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate 219 + */ 220 + #define __section(S) __attribute__((__section__(#S))) 221 + 222 + /* 223 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute 224 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-unused-type-attribute 225 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-unused-variable-attribute 226 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-unused-label-attribute 227 + * clang: https://clang.llvm.org/docs/AttributeReference.html#maybe-unused-unused 228 + */ 229 + #define __always_unused __attribute__((__unused__)) 230 + #define __maybe_unused __attribute__((__unused__)) 231 + 232 + /* 233 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-used-function-attribute 234 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-used-variable-attribute 235 + */ 236 + #define __used __attribute__((__used__)) 237 + 238 + /* 239 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-weak-function-attribute 240 + * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-weak-variable-attribute 241 + */ 242 + #define __weak __attribute__((__weak__)) 243 + 244 + #endif /* __LINUX_COMPILER_ATTRIBUTES_H */
+10 -64
include/linux/compiler_types.h
··· 55 55 56 56 #ifdef __KERNEL__ 57 57 58 + /* Attributes */ 59 + #include <linux/compiler_attributes.h> 60 + 58 61 /* Compiler specific macros. */ 59 62 #ifdef __clang__ 60 63 #include <linux/compiler-clang.h> ··· 82 79 #include <asm/compiler.h> 83 80 #endif 84 81 85 - /* 86 - * Generic compiler-independent macros required for kernel 87 - * build go below this comment. Actual compiler/compiler version 88 - * specific implementations come from the above header files 89 - */ 90 - 91 82 struct ftrace_branch_data { 92 83 const char *func; 93 84 const char *file; ··· 104 107 unsigned long constant; 105 108 }; 106 109 107 - /* Don't. Just don't. */ 108 - #define __deprecated 109 - 110 110 #endif /* __KERNEL__ */ 111 111 112 112 #endif /* __ASSEMBLY__ */ ··· 113 119 * compilers. We don't consider that to be an error, so set them to nothing. 114 120 * For example, some of them are for compiler specific plugins. 115 121 */ 116 - #ifndef __designated_init 117 - # define __designated_init 118 - #endif 119 - 120 122 #ifndef __latent_entropy 121 123 # define __latent_entropy 122 124 #endif ··· 130 140 # define randomized_struct_fields_end 131 141 #endif 132 142 133 - #ifndef __visible 134 - #define __visible 135 - #endif 136 - 137 - /* 138 - * Assume alignment of return value. 139 - */ 140 - #ifndef __assume_aligned 141 - #define __assume_aligned(a, ...) 142 - #endif 143 - 144 143 /* Are two types/vars the same type (ignoring qualifiers)? */ 145 144 #define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) 146 145 ··· 137 158 #define __native_word(t) \ 138 159 (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \ 139 160 sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) 140 - 141 - #ifndef __noclone 142 - #define __noclone 143 - #endif 144 161 145 162 /* Helpers for emitting diagnostics in pragmas. */ 146 163 #ifndef __diag ··· 156 181 __diag_ ## compiler(version, warn, option) 157 182 #define __diag_error(compiler, version, option, comment) \ 158 183 __diag_ ## compiler(version, error, option) 159 - 160 - /* 161 - * From the GCC manual: 162 - * 163 - * Many functions have no effects except the return value and their 164 - * return value depends only on the parameters and/or global 165 - * variables. Such a function can be subject to common subexpression 166 - * elimination and loop optimization just as an arithmetic operator 167 - * would be. 168 - * [...] 169 - */ 170 - #define __pure __attribute__((__pure__)) 171 - #define __attribute_const__ __attribute__((__const__)) 172 - #define __aligned(x) __attribute__((__aligned__(x))) 173 - #define __aligned_largest __attribute__((__aligned__)) 174 - #define __printf(a, b) __attribute__((__format__(printf, a, b))) 175 - #define __scanf(a, b) __attribute__((__format__(scanf, a, b))) 176 - #define __maybe_unused __attribute__((__unused__)) 177 - #define __always_unused __attribute__((__unused__)) 178 - #define __mode(x) __attribute__((__mode__(x))) 179 - #define __malloc __attribute__((__malloc__)) 180 - #define __used __attribute__((__used__)) 181 - #define __noreturn __attribute__((__noreturn__)) 182 - #define __packed __attribute__((__packed__)) 183 - #define __weak __attribute__((__weak__)) 184 - #define __alias(symbol) __attribute__((__alias__(#symbol))) 185 - #define __cold __attribute__((__cold__)) 186 - #define __section(S) __attribute__((__section__(#S))) 187 - #define __always_inline inline __attribute__((__always_inline__)) 188 - #define __gnu_inline __attribute__((__gnu_inline__)) 189 - 190 184 191 185 #ifdef CONFIG_ENABLE_MUST_CHECK 192 186 #define __must_check __attribute__((__warn_unused_result__)) ··· 190 246 * semantics rather than c99. This prevents multiple symbol definition errors 191 247 * of extern inline functions at link time. 192 248 * A lot of inline functions can cause havoc with function tracing. 249 + * Do not use __always_inline here, since currently it expands to inline again 250 + * (which would break users of __always_inline). 193 251 */ 194 252 #if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ 195 253 !defined(CONFIG_OPTIMIZE_INLINING) 196 - #define inline \ 197 - inline __attribute__((__always_inline__, __unused__)) notrace __gnu_inline 254 + #define inline inline __attribute__((__always_inline__)) __gnu_inline \ 255 + __maybe_unused notrace 198 256 #else 199 - #define inline inline __attribute__((__unused__)) notrace __gnu_inline 257 + #define inline inline __gnu_inline \ 258 + __maybe_unused notrace 200 259 #endif 201 260 202 261 #define __inline__ inline 203 - #define __inline inline 204 - #define noinline __attribute__((__noinline__)) 262 + #define __inline inline 205 263 206 264 /* 207 265 * Rather then using noinline to prevent stack consumption, use