[RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family

Jesse Taube posted 1 patch 1 week, 4 days ago
include/linux/overflow.h | 58 +++++++++++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 4 deletions(-)
[RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family
Posted by Jesse Taube 1 week, 4 days ago
Add new DECLARE_SIZED_FLEX() helper to set the default size of a
flexible-array member. The code is identical to the declaration in
__DEFINE_FLEX() which has also been changed to use DECLARE_SIZED_FLEX().

Add DECLARE_COUNTED_FLEX_ARRAY() helper which is a variant of
DECLARE_FLEX_ARRAY() with a counted-by attribute.

Also add default sized variants of
DECLARE_FLEX_ARRAY(), DECLARE_SIZED_FLEX(), and
DECLARE_COUNTED_FLEX_ARRAY(), DECLARE_COUNTED_SIZED_FLEX().

Signed-off-by: Jesse Taube <jtaubepe@redhat.com>
---
 include/linux/overflow.h | 58 +++++++++++++++++++++++++++++++++++++---
 1 file changed, 54 insertions(+), 4 deletions(-)

diff --git a/include/linux/overflow.h b/include/linux/overflow.h
index a8cb6319b4fb..a3384cae49e5 100644
--- a/include/linux/overflow.h
+++ b/include/linux/overflow.h
@@ -464,6 +464,59 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
  */
 #define struct_offset(p, member) (offsetof(typeof(*(p)), member))
 
+/**
+ * __DECLARE_SIZED_FLEX() - helper macro for DECLARE_SIZED_FLEX() family.
+ * Allows for easily declaring a structure with a trailing flexible array member
+ * to have a specific size.
+ *
+ * @obj: object to be given a specific size
+ * @name: Name of the array member.
+ * @count: Number of elements in the array; must be compile-time const.
+ */
+#define __DECLARE_SIZED_FLEX(obj, name, count)	\
+	_Static_assert(__builtin_constant_p(count),		\
+		       "default sized flex array members require compile-time const count");	\
+	union {							\
+		u8 bytes[struct_size_t(obj, name, count)];	\
+		obj;						\
+	}
+
+/**
+ * DECLARE_COUNTED_FLEX_ARRAY() - Declare a counted flexible array
+ *
+ * @type: Type name.
+ * @name: Name of the array member.
+ * @counter: Name of the __counted_by member.
+ */
+#define DECLARE_COUNTED_FLEX_ARRAY(type, name, counter)\
+	struct { \
+		size_t counter; \
+		type name[] __counted_by(counter); \
+	}
+
+/**
+ * DECLARE_SIZED_FLEX() - Declare a structure with a trailing flexible array
+ * member with a default size.
+ *
+ * @type: Type name.
+ * @name: Name of the array member.
+ * @count: Number of elements in the array; must be compile-time const.
+ */
+#define DECLARE_SIZED_FLEX(type, name, count)	\
+	__DECLARE_SIZED_FLEX(type name[], name, count)
+
+/**
+ * DECLARE_COUNTED_SIZED_FLEX() - Declare a structure with a trailing flexible
+ * array member counted by count, with a default size.
+ *
+ * @type: Type name.
+ * @name: Name of the array member.
+ * @counter: Name of the __counted_by member.
+ * @count: Number of elements in the array; must be compile-time const.
+ */
+#define DECLARE_COUNTED_SIZED_FLEX(type, name, counter, count)	\
+	__DECLARE_SIZED_FLEX(DECLARE_COUNTED_FLEX_ARRAY(type, name, counter), name, count)
+
 /**
  * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
  * Enables caller macro to pass arbitrary trailing expressions
@@ -477,10 +530,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
 #define __DEFINE_FLEX(type, name, member, count, trailer...)			\
 	_Static_assert(__builtin_constant_p(count),				\
 		       "onstack flex array members require compile-time const count"); \
-	union {									\
-		u8 bytes[struct_size_t(type, member, count)];			\
-		type obj;							\
-	} name##_u trailer;							\
+	__DECLARE_SIZED_FLEX(type obj, member, count) name##_u trailer;		\
 	type *name = (type *)&name##_u
 
 /**
-- 
2.54.0
Re: [RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family
Posted by Kees Cook 1 week, 3 days ago
On Tue, Jul 14, 2026 at 11:18:18AM -0400, Jesse Taube wrote:
> Add new DECLARE_SIZED_FLEX() helper to set the default size of a
> flexible-array member. The code is identical to the declaration in
> __DEFINE_FLEX() which has also been changed to use DECLARE_SIZED_FLEX().
> 
> Add DECLARE_COUNTED_FLEX_ARRAY() helper which is a variant of
> DECLARE_FLEX_ARRAY() with a counted-by attribute.
> 
> Also add default sized variants of
> DECLARE_FLEX_ARRAY(), DECLARE_SIZED_FLEX(), and
> DECLARE_COUNTED_FLEX_ARRAY(), DECLARE_COUNTED_SIZED_FLEX().

Where do you want to use these new helpers?

> Signed-off-by: Jesse Taube <jtaubepe@redhat.com>
> ---
>  include/linux/overflow.h | 58 +++++++++++++++++++++++++++++++++++++---
>  1 file changed, 54 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> index a8cb6319b4fb..a3384cae49e5 100644
> --- a/include/linux/overflow.h
> +++ b/include/linux/overflow.h
> @@ -464,6 +464,59 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
>   */
>  #define struct_offset(p, member) (offsetof(typeof(*(p)), member))
>  
> +/**
> + * __DECLARE_SIZED_FLEX() - helper macro for DECLARE_SIZED_FLEX() family.
> + * Allows for easily declaring a structure with a trailing flexible array member
> + * to have a specific size.
> + *
> + * @obj: object to be given a specific size
> + * @name: Name of the array member.
> + * @count: Number of elements in the array; must be compile-time const.
> + */
> +#define __DECLARE_SIZED_FLEX(obj, name, count)	\
> +	_Static_assert(__builtin_constant_p(count),		\
> +		       "default sized flex array members require compile-time const count");	\
> +	union {							\
> +		u8 bytes[struct_size_t(obj, name, count)];	\
> +		obj;						\
> +	}
> +
> +/**
> + * DECLARE_COUNTED_FLEX_ARRAY() - Declare a counted flexible array
> + *
> + * @type: Type name.
> + * @name: Name of the array member.
> + * @counter: Name of the __counted_by member.
> + */
> +#define DECLARE_COUNTED_FLEX_ARRAY(type, name, counter)\
> +	struct { \
> +		size_t counter; \
> +		type name[] __counted_by(counter); \
> +	}
> +
> +/**
> + * DECLARE_SIZED_FLEX() - Declare a structure with a trailing flexible array
> + * member with a default size.
> + *
> + * @type: Type name.
> + * @name: Name of the array member.
> + * @count: Number of elements in the array; must be compile-time const.
> + */
> +#define DECLARE_SIZED_FLEX(type, name, count)	\
> +	__DECLARE_SIZED_FLEX(type name[], name, count)
> +
> +/**
> + * DECLARE_COUNTED_SIZED_FLEX() - Declare a structure with a trailing flexible
> + * array member counted by count, with a default size.
> + *
> + * @type: Type name.
> + * @name: Name of the array member.
> + * @counter: Name of the __counted_by member.
> + * @count: Number of elements in the array; must be compile-time const.
> + */
> +#define DECLARE_COUNTED_SIZED_FLEX(type, name, counter, count)	\
> +	__DECLARE_SIZED_FLEX(DECLARE_COUNTED_FLEX_ARRAY(type, name, counter), name, count)

I ask about where these will be used because one of the things I want to
keep tied together is the "counter" and "count", which usually means the
declaration should be combined with an initializer in some way so that
the counter gets assigned, as DEFINE_FLEX() ultimately does.

I'm worried that extracting the internal construction of __DEFINE_FLEX
means we may run the risk of increasing the risk of losing that tie.

So, I'd love to understand how you want to use this, as that would help
my understanding and potentially shape the design so we can keep counter
and count strongly associated.

> +
>  /**
>   * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
>   * Enables caller macro to pass arbitrary trailing expressions
> @@ -477,10 +530,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
>  #define __DEFINE_FLEX(type, name, member, count, trailer...)			\
>  	_Static_assert(__builtin_constant_p(count),				\
>  		       "onstack flex array members require compile-time const count"); \
> -	union {									\
> -		u8 bytes[struct_size_t(type, member, count)];			\
> -		type obj;							\
> -	} name##_u trailer;							\
> +	__DECLARE_SIZED_FLEX(type obj, member, count) name##_u trailer;		\
>  	type *name = (type *)&name##_u

-Kees

-- 
Kees Cook
Re: [RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family
Posted by Jesse Taube 1 week, 1 day ago
On Wed, Jul 15, 2026 at 12:12 PM Kees Cook <kees@kernel.org> wrote:
>
> On Tue, Jul 14, 2026 at 11:18:18AM -0400, Jesse Taube wrote:
> > Add new DECLARE_SIZED_FLEX() helper to set the default size of a
> > flexible-array member. The code is identical to the declaration in
> > __DEFINE_FLEX() which has also been changed to use DECLARE_SIZED_FLEX().
> >
> > Add DECLARE_COUNTED_FLEX_ARRAY() helper which is a variant of
> > DECLARE_FLEX_ARRAY() with a counted-by attribute.
> >
> > Also add default sized variants of
> > DECLARE_FLEX_ARRAY(), DECLARE_SIZED_FLEX(), and
> > DECLARE_COUNTED_FLEX_ARRAY(), DECLARE_COUNTED_SIZED_FLEX().
>
> Where do you want to use these new helpers?
>
> > Signed-off-by: Jesse Taube <jtaubepe@redhat.com>
> > ---
> >  include/linux/overflow.h | 58 +++++++++++++++++++++++++++++++++++++---
> >  1 file changed, 54 insertions(+), 4 deletions(-)
> >
> > diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> > index a8cb6319b4fb..a3384cae49e5 100644
> > --- a/include/linux/overflow.h
> > +++ b/include/linux/overflow.h
> > @@ -464,6 +464,59 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
> >   */
> >  #define struct_offset(p, member) (offsetof(typeof(*(p)), member))
> >
> > +/**
> > + * __DECLARE_SIZED_FLEX() - helper macro for DECLARE_SIZED_FLEX() family.
> > + * Allows for easily declaring a structure with a trailing flexible array member
> > + * to have a specific size.
> > + *
> > + * @obj: object to be given a specific size
> > + * @name: Name of the array member.
> > + * @count: Number of elements in the array; must be compile-time const.
> > + */
> > +#define __DECLARE_SIZED_FLEX(obj, name, count)       \
> > +     _Static_assert(__builtin_constant_p(count),             \
> > +                    "default sized flex array members require compile-time const count");    \
> > +     union {                                                 \
> > +             u8 bytes[struct_size_t(obj, name, count)];      \
> > +             obj;                                            \
> > +     }
> > +
> > +/**
> > + * DECLARE_COUNTED_FLEX_ARRAY() - Declare a counted flexible array
> > + *
> > + * @type: Type name.
> > + * @name: Name of the array member.
> > + * @counter: Name of the __counted_by member.
> > + */
> > +#define DECLARE_COUNTED_FLEX_ARRAY(type, name, counter)\
> > +     struct { \
> > +             size_t counter; \
> > +             type name[] __counted_by(counter); \
> > +     }
> > +
> > +/**
> > + * DECLARE_SIZED_FLEX() - Declare a structure with a trailing flexible array
> > + * member with a default size.
> > + *
> > + * @type: Type name.
> > + * @name: Name of the array member.
> > + * @count: Number of elements in the array; must be compile-time const.
> > + */
> > +#define DECLARE_SIZED_FLEX(type, name, count)        \
> > +     __DECLARE_SIZED_FLEX(type name[], name, count)
> > +
> > +/**
> > + * DECLARE_COUNTED_SIZED_FLEX() - Declare a structure with a trailing flexible
> > + * array member counted by count, with a default size.
> > + *
> > + * @type: Type name.
> > + * @name: Name of the array member.
> > + * @counter: Name of the __counted_by member.
> > + * @count: Number of elements in the array; must be compile-time const.
> > + */
> > +#define DECLARE_COUNTED_SIZED_FLEX(type, name, counter, count)       \
> > +     __DECLARE_SIZED_FLEX(DECLARE_COUNTED_FLEX_ARRAY(type, name, counter), name, count)
>
> I ask about where these will be used because one of the things I want to
> keep tied together is the "counter" and "count", which usually means the
> declaration should be combined with an initializer in some way so that
> the counter gets assigned, as DEFINE_FLEX() ultimately does.
>
> I'm worried that extracting the internal construction of __DEFINE_FLEX
> means we may run the risk of increasing the risk of losing that tie.

We can add a comment to make sure to set count, or use DEFINE_FLEX
to allocate it. Im not sure if there is a way for this to be a compile time
error though.

> So, I'd love to understand how you want to use this, as that would help
> my understanding and potentially shape the design so we can keep counter
> and count strongly associated.

Basically, I want to use `DECLARE_COUNTED_SIZED_FLEX` for a version of
this patch that
uses `__counted_by`
https://lore.kernel.org/linux-scsi/97526d45-ec7d-48a0-bdc6-659f75839f53@embeddedor.com/
I have checked that it does always set the `counter` variable correctly.

As for `DECLARE_COUNTED_FLEX_ARRAY` there is already `DECLARE_FLEX_ARRAY` and
the counted variant is already used in a few places. A good example is
`struct max77759_maxq_response` which subsiqently gets allocated with
`DEFINE_FLEX`
https://elixir.bootlin.com/linux/v7.2-rc1/source/include/linux/mfd/max77759.h#L253

I assume you are ok with adding `__DECLARE_SIZED_FLEX` and
`DECLARE_SIZED_FLEX` as
they are usefull in cases where keeping structure offsets is
important, similar to
TRAILING_OVERLAP. An example of where `__DECLARE_SIZED_FLEX` could be used is:
https://lore.kernel.org/all/20260714185621.610105-1-jtaubepe@redhat.com/

Thanks,
Jesse Taube

>
> > +
> >  /**
> >   * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
> >   * Enables caller macro to pass arbitrary trailing expressions
> > @@ -477,10 +530,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
> >  #define __DEFINE_FLEX(type, name, member, count, trailer...)                 \
> >       _Static_assert(__builtin_constant_p(count),                             \
> >                      "onstack flex array members require compile-time const count"); \
> > -     union {                                                                 \
> > -             u8 bytes[struct_size_t(type, member, count)];                   \
> > -             type obj;                                                       \
> > -     } name##_u trailer;                                                     \
> > +     __DECLARE_SIZED_FLEX(type obj, member, count) name##_u trailer;         \
> >       type *name = (type *)&name##_u
>
> -Kees
>
> --
> Kees Cook
>
Re: [RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family
Posted by Gustavo A. R. Silva 1 week ago
Hi!

On 7/17/26 10:17, Jesse Taube wrote:
> On Wed, Jul 15, 2026 at 12:12 PM Kees Cook <kees@kernel.org> wrote:
>>
>> On Tue, Jul 14, 2026 at 11:18:18AM -0400, Jesse Taube wrote:
>>> Add new DECLARE_SIZED_FLEX() helper to set the default size of a
>>> flexible-array member. The code is identical to the declaration in
>>> __DEFINE_FLEX() which has also been changed to use DECLARE_SIZED_FLEX().
>>>
>>> Add DECLARE_COUNTED_FLEX_ARRAY() helper which is a variant of
>>> DECLARE_FLEX_ARRAY() with a counted-by attribute.
>>>
>>> Also add default sized variants of
>>> DECLARE_FLEX_ARRAY(), DECLARE_SIZED_FLEX(), and
>>> DECLARE_COUNTED_FLEX_ARRAY(), DECLARE_COUNTED_SIZED_FLEX().
>>
>> Where do you want to use these new helpers?
>>
>>> Signed-off-by: Jesse Taube <jtaubepe@redhat.com>
>>> ---
>>>   include/linux/overflow.h | 58 +++++++++++++++++++++++++++++++++++++---
>>>   1 file changed, 54 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
>>> index a8cb6319b4fb..a3384cae49e5 100644
>>> --- a/include/linux/overflow.h
>>> +++ b/include/linux/overflow.h
>>> @@ -464,6 +464,59 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
>>>    */
>>>   #define struct_offset(p, member) (offsetof(typeof(*(p)), member))
>>>
>>> +/**
>>> + * __DECLARE_SIZED_FLEX() - helper macro for DECLARE_SIZED_FLEX() family.
>>> + * Allows for easily declaring a structure with a trailing flexible array member
>>> + * to have a specific size.
>>> + *
>>> + * @obj: object to be given a specific size
>>> + * @name: Name of the array member.
>>> + * @count: Number of elements in the array; must be compile-time const.
>>> + */
>>> +#define __DECLARE_SIZED_FLEX(obj, name, count)       \
>>> +     _Static_assert(__builtin_constant_p(count),             \
>>> +                    "default sized flex array members require compile-time const count");    \
>>> +     union {                                                 \
>>> +             u8 bytes[struct_size_t(obj, name, count)];      \
>>> +             obj;                                            \
>>> +     }
>>> +
>>> +/**
>>> + * DECLARE_COUNTED_FLEX_ARRAY() - Declare a counted flexible array
>>> + *
>>> + * @type: Type name.
>>> + * @name: Name of the array member.
>>> + * @counter: Name of the __counted_by member.
>>> + */
>>> +#define DECLARE_COUNTED_FLEX_ARRAY(type, name, counter)\
>>> +     struct { \
>>> +             size_t counter; \
>>> +             type name[] __counted_by(counter); \
>>> +     }
>>> +
>>> +/**
>>> + * DECLARE_SIZED_FLEX() - Declare a structure with a trailing flexible array
>>> + * member with a default size.
>>> + *
>>> + * @type: Type name.
>>> + * @name: Name of the array member.
>>> + * @count: Number of elements in the array; must be compile-time const.
>>> + */
>>> +#define DECLARE_SIZED_FLEX(type, name, count)        \
>>> +     __DECLARE_SIZED_FLEX(type name[], name, count)
>>> +
>>> +/**
>>> + * DECLARE_COUNTED_SIZED_FLEX() - Declare a structure with a trailing flexible
>>> + * array member counted by count, with a default size.
>>> + *
>>> + * @type: Type name.
>>> + * @name: Name of the array member.
>>> + * @counter: Name of the __counted_by member.
>>> + * @count: Number of elements in the array; must be compile-time const.
>>> + */
>>> +#define DECLARE_COUNTED_SIZED_FLEX(type, name, counter, count)       \
>>> +     __DECLARE_SIZED_FLEX(DECLARE_COUNTED_FLEX_ARRAY(type, name, counter), name, count)
>>
>> I ask about where these will be used because one of the things I want to
>> keep tied together is the "counter" and "count", which usually means the
>> declaration should be combined with an initializer in some way so that
>> the counter gets assigned, as DEFINE_FLEX() ultimately does.
>>
>> I'm worried that extracting the internal construction of __DEFINE_FLEX
>> means we may run the risk of increasing the risk of losing that tie.
> 
> We can add a comment to make sure to set count, or use DEFINE_FLEX
> to allocate it. Im not sure if there is a way for this to be a compile time
> error though.
> 
>> So, I'd love to understand how you want to use this, as that would help
>> my understanding and potentially shape the design so we can keep counter
>> and count strongly associated.
> 
> Basically, I want to use `DECLARE_COUNTED_SIZED_FLEX` for a version of
> this patch that
> uses `__counted_by`
> https://lore.kernel.org/linux-scsi/97526d45-ec7d-48a0-bdc6-659f75839f53@embeddedor.com/
> I have checked that it does always set the `counter` variable correctly.
> 
> As for `DECLARE_COUNTED_FLEX_ARRAY` there is already `DECLARE_FLEX_ARRAY` and
> the counted variant is already used in a few places. A good example is
> `struct max77759_maxq_response` which subsiqently gets allocated with
> `DEFINE_FLEX`
> https://elixir.bootlin.com/linux/v7.2-rc1/source/include/linux/mfd/max77759.h#L253
> 
> I assume you are ok with adding `__DECLARE_SIZED_FLEX` and
> `DECLARE_SIZED_FLEX` as
> they are usefull in cases where keeping structure offsets is
> important, similar to
> TRAILING_OVERLAP. An example of where `__DECLARE_SIZED_FLEX` could be used is:
> https://lore.kernel.org/all/20260714185621.610105-1-jtaubepe@redhat.com/

Please show us examples of how exactly you'd use the helpers you propose
for the cases you mentioned above.

Thanks
-Gustavo

> 
> Thanks,
> Jesse Taube
> 
>>
>>> +
>>>   /**
>>>    * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
>>>    * Enables caller macro to pass arbitrary trailing expressions
>>> @@ -477,10 +530,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
>>>   #define __DEFINE_FLEX(type, name, member, count, trailer...)                 \
>>>        _Static_assert(__builtin_constant_p(count),                             \
>>>                       "onstack flex array members require compile-time const count"); \
>>> -     union {                                                                 \
>>> -             u8 bytes[struct_size_t(type, member, count)];                   \
>>> -             type obj;                                                       \
>>> -     } name##_u trailer;                                                     \
>>> +     __DECLARE_SIZED_FLEX(type obj, member, count) name##_u trailer;         \
>>>        type *name = (type *)&name##_u
>>
>> -Kees
>>
>> --
>> Kees Cook
>>
> 

Re: [RFC PATCH] overflow: Add DECLARE_SIZED_FLEX() helper family
Posted by Jesse Taube 3 days, 23 hours ago
On Fri, Jul 17, 2026 at 4:19 PM Gustavo A. R. Silva
<gustavo@embeddedor.com> wrote:
>
> Hi!
>
> On 7/17/26 10:17, Jesse Taube wrote:
> > On Wed, Jul 15, 2026 at 12:12 PM Kees Cook <kees@kernel.org> wrote:
> >>
> >> On Tue, Jul 14, 2026 at 11:18:18AM -0400, Jesse Taube wrote:
> >>> Add new DECLARE_SIZED_FLEX() helper to set the default size of a
> >>> flexible-array member. The code is identical to the declaration in
> >>> __DEFINE_FLEX() which has also been changed to use DECLARE_SIZED_FLEX().
> >>>
> >>> Add DECLARE_COUNTED_FLEX_ARRAY() helper which is a variant of
> >>> DECLARE_FLEX_ARRAY() with a counted-by attribute.
> >>>
> >>> Also add default sized variants of
> >>> DECLARE_FLEX_ARRAY(), DECLARE_SIZED_FLEX(), and
> >>> DECLARE_COUNTED_FLEX_ARRAY(), DECLARE_COUNTED_SIZED_FLEX().
> >>
> >> Where do you want to use these new helpers?
> >>
> >>> Signed-off-by: Jesse Taube <jtaubepe@redhat.com>
> >>> ---
> >>>   include/linux/overflow.h | 58 +++++++++++++++++++++++++++++++++++++---
> >>>   1 file changed, 54 insertions(+), 4 deletions(-)
> >>>
> >>> diff --git a/include/linux/overflow.h b/include/linux/overflow.h
> >>> index a8cb6319b4fb..a3384cae49e5 100644
> >>> --- a/include/linux/overflow.h
> >>> +++ b/include/linux/overflow.h
> >>> @@ -464,6 +464,59 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
> >>>    */
> >>>   #define struct_offset(p, member) (offsetof(typeof(*(p)), member))
> >>>
> >>> +/**
> >>> + * __DECLARE_SIZED_FLEX() - helper macro for DECLARE_SIZED_FLEX() family.
> >>> + * Allows for easily declaring a structure with a trailing flexible array member
> >>> + * to have a specific size.
> >>> + *
> >>> + * @obj: object to be given a specific size
> >>> + * @name: Name of the array member.
> >>> + * @count: Number of elements in the array; must be compile-time const.
> >>> + */
> >>> +#define __DECLARE_SIZED_FLEX(obj, name, count)       \
> >>> +     _Static_assert(__builtin_constant_p(count),             \
> >>> +                    "default sized flex array members require compile-time const count");    \
> >>> +     union {                                                 \
> >>> +             u8 bytes[struct_size_t(obj, name, count)];      \
> >>> +             obj;                                            \
> >>> +     }
> >>> +
> >>> +/**
> >>> + * DECLARE_COUNTED_FLEX_ARRAY() - Declare a counted flexible array
> >>> + *
> >>> + * @type: Type name.
> >>> + * @name: Name of the array member.
> >>> + * @counter: Name of the __counted_by member.
> >>> + */
> >>> +#define DECLARE_COUNTED_FLEX_ARRAY(type, name, counter)\
> >>> +     struct { \
> >>> +             size_t counter; \
> >>> +             type name[] __counted_by(counter); \
> >>> +     }
> >>> +
> >>> +/**
> >>> + * DECLARE_SIZED_FLEX() - Declare a structure with a trailing flexible array
> >>> + * member with a default size.
> >>> + *
> >>> + * @type: Type name.
> >>> + * @name: Name of the array member.
> >>> + * @count: Number of elements in the array; must be compile-time const.
> >>> + */
> >>> +#define DECLARE_SIZED_FLEX(type, name, count)        \
> >>> +     __DECLARE_SIZED_FLEX(type name[], name, count)
> >>> +
> >>> +/**
> >>> + * DECLARE_COUNTED_SIZED_FLEX() - Declare a structure with a trailing flexible
> >>> + * array member counted by count, with a default size.
> >>> + *
> >>> + * @type: Type name.
> >>> + * @name: Name of the array member.
> >>> + * @counter: Name of the __counted_by member.
> >>> + * @count: Number of elements in the array; must be compile-time const.
> >>> + */
> >>> +#define DECLARE_COUNTED_SIZED_FLEX(type, name, counter, count)       \
> >>> +     __DECLARE_SIZED_FLEX(DECLARE_COUNTED_FLEX_ARRAY(type, name, counter), name, count)
> >>
> >> I ask about where these will be used because one of the things I want to
> >> keep tied together is the "counter" and "count", which usually means the
> >> declaration should be combined with an initializer in some way so that
> >> the counter gets assigned, as DEFINE_FLEX() ultimately does.
> >>
> >> I'm worried that extracting the internal construction of __DEFINE_FLEX
> >> means we may run the risk of increasing the risk of losing that tie.
> >
> > We can add a comment to make sure to set count, or use DEFINE_FLEX
> > to allocate it. Im not sure if there is a way for this to be a compile time
> > error though.
> >
> >> So, I'd love to understand how you want to use this, as that would help
> >> my understanding and potentially shape the design so we can keep counter
> >> and count strongly associated.
> >
> > Basically, I want to use `DECLARE_COUNTED_SIZED_FLEX` for a version of
> > this patch that
> > uses `__counted_by`
> > https://lore.kernel.org/linux-scsi/97526d45-ec7d-48a0-bdc6-659f75839f53@embeddedor.com/
> > I have checked that it does always set the `counter` variable correctly.
> >
> > As for `DECLARE_COUNTED_FLEX_ARRAY` there is already `DECLARE_FLEX_ARRAY` and
> > the counted variant is already used in a few places. A good example is
> > `struct max77759_maxq_response` which subsiqently gets allocated with
> > `DEFINE_FLEX`
> > https://elixir.bootlin.com/linux/v7.2-rc1/source/include/linux/mfd/max77759.h#L253
> >
> > I assume you are ok with adding `__DECLARE_SIZED_FLEX` and
> > `DECLARE_SIZED_FLEX` as
> > they are usefull in cases where keeping structure offsets is
> > important, similar to
> > TRAILING_OVERLAP. An example of where `__DECLARE_SIZED_FLEX` could be used is:
> > https://lore.kernel.org/all/20260714185621.610105-1-jtaubepe@redhat.com/
>
> Please show us examples of how exactly you'd use the helpers you propose
> for the cases you mentioned above.


Sorry for the late reply.

Here is an example of DECLARE_COUNTED_FLEX_ARRAY,
I notice now that the macro should be passed the count variable's type
and not have it as size_t.
```c
+++ b/drivers/net/wireless/ath/ath10k/bmi.h
@@ -136,21 +136,12 @@ struct bmi_cmd {
                struct {
                        __le32 patch_id;
                } rompatch_uninstall;
-               struct {
-                       __le32 count;
-                       __le32 patch_ids[]; /* length of @count */
-               } rompatch_activate;
-               struct {
-                       __le32 count;
-                       __le32 patch_ids[]; /* length of @count */
-               } rompatch_deactivate;
+               DECLARE_COUNTED_FLEX_ARRAY(__le32, patch_ids, count)
rompatch_activate;
+               DECLARE_COUNTED_FLEX_ARRAY(__le32, patch_ids, count)
rompatch_deactivate;
                struct {
                        __le32 addr;
                } lz_start;
-               struct {
-                       __le32 len; /* max BMI_MAX_DATA_SIZE */
-                       u8 payload[]; /* length of @len */
-               } lz_data;
+               DECLARE_COUNTED_FLEX_ARRAY(u8, payload, len) lz_data;
                struct {
                        u8 name[BMI_NVRAM_SEG_NAME_SZ];
                } nvram_process;
```

Here is where i want to use DECLARE_COUNTED_SIZED_FLEX, it would fix the
"memcpy: detected field-spanning write (size 60) of single field".
It seems like the only two places where a structure like this occurs is in
qla2xxx and qla4xxx
https://lore.kernel.org/linux-scsi/20250813200744.17975-10-bgurney@redhat.com/
```c
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index 5593ad7fad27..7241cf6e6c7e 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -4912,10 +4912,7 @@ struct purex_item {
        void (*process_item)(struct scsi_qla_host *vha,
                             struct purex_item *pkt);
        atomic_t in_use;
-       uint16_t size;
-       struct {
-               uint8_t iocb[64];
-       } iocb;
+       DECLARE_COUNTED_SIZED_FLEX(uint8_t, iocb, size, 64);
 };
```

Here is an example of DECLARE_SIZED_FLEX:
```c
#define DEFUALT_SIZE 64

struct flex_array {
int some_element;
DECLARE_SIZED_FLEX(uint8_t, payload, DEFUALT_SIZE);
};

struct struct_with_flex_array {
int some_element;
struct flex_array flex_array;
};

int main() {
struct struct_with_flex_array my_struct;
struct flex_array *my_struct2;
uint8_t big_payload[100] = {};

/* Size of struct_with_flex_array: 72*/
printf("Size of struct_with_flex_array: %zu\n", sizeof(my_struct));
/* kzalloc_flex would need the size to be (sizeof(big_payload) -
DEFUALT_SIZE) */
my_struct2 = kzalloc(sizeof(*my_struct2) + sizeof(big_payload) -
DEFUALT_SIZE, GFP_KERNEL);

/* Size of allocated flex_array: 104 */
printf("Size of allocated flex_array: %zu\n", sizeof(*my_struct2) +
sizeof(big_payload) - DEFUALT_SIZE);

/* Avoids "memcpy: detected field-spanning write (size 100) of single field" */
memcpy(my_struct.flex_array.payload, big_payload, sizeof(big_payload));
return 0;
}
```

Thanks,
Jesse Taube


>
> Thanks
> -Gustavo
>
> >
> > Thanks,
> > Jesse Taube
> >
> >>
> >>> +
> >>>   /**
> >>>    * __DEFINE_FLEX() - helper macro for DEFINE_FLEX() family.
> >>>    * Enables caller macro to pass arbitrary trailing expressions
> >>> @@ -477,10 +530,7 @@ static __always_inline size_t __must_check size_sub(size_t minuend, size_t subtr
> >>>   #define __DEFINE_FLEX(type, name, member, count, trailer...)                 \
> >>>        _Static_assert(__builtin_constant_p(count),                             \
> >>>                       "onstack flex array members require compile-time const count"); \
> >>> -     union {                                                                 \
> >>> -             u8 bytes[struct_size_t(type, member, count)];                   \
> >>> -             type obj;                                                       \
> >>> -     } name##_u trailer;                                                     \
> >>> +     __DECLARE_SIZED_FLEX(type obj, member, count) name##_u trailer;         \
> >>>        type *name = (type *)&name##_u
> >>
> >> -Kees
> >>
> >> --
> >> Kees Cook
> >>
> >
>