2022-02-03 01:28:47

by Rasmus Villemoes

[permalink] [raw]
Subject: [PATCH] include: drop pointless __compiler_offsetof indirection

(1) compiler_types.h is unconditionally included via an -include
flag (see scripts/Makefile.lib), and it defines __compiler_offsetof
unconditionally. So testing for definedness of __compiler_offsetof is
mostly pointless.

(2) Every relevant compiler provides __builtin_offsetof (even sparse
has had that for 14 years), and if for whatever reason one would end
up picking up the poor man's fallback definition (C file compiler with
completely custom CFLAGS?), newer clang versions won't treat the
result as an Integer Constant Expression, so if used in place where
such is required (static initializer or static_assert), one would
get errors like

t.c:11:16: error: static_assert expression is not an integral constant expression
t.c:11:16: note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
t.c:4:33: note: expanded from macro 'offsetof'
#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)

So just define offsetof unconditionally and directly in terms of
__builtin_offsetof.

Signed-off-by: Rasmus Villemoes <[email protected]>
---
include/linux/compiler_types.h | 2 --
include/linux/stddef.h | 6 +-----
2 files changed, 1 insertion(+), 7 deletions(-)

diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 3c1795fdb568..83ee7f7ada5d 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -137,8 +137,6 @@ struct ftrace_likely_data {
*/
#define __naked __attribute__((__naked__)) notrace

-#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
-
/*
* Prefer gnu_inline, so that extern inline functions do not emit an
* externally visible function. This makes extern inline behave as per gnu89
diff --git a/include/linux/stddef.h b/include/linux/stddef.h
index ca507bd5f808..929d67710cc5 100644
--- a/include/linux/stddef.h
+++ b/include/linux/stddef.h
@@ -13,11 +13,7 @@ enum {
};

#undef offsetof
-#ifdef __compiler_offsetof
-#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
-#else
-#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
-#endif
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)

/**
* sizeof_field() - Report the size of a struct field in bytes
--
2.31.1


2022-02-03 20:37:26

by Nick Desaulniers

[permalink] [raw]
Subject: Re: [PATCH] include: drop pointless __compiler_offsetof indirection

On Wed, Feb 2, 2022 at 2:21 AM Rasmus Villemoes
<[email protected]> wrote:
>
> (1) compiler_types.h is unconditionally included via an -include
> flag (see scripts/Makefile.lib), and it defines __compiler_offsetof
> unconditionally. So testing for definedness of __compiler_offsetof is
> mostly pointless.
>
> (2) Every relevant compiler provides __builtin_offsetof (even sparse
> has had that for 14 years), and if for whatever reason one would end
> up picking up the poor man's fallback definition (C file compiler with
> completely custom CFLAGS?), newer clang versions won't treat the
> result as an Integer Constant Expression, so if used in place where
> such is required (static initializer or static_assert), one would
> get errors like
>
> t.c:11:16: error: static_assert expression is not an integral constant expression
> t.c:11:16: note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
> t.c:4:33: note: expanded from macro 'offsetof'
> #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
>
> So just define offsetof unconditionally and directly in terms of
> __builtin_offsetof.
>
> Signed-off-by: Rasmus Villemoes <[email protected]>
> ---
> include/linux/compiler_types.h | 2 --
> include/linux/stddef.h | 6 +-----
> 2 files changed, 1 insertion(+), 7 deletions(-)
>
> diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
> index 3c1795fdb568..83ee7f7ada5d 100644
> --- a/include/linux/compiler_types.h
> +++ b/include/linux/compiler_types.h
> @@ -137,8 +137,6 @@ struct ftrace_likely_data {
> */
> #define __naked __attribute__((__naked__)) notrace
>
> -#define __compiler_offsetof(a, b) __builtin_offsetof(a, b)
> -
> /*
> * Prefer gnu_inline, so that extern inline functions do not emit an
> * externally visible function. This makes extern inline behave as per gnu89
> diff --git a/include/linux/stddef.h b/include/linux/stddef.h
> index ca507bd5f808..929d67710cc5 100644
> --- a/include/linux/stddef.h
> +++ b/include/linux/stddef.h
> @@ -13,11 +13,7 @@ enum {
> };
>
> #undef offsetof
> -#ifdef __compiler_offsetof
> -#define offsetof(TYPE, MEMBER) __compiler_offsetof(TYPE, MEMBER)
> -#else
> -#define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)

RIP `((size_t)&((TYPE *)0)->MEMBER)`; you were beautiful in a way only
a mother could love.
Acked-by: Nick Desaulniers <[email protected]>

> -#endif
> +#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
>
> /**
> * sizeof_field() - Report the size of a struct field in bytes
> --
> 2.31.1
>


--
Thanks,
~Nick Desaulniers

2022-02-04 13:52:43

by Kees Cook

[permalink] [raw]
Subject: Re: [PATCH] include: drop pointless __compiler_offsetof indirection

On Wed, Feb 02, 2022 at 11:21:47AM +0100, Rasmus Villemoes wrote:
> (1) compiler_types.h is unconditionally included via an -include
> flag (see scripts/Makefile.lib), and it defines __compiler_offsetof
> unconditionally. So testing for definedness of __compiler_offsetof is
> mostly pointless.
>
> (2) Every relevant compiler provides __builtin_offsetof (even sparse
> has had that for 14 years), and if for whatever reason one would end
> up picking up the poor man's fallback definition (C file compiler with
> completely custom CFLAGS?), newer clang versions won't treat the
> result as an Integer Constant Expression, so if used in place where
> such is required (static initializer or static_assert), one would
> get errors like
>
> t.c:11:16: error: static_assert expression is not an integral constant expression
> t.c:11:16: note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
> t.c:4:33: note: expanded from macro 'offsetof'
> #define offsetof(TYPE, MEMBER) ((size_t)&((TYPE *)0)->MEMBER)
>
> So just define offsetof unconditionally and directly in terms of
> __builtin_offsetof.
>
> Signed-off-by: Rasmus Villemoes <[email protected]>

Yes please. :)

Reviewed-by: Kees Cook <[email protected]>

--
Kees Cook