http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52944
--- Comment #3 from Richard Guenther <rguenth at gcc dot gnu.org> 2012-04-12
15:28:10 UTC ---
(In reply to comment #2)
> if you look at the tftp example, you'd see that your proposed struct does not
> work. the protocol needs two flexible array members at different starting
> points.
Ah, indeed. Now when inspecting your description closer.
---
with tftp, the packet is described by:
struct tftphdr {
short opcode;
union {
unsigned short tu_block;
short tu_code;
char tu_stuff[0];
};
char th_data[];
};
when opcode is 1, the rest of the packet is a C string. i.e. the buffer:
char x[] = { 1, 0, 'f', 'i', 'l', 'e', '\0', };
opcode = 1, tu_stuff = "file"
when opcode is 3 though, the tu_block field will be a number, and the rest of
the data will be in th_data. i.e. the buffer:
char x[] = { 2, 0, 3, 0, <8KiB>, };
opcode = 2, tu_block = 3, th_data = 8KiB
---
So
struct tftphdr {
short opcode;
union {
struct opcode_3 {
unsigned short tu_block;
char th_data[];
} opcode3;
short tu_code;
char tu_stuff[0];
};
};
would work. At least
struct stct {
int i;
union {
struct {
short k;
char tail[];
} x;
char buf[0];
};
};
char buf[100];
main()
{
struct stct *foo = (void *)buf;
printf("%i\n", __builtin_object_size(foo->buf, 1));
printf("%i\n", __builtin_object_size(foo->x.tail, 1));
}
produces the expected 96, 94 values?
> the 96 isn't conservative in this case, it's correct. i declared a buffer of
> 100 bytes, so buf[0] can cover 96 bytes (as the leading integer is 32bits).
> is
> there a "simplish" patch that could be backported to the 4.5/4.6 branches for
> that ?
No, and it's only because optimization triggers and we get to see buf[] here.
Otherwise you'd get still zero.
> thinking a bit more, the requirements can probably be pulled off with more
> anonymous unions/structs like so:
>
> struct tftphdr {
> short opcode;
> union {
> struct {
> union {
> unsigned short tu_block;
> short tu_code;
> };
> char tu_data[0];
> };
> char tu_stuff[0];
> } __attribute__ ((__packed__));
> } __attribute__ ((__packed__));
I don't see how this would avoid the issue for __builtin_object_size
(foo->...tu_data) though.