Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp987003imm; Wed, 22 Aug 2018 16:40:50 -0700 (PDT) X-Google-Smtp-Source: AA+uWPzgW6MTsR0FhchzEtQmLSDRAd45zss7t9dfUz0rkYRnRRLHD1ZVExC/uhKhVUJsyODaXT7F X-Received: by 2002:a63:e516:: with SMTP id r22-v6mr53120285pgh.170.1534981250344; Wed, 22 Aug 2018 16:40:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1534981250; cv=none; d=google.com; s=arc-20160816; b=ZPwjX/ZVUWq5/+sPMqMk2VKxsQf/0DzEBnaftfZL3QjI4GweURbsWm3ntG7wHRxYF7 thNvoZiJXgbLqGw7eJzz69UqhscO7H6dQ2U05KGHFInYDM78qhPGwoedjUEVdZwmRuul 12B0p0/2JIcsWKGeoxkRxBRjUEHwDRV6ymbREO6a2C3zf1wMMIrmETpUqUaHEAlp5nBz 5AE3DcVEjA/vLZEWIdLpYPUT5UHajVmro1ArUgsswijEfGhZ3dZeK/9/DSLBMJ6W/ube zXoZiL10t5p+S9HV28LFLNY4rvieFrDHOA3IG8PZWrBVKPmYZRV9Lg1juu7w+G3m0zz/ Lmiw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:from:subject:mime-version :message-id:date:dkim-signature:arc-authentication-results; bh=lUeu8zi/hsOcT3UBs0nciHHvGfJYtNdVj8RrQ1c9zTs=; b=zWlOtIVYgkXBIkmbSP3wdZO5D4YGQciKNZuhHJnCERXf0bYGdgRZa43rCTTOjIF9ms 8E6BzzxXoI9uZrFI88c2WvWSzqLAf3JuhKolOAW1rf30mzDb4VhOmkXie4UjWWUTK7J9 XRl4mk+EAmBI8uZRYhE7k5jQrCiH6A2YqzD3fIn38qzg3yoEROf6vzgkH3xRyDOEhsX8 +Azdrm9RdEKimwy4awjUvfZAekDLJKwzVy0ZaSdmBeUnv//BAjMGvuC5uTZdcctrNE5U a8OdfDR/Qe21+G2Iu++qeFTigp9O8pQYl70f+8CnMcdxMLz8j2/oHjzikdce4AOX7K0i h8ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=KKYlKYYF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o20-v6si2809511pgh.319.2018.08.22.16.40.34; Wed, 22 Aug 2018 16:40:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=KKYlKYYF; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727162AbeHWDGW (ORCPT + 99 others); Wed, 22 Aug 2018 23:06:22 -0400 Received: from mail-vk0-f74.google.com ([209.85.213.74]:47316 "EHLO mail-vk0-f74.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726424AbeHWDGV (ORCPT ); Wed, 22 Aug 2018 23:06:21 -0400 Received: by mail-vk0-f74.google.com with SMTP id b63-v6so1409040vkf.14 for ; Wed, 22 Aug 2018 16:39:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=lUeu8zi/hsOcT3UBs0nciHHvGfJYtNdVj8RrQ1c9zTs=; b=KKYlKYYFmRLGJTwDYSKH2Nh/GxDqWMy2mi9SR+sMHPRt8E6p9y3SynQWdODl2Kmbmk JlWMM7otrLSd+Q2yS32VMX35C+MRjcfZJMqsT125J9IS2IjLaCAT5AZ7C6Ut5XGX9wRU Sd8Smxu4L8xZc0VV/e1kuloJzX2fPjqzzyAH9v+gH14E51tlhzPe7u6mQ43jh8ZG1SW3 oFLPepHNVGnAEDoiyHXhsQQND5+iyFvzwMZWectaDFEb0Ox/KEPsCb+frBZstUkKawjQ FylAHYPxgsaUjPgUlYwGqBaAwckcIFMbUKUWis12M7WDLZ+3cNHbNusEssu214mxMtNH v6LA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=lUeu8zi/hsOcT3UBs0nciHHvGfJYtNdVj8RrQ1c9zTs=; b=fwP4HultRGt3ww0EuEC6wgiGX1NVAdYx7RSsv/fLKor+o1oCi4QdsGT6shhW+lJKxv 24wP1kuc7Zsiaimnrad2OnAJ2OXKGYJESQ+YBBUlIFFILV99Fs+FLEHwyAC+hf26i0Yd HshkP+7IBALI7DM7cFNNPMtcLc2hPydIQ2vGTAlImPQ+xiTNuPSOfz1fCMXFtAPKX+RC cGH9CyO6m30/LMv421HSeQhtf7v0cpCXwvy6aClYBsdmTV1s1zCdMxQQ/kcLs2C5DpSn fxIHrPHD/kwA2rrtKgU7tSZWRWnZA2oi5a+blmZPNcPV0mDnwHbt1LyCiLbZ1mlPTduL 16XA== X-Gm-Message-State: AOUpUlHhMetyhTpgbxgRn6ZSfZBYH6fmwHU5xYTuj4L1cbqxQqPuHbx+ p/m2S5nNcSH7Jg56+OKJMVs5Z/LER8nTDeY0A6I= X-Received: by 2002:a1f:104c:: with SMTP id g73-v6mr9797738vki.2.1534981166434; Wed, 22 Aug 2018 16:39:26 -0700 (PDT) Date: Wed, 22 Aug 2018 16:37:24 -0700 Message-Id: <20180822233724.110454-1-ndesaulniers@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.18.0.1017.ga543ac7ca45-goog Subject: [PATCH] include/linux/compiler*.h: make compiler-*.h mutually exclusive From: Nick Desaulniers To: torvalds@linux-foundation.org Cc: keescook@chromium.org, joe@perches.com, corbet@lwn.net, yamada.masahiro@socionext.com, arnd@arndb.de, dwmw@amazon.co.uk, linux-kernel@vger.kernel.org, tglx@linutronix.de, will.deacon@arm.com, geert@linux-m68k.org, mingo@kernel.org, akpm@linux-foundation.org, asmadeus@codewreck.org, daniel@iogearbox.net, hpa@zytor.com, Nick Desaulniers Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit cafa0010cd51 ("Raise the minimum required gcc version to 4.6") recently exposed a brittle part of the build for supporting non-gcc compilers. Both Clang and ICC define __GNUC__, __GNUC_MINOR__, and __GNUC_PATCHLEVEL__ for quick compatibility with code bases that haven't added compiler specific checks for __clang__ or __INTEL_COMPILER. This is brittle, as they happened to get compatibility by posing as a certain version of GCC. This broke when upgrading the minimal version of GCC required to build the kernel, to a version above what ICC and Clang claim to be. Rather than always including compiler-gcc.h then undefining or redefining macros in compiler-intel.h or compiler-clang.h, let's separate out the compiler specific macro definitions into mutually exclusive headers, do more proper compiler detection, and keep shared definitions in compiler_types.h. Reported-by: Masahiro Yamada Suggested-by: Eli Friedman Suggested-by: Joe Perches Signed-off-by: Nick Desaulniers --- arch/arm/kernel/asm-offsets.c | 13 +- drivers/gpu/drm/i915/i915_utils.h | 2 +- drivers/watchdog/kempld_wdt.c | 5 - include/linux/compiler-clang.h | 20 ++- include/linux/compiler-gcc.h | 88 ----------- include/linux/compiler-intel.h | 13 +- include/linux/compiler_types.h | 238 ++++++++++++++---------------- mm/ksm.c | 4 +- mm/migrate.c | 3 +- 9 files changed, 133 insertions(+), 253 deletions(-) diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 974d8d7d1bcd..3968d6c22455 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -38,25 +38,14 @@ #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32 #endif /* - * GCC 3.0, 3.1: general bad code generation. - * GCC 3.2.0: incorrect function argument offset calculation. - * GCC 3.2.x: miscompiles NEW_AUX_ENT in fs/binfmt_elf.c - * (http://gcc.gnu.org/PR8896) and incorrect structure - * initialisation in fs/jffs2/erase.c * GCC 4.8.0-4.8.2: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58854 * miscompiles find_get_entry(), and can result in EXT3 and EXT4 * filesystem corruption (possibly other FS too). */ -#ifdef __GNUC__ -#if (__GNUC__ == 3 && __GNUC_MINOR__ < 3) -#error Your compiler is too buggy; it is known to miscompile kernels. -#error Known good compilers: 3.3, 4.x -#endif -#if GCC_VERSION >= 40800 && GCC_VERSION < 40803 +#if defined(GCC_VERSION) && GCC_VERSION >= 40800 && GCC_VERSION < 40803 #error Your compiler is too buggy; it is known to miscompile kernels #error and result in filesystem corruption and oopses. #endif -#endif int main(void) { diff --git a/drivers/gpu/drm/i915/i915_utils.h b/drivers/gpu/drm/i915/i915_utils.h index 00165ad55fb3..395dd2511568 100644 --- a/drivers/gpu/drm/i915/i915_utils.h +++ b/drivers/gpu/drm/i915/i915_utils.h @@ -43,7 +43,7 @@ #define MISSING_CASE(x) WARN(1, "Missing case (%s == %ld)\n", \ __stringify(x), (long)(x)) -#if GCC_VERSION >= 70000 +#if defined(GCC_VERSION) && GCC_VERSION >= 70000 #define add_overflows(A, B) \ __builtin_add_overflow_p((A), (B), (typeof((A) + (B)))0) #else diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c index 2f3b049ea301..e268add43010 100644 --- a/drivers/watchdog/kempld_wdt.c +++ b/drivers/watchdog/kempld_wdt.c @@ -146,12 +146,7 @@ static int kempld_wdt_set_stage_timeout(struct kempld_wdt_data *wdt_data, u32 remainder; u8 stage_cfg; -#if GCC_VERSION < 40400 - /* work around a bug compiling do_div() */ - prescaler = READ_ONCE(kempld_prescaler[PRESCALER_21]); -#else prescaler = kempld_prescaler[PRESCALER_21]; -#endif if (!stage) return -EINVAL; diff --git a/include/linux/compiler-clang.h b/include/linux/compiler-clang.h index 7087446c24c8..5f0754692ce6 100644 --- a/include/linux/compiler-clang.h +++ b/include/linux/compiler-clang.h @@ -6,11 +6,7 @@ /* Some compiler specific definitions are overwritten here * for Clang compiler */ - -#ifdef uninitialized_var -#undef uninitialized_var #define uninitialized_var(x) x = *(&(x)) -#endif /* same as gcc, this was present in clang-2.6 so we can assume it works * with any version that can compile the kernel @@ -25,14 +21,8 @@ #define __SANITIZE_ADDRESS__ #endif -#undef __no_sanitize_address #define __no_sanitize_address __attribute__((no_sanitize("address"))) -/* Clang doesn't have a way to turn it off per-function, yet. */ -#ifdef __noretpoline -#undef __noretpoline -#endif - /* * Not all versions of clang implement the the type-generic versions * of the builtin overflow checkers. Fortunately, clang implements @@ -40,9 +30,17 @@ * checks. Unfortunately, we don't know which version of gcc clang * pretends to be, so the macro may or may not be defined. */ -#undef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW #if __has_builtin(__builtin_mul_overflow) && \ __has_builtin(__builtin_add_overflow) && \ __has_builtin(__builtin_sub_overflow) #define COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW 1 #endif + +/* The following are for compatibility with GCC, from compiler-gcc.h, + * and may be redefined here because they should not be shared with other + * compilers, like ICC. + */ +#define barrier() (__asm__ __volatile__("" : : : "memory")) +#define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +#define __assume_aligned(a, ...) \ + __attribute__((__assume_aligned__(a, ## __VA_ARGS__))) diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h index 250b9b7cfd60..763bbad1e258 100644 --- a/include/linux/compiler-gcc.h +++ b/include/linux/compiler-gcc.h @@ -75,48 +75,6 @@ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) #endif -/* - * Feature detection for gnu_inline (gnu89 extern inline semantics). Either - * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics, - * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not - * defined so the gnu89 semantics are the default. - */ -#ifdef __GNUC_STDC_INLINE__ -# define __gnu_inline __attribute__((gnu_inline)) -#else -# define __gnu_inline -#endif - -/* - * Force always-inline if the user requests it so via the .config, - * or if gcc is too old. - * GCC does not warn about unused static inline functions for - * -Wunused-function. This turns out to avoid the need for complex #ifdef - * directives. Suppress the warning in clang as well by using "unused" - * function attribute, which is redundant but not harmful for gcc. - * Prefer gnu_inline, so that extern inline functions do not emit an - * externally visible function. This makes extern inline behave as per gnu89 - * semantics rather than c99. This prevents multiple symbol definition errors - * of extern inline functions at link time. - * A lot of inline functions can cause havoc with function tracing. - */ -#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ - !defined(CONFIG_OPTIMIZE_INLINING) -#define inline \ - inline __attribute__((always_inline, unused)) notrace __gnu_inline -#else -#define inline inline __attribute__((unused)) notrace __gnu_inline -#endif - -#define __inline__ inline -#define __inline inline -#define __always_inline inline __attribute__((always_inline)) -#define noinline __attribute__((noinline)) - -#define __packed __attribute__((packed)) -#define __weak __attribute__((weak)) -#define __alias(symbol) __attribute__((alias(#symbol))) - #ifdef RETPOLINE #define __noretpoline __attribute__((indirect_branch("keep"))) #endif @@ -135,55 +93,9 @@ */ #define __naked __attribute__((naked)) noinline __noclone notrace -#define __noreturn __attribute__((noreturn)) - -/* - * From the GCC manual: - * - * Many functions have no effects except the return value and their - * return value depends only on the parameters and/or global - * variables. Such a function can be subject to common subexpression - * elimination and loop optimization just as an arithmetic operator - * would be. - * [...] - */ -#define __pure __attribute__((pure)) -#define __aligned(x) __attribute__((aligned(x))) -#define __aligned_largest __attribute__((aligned)) -#define __printf(a, b) __attribute__((format(printf, a, b))) -#define __scanf(a, b) __attribute__((format(scanf, a, b))) -#define __attribute_const__ __attribute__((__const__)) -#define __maybe_unused __attribute__((unused)) -#define __always_unused __attribute__((unused)) -#define __mode(x) __attribute__((mode(x))) - -#define __must_check __attribute__((warn_unused_result)) -#define __malloc __attribute__((__malloc__)) - -#define __used __attribute__((__used__)) -#define __compiler_offsetof(a, b) \ - __builtin_offsetof(a, b) - -/* Mark functions as cold. gcc will assume any path leading to a call - * to them will be unlikely. This means a lot of manual unlikely()s - * are unnecessary now for any paths leading to the usual suspects - * like BUG(), printk(), panic() etc. [but let's keep them for now for - * older compilers] - * - * Early snapshots of gcc 4.3 don't support this and we can't detect this - * in the preprocessor, but we can live with this because they're unreleased. - * Maketime probing would be overkill here. - * - * gcc also has a __attribute__((__hot__)) to move hot functions into - * a special section, but I don't see any sense in this right now in - * the kernel context - */ -#define __cold __attribute__((__cold__)) - #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) #define __optimize(level) __attribute__((__optimize__(level))) -#define __nostackprotector __optimize("no-stack-protector") #define __compiletime_object_size(obj) __builtin_object_size(obj, 0) diff --git a/include/linux/compiler-intel.h b/include/linux/compiler-intel.h index 547cdc920a3c..4c7f9befa9f6 100644 --- a/include/linux/compiler-intel.h +++ b/include/linux/compiler-intel.h @@ -14,10 +14,6 @@ /* Intel ECC compiler doesn't support gcc specific asm stmts. * It uses intrinsics to do the equivalent things. */ -#undef barrier -#undef barrier_data -#undef RELOC_HIDE -#undef OPTIMIZER_HIDE_VAR #define barrier() __memory_barrier() #define barrier_data(ptr) barrier() @@ -38,13 +34,12 @@ #endif -#ifndef __HAVE_BUILTIN_BSWAP16__ /* icc has this, but it's called _bswap16 */ #define __HAVE_BUILTIN_BSWAP16__ #define __builtin_bswap16 _bswap16 -#endif -/* - * icc defines __GNUC__, but does not implement the builtin overflow checkers. +/* The following are for compatibility with GCC, from compiler-gcc.h, + * and may be redefined here because they should not be shared with other + * compilers, like clang. */ -#undef COMPILER_HAS_GENERIC_BUILTIN_OVERFLOW +#define __visible __attribute__((externally_visible)) diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h index fbf337933fd8..90479a0f3986 100644 --- a/include/linux/compiler_types.h +++ b/include/linux/compiler_types.h @@ -54,32 +54,20 @@ extern void __chk_io_ptr(const volatile void __iomem *); #ifdef __KERNEL__ -#ifdef __GNUC__ -#include -#endif - -#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__) -#define notrace __attribute__((hotpatch(0,0))) -#else -#define notrace __attribute__((no_instrument_function)) -#endif - -/* Intel compiler defines __GNUC__. So we will overwrite implementations - * coming from above header files here - */ -#ifdef __INTEL_COMPILER -# include -#endif - -/* Clang compiler defines __GNUC__. So we will overwrite implementations - * coming from above header files here - */ +/* Compiler specific macros. */ #ifdef __clang__ #include +#elif defined(__INTEL_COMPILER) +#include +#elif defined(__GNUC__) +/* The above compilers also define __GNUC__, so order is important here. */ +#include +#else +#error "Unknown compiler" #endif /* - * Generic compiler-dependent macros required for kernel + * Generic compiler-independent macros required for kernel * build go below this comment. Actual compiler/compiler version * specific implementations come from the above header files */ @@ -106,93 +94,19 @@ struct ftrace_likely_data { unsigned long constant; }; -#endif /* __KERNEL__ */ - -#endif /* __ASSEMBLY__ */ - -#ifdef __KERNEL__ - /* Don't. Just don't. */ #define __deprecated #define __deprecated_for_modules -#ifndef __must_check -#define __must_check -#endif - -#ifndef CONFIG_ENABLE_MUST_CHECK -#undef __must_check -#define __must_check -#endif - -#ifndef __malloc -#define __malloc -#endif - -/* - * Allow us to avoid 'defined but not used' warnings on functions and data, - * as well as force them to be emitted to the assembly file. - * - * As of gcc 3.4, static functions that are not marked with attribute((used)) - * may be elided from the assembly file. As of gcc 3.4, static data not so - * marked will not be elided, but this may change in a future gcc version. - * - * NOTE: Because distributions shipped with a backported unit-at-a-time - * compiler in gcc 3.3, we must define __used to be __attribute__((used)) - * for gcc >=3.3 instead of 3.4. - * - * In prior versions of gcc, such functions and data would be emitted, but - * would be warned about except with attribute((unused)). - * - * Mark functions that are referenced only in inline assembly as __used so - * the code is emitted even though it appears to be unreferenced. - */ -#ifndef __used -# define __used /* unimplemented */ -#endif - -#ifndef __maybe_unused -# define __maybe_unused /* unimplemented */ -#endif - -#ifndef __always_unused -# define __always_unused /* unimplemented */ -#endif - -#ifndef noinline -#define noinline -#endif - -/* - * Rather then using noinline to prevent stack consumption, use - * noinline_for_stack instead. For documentation reasons. - */ -#define noinline_for_stack noinline - -#ifndef __always_inline -#define __always_inline inline -#endif - #endif /* __KERNEL__ */ +#endif /* __ASSEMBLY__ */ + /* - * From the GCC manual: - * - * Many functions do not examine any values except their arguments, - * and have no effects except the return value. Basically this is - * just slightly more strict class than the `pure' attribute above, - * since function is not allowed to read global memory. - * - * Note that a function that has pointer arguments and examines the - * data pointed to must _not_ be declared `const'. Likewise, a - * function that calls a non-`const' function usually must not be - * `const'. It does not make sense for a `const' function to return - * `void'. + * The below symbols may be defined for one or more, but not ALL, of the above + * compilers. We don't consider that to be an error, so set them to nothing. + * For example, some of them are for compiler specific plugins. */ -#ifndef __attribute_const__ -# define __attribute_const__ /* unimplemented */ -#endif - #ifndef __designated_init # define __designated_init #endif @@ -214,28 +128,10 @@ struct ftrace_likely_data { # define randomized_struct_fields_end #endif -/* - * Tell gcc if a function is cold. The compiler will assume any path - * directly leading to the call is unlikely. - */ - -#ifndef __cold -#define __cold -#endif - -/* Simple shorthand for a section definition */ -#ifndef __section -# define __section(S) __attribute__ ((__section__(#S))) -#endif - #ifndef __visible #define __visible #endif -#ifndef __nostackprotector -# define __nostackprotector -#endif - /* * Assume alignment of return value. */ @@ -243,17 +139,23 @@ struct ftrace_likely_data { #define __assume_aligned(a, ...) #endif - /* Are two types/vars the same type (ignoring qualifiers)? */ -#ifndef __same_type -# define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) -#endif +#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) /* Is this type a native word size -- useful for atomic operations */ -#ifndef __native_word -# define __native_word(t) (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) +#define __native_word(t) \ + (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \ + sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) + +#ifndef __attribute_const__ +#define __attribute_const__ __attribute__((__const__)) #endif +#ifndef __noclone +#define __noclone +#endif + +/* Helpers for emitting diagnostics in pragmas. */ #ifndef __diag #define __diag(string) #endif @@ -272,4 +174,92 @@ struct ftrace_likely_data { #define __diag_error(compiler, version, option, comment) \ __diag_ ## compiler(version, error, option) +/* + * From the GCC manual: + * + * Many functions have no effects except the return value and their + * return value depends only on the parameters and/or global + * variables. Such a function can be subject to common subexpression + * elimination and loop optimization just as an arithmetic operator + * would be. + * [...] + */ +#define __pure __attribute__((pure)) +#define __aligned(x) __attribute__((aligned(x))) +#define __aligned_largest __attribute__((aligned)) +#define __printf(a, b) __attribute__((format(printf, a, b))) +#define __scanf(a, b) __attribute__((format(scanf, a, b))) +#define __maybe_unused __attribute__((unused)) +#define __always_unused __attribute__((unused)) +#define __mode(x) __attribute__((mode(x))) +#define __malloc __attribute__((__malloc__)) +#define __used __attribute__((__used__)) +#define __noreturn __attribute__((noreturn)) +#define __packed __attribute__((packed)) +#define __weak __attribute__((weak)) +#define __alias(symbol) __attribute__((alias(#symbol))) +#define __cold __attribute__((cold)) +#define __section(S) __attribute__((__section__(#S))) + + +#ifdef CONFIG_ENABLE_MUST_CHECK +#define __must_check __attribute__((warn_unused_result)) +#else +#define __must_check +#endif + +#if defined(CC_USING_HOTPATCH) && !defined(__CHECKER__) +#define notrace __attribute__((hotpatch(0, 0))) +#else +#define notrace __attribute__((no_instrument_function)) +#endif + +#define __compiler_offsetof(a, b) __builtin_offsetof(a, b) + +/* + * Feature detection for gnu_inline (gnu89 extern inline semantics). Either + * __GNUC_STDC_INLINE__ is defined (not using gnu89 extern inline semantics, + * and we opt in to the gnu89 semantics), or __GNUC_STDC_INLINE__ is not + * defined so the gnu89 semantics are the default. + */ +#ifdef __GNUC_STDC_INLINE__ +# define __gnu_inline __attribute__((gnu_inline)) +#else +# define __gnu_inline +#endif + +/* + * Force always-inline if the user requests it so via the .config. + * GCC does not warn about unused static inline functions for + * -Wunused-function. This turns out to avoid the need for complex #ifdef + * directives. Suppress the warning in clang as well by using "unused" + * function attribute, which is redundant but not harmful for gcc. + * Prefer gnu_inline, so that extern inline functions do not emit an + * externally visible function. This makes extern inline behave as per gnu89 + * semantics rather than c99. This prevents multiple symbol definition errors + * of extern inline functions at link time. + * A lot of inline functions can cause havoc with function tracing. + */ +#if !defined(CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING) || \ + !defined(CONFIG_OPTIMIZE_INLINING) +#define inline \ + inline __attribute__((always_inline, unused)) notrace __gnu_inline +#else +#define inline inline __attribute__((unused)) notrace __gnu_inline +#endif + +#define __inline__ inline +#define __inline inline +#define noinline __attribute__((noinline)) + +#ifndef __always_inline +#define __always_inline inline __attribute__((always_inline)) +#endif + +/* + * Rather then using noinline to prevent stack consumption, use + * noinline_for_stack instead. For documentation reasons. + */ +#define noinline_for_stack noinline + #endif /* __LINUX_COMPILER_TYPES_H */ diff --git a/mm/ksm.c b/mm/ksm.c index 1bd514c9e5d0..5b0894b45ee5 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -652,9 +652,9 @@ static void remove_node_from_stable_tree(struct stable_node *stable_node) * list_head to stay clear from the rb_parent_color union * (aligned and different than any node) and also different * from &migrate_nodes. This will verify that future list.h changes - * don't break STABLE_NODE_DUP_HEAD. + * don't break STABLE_NODE_DUP_HEAD. Only recent gcc can handle it. */ -#if GCC_VERSION >= 40903 /* only recent gcc can handle it */ +#if defined(GCC_VERSION) && GCC_VERSION >= 40903 BUILD_BUG_ON(STABLE_NODE_DUP_HEAD <= &migrate_nodes); BUILD_BUG_ON(STABLE_NODE_DUP_HEAD >= &migrate_nodes + 1); #endif diff --git a/mm/migrate.c b/mm/migrate.c index 4a83268e23c2..c27e97b5b69d 100644 --- a/mm/migrate.c +++ b/mm/migrate.c @@ -1131,7 +1131,8 @@ static int __unmap_and_move(struct page *page, struct page *newpage, * gcc 4.7 and 4.8 on arm get an ICEs when inlining unmap_and_move(). Work * around it. */ -#if (GCC_VERSION >= 40700 && GCC_VERSION < 40900) && defined(CONFIG_ARM) +#if defined(CONFIG_ARM) && \ + defined(GCC_VERSION) && GCC_VERSION < 40900 && GCC_VERSION >= 40700 #define ICE_noinline noinline #else #define ICE_noinline -- 2.18.0.1017.ga543ac7ca45-goog