Closed GustavoARSilva closed 2 years ago
I think the wrapper needs have named structs, so we can use __UNIQUE_ID() for that:
#define flex_array_union(flex1, flex2) \
union { \
struct { \
struct { } __UNIQUE_ID(__fau_); \
flex1; \
}; \
struct { \
struct { } __UNIQUE_ID(__fau_); \
flex2; \
}; \
}
Commit 3080ea5553cc909b000d1f1d964a9041962f2c5b and commit fa7845cfd53f3b1d3f60efa55db89805595bc045 (v5.16)
There is a special case in the kernel where two flexible arrays are needed at the end of a structure, and that are intended to share the same memory layout[1]:
A possible solution for this is to use a union. However, flexible arrays are not allowed as direct members in unions[2][3]. So, in order to work around this issue we can use something like the following macro formed by an anonymous union and a couple of embedded structures, each of which containing a flexible-array member together with a zero-sized struct which, in turn, serves as a mandatory object for an otherwise not allowed structure-with-flex-array-as-only-member[4][5], this is: "Flexible array members may only appear as the last member of a struct that is otherwise non-empty"[6] (yep; it's a bit tricky and complex to explain :) ):
Here are some instances that need to be addressed:
The instances above were found with the following Coccinelle script:
[1] https://git.kernel.org/linus/d26c0cc53950464a24adfa76867f1d71f0cbbea6 [2] https://godbolt.org/z/osPhqaGxo [3] https://godbolt.org/z/jnqK84bsK [4] https://godbolt.org/z/hhjjY3bx4 [5] https://godbolt.org/z/osef3eveK [6] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html