> On Jun 30, 2022, at 1:03 PM, Jakub Jelinek <[email protected]> wrote:
>
> On Thu, Jun 30, 2022 at 03:31:00PM +0000, Qing Zhao wrote:
>>> No, that’s not true. A FIELD_DELC is only shared for cv variants of a
>>> structure.
>>
>> Sorry for my dump questions:
>>
>> 1. What do you mean by “cv variants” of a structure?
>
> const/volatile qualified variants. So
Okay. I see. thanks.
>
>> 2. For the following example:
>>
>> struct AX { int n; short ax[];};
>
> struct AX, const struct AX, volatile const struct AX etc. types will share
> the FIELD_DECLs.
Okay.
>
>> struct UX {struct AX b; int m;};
>>
>> Are there two different FIELD_DECLs in the IR, one for AX.ax, the other one
>> is for UX.b.ax?
>
> No, there are just n and ax FIELD_DECLs with DECL_CONTEXT of struct AX and
> b and m FIELD_DECLs with DECL_CONTEXT of struct UX.
Ah, right.
>
> But, what is important is that when some FIELD_DECL is last in some
> structure and has array type, it doesn't mean it should have an
> unconstrained length.
> In the above case, when struct AX is is followed by some other member, it
> acts as a strict short ax[0]; field (even when that is an exception), one
> can tak address of &UX.b.ax[0], but can't dereference that, or &UX.b.ax[1].
So, is this a GNU extension. I see that CLANG gives a warning by default and
GCC gives a warning when specify -pedantic:
[opc@qinzhao-ol8u3-x86 trailing_array]$ cat t3.c
struct AX
{
int n;
short ax[];
};
struct UX
{
struct AX b;
int m;
};
void warn_ax_local (struct AX *p, struct UX *q)
{
p->ax[2] = 0;
q->b.ax[2] = 0;
}
[opc@qinzhao-ol8u3-x86 trailing_array]$ clang -O2 -Wall t3.c -S
t3.c:9:13: warning: field 'b' with variable sized type 'struct AX' not at the
end of a struct or class is a GNU extension
[-Wgnu-variable-sized-type-not-at-end]
struct AX b;
^
[opc@qinzhao-ol8u3-x86 trailing_array]$ gcc -O2 -Wall t3.c -pedantic -S
t3.c:9:13: warning: invalid use of structure with flexible array member
[-Wpedantic]
9 | struct AX b;
| ^
But, Yes, I agree, even though this is only a GNU extension, We still need to
handle it and accept it as legal code.
Then, yes, I also agree that encoding the info of is_flexible_array into
FIELD_DECL is not good.
How about encoding the info of “has_flexible_array” into the enclosing
RECORD_TYPE or UNION_TYPE node?
For example, in the above example, the RECORD_TYPE for “struct AX” will be
marked as “has_flexible_array”, but that for “struct UX” will not.
>
> I believe pedantically flexible array members in such cases don't
> necessarily mean zero length array, could be longer, e.g. for the usual
> x86_64 alignments
> struct BX { long long n; short o; short ax[]; };
> struct VX { struct BX b; int m; };
> I think it acts as short ax[3]; because the padding at the end of struct BX
> is so long that 3 short elements fit in there.
> While if one uses
> struct BX bx = { 1LL, 2, { 3, 4, 5, 6, 7, 8, 9, 10 } };
> (a GNU extension), then it acts as short ax[11]; - the initializer is 8
> elements and after short ax[8]; is padding for another 3 full elemenets.
> And of course:
> struct BX *p = malloc (offsetof (struct BX, ax) + n * sizeof (short));
> means short ax[n].
> Whether struct WX { struct BX b; };
> struct WX *p = malloc (offsetof (struct WX, b.ax) + n * sizeof (short));
> is pedantically acting as short ax[n]; is unclear to me, but we are
> generally allowing that and people expect it.
Okay, I see now.
>
> Though, on the GCC side, I think we are only treating like flexible arrays
> what is really at the end of structs, not followed by other members.
My understanding is, Permitting flexible array to be followed by other members
is a GNU extension. (Actually, it’s not allowed by standard?).
Thanks a lot for your patience and help.
Qing
>
> Jakub
>