> On Jun 30, 2022, at 1:03 PM, Jakub Jelinek <ja...@redhat.com> 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 >