diff mbox series

[RFC] btrfs: fix static_assert for older gcc

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

Commit Message

Anand Jain May 4, 2023, 1:56 p.m. UTC
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(-)

Comments

David Sterba May 4, 2023, 2:33 p.m. UTC | #1
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?
Anand Jain May 4, 2023, 2:56 p.m. UTC | #2
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
Anand Jain May 4, 2023, 3:03 p.m. UTC | #3
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)"
David Sterba May 4, 2023, 9:10 p.m. UTC | #4
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 mbox series

Patch

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);