> On Jun 24, 2025, at 03:26, Richard Biener <richard.guent...@gmail.com> wrote: > > On Mon, Jun 23, 2025 at 4:44 PM Qing Zhao <qing.z...@oracle.com> wrote: >> >> gcc/ChangeLog: >> >> * tree-object-size.cc (access_with_size_object_size): Update comments >> for pointers with .ACCESS_WITH_SIZE. >> (collect_object_sizes_for): Propagate size info through GIMPLE_ASSIGN >> for pointers with .ACCESS_WITH_SIZE. >> >> gcc/testsuite/ChangeLog: >> >> * gcc.dg/pointer-counted-by-4-char.c: New test. >> * gcc.dg/pointer-counted-by-4-float.c: New test. >> * gcc.dg/pointer-counted-by-4-struct.c: New test. >> * gcc.dg/pointer-counted-by-4-union.c: New test. >> * gcc.dg/pointer-counted-by-4.c: New test. >> * gcc.dg/pointer-counted-by-5.c: New test. >> * gcc.dg/pointer-counted-by-6.c: New test. >> * gcc.dg/pointer-counted-by-7.c: New test. >> --- >> .../gcc.dg/pointer-counted-by-4-char.c | 6 ++ >> .../gcc.dg/pointer-counted-by-4-float.c | 6 ++ >> .../gcc.dg/pointer-counted-by-4-struct.c | 10 +++ >> .../gcc.dg/pointer-counted-by-4-union.c | 10 +++ >> gcc/testsuite/gcc.dg/pointer-counted-by-4.c | 77 +++++++++++++++++++ >> gcc/testsuite/gcc.dg/pointer-counted-by-5.c | 56 ++++++++++++++ >> gcc/testsuite/gcc.dg/pointer-counted-by-6.c | 54 +++++++++++++ >> gcc/testsuite/gcc.dg/pointer-counted-by-7.c | 30 ++++++++ >> gcc/tree-object-size.cc | 18 ++++- >> 9 files changed, 264 insertions(+), 3 deletions(-) >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-4-char.c >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-4-float.c >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-4-struct.c >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-4-union.c >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-4.c >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-5.c >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-6.c >> create mode 100644 gcc/testsuite/gcc.dg/pointer-counted-by-7.c >> >> 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)); >> +} >> + >> +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); >> +} >> + >> +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; >> +} >> 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) > > && integer_zerop (TREE_OPERAND (rhs, 1)) > > ?
Yes, you are right, will fix that and send the updated patch again. Thanks. Qing > >> + reexamine = merge_object_sizes (osi, var, TREE_OPERAND (rhs, >> 0)); >> else >> expr_object_size (osi, var, rhs); >> } >> -- >> 2.31.1