> On Jun 23, 2025, at 18:00, Siddhesh Poyarekar <siddh...@gotplt.org> wrote:
> 
> Thanks, there are some formatting nits below that need fixing, otherwise this 
> looks good to me.  I can't approve though, so please ping a maintainer for 
> that.

Hi, Sid,

Thanks a lot for your review. 
I will fix the format issues before committing the patch. 

Jakub and Richard, could you please approve the patch #2, which is a simple and 
straightforward change in tree-object-size.cc <http://tree-object-size.cc/>?

Thanks a lot.

Qing


> 
> Sid
> 
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
>> new file mode 100644
>> index 00000000000..c404e5b8cce
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c
>> @@ -0,0 +1,6 @@
>> +/* Test the attribute counted_by for pointer field and its usage in
>> + * __builtin_dynamic_object_size.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +#define PTR_TYPE char
>> +#include "pointer-counted-by-4.c"
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
>> new file mode 100644
>> index 00000000000..383d8fb656d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c
>> @@ -0,0 +1,6 @@
>> +/* Test the attribute counted_by for pointer field and its usage in
>> + * __builtin_dynamic_object_size.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +#define PTR_TYPE float
>> +#include "pointer-counted-by-4.c"
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
>> new file mode 100644
>> index 00000000000..50246d29477
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c
>> @@ -0,0 +1,10 @@
>> +/* Test the attribute counted_by for pointer field and its usage in
>> + * __builtin_dynamic_object_size.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +struct A {
>> +  int a;
>> +  char *b;
>> +};
>> +#define PTR_TYPE struct A
>> +#include "pointer-counted-by-4.c"
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
>> new file mode 100644
>> index 00000000000..e786d996147
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c
>> @@ -0,0 +1,10 @@
>> +/* Test the attribute counted_by for pointer field and its usage in
>> + * __builtin_dynamic_object_size.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +union A {
>> +  int a;
>> +  float b;
>> +};
>> +#define PTR_TYPE union A
>> +#include "pointer-counted-by-4.c"
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-4.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
>> new file mode 100644
>> index 00000000000..11ae6288030
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-4.c
>> @@ -0,0 +1,77 @@
>> +/* Test the attribute counted_by for pointer field and its usage in
>> + * __builtin_dynamic_object_size.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +
>> +#include "builtin-object-size-common.h"
>> +#ifndef PTR_TYPE
>> +#define PTR_TYPE int
>> +#endif
>> +struct pointer_array {
>> +  int b;
>> +  PTR_TYPE *c;
>> +} *p_array;
>> +
>> +struct annotated {
>> +  PTR_TYPE *c __attribute__ ((counted_by (b)));
>> +  int b;
>> +} *p_array_annotated;
>> +
>> +struct nested_annotated {
>> +  PTR_TYPE *c __attribute__ ((counted_by (b)));
>> +  struct {
>> +    union {
>> +      int b;
>> +      float f; 
>> +    };
>> +    int n;
>> +  };
>> +} *p_array_nested_annotated;
>> +
>> +void __attribute__((__noinline__)) setup (int normal_count, int attr_count)
>> +{
>> +  p_array
>> +    = (struct pointer_array *) malloc (sizeof (struct pointer_array));
>> +  p_array->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * normal_count);
>> +  p_array->b = normal_count;
>> +
>> +  p_array_annotated
>> +    = (struct annotated *) malloc (sizeof (struct annotated));
>> +  p_array_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * 
>> attr_count);
>> +  p_array_annotated->b = attr_count;
>> +
>> +  p_array_nested_annotated
>> +    = (struct nested_annotated *) malloc (sizeof (struct nested_annotated));
>> +  p_array_nested_annotated->c = (PTR_TYPE *) malloc (sizeof (PTR_TYPE) * 
>> attr_count);
>> +  p_array_nested_annotated->b = attr_count;
>> +
>> +  return;
>> +}
>> +
>> +void __attribute__((__noinline__)) test ()
>> +{
>> +    EXPECT(__builtin_dynamic_object_size(p_array->c, 1), -1);
>> +    EXPECT(__builtin_dynamic_object_size(p_array_annotated->c, 1),
>> +    p_array_annotated->b * sizeof (PTR_TYPE));
>> +    EXPECT(__builtin_dynamic_object_size(p_array_nested_annotated->c, 1),
>> +    p_array_nested_annotated->b * sizeof (PTR_TYPE));
> 
> Indentation is off here.
> 
>> +}
>> +
>> +void cleanup ()
>> +{
>> +  free (p_array->c);
>> +  free (p_array);
>> +  free (p_array_annotated->c);
>> +  free (p_array_annotated);
>> +  free (p_array_nested_annotated->c);
>> +  free (p_array_nested_annotated);
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +  setup (10,10);
>> +  test ();
>> +  DONE ();
>> +  cleanup ();
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-5.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
>> new file mode 100644
>> index 00000000000..567ad9fa4bd
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-5.c
>> @@ -0,0 +1,56 @@
>> +/* Test the attribute counted_by for pointer fields and its usage in
>> + * __builtin_dynamic_object_size: when the counted_by field is negative.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +
>> +#include "builtin-object-size-common.h"
>> +
>> +struct annotated {
>> +  int b;
>> +  int *c __attribute__ ((counted_by (b)));
>> +} *array_annotated;
>> +
>> +struct nested_annotated {
>> +  int *c __attribute__ ((counted_by (b)));
>> +  struct {
>> +    union {
>> +      int b;
>> +      float f; 
>> +    };
>> +    int n;
>> +  };
>> +} *array_nested_annotated;
>> +
>> +void __attribute__((__noinline__)) setup (int attr_count)
>> +{
>> +  array_annotated
>> +    = (struct annotated *)malloc (sizeof (struct annotated));
>> +  array_annotated->b = attr_count;
>> +
>> +  array_nested_annotated
>> +    = (struct nested_annotated *)malloc (sizeof (struct nested_annotated));
>> +  array_nested_annotated->b = attr_count - 1;
>> +
>> +  return;
>> +}
>> +
>> +void __attribute__((__noinline__)) test ()
>> +{
>> +    EXPECT(__builtin_dynamic_object_size(array_annotated->c, 1), 0);
>> +    EXPECT(__builtin_dynamic_object_size(array_nested_annotated->c, 1), 0);
> 
> Indentation is off here.
> 
>> +}
>> +
>> +void cleanup ()
>> +{
>> +  free (array_annotated);
>> +  free (array_nested_annotated);
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +  setup (-10);
>> +  test ();
>> +  DONE ();
>> +  cleanup ();
>> +  return 0;
>> +}
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-6.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
>> new file mode 100644
>> index 00000000000..fb1d8620afc
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c
>> @@ -0,0 +1,54 @@
>> +/* Test the attribute counted_by for pointer fields and its usage in
>> + * __builtin_dynamic_object_size: when the type of the pointer
>> + * is casting to another type.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +
>> +#include "builtin-object-size-common.h"
>> +
>> +typedef unsigned short u16;
>> +
>> +struct info {
>> +       u16 data_len;
>> +       char *data __attribute__((counted_by(data_len)));
>> +};
>> +
>> +struct foo {
>> +       int a;
>> +       int b;
>> +};
>> +
>> +static __attribute__((__noinline__))
>> +struct info *setup ()
>> +{
>> + struct info *p;
>> + size_t bytes = 3 * sizeof(struct foo);
>> +
>> + p = (struct info *) malloc (sizeof (struct info));
>> + p->data = (char *) malloc (bytes);
>> + p->data_len = bytes;
>> +
>> + return p;
>> +}
>> +
>> +static void
>> +__attribute__((__noinline__)) report (struct info *p)
>> +{
>> + struct foo *bar = (struct foo *)p->data;
>> + EXPECT(__builtin_dynamic_object_size((char *)(bar + 1), 1), sizeof (struct 
>> foo) * 2);
>> + EXPECT(__builtin_dynamic_object_size((char *)(bar + 2), 1), sizeof (struct 
>> foo));
>> +}
>> +
>> +void cleanup (struct info *p)
>> +{
>> +  free (p->data);
>> +  free (p);
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> + struct info *p = setup();
>> + report(p);
>> + cleanup (p);
>> + return 0;
>> +}
> 
> Code formatting overall looks off in this file.
> 
>> diff --git a/gcc/testsuite/gcc.dg/pointer-counted-by-7.c 
>> b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
>> new file mode 100644
>> index 00000000000..01addbb857d
>> --- /dev/null
>> +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c
>> @@ -0,0 +1,30 @@
>> +/* Additional test of the attribute counted_by for pointer field and its 
>> usage
>> +   in __builtin_dynamic_object_size.  */
>> +/* { dg-do run } */
>> +/* { dg-options "-O2" } */
>> +
>> +#include "builtin-object-size-common.h"
>> +
>> +struct annotated {
>> +  int b;
>> +  int *c __attribute__ ((counted_by (b)));
>> +};
>> +
>> +struct annotated __attribute__((__noinline__)) setup (int attr_count)
>> +{
>> +  struct annotated p_array_annotated;
>> +  p_array_annotated.c = (int *) malloc (sizeof (int) * attr_count);
>> +  p_array_annotated.b = attr_count;
>> +
>> +  return p_array_annotated;
>> +}
>> +
>> +int main(int argc, char *argv[])
>> +{
>> +  struct annotated x = setup (10);
>> +  int *p = x.c;
>> +  x = setup (20);
>> +  EXPECT(__builtin_dynamic_object_size (p, 1), 10 * sizeof (int));
>> +  EXPECT(__builtin_dynamic_object_size (x.c, 1), 20 * sizeof (int));
>> +  DONE ();
>> +}
>> diff --git a/gcc/tree-object-size.cc b/gcc/tree-object-size.cc
>> index f348673ae75..4e9ddde49c1 100644
>> --- a/gcc/tree-object-size.cc
>> +++ b/gcc/tree-object-size.cc
>> @@ -773,10 +773,12 @@ addr_object_size (struct object_size_info *osi, 
>> const_tree ptr,
>>     4th argument TYPE_OF_SIZE: A constant 0 with its TYPE being the same as 
>> the TYPE
>>      of the object referenced by REF_TO_SIZE
>>     6th argument: A constant 0 with the pointer TYPE to the original flexible
>> -     array type.
>> +     array type or pointer field type.
>>       The size of the element can be retrived from the TYPE of the 6th 
>> argument
>> -   of the call, which is the pointer to the array type.  */
>> +   of the call, which is the pointer to the original flexible array type or
>> +   the type of the original pointer field.  */
>> +
>>  static tree
>>  access_with_size_object_size (const gcall *call, int object_size_type)
>>  {
>> @@ -786,7 +788,7 @@ access_with_size_object_size (const gcall *call, int 
>> object_size_type)
>>      gcc_assert (gimple_call_internal_p (call, IFN_ACCESS_WITH_SIZE));
>>    /* The type of the 6th argument type is the pointer TYPE to the original
>> -     flexible array type.  */
>> +     flexible array type or to the original pointer type.  */
>>    tree pointer_to_array_type = TREE_TYPE (gimple_call_arg (call, 5));
>>    gcc_assert (POINTER_TYPE_P (pointer_to_array_type));
>>    tree element_type = TREE_TYPE (TREE_TYPE (pointer_to_array_type));
>> @@ -1854,6 +1856,16 @@ collect_object_sizes_for (struct object_size_info 
>> *osi, tree var)
>>              if (TREE_CODE (rhs) == SSA_NAME
>>                  && POINTER_TYPE_P (TREE_TYPE (rhs)))
>>         reexamine = merge_object_sizes (osi, var, rhs);
>> +     /* Handle the following stmt #2 to propagate the size from the
>> +        stmt #1 to #3:
>> + 1  _1 = .ACCESS_WITH_SIZE (_3, _4, 1, 0, -1, 0B);
>> + 2  _5 = *_1;
>> + 3  _6 = __builtin_dynamic_object_size (_5, 1);
>> +      */
>> +     else if (TREE_CODE (rhs) == MEM_REF
>> +      && POINTER_TYPE_P (TREE_TYPE (rhs))
>> +      && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME)
>> +       reexamine = merge_object_sizes (osi, var, TREE_OPERAND (rhs, 0));
>>              else
>>                expr_object_size (osi, var, rhs);
>>            }


Reply via email to