This removes a double-accounting for MEM_REF offsets. The code still looks somewhat fishy, but at least is consistent in what it does now ;)
Bootstrapped and tested on x86_64-unknonw-linux-gnu, applied to trunk. Richard. 2011-03-24 Richard Guenther <rguent...@suse.de> PR middle-end/48269 * tree-object-size.c (addr_object_size): Do not double-account for MEM_REF offsets. * gcc.dg/builtin-object-size-10.c: New testcase. Index: gcc/tree-object-size.c =================================================================== *** gcc/tree-object-size.c (revision 171384) --- gcc/tree-object-size.c (working copy) *************** addr_object_size (struct object_size_inf *** 348,355 **** tree bytes2 = compute_object_offset (TREE_OPERAND (ptr, 0), pt_var); if (bytes2 != error_mark_node) { - bytes2 = size_binop (PLUS_EXPR, bytes2, - TREE_OPERAND (pt_var, 1)); if (TREE_CODE (bytes2) == INTEGER_CST && tree_int_cst_lt (pt_var_size, bytes2)) bytes2 = size_zero_node; --- 348,353 ---- Index: gcc/testsuite/gcc.dg/builtin-object-size-10.c =================================================================== *** gcc/testsuite/gcc.dg/builtin-object-size-10.c (revision 0) --- gcc/testsuite/gcc.dg/builtin-object-size-10.c (revision 0) *************** *** 0 **** --- 1,26 ---- + /* { dg-do compile } */ + /* { dg-options "-O2 -fdump-tree-objsz-details" } */ + + typedef struct { + char sentinel[4]; + char data[0]; + } drone_packet; + typedef struct { + char type_str[16]; + char channel_hop; + } drone_source_packet; + drone_packet * + foo(char *x) + { + drone_packet *dpkt = __builtin_malloc(sizeof(drone_packet) + + sizeof(drone_source_packet)); + drone_source_packet *spkt = (drone_source_packet *) dpkt->data; + __builtin___snprintf_chk (spkt->type_str, 16, + 1, __builtin_object_size (spkt->type_str, 1), + "%s", x); + return dpkt; + } + + /* { dg-final { scan-tree-dump "maximum object size 21" "objsz" } } */ + /* { dg-final { scan-tree-dump "maximum subobject size 16" "objsz" } } */ + /* { dg-final { cleanup-tree-dump "objsz" } } */