[v3,1/4] Allow flexible array members in unions and alone in structures [PR53548]

Message ID 20240430145833.1366425-2-qing.zhao@oracle.com
State New
Headers
Series Allow flexible array members in unions and alone in structures [PR53548] |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Testing passed

Commit Message

Qing Zhao April 30, 2024, 2:58 p.m. UTC
  The request for GCC to accept that the C99 flexible array member can be
in a union or alone in a structure has been made a long time ago around 2012
for supporting several practical cases including glibc.

A GCC PR has been opened for such request at that time:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548

However, this PR was closed as WONTFIX around 2015 due to the following reason:

"there is an existing extension that makes the requested functionality possible"
i.e GCC fully supported that the zero-length array can be in a union or alone
in a structure for a long time. (though I didn't see any official documentation
on such extension)

It's reasonable to close PR53548 at that time since zero-length array extension
can be used for such purpose.

However, since GCC13, in order to improve the C/C++ security, we introduced
-fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
usages from C/C++ source code. As a result, zero-length arrays eventually
will be replaced by C99 flexiable array member completely.

Therefore, GCC needs to explicitly allow such extensions directly for C99
flexible arrays, since flexable array member in unions or alone in structs
are common code patterns in active use by the Linux kernel (and other projects).

For example, these do not error by default with GCC:

union one {
  int a;
  int b[0];
};

union two {
  int a;
  struct {
    struct { } __empty;
    int b[];
  };
};

But these do:

union three {
  int a;
  int b[];
};

struct four {
  int b[];
}

Clang has supported such extensions since March, 2024
https://github.com/llvm/llvm-project/pull/84428

GCC should also support such extensions. This will allow for
a seamless transition for code bases away from zero-length arrays without
losing existing code patterns.

gcc/ChangeLog:

	* doc/extend.texi: Add documentation for Flexible Array Members in
	Unions and Flexible Array Members alone in Structures.
---
 gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
  

Comments

Jason Merrill April 30, 2024, 9:27 p.m. UTC | #1
On 4/30/24 07:58, Qing Zhao wrote:
> The request for GCC to accept that the C99 flexible array member can be
> in a union or alone in a structure has been made a long time ago around 2012
> for supporting several practical cases including glibc.
> 
> A GCC PR has been opened for such request at that time:
> 
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
> 
> However, this PR was closed as WONTFIX around 2015 due to the following reason:
> 
> "there is an existing extension that makes the requested functionality possible"
> i.e GCC fully supported that the zero-length array can be in a union or alone
> in a structure for a long time. (though I didn't see any official documentation
> on such extension)
> 
> It's reasonable to close PR53548 at that time since zero-length array extension
> can be used for such purpose.
> 
> However, since GCC13, in order to improve the C/C++ security, we introduced
> -fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
> usages from C/C++ source code. As a result, zero-length arrays eventually
> will be replaced by C99 flexiable array member completely.
> 
> Therefore, GCC needs to explicitly allow such extensions directly for C99
> flexible arrays, since flexable array member in unions or alone in structs
> are common code patterns in active use by the Linux kernel (and other projects).
> 
> For example, these do not error by default with GCC:
> 
> union one {
>    int a;
>    int b[0];
> };
> 
> union two {
>    int a;
>    struct {
>      struct { } __empty;
>      int b[];
>    };
> };
> 
> But these do:
> 
> union three {
>    int a;
>    int b[];
> };
> 
> struct four {
>    int b[];
> }
> 
> Clang has supported such extensions since March, 2024
> https://github.com/llvm/llvm-project/pull/84428
> 
> GCC should also support such extensions. This will allow for
> a seamless transition for code bases away from zero-length arrays without
> losing existing code patterns.
> 
> gcc/ChangeLog:
> 
> 	* doc/extend.texi: Add documentation for Flexible Array Members in
> 	Unions and Flexible Array Members alone in Structures.
> ---
>   gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
>   1 file changed, 34 insertions(+)
> 
> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> index 7b54a241a7bf..cba98c8aadd7 100644
> --- a/gcc/doc/extend.texi
> +++ b/gcc/doc/extend.texi
> @@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
>   * Named Address Spaces::Named address spaces.
>   * Zero Length::         Zero-length arrays.
>   * Empty Structures::    Structures with no members.
> +* Flexible Array Members in Unions::  Unions with Flexible Array Members.
> +* Flexible Array Members alone in Structures::  Structures with only Flexible Array Members.
>   * Variable Length::     Arrays whose length is computed at run time.
>   * Variadic Macros::     Macros with a variable number of arguments.
>   * Escaped Newlines::    Slightly looser rules for escaped newlines.
> @@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures are part
>   of the language.  G++ treats empty structures as if they had a single
>   member of type @code{char}.
>   
> +@node Flexible Array Members in Unions
> +@section Unions with Flexible Array Members
> +@cindex unions with flexible array members
> +@cindex unions with FAMs
> +
> +GCC permits a C99 flexible array member (FAM) to be in a union:
> +
> +@smallexample
> +union with_fam @{
> +  int a;
> +  int b[];
> +@};
> +@end smallexample
> +
> +If all the members of a union are flexible array member, the size of

"If the only member of a union is a flexible array member"

> +such union is zero.

"such a union"

> +
> +@node Flexible Array Members alone in Structures
> +@section Structures with only Flexible Array Members
> +@cindex structures with only flexible array members
> +@cindex structures with only FAMs
> +
> +GCC permits a C99 flexible array member (FAM) to be alone in a structure:
> +
> +@smallexample
> +struct only_fam @{
> +  int b[];
> +@};
> +@end smallexample
> +
> +The size of such structure gives the size zero.

"The size of such a structure is zero"

> +
>   @node Variable Length
>   @section Arrays of Variable Length
>   @cindex variable-length arrays
  
Qing Zhao April 30, 2024, 9:45 p.m. UTC | #2
On Apr 30, 2024, at 15:27, Jason Merrill <jason@redhat.com> wrote:

On 4/30/24 07:58, Qing Zhao wrote:
The request for GCC to accept that the C99 flexible array member can be
in a union or alone in a structure has been made a long time ago around 2012
for supporting several practical cases including glibc.
A GCC PR has been opened for such request at that time:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
However, this PR was closed as WONTFIX around 2015 due to the following reason:
"there is an existing extension that makes the requested functionality possible"
i.e GCC fully supported that the zero-length array can be in a union or alone
in a structure for a long time. (though I didn't see any official documentation
on such extension)
It's reasonable to close PR53548 at that time since zero-length array extension
can be used for such purpose.
However, since GCC13, in order to improve the C/C++ security, we introduced
-fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
usages from C/C++ source code. As a result, zero-length arrays eventually
will be replaced by C99 flexiable array member completely.
Therefore, GCC needs to explicitly allow such extensions directly for C99
flexible arrays, since flexable array member in unions or alone in structs
are common code patterns in active use by the Linux kernel (and other projects).
For example, these do not error by default with GCC:
union one {
  int a;
  int b[0];
};
union two {
  int a;
  struct {
    struct { } __empty;
    int b[];
  };
};
But these do:
union three {
  int a;
  int b[];
};
struct four {
  int b[];
}
Clang has supported such extensions since March, 2024
https://github.com/llvm/llvm-project/pull/84428
GCC should also support such extensions. This will allow for
a seamless transition for code bases away from zero-length arrays without
losing existing code patterns.
gcc/ChangeLog:
* doc/extend.texi: Add documentation for Flexible Array Members in
Unions and Flexible Array Members alone in Structures.
---
 gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length::         Zero-length arrays.
 * Empty Structures::    Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array Members.
+* Flexible Array Members alone in Structures::  Structures with only Flexible Array Members.
 * Variable Length::     Arrays whose length is computed at run time.
 * Variadic Macros::     Macros with a variable number of arguments.
 * Escaped Newlines::    Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures are part
 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 +@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of

It’s for the following case:

union with_fam_3 {
  char a[];
  int b[];
}

And also include:  (the only member of a union is a flexible array member as you mentioned below)

union with_fam_1 {
  char a[];
}

So, I think the original sentence:

“If all the members of a union are flexible array member, the size of”

Should be better than the below:

"If the only member of a union is a flexible array member”


+such union is zero.

"such a union"

Okay.


+
+@node Flexible Array Members alone in Structures
+@section Structures with only Flexible Array Members
+@cindex structures with only flexible array members
+@cindex structures with only FAMs
+
+GCC permits a C99 flexible array member (FAM) to be alone in a structure:
+
+@smallexample
+struct only_fam @{
+  int b[];
+@};
+@end smallexample
+
+The size of such structure gives the size zero.

"The size of such a structure is zero"

Okay.

thanks.

Qing

+
 @node Variable Length
 @section Arrays of Variable Length
 @cindex variable-length arrays
  
Qing Zhao April 30, 2024, 9:49 p.m. UTC | #3
On Apr 30, 2024, at 15:45, Qing Zhao <qing.zhao@oracle.com> wrote:



 gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length::         Zero-length arrays.
 * Empty Structures::    Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array Members.
+* Flexible Array Members alone in Structures::  Structures with only Flexible Array Members.
 * Variable Length::     Arrays whose length is computed at run time.
 * Variadic Macros::     Macros with a variable number of arguments.
 * Escaped Newlines::    Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures are part
 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 +@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of

It’s for the following case:

union with_fam_3 {
  char a[];
  int b[];
}

And also include:  (the only member of a union is a flexible array member as you mentioned below)

union with_fam_1 {
  char a[];
}

So, I think the original sentence:

“If all the members of a union are flexible array member, the size of”

Should be better than the below:

"If the only member of a union is a flexible array member”

How about the following wording?

"If every member of a union is flexible array member, the size of”

Qing


+such union is zero.

"such a union"

Okay.


+
+@node Flexible Array Members alone in Structures
+@section Structures with only Flexible Array Members
+@cindex structures with only flexible array members
+@cindex structures with only FAMs
+
+GCC permits a C99 flexible array member (FAM) to be alone in a structure:
+
+@smallexample
+struct only_fam @{
+  int b[];
+@};
+@end smallexample
+
+The size of such structure gives the size zero.

"The size of such a structure is zero"

Okay.

thanks.

Qing

+
 @node Variable Length
 @section Arrays of Variable Length
 @cindex variable-length arrays
  
Jason Merrill April 30, 2024, 9:51 p.m. UTC | #4
On 4/30/24 14:45, Qing Zhao wrote:
> 
> 
>> On Apr 30, 2024, at 15:27, Jason Merrill <jason@redhat.com> wrote:
>>
>> On 4/30/24 07:58, Qing Zhao wrote:
>>> The request for GCC to accept that the C99 flexible array member can be
>>> in a union or alone in a structure has been made a long time ago 
>>> around 2012
>>> for supporting several practical cases including glibc.
>>> A GCC PR has been opened for such request at that time:
>>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
>>> However, this PR was closed as WONTFIX around 2015 due to the 
>>> following reason:
>>> "there is an existing extension that makes the requested 
>>> functionality possible"
>>> i.e GCC fully supported that the zero-length array can be in a union 
>>> or alone
>>> in a structure for a long time. (though I didn't see any official 
>>> documentation
>>> on such extension)
>>> It's reasonable to close PR53548 at that time since zero-length array 
>>> extension
>>> can be used for such purpose.
>>> However, since GCC13, in order to improve the C/C++ security, we 
>>> introduced
>>> -fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
>>> usages from C/C++ source code. As a result, zero-length arrays eventually
>>> will be replaced by C99 flexiable array member completely.
>>> Therefore, GCC needs to explicitly allow such extensions directly for C99
>>> flexible arrays, since flexable array member in unions or alone in 
>>> structs
>>> are common code patterns in active use by the Linux kernel (and other 
>>> projects).
>>> For example, these do not error by default with GCC:
>>> union one {
>>>   int a;
>>>   int b[0];
>>> };
>>> union two {
>>>   int a;
>>>   struct {
>>>     struct { } __empty;
>>>     int b[];
>>>   };
>>> };
>>> But these do:
>>> union three {
>>>   int a;
>>>   int b[];
>>> };
>>> struct four {
>>>   int b[];
>>> }
>>> Clang has supported such extensions since March, 2024
>>> https://github.com/llvm/llvm-project/pull/84428
>>> GCC should also support such extensions. This will allow for
>>> a seamless transition for code bases away from zero-length arrays without
>>> losing existing code patterns.
>>> gcc/ChangeLog:
>>> * doc/extend.texi: Add documentation for Flexible Array Members in
>>> Unions and Flexible Array Members alone in Structures.
>>> ---
>>>  gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
>>>  1 file changed, 34 insertions(+)
>>> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
>>> index 7b54a241a7bf..cba98c8aadd7 100644
>>> --- a/gcc/doc/extend.texi
>>> +++ b/gcc/doc/extend.texi
>>> @@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
>>>  * Named Address Spaces::Named address spaces.
>>>  * Zero Length::         Zero-length arrays.
>>>  * Empty Structures::    Structures with no members.
>>> +* Flexible Array Members in Unions::  Unions with Flexible Array 
>>> Members.
>>> +* Flexible Array Members alone in Structures::  Structures with only 
>>> Flexible Array Members.
>>>  * Variable Length::     Arrays whose length is computed at run time.
>>>  * Variadic Macros::     Macros with a variable number of arguments.
>>>  * Escaped Newlines::    Slightly looser rules for escaped newlines.
>>> @@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty 
>>> structures are part
>>>  of the language.  G++ treats empty structures as if they had a single
>>>  member of type @code{char}.
>>>  +@node Flexible Array Members in Unions
>>> +@section Unions with Flexible Array Members
>>> +@cindex unions with flexible array members
>>> +@cindex unions with FAMs
>>> +
>>> +GCC permits a C99 flexible array member (FAM) to be in a union:
>>> +
>>> +@smallexample
>>> +union with_fam @{
>>> +  int a;
>>> +  int b[];
>>> +@};
>>> +@end smallexample
>>> +
>>> +If all the members of a union are flexible array member, the size of
> 
> It’s for the following case:
> 
> union with_fam_3 {
>    char a[];
>    int b[];
> }
> 
> And also include:  (the only member of a union is a flexible array 
> member as you mentioned below)
> 
> union with_fam_1 {
>    char a[];
> }
> 
> So, I think the original sentence:
> 
> “If all the members of a union are flexible array member, the size of”
> 
> Should be better than the below:
>>
>> "If the only member of a union is a flexible array member”

Makes sense, but then it should be "members" both times rather than 
"members" and then "member".

Jason
  
Jason Merrill April 30, 2024, 9:52 p.m. UTC | #5
On 4/30/24 14:49, Qing Zhao wrote:
> 
> 
>> On Apr 30, 2024, at 15:45, Qing Zhao <qing.zhao@oracle.com> wrote:
>>
>>
>>
>>>>  gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
>>>>  1 file changed, 34 insertions(+)
>>>> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
>>>> index 7b54a241a7bf..cba98c8aadd7 100644
>>>> --- a/gcc/doc/extend.texi
>>>> +++ b/gcc/doc/extend.texi
>>>> @@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
>>>>  * Named Address Spaces::Named address spaces.
>>>>  * Zero Length::         Zero-length arrays.
>>>>  * Empty Structures::    Structures with no members.
>>>> +* Flexible Array Members in Unions::  Unions with Flexible Array 
>>>> Members.
>>>> +* Flexible Array Members alone in Structures::  Structures with 
>>>> only Flexible Array Members.
>>>>  * Variable Length::     Arrays whose length is computed at run time.
>>>>  * Variadic Macros::     Macros with a variable number of arguments.
>>>>  * Escaped Newlines::    Slightly looser rules for escaped newlines.
>>>> @@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty 
>>>> structures are part
>>>>  of the language.  G++ treats empty structures as if they had a single
>>>>  member of type @code{char}.
>>>>  +@node Flexible Array Members in Unions
>>>> +@section Unions with Flexible Array Members
>>>> +@cindex unions with flexible array members
>>>> +@cindex unions with FAMs
>>>> +
>>>> +GCC permits a C99 flexible array member (FAM) to be in a union:
>>>> +
>>>> +@smallexample
>>>> +union with_fam @{
>>>> +  int a;
>>>> +  int b[];
>>>> +@};
>>>> +@end smallexample
>>>> +
>>>> +If all the members of a union are flexible array member, the size of
>>
>> It’s for the following case:
>>
>> union with_fam_3 {
>>   char a[];
>>   int b[];
>> }
>>
>> And also include:  (the only member of a union is a flexible array 
>> member as you mentioned below)
>>
>> union with_fam_1 {
>>   char a[];
>> }
>>
>> So, I think the original sentence:
>>
>> “If all the members of a union are flexible array member, the size of”
>>
>> Should be better than the below:
>>>
>>> "If the only member of a union is a flexible array member”
> 
> How about the following wording?
> 
> "If every member of a union is flexible array member, the size of”

"is a flexible array member", sure.

Jason
  
Qing Zhao April 30, 2024, 9:53 p.m. UTC | #6
> On Apr 30, 2024, at 15:52, Jason Merrill <jason@redhat.com> wrote:
> 
> On 4/30/24 14:49, Qing Zhao wrote:
>>> On Apr 30, 2024, at 15:45, Qing Zhao <qing.zhao@oracle.com> wrote:
>>> 
>>> 
>>> 
>>>>>  gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
>>>>>  1 file changed, 34 insertions(+)
>>>>> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
>>>>> index 7b54a241a7bf..cba98c8aadd7 100644
>>>>> --- a/gcc/doc/extend.texi
>>>>> +++ b/gcc/doc/extend.texi
>>>>> @@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
>>>>>  * Named Address Spaces::Named address spaces.
>>>>>  * Zero Length::         Zero-length arrays.
>>>>>  * Empty Structures::    Structures with no members.
>>>>> +* Flexible Array Members in Unions::  Unions with Flexible Array Members.
>>>>> +* Flexible Array Members alone in Structures::  Structures with only Flexible Array Members.
>>>>>  * Variable Length::     Arrays whose length is computed at run time.
>>>>>  * Variadic Macros::     Macros with a variable number of arguments.
>>>>>  * Escaped Newlines::    Slightly looser rules for escaped newlines.
>>>>> @@ -1873,6 +1875,38 @@ The structure has size zero.  In C++, empty structures are part
>>>>>  of the language.  G++ treats empty structures as if they had a single
>>>>>  member of type @code{char}.
>>>>>  +@node Flexible Array Members in Unions
>>>>> +@section Unions with Flexible Array Members
>>>>> +@cindex unions with flexible array members
>>>>> +@cindex unions with FAMs
>>>>> +
>>>>> +GCC permits a C99 flexible array member (FAM) to be in a union:
>>>>> +
>>>>> +@smallexample
>>>>> +union with_fam @{
>>>>> +  int a;
>>>>> +  int b[];
>>>>> +@};
>>>>> +@end smallexample
>>>>> +
>>>>> +If all the members of a union are flexible array member, the size of
>>> 
>>> It’s for the following case:
>>> 
>>> union with_fam_3 {
>>>   char a[];
>>>   int b[];
>>> }
>>> 
>>> And also include:  (the only member of a union is a flexible array member as you mentioned below)
>>> 
>>> union with_fam_1 {
>>>   char a[];
>>> }
>>> 
>>> So, I think the original sentence:
>>> 
>>> “If all the members of a union are flexible array member, the size of”
>>> 
>>> Should be better than the below:
>>>> 
>>>> "If the only member of a union is a flexible array member”
>> How about the following wording?
>> "If every member of a union is flexible array member, the size of”
> 
> "is a flexible array member", sure.

Okay, will update the doc.

Thanks a lot.

Qing
> 
> Jason
>
  
Kees Cook April 30, 2024, 11:55 p.m. UTC | #7
On Tue, Apr 30, 2024 at 05:51:20PM -0400, Jason Merrill wrote:
> On 4/30/24 14:45, Qing Zhao wrote:
> > 
> > 
> > > On Apr 30, 2024, at 15:27, Jason Merrill <jason@redhat.com> wrote:
> > > 
> > > On 4/30/24 07:58, Qing Zhao wrote:
> > > > The request for GCC to accept that the C99 flexible array member can be
> > > > in a union or alone in a structure has been made a long time ago
> > > > around 2012
> > > > for supporting several practical cases including glibc.
> > > > A GCC PR has been opened for such request at that time:
> > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
> > > > However, this PR was closed as WONTFIX around 2015 due to the
> > > > following reason:
> > > > "there is an existing extension that makes the requested
> > > > functionality possible"
> > > > i.e GCC fully supported that the zero-length array can be in a
> > > > union or alone
> > > > in a structure for a long time. (though I didn't see any
> > > > official documentation
> > > > on such extension)
> > > > It's reasonable to close PR53548 at that time since zero-length
> > > > array extension
> > > > can be used for such purpose.
> > > > However, since GCC13, in order to improve the C/C++ security, we
> > > > introduced
> > > > -fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
> > > > usages from C/C++ source code. As a result, zero-length arrays eventually
> > > > will be replaced by C99 flexiable array member completely.
> > > > Therefore, GCC needs to explicitly allow such extensions directly for C99
> > > > flexible arrays, since flexable array member in unions or alone
> > > > in structs
> > > > are common code patterns in active use by the Linux kernel (and
> > > > other projects).
> > > > For example, these do not error by default with GCC:
> > > > union one {
> > > >   int a;
> > > >   int b[0];
> > > > };
> > > > union two {
> > > >   int a;
> > > >   struct {
> > > >     struct { } __empty;
> > > >     int b[];
> > > >   };
> > > > };
> > > > But these do:
> > > > union three {
> > > >   int a;
> > > >   int b[];
> > > > };
> > > > struct four {
> > > >   int b[];
> > > > }
> > > > Clang has supported such extensions since March, 2024
> > > > https://github.com/llvm/llvm-project/pull/84428
> > > > GCC should also support such extensions. This will allow for
> > > > a seamless transition for code bases away from zero-length arrays without
> > > > losing existing code patterns.
> > > > gcc/ChangeLog:
> > > > * doc/extend.texi: Add documentation for Flexible Array Members in
> > > > Unions and Flexible Array Members alone in Structures.
> > > > ---
> > > >  gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
> > > >  1 file changed, 34 insertions(+)
> > > > diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
> > > > index 7b54a241a7bf..cba98c8aadd7 100644
> > > > --- a/gcc/doc/extend.texi
> > > > +++ b/gcc/doc/extend.texi
> > > > @@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
> > > >  * Named Address Spaces::Named address spaces.
> > > >  * Zero Length::         Zero-length arrays.
> > > >  * Empty Structures::    Structures with no members.
> > > > +* Flexible Array Members in Unions::  Unions with Flexible
> > > > Array Members.
> > > > +* Flexible Array Members alone in Structures::  Structures with
> > > > only Flexible Array Members.
> > > >  * Variable Length::     Arrays whose length is computed at run time.
> > > >  * Variadic Macros::     Macros with a variable number of arguments.
> > > >  * Escaped Newlines::    Slightly looser rules for escaped newlines.
> > > > @@ -1873,6 +1875,38 @@ The structure has size zero.  In C++,
> > > > empty structures are part
> > > >  of the language.  G++ treats empty structures as if they had a single
> > > >  member of type @code{char}.
> > > >  +@node Flexible Array Members in Unions
> > > > +@section Unions with Flexible Array Members
> > > > +@cindex unions with flexible array members
> > > > +@cindex unions with FAMs
> > > > +
> > > > +GCC permits a C99 flexible array member (FAM) to be in a union:
> > > > +
> > > > +@smallexample
> > > > +union with_fam @{
> > > > +  int a;
> > > > +  int b[];
> > > > +@};
> > > > +@end smallexample
> > > > +
> > > > +If all the members of a union are flexible array member, the size of
> > 
> > It’s for the following case:
> > 
> > union with_fam_3 {
> >    char a[];
> >    int b[];
> > }
> > 
> > And also include:  (the only member of a union is a flexible array
> > member as you mentioned below)
> > 
> > union with_fam_1 {
> >    char a[];
> > }
> > 
> > So, I think the original sentence:
> > 
> > “If all the members of a union are flexible array member, the size of”
> > 
> > Should be better than the below:
> > > 
> > > "If the only member of a union is a flexible array member”
> 
> Makes sense, but then it should be "members" both times rather than
> "members" and then "member".

"If every member of a union is a flexible array, the size ..." ?
  
Qing Zhao May 1, 2024, 2:02 p.m. UTC | #8
On Apr 30, 2024, at 17:55, Kees Cook <keescook@chromium.org> wrote:

On Tue, Apr 30, 2024 at 05:51:20PM -0400, Jason Merrill wrote:
On 4/30/24 14:45, Qing Zhao wrote:


On Apr 30, 2024, at 15:27, Jason Merrill <jason@redhat.com> wrote:

On 4/30/24 07:58, Qing Zhao wrote:
The request for GCC to accept that the C99 flexible array member can be
in a union or alone in a structure has been made a long time ago
around 2012
for supporting several practical cases including glibc.
A GCC PR has been opened for such request at that time:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53548
However, this PR was closed as WONTFIX around 2015 due to the
following reason:
"there is an existing extension that makes the requested
functionality possible"
i.e GCC fully supported that the zero-length array can be in a
union or alone
in a structure for a long time. (though I didn't see any
official documentation
on such extension)
It's reasonable to close PR53548 at that time since zero-length
array extension
can be used for such purpose.
However, since GCC13, in order to improve the C/C++ security, we
introduced
-fstrict-flex-arrays=n to gradually eliminate the "fake flexible array"
usages from C/C++ source code. As a result, zero-length arrays eventually
will be replaced by C99 flexiable array member completely.
Therefore, GCC needs to explicitly allow such extensions directly for C99
flexible arrays, since flexable array member in unions or alone
in structs
are common code patterns in active use by the Linux kernel (and
other projects).
For example, these do not error by default with GCC:
union one {
  int a;
  int b[0];
};
union two {
  int a;
  struct {
    struct { } __empty;
    int b[];
  };
};
But these do:
union three {
  int a;
  int b[];
};
struct four {
  int b[];
}
Clang has supported such extensions since March, 2024
https://github.com/llvm/llvm-project/pull/84428
GCC should also support such extensions. This will allow for
a seamless transition for code bases away from zero-length arrays without
losing existing code patterns.
gcc/ChangeLog:
* doc/extend.texi: Add documentation for Flexible Array Members in
Unions and Flexible Array Members alone in Structures.
---
 gcc/doc/extend.texi | 34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@ extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length::         Zero-length arrays.
 * Empty Structures::    Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible
Array Members.
+* Flexible Array Members alone in Structures::  Structures with
only Flexible Array Members.
 * Variable Length::     Arrays whose length is computed at run time.
 * Variadic Macros::     Macros with a variable number of arguments.
 * Escaped Newlines::    Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@ The structure has size zero.  In C++,
empty structures are part
 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 +@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of

It’s for the following case:

union with_fam_3 {
  char a[];
  int b[];
}

And also include:  (the only member of a union is a flexible array
member as you mentioned below)

union with_fam_1 {
  char a[];
}

So, I think the original sentence:

“If all the members of a union are flexible array member, the size of”

Should be better than the below:

"If the only member of a union is a flexible array member”

Makes sense, but then it should be "members" both times rather than
"members" and then "member".

"If every member of a union is a flexible array, the size ..." ?

Yes, I have updated the doc as this. -:).

Qing

--
Kees Cook
  

Patch

diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 7b54a241a7bf..cba98c8aadd7 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -42,6 +42,8 @@  extensions, accepted by GCC in C90 mode and in C++.
 * Named Address Spaces::Named address spaces.
 * Zero Length::         Zero-length arrays.
 * Empty Structures::    Structures with no members.
+* Flexible Array Members in Unions::  Unions with Flexible Array Members.
+* Flexible Array Members alone in Structures::  Structures with only Flexible Array Members.
 * Variable Length::     Arrays whose length is computed at run time.
 * Variadic Macros::     Macros with a variable number of arguments.
 * Escaped Newlines::    Slightly looser rules for escaped newlines.
@@ -1873,6 +1875,38 @@  The structure has size zero.  In C++, empty structures are part
 of the language.  G++ treats empty structures as if they had a single
 member of type @code{char}.
 
+@node Flexible Array Members in Unions
+@section Unions with Flexible Array Members
+@cindex unions with flexible array members
+@cindex unions with FAMs
+
+GCC permits a C99 flexible array member (FAM) to be in a union:
+
+@smallexample
+union with_fam @{
+  int a;
+  int b[];
+@};
+@end smallexample
+
+If all the members of a union are flexible array member, the size of
+such union is zero.
+
+@node Flexible Array Members alone in Structures
+@section Structures with only Flexible Array Members
+@cindex structures with only flexible array members
+@cindex structures with only FAMs
+
+GCC permits a C99 flexible array member (FAM) to be alone in a structure:
+
+@smallexample
+struct only_fam @{
+  int b[];
+@};
+@end smallexample
+
+The size of such structure gives the size zero.
+
 @node Variable Length
 @section Arrays of Variable Length
 @cindex variable-length arrays