This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug tree-optimization/65724] New: __builtin_object_size difference for C and C++


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]