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.