Message ID | 85f3af8298a4d7b6e40045aa7c6873d7ae1bc311.1683206686.git.anand.jain@oracle.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [RFC] btrfs: fix static_assert for older gcc | expand |
On Thu, May 04, 2023 at 09:56:37PM +0800, Anand Jain wrote: > Make is failing on gcc 8.5 with definition miss match error. It looks > like the definition of static_assert has changed > > Signed-off-by: Anand Jain <anand.jain@oracle.com> > --- > fs/btrfs/accessors.h | 14 ++++++++------ > 1 file changed, 8 insertions(+), 6 deletions(-) > > diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h > index ceadfc5d6c66..c480205afac2 100644 > --- a/fs/btrfs/accessors.h > +++ b/fs/btrfs/accessors.h > @@ -58,29 +58,31 @@ DECLARE_BTRFS_SETGET_BITS(16) > DECLARE_BTRFS_SETGET_BITS(32) > DECLARE_BTRFS_SETGET_BITS(64) > > +#define _static_assert(x) static_assert(x, "") So the problem is that the message is mandatory on older compilers?
On 04/05/2023 22:33, David Sterba wrote: > On Thu, May 04, 2023 at 09:56:37PM +0800, Anand Jain wrote: >> Make is failing on gcc 8.5 with definition miss match error. It looks >> like the definition of static_assert has changed >> >> Signed-off-by: Anand Jain <anand.jain@oracle.com> >> --- >> fs/btrfs/accessors.h | 14 ++++++++------ >> 1 file changed, 8 insertions(+), 6 deletions(-) >> >> diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h >> index ceadfc5d6c66..c480205afac2 100644 >> --- a/fs/btrfs/accessors.h >> +++ b/fs/btrfs/accessors.h >> @@ -58,29 +58,31 @@ DECLARE_BTRFS_SETGET_BITS(16) >> DECLARE_BTRFS_SETGET_BITS(32) >> DECLARE_BTRFS_SETGET_BITS(64) >> >> +#define _static_assert(x) static_assert(x, "") > > So the problem is that the message is mandatory on older compilers? I couldn't confirm the GCC version and static_assert changes, but found the kernel wrapper in ./tools/include/linux/build_bug.h. /** * static_assert - check integer constant expression at build time * * static_assert() is a wrapper for the C11 _Static_assert, with a * little macro magic to make the message optional (defaulting to the * stringification of the tested expression). * * Contrary to BUILD_BUG_ON(), static_assert() can be used at global * scope, but requires the expression to be an integer constant * expression (i.e., it is not enough that __builtin_constant_p() is * true for expr). * * Also note that BUILD_BUG_ON() fails the build if the condition is * true, while static_assert() fails the build if the expression is * false. */ #ifndef static_assert #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr) #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) #endif // static_assert
On 04/05/2023 22:56, Anand Jain wrote: > > > On 04/05/2023 22:33, David Sterba wrote: >> On Thu, May 04, 2023 at 09:56:37PM +0800, Anand Jain wrote: >>> Make is failing on gcc 8.5 with definition miss match error. It looks >>> like the definition of static_assert has changed >>> >>> Signed-off-by: Anand Jain <anand.jain@oracle.com> >>> --- >>> fs/btrfs/accessors.h | 14 ++++++++------ >>> 1 file changed, 8 insertions(+), 6 deletions(-) >>> >>> diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h >>> index ceadfc5d6c66..c480205afac2 100644 >>> --- a/fs/btrfs/accessors.h >>> +++ b/fs/btrfs/accessors.h >>> @@ -58,29 +58,31 @@ DECLARE_BTRFS_SETGET_BITS(16) >>> DECLARE_BTRFS_SETGET_BITS(32) >>> DECLARE_BTRFS_SETGET_BITS(64) >>> +#define _static_assert(x) static_assert(x, "") >> >> So the problem is that the message is mandatory on older compilers? > > > I couldn't confirm the GCC version and static_assert changes, but found > the kernel wrapper in ./tools/include/linux/build_bug.h. > > > /** > * static_assert - check integer constant expression at build time > * > * static_assert() is a wrapper for the C11 _Static_assert, with a > * little macro magic to make the message optional (defaulting to the > * stringification of the tested expression). > * > * Contrary to BUILD_BUG_ON(), static_assert() can be used at global > * scope, but requires the expression to be an integer constant > * expression (i.e., it is not enough that __builtin_constant_p() is > * true for expr). > * > * Also note that BUILD_BUG_ON() fails the build if the condition is > * true, while static_assert() fails the build if the expression is > * false. > */ > #ifndef static_assert > #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, > #expr) > #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) > #endif // static_assert Closest I could find is https://en.cppreference.com/w/cpp/language/static_assert "message can be omitted. (since C++17)"
On Thu, May 04, 2023 at 10:56:18PM +0800, Anand Jain wrote: > > > On 04/05/2023 22:33, David Sterba wrote: > > On Thu, May 04, 2023 at 09:56:37PM +0800, Anand Jain wrote: > >> Make is failing on gcc 8.5 with definition miss match error. It looks > >> like the definition of static_assert has changed > >> > >> Signed-off-by: Anand Jain <anand.jain@oracle.com> > >> --- > >> fs/btrfs/accessors.h | 14 ++++++++------ > >> 1 file changed, 8 insertions(+), 6 deletions(-) > >> > >> diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h > >> index ceadfc5d6c66..c480205afac2 100644 > >> --- a/fs/btrfs/accessors.h > >> +++ b/fs/btrfs/accessors.h > >> @@ -58,29 +58,31 @@ DECLARE_BTRFS_SETGET_BITS(16) > >> DECLARE_BTRFS_SETGET_BITS(32) > >> DECLARE_BTRFS_SETGET_BITS(64) > >> > >> +#define _static_assert(x) static_assert(x, "") > > > > So the problem is that the message is mandatory on older compilers? > > > I couldn't confirm the GCC version and static_assert changes, but found > the kernel wrapper in ./tools/include/linux/build_bug.h. This is in tools but there's same in linux/include/build_bug.h, without the ifdef. > /** > * static_assert - check integer constant expression at build time > * > * static_assert() is a wrapper for the C11 _Static_assert, with a > * little macro magic to make the message optional (defaulting to the > * stringification of the tested expression). > * > * Contrary to BUILD_BUG_ON(), static_assert() can be used at global > * scope, but requires the expression to be an integer constant > * expression (i.e., it is not enough that __builtin_constant_p() is > * true for expr). > * > * Also note that BUILD_BUG_ON() fails the build if the condition is > * true, while static_assert() fails the build if the expression is > * false. > */ > #ifndef static_assert > #define static_assert(expr, ...) __static_assert(expr, ##__VA_ARGS__, #expr) > #define __static_assert(expr, msg, ...) _Static_assert(expr, msg) > #endif // static_assert The static_assert is defined by compiler so the first thing we see is that one (I think) but kernel defines its own and that has the mesage optional. For the fix I added a _static_assert(expr) that does does not clash with the existing static_assert and only expands the expression to the message and then passes it to _Static_assert.
diff --git a/fs/btrfs/accessors.h b/fs/btrfs/accessors.h index ceadfc5d6c66..c480205afac2 100644 --- a/fs/btrfs/accessors.h +++ b/fs/btrfs/accessors.h @@ -58,29 +58,31 @@ DECLARE_BTRFS_SETGET_BITS(16) DECLARE_BTRFS_SETGET_BITS(32) DECLARE_BTRFS_SETGET_BITS(64) +#define _static_assert(x) static_assert(x, "") + #define BTRFS_SETGET_FUNCS(name, type, member, bits) \ static inline u##bits btrfs_##name(const struct extent_buffer *eb, \ const type *s) \ { \ - static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ + _static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ return btrfs_get_##bits(eb, s, offsetof(type, member)); \ } \ static inline void btrfs_set_##name(const struct extent_buffer *eb, type *s, \ u##bits val) \ { \ - static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ + _static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ btrfs_set_##bits(eb, s, offsetof(type, member), val); \ } \ static inline u##bits btrfs_token_##name(struct btrfs_map_token *token, \ const type *s) \ { \ - static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ + _static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ return btrfs_get_token_##bits(token, s, offsetof(type, member));\ } \ static inline void btrfs_set_token_##name(struct btrfs_map_token *token,\ type *s, u##bits val) \ { \ - static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ + _static_assert(sizeof(u##bits) == sizeof(((type *)0))->member); \ btrfs_set_token_##bits(token, s, offsetof(type, member), val); \ } @@ -111,7 +113,7 @@ static inline void btrfs_set_##name(type *s, u##bits val) \ static inline u64 btrfs_device_total_bytes(const struct extent_buffer *eb, struct btrfs_dev_item *s) { - static_assert(sizeof(u64) == + _static_assert(sizeof(u64) == sizeof(((struct btrfs_dev_item *)0))->total_bytes); return btrfs_get_64(eb, s, offsetof(struct btrfs_dev_item, total_bytes)); @@ -120,7 +122,7 @@ static inline void btrfs_set_device_total_bytes(const struct extent_buffer *eb, struct btrfs_dev_item *s, u64 val) { - static_assert(sizeof(u64) == + _static_assert(sizeof(u64) == sizeof(((struct btrfs_dev_item *)0))->total_bytes); WARN_ON(!IS_ALIGNED(val, eb->fs_info->sectorsize)); btrfs_set_64(eb, s, offsetof(struct btrfs_dev_item, total_bytes), val);
Make is failing on gcc 8.5 with definition miss match error. It looks like the definition of static_assert has changed Signed-off-by: Anand Jain <anand.jain@oracle.com> --- fs/btrfs/accessors.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-)