__if_constexpr(expr, if_const, if_not_const) returns 'if_const' if 'expr' is a 'constant integer expression' otherwise 'if_not_const'. The two values may have different types. __is_constexpr(expr) is equivalent to __if_constexpr(expr, 1, 0). Signed-off-by: David Laight <david.laight@xxxxxxxxxx> --- v2: - Don't change __is_constexpr() include/linux/compiler.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 2594553bb30b..35d5b2fa4786 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -242,6 +242,23 @@ static inline void *offset_to_ptr(const int *off) /* &a[0] degrades to a pointer: a different type from an array */ #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) +/** + * __if_constexpr - Check whether an expression is an 'integer + * constant expression' + * @expr: Expression to test, not evaluated, can be a pointer + * @if_const: return value if constant + * @if_not_const: return value if not constant + * + * The return values @if_const and @if_not_const can have different types. + * + * Relies on typeof(x ? NULL : ptr_type) being ptr_type and + * typeof(x ? (void *)y : ptr_type) being 'void *'. + */ +#define __if_constexpr(expr, if_const, if_not_const) \ + _Generic(0 ? ((void *)((long)(expr) * 0l)) : (char *)0, \ + char *: (if_const), \ + void *: (if_not_const)) + /* * This returns a constant expression while determining if an argument is * a constant expression, most importantly without evaluating the argument. -- 2.17.1 - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)