https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65724
Bug ID: 65724 Summary: __builtin_object_size difference for C and C++ Product: gcc Version: unknown Status: UNCONFIRMED Severity: normal Priority: P3 Component: tree-optimization Assignee: unassigned at gcc dot gnu.org Reporter: xur at google dot com For the following code: -------------- #include <stdio.h> #include <stdlib.h> typedef struct { int i; char data[]; } foo; typedef struct { foo foo_var; } bar; int main() { bar *bar_var = (bar *) malloc(atoi("1000")); printf("size %zd\n", __builtin_object_size(bar_var->foo_var.data, 1)); return 0; } ------------------ "gcc -O2" prints out -1 while "g++ -O2" prints out a wrong value of 0. There are some frontend difference that triggers different code path in addr_object_size() in tree-object-size.c. (g++ sets the TYPE_SIZE_UNIT for the array as 0.) But nevertheless, it's reasonable to expect the same output with gcc or g++. In addr_object_size(), it seems we should always return a unknown size for the last field if it's an array (due to zero size of flexible size array). The code works if the field access is one level, but it breaks for multi-level field accesses like in the above example. More specifically, the following is questionable: 337 while (v != pt_var && TREE_CODE (v) == COMPONENT_REF) 338 if (TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) 339 != UNION_TYPE 340 && TREE_CODE (TREE_TYPE (TREE_OPERAND (v, 0))) 341 != QUAL_UNION_TYPE) 342 break; 343 else 344 v = TREE_OPERAND (v, 0); It seems to me after we detect this is the last array field, we should always peel the field,i.e removing code from line 338 to 343.