Raise gcc version requirement to 4.9

I realize that we fairly recently raised it to 4.8, but the fact is, 4.9
is a much better minimum version to target.

We have a number of workarounds for actual bugs in pre-4.9 gcc versions
(including things like internal compiler errors on ARM), but we also
have some syntactic workarounds for lacking features.

In particular, raising the minimum to 4.9 means that we can now just
assume _Generic() exists, which is likely the much better replacement
for a lot of very convoluted built-time magic with conditionals on
sizeof and/or __builtin_choose_expr() with same_type() etc.

Using _Generic also means that you will need to have a very recent
version of 'sparse', but thats easy to build yourself, and much less of
a hassle than some old gcc version can be.

The latest (in a long string) of reasons for minimum compiler version
upgrades was commit 5435f73d5c ("efi/x86: Fix build with gcc 4").

Ard points out that RHEL 7 uses gcc-4.8, but the people who stay back on
old RHEL versions persumably also don't build their own kernels anyway.
And maybe they should cross-built or just have a little side affair with
a newer compiler?

Acked-by: Ard Biesheuvel <ardb@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2020-07-08 10:48:35 -07:00
parent dcde237b9b
commit 6ec4476ac8
7 changed files with 8 additions and 56 deletions

View file

@ -31,15 +31,6 @@
#if defined(__APCS_26__) #if defined(__APCS_26__)
#error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32 #error Sorry, your compiler targets APCS-26 but this kernel requires APCS-32
#endif #endif
/*
* 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).
*/
#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
int main(void) int main(void)
{ {

View file

@ -19,14 +19,13 @@
\ \
/* \ /* \
* We can't unroll if the number of iterations isn't \ * We can't unroll if the number of iterations isn't \
* compile-time constant. Unfortunately GCC versions \ * compile-time constant. Unfortunately clang versions \
* up until 4.6 tend to miss obvious constants & cause \ * up until 8.0 tend to miss obvious constants & cause \
* this check to fail, even though they go on to \ * this check to fail, even though they go on to \
* generate reasonable code for the switch statement, \ * generate reasonable code for the switch statement, \
* so we skip the sanity check for those compilers. \ * so we skip the sanity check for those compilers. \
*/ \ */ \
BUILD_BUG_ON((CONFIG_GCC_VERSION >= 40700 || \ BUILD_BUG_ON((CONFIG_CLANG_VERSION >= 80000) && \
CONFIG_CLANG_VERSION >= 80000) && \
!__builtin_constant_p(times)); \ !__builtin_constant_p(times)); \
\ \
switch (times) { \ switch (times) { \

View file

@ -18,8 +18,7 @@
* position @h. For example * position @h. For example
* GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
*/ */
#if !defined(__ASSEMBLY__) && \ #if !defined(__ASSEMBLY__)
(!defined(CONFIG_CC_IS_GCC) || CONFIG_GCC_VERSION >= 49000)
#include <linux/build_bug.h> #include <linux/build_bug.h>
#define GENMASK_INPUT_CHECK(h, l) \ #define GENMASK_INPUT_CHECK(h, l) \
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \

View file

@ -11,7 +11,7 @@
+ __GNUC_PATCHLEVEL__) + __GNUC_PATCHLEVEL__)
/* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 */ /* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 */
#if GCC_VERSION < 40800 #if GCC_VERSION < 40900
# error Sorry, your compiler is too old - please upgrade it. # error Sorry, your compiler is too old - please upgrade it.
#endif #endif

View file

@ -252,32 +252,8 @@ struct ftrace_likely_data {
* __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving * __unqual_scalar_typeof(x) - Declare an unqualified scalar type, leaving
* non-scalar types unchanged. * non-scalar types unchanged.
*/ */
#if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 40900) || defined(__CHECKER__)
/* /*
* We build this out of a couple of helper macros in a vain attempt to * Prefer C11 _Generic for better compile-times and simpler code. Note: 'char'
* help you keep your lunch down while reading it.
*/
#define __pick_scalar_type(x, type, otherwise) \
__builtin_choose_expr(__same_type(x, type), (type)0, otherwise)
/*
* 'char' is not type-compatible with either 'signed char' or 'unsigned char',
* so we include the naked type here as well as the signed/unsigned variants.
*/
#define __pick_integer_type(x, type, otherwise) \
__pick_scalar_type(x, type, \
__pick_scalar_type(x, unsigned type, \
__pick_scalar_type(x, signed type, otherwise)))
#define __unqual_scalar_typeof(x) typeof( \
__pick_integer_type(x, char, \
__pick_integer_type(x, short, \
__pick_integer_type(x, int, \
__pick_integer_type(x, long, \
__pick_integer_type(x, long long, x))))))
#else
/*
* If supported, prefer C11 _Generic for better compile-times. As above, 'char'
* is not type-compatible with 'signed char', and we define a separate case. * is not type-compatible with 'signed char', and we define a separate case.
*/ */
#define __scalar_type_to_expr_cases(type) \ #define __scalar_type_to_expr_cases(type) \
@ -293,7 +269,6 @@ struct ftrace_likely_data {
__scalar_type_to_expr_cases(long), \ __scalar_type_to_expr_cases(long), \
__scalar_type_to_expr_cases(long long), \ __scalar_type_to_expr_cases(long long), \
default: (x))) default: (x)))
#endif
/* Is this type a native word size -- useful for atomic operations */ /* Is this type a native word size -- useful for atomic operations */
#define __native_word(t) \ #define __native_word(t) \

View file

@ -1160,22 +1160,11 @@ static int __unmap_and_move(struct page *page, struct page *newpage,
return rc; return rc;
} }
/*
* gcc 4.7 and 4.8 on arm get an ICEs when inlining unmap_and_move(). Work
* around it.
*/
#if defined(CONFIG_ARM) && \
defined(GCC_VERSION) && GCC_VERSION < 40900 && GCC_VERSION >= 40700
#define ICE_noinline noinline
#else
#define ICE_noinline
#endif
/* /*
* Obtain the lock on page, remove all ptes and migrate the page * Obtain the lock on page, remove all ptes and migrate the page
* to the newly allocated page in newpage. * to the newly allocated page in newpage.
*/ */
static ICE_noinline int unmap_and_move(new_page_t get_new_page, static int unmap_and_move(new_page_t get_new_page,
free_page_t put_new_page, free_page_t put_new_page,
unsigned long private, struct page *page, unsigned long private, struct page *page,
int force, enum migrate_mode mode, int force, enum migrate_mode mode,

View file

@ -18,8 +18,7 @@
* position @h. For example * position @h. For example
* GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
*/ */
#if !defined(__ASSEMBLY__) && \ #if !defined(__ASSEMBLY__)
(!defined(CONFIG_CC_IS_GCC) || CONFIG_GCC_VERSION >= 49000)
#include <linux/build_bug.h> #include <linux/build_bug.h>
#define GENMASK_INPUT_CHECK(h, l) \ #define GENMASK_INPUT_CHECK(h, l) \
(BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \