On 2/24/23 11:35, Qing Zhao via Gcc-patches wrote:
gcc/c-family/ChangeLog:
* c.opt: New option -Wgnu-variable-sized-type-not-at-end.
gcc/c/ChangeLog:
* c-decl.cc (finish_struct): Issue warnings for new option.
gcc/ChangeLog:
* doc/extend.texi: Document GCC extension on a structure containing
a flexible array member to be a member of another structure.
gcc/testsuite/ChangeLog:
* gcc.dg/variable-sized-type-flex-array.c: New test.
I'm only a documentation (and nios2) maintainer so I cannot approve
adding a new option or warning. I was going to review the documentation
parts, at least, but I think this proposal is technically flawed because
it is trying to document something that is undefined behavior in ways
that it doesn't actually behave on all targets.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index c1122916255..e278148c332 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1748,7 +1748,53 @@ Flexible array members may only appear as the last
member of a
A structure containing a flexible array member, or a union containing
such a structure (possibly recursively), may not be a member of a
structure or an element of an array. (However, these uses are
-permitted by GCC as extensions.)
+permitted by GCC as extensions, see details below.)
+@end itemize
+
+GCC extension accepts a structure containing an ISO C99 @dfn{flexible array
+member}, or a union containing such a structure (possibly recursively)
+to be a member of a structure.
+
+There are two situations:
+
+@itemize @bullet
+@item
+The structure with a C99 flexible array member is the last field of another
+structure, for example:
+
+@smallexample
+struct flex @{ int length; char data[]; @};
+union union_flex @{ int others; struct flex f; @};
+
+struct out_flex_struct @{ int m; struct flex flex_data; @};
+struct out_flex_union @{ int n; union union_flex flex_data; @};
+@end smallexample
+
+In the above, both @code{out_flex_struct.flex_data.data[]} and
+@code{out_flex_union.flex_data.f.data[]} are considered as flexible arrays too.
+
+
+@item
+The structure with a C99 flexible array member is the middle field of another
+structure, for example:
+
+@smallexample
+struct flex @{ int length; char data[]; @};
+
+struct mid_flex @{ int m; struct flex flex_data; int n; @};
+@end smallexample
+
+In the above, @code{mid_flex.flex_data.data[]} is allowed to be extended
+flexibly to the padding. E.g, up to 4 elements.
I think this paragraph is incorrect; how GCC lays out this structure
depends on the target and ABI. Looking at output from a GCC 12
nios2-elf build I have handy, I see it is in fact laying out mid_flex so
that member n is at the same address at offset 8 as flex_data.data[0],
which is not useful at all.
+However, relying on space in struct padding is a bad programming practice,
+compilers do not handle such extension consistently, Any code relying on
+this behavior should be modified to ensure that flexible array members
+only end up at the ends of structures.
+
+Please use warning option @option{-Wgnu-variable-sized-type-not-at-end} to
+identify all such cases in the source code and modify them. This extension
+will be deprecated from gcc in the next release.
My suggestion would be to make this a hard error instead of a warning,
unless there is some real body of code out there that depends on this
feature on a target that actually does insert padding. If it's a
warning, it ought to be enabled by default. And, rather than trying to
document the behavior, the manual should just say it's undefined.
-Sandra