| From 30c7bbec521f0b91b0530f970e4e33d4fbb7beba Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 22 May 2021 17:42:02 -0700 |
| Subject: linux/bits.h: fix compilation error with GENMASK |
| |
| From: Rikard Falkeborn <rikard.falkeborn@gmail.com> |
| |
| [ Upstream commit f747e6667ebb2ffb8133486c9cd19800d72b0d98 ] |
| |
| GENMASK() has an input check which uses __builtin_choose_expr() to |
| enable a compile time sanity check of its inputs if they are known at |
| compile time. |
| |
| However, it turns out that __builtin_constant_p() does not always return |
| a compile time constant [0]. It was thought this problem was fixed with |
| gcc 4.9 [1], but apparently this is not the case [2]. |
| |
| Switch to use __is_constexpr() instead which always returns a compile time |
| constant, regardless of its inputs. |
| |
| Link: https://lore.kernel.org/lkml/42b4342b-aefc-a16a-0d43-9f9c0d63ba7a@rasmusvillemoes.dk [0] |
| Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=19449 [1] |
| Link: https://lore.kernel.org/lkml/1ac7bbc2-45d9-26ed-0b33-bf382b8d858b@I-love.SAKURA.ne.jp [2] |
| Link: https://lkml.kernel.org/r/20210511203716.117010-1-rikard.falkeborn@gmail.com |
| Signed-off-by: Rikard Falkeborn <rikard.falkeborn@gmail.com> |
| Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> |
| Acked-by: Arnd Bergmann <arnd@arndb.de> |
| Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com> |
| Cc: Ard Biesheuvel <ardb@kernel.org> |
| Cc: Yury Norov <yury.norov@gmail.com> |
| Cc: Peter Zijlstra <peterz@infradead.org> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| include/linux/bits.h | 2 +- |
| include/linux/const.h | 8 ++++++++ |
| include/linux/minmax.h | 10 ++-------- |
| tools/include/linux/bits.h | 2 +- |
| tools/include/linux/const.h | 8 ++++++++ |
| 5 files changed, 20 insertions(+), 10 deletions(-) |
| |
| diff --git a/include/linux/bits.h b/include/linux/bits.h |
| index 7f475d59a097..87d112650dfb 100644 |
| --- a/include/linux/bits.h |
| +++ b/include/linux/bits.h |
| @@ -22,7 +22,7 @@ |
| #include <linux/build_bug.h> |
| #define GENMASK_INPUT_CHECK(h, l) \ |
| (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ |
| - __builtin_constant_p((l) > (h)), (l) > (h), 0))) |
| + __is_constexpr((l) > (h)), (l) > (h), 0))) |
| #else |
| /* |
| * BUILD_BUG_ON_ZERO is not available in h files included from asm files, |
| diff --git a/include/linux/const.h b/include/linux/const.h |
| index 81b8aae5a855..435ddd72d2c4 100644 |
| --- a/include/linux/const.h |
| +++ b/include/linux/const.h |
| @@ -3,4 +3,12 @@ |
| |
| #include <vdso/const.h> |
| |
| +/* |
| + * This returns a constant expression while determining if an argument is |
| + * a constant expression, most importantly without evaluating the argument. |
| + * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de> |
| + */ |
| +#define __is_constexpr(x) \ |
| + (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) |
| + |
| #endif /* _LINUX_CONST_H */ |
| diff --git a/include/linux/minmax.h b/include/linux/minmax.h |
| index c0f57b0c64d9..5433c08fcc68 100644 |
| --- a/include/linux/minmax.h |
| +++ b/include/linux/minmax.h |
| @@ -2,6 +2,8 @@ |
| #ifndef _LINUX_MINMAX_H |
| #define _LINUX_MINMAX_H |
| |
| +#include <linux/const.h> |
| + |
| /* |
| * min()/max()/clamp() macros must accomplish three things: |
| * |
| @@ -17,14 +19,6 @@ |
| #define __typecheck(x, y) \ |
| (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) |
| |
| -/* |
| - * This returns a constant expression while determining if an argument is |
| - * a constant expression, most importantly without evaluating the argument. |
| - * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de> |
| - */ |
| -#define __is_constexpr(x) \ |
| - (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) |
| - |
| #define __no_side_effects(x, y) \ |
| (__is_constexpr(x) && __is_constexpr(y)) |
| |
| diff --git a/tools/include/linux/bits.h b/tools/include/linux/bits.h |
| index 7f475d59a097..87d112650dfb 100644 |
| --- a/tools/include/linux/bits.h |
| +++ b/tools/include/linux/bits.h |
| @@ -22,7 +22,7 @@ |
| #include <linux/build_bug.h> |
| #define GENMASK_INPUT_CHECK(h, l) \ |
| (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ |
| - __builtin_constant_p((l) > (h)), (l) > (h), 0))) |
| + __is_constexpr((l) > (h)), (l) > (h), 0))) |
| #else |
| /* |
| * BUILD_BUG_ON_ZERO is not available in h files included from asm files, |
| diff --git a/tools/include/linux/const.h b/tools/include/linux/const.h |
| index 81b8aae5a855..435ddd72d2c4 100644 |
| --- a/tools/include/linux/const.h |
| +++ b/tools/include/linux/const.h |
| @@ -3,4 +3,12 @@ |
| |
| #include <vdso/const.h> |
| |
| +/* |
| + * This returns a constant expression while determining if an argument is |
| + * a constant expression, most importantly without evaluating the argument. |
| + * Glory to Martin Uecker <Martin.Uecker@med.uni-goettingen.de> |
| + */ |
| +#define __is_constexpr(x) \ |
| + (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) * 0l)) : (int *)8))) |
| + |
| #endif /* _LINUX_CONST_H */ |
| -- |
| 2.30.2 |
| |