Re: [V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896]
Hi, Sid, Thanks a lot for the detailed comments. See my responds embedded below. Qing > On Oct 5, 2023, at 4:01 PM, Siddhesh Poyarekar wrote: > > > > On 2023-08-25 11:24, Qing Zhao wrote: >> Use the counted_by atribute info in builtin object size to compute the >> subobject size for flexible array members. >> gcc/ChangeLog: >> PR C/108896 >> * tree-object-size.cc (addr_object_size): Use the counted_by >> attribute info. >> * tree.cc (component_ref_has_counted_by_p): New function. >> (component_ref_get_counted_by): New function. >> * tree.h (component_ref_has_counted_by_p): New prototype. >> (component_ref_get_counted_by): New prototype. >> gcc/testsuite/ChangeLog: >> PR C/108896 >> * gcc.dg/flex-array-counted-by-2.c: New test. >> * gcc.dg/flex-array-counted-by-3.c: New test. >> --- >> .../gcc.dg/flex-array-counted-by-2.c | 74 ++ >> .../gcc.dg/flex-array-counted-by-3.c | 210 ++ >> gcc/tree-object-size.cc | 37 ++- >> gcc/tree.cc | 95 +++- >> gcc/tree.h| 10 + >> 5 files changed, 418 insertions(+), 8 deletions(-) >> create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-2.c >> create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-3.c >> diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c >> b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c >> new file mode 100644 >> index ..ec580c1f1f01 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c >> @@ -0,0 +1,74 @@ >> +/* test the attribute counted_by and its usage in >> + * __builtin_dynamic_object_size. */ >> +/* { dg-do run } */ >> +/* { dg-options "-O2" } */ >> + >> +#include "builtin-object-size-common.h" >> + >> +#define expect(p, _v) do { \ >> +size_t v = _v; \ >> +if (p == v) \ >> +__builtin_printf ("ok: %s == %zd\n", #p, p); \ >> +else \ >> +{ \ >> + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ >> + FAIL (); \ >> +} \ >> +} while (0); > > You're using this in a bunch of tests already; does it make sense to > consolidate it into builtin-object-size-common.h? Will do this. > >> + >> +struct flex { >> + int b; >> + int c[]; >> +} *array_flex; >> + >> +struct annotated { >> + int b; >> + int c[] __attribute__ ((counted_by (b))); >> +} *array_annotated; >> + >> +struct nested_annotated { >> + struct { >> +union { >> + int b; >> + float f; >> +}; >> +int n; >> + }; >> + int c[] __attribute__ ((counted_by (b))); >> +} *array_nested_annotated; >> + >> +void __attribute__((__noinline__)) setup (int normal_count, int attr_count) >> +{ >> + array_flex >> += (struct flex *)malloc (sizeof (struct flex) >> + + normal_count * sizeof (int)); >> + array_flex->b = normal_count; >> + >> + array_annotated >> += (struct annotated *)malloc (sizeof (struct annotated) >> + + attr_count * sizeof (int)); >> + array_annotated->b = attr_count; >> + >> + array_nested_annotated >> += (struct nested_annotated *)malloc (sizeof (struct nested_annotated) >> + + attr_count * sizeof (int)); >> + array_nested_annotated->b = attr_count; >> + >> + return; >> +} >> + >> +void __attribute__((__noinline__)) test () >> +{ >> +expect(__builtin_dynamic_object_size(array_flex->c, 1), -1); >> +expect(__builtin_dynamic_object_size(array_annotated->c, 1), >> + array_annotated->b * sizeof (int)); >> +expect(__builtin_dynamic_object_size(array_nested_annotated->c, 1), >> + array_nested_annotated->b * sizeof (int)); >> +} > > Maybe another test where the allocation, size assignment and __bdos call > happen in the same function, where the allocator is not recognized by gcc: > > void * > __attribute__ ((noinline)) > alloc (size_t sz) > { > return __builtin_malloc (sz); > } > > void test (size_t sz) > { > array_annotated = alloc (sz); > array_annotated->b = sz; > return __builtin_dynamic_object_size (array_annotated->c, 1); > } > > The interesting thing to test (and ensure in the codegen) is that the > assignment to array_annotated->b does not get reordered to below the > __builtin_dynamic_object_size call since technically there is no data > dependency between the two. Good point. Will add such testing case. > >> + >> +int main(int argc, char *argv[]) >> +{ >> + setup (10,10); >> + test (); >> + DONE (); >> +} >> diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c >> b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c >> new file mode 100644 >> index ..a0c3cb88ec71 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c >> @@ -0,0 +1,210 @@ >> +/* test the attribute counted_by and its usage in >> +__builtin_dynamic_object_size: what's the correct behavior when the >>
Re: [V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896]
On 2023-08-25 11:24, Qing Zhao wrote: Use the counted_by atribute info in builtin object size to compute the subobject size for flexible array members. gcc/ChangeLog: PR C/108896 * tree-object-size.cc (addr_object_size): Use the counted_by attribute info. * tree.cc (component_ref_has_counted_by_p): New function. (component_ref_get_counted_by): New function. * tree.h (component_ref_has_counted_by_p): New prototype. (component_ref_get_counted_by): New prototype. gcc/testsuite/ChangeLog: PR C/108896 * gcc.dg/flex-array-counted-by-2.c: New test. * gcc.dg/flex-array-counted-by-3.c: New test. --- .../gcc.dg/flex-array-counted-by-2.c | 74 ++ .../gcc.dg/flex-array-counted-by-3.c | 210 ++ gcc/tree-object-size.cc | 37 ++- gcc/tree.cc | 95 +++- gcc/tree.h| 10 + 5 files changed, 418 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-2.c create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-3.c diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c new file mode 100644 index ..ec580c1f1f01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c @@ -0,0 +1,74 @@ +/* test the attribute counted_by and its usage in + * __builtin_dynamic_object_size. */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include "builtin-object-size-common.h" + +#define expect(p, _v) do { \ +size_t v = _v; \ +if (p == v) \ + __builtin_printf ("ok: %s == %zd\n", #p, p); \ +else \ + { \ + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + FAIL (); \ + } \ +} while (0); You're using this in a bunch of tests already; does it make sense to consolidate it into builtin-object-size-common.h? + +struct flex { + int b; + int c[]; +} *array_flex; + +struct annotated { + int b; + int c[] __attribute__ ((counted_by (b))); +} *array_annotated; + +struct nested_annotated { + struct { +union { + int b; + float f; +}; +int n; + }; + int c[] __attribute__ ((counted_by (b))); +} *array_nested_annotated; + +void __attribute__((__noinline__)) setup (int normal_count, int attr_count) +{ + array_flex += (struct flex *)malloc (sizeof (struct flex) ++ normal_count * sizeof (int)); + array_flex->b = normal_count; + + array_annotated += (struct annotated *)malloc (sizeof (struct annotated) + + attr_count * sizeof (int)); + array_annotated->b = attr_count; + + array_nested_annotated += (struct nested_annotated *)malloc (sizeof (struct nested_annotated) ++ attr_count * sizeof (int)); + array_nested_annotated->b = attr_count; + + return; +} + +void __attribute__((__noinline__)) test () +{ +expect(__builtin_dynamic_object_size(array_flex->c, 1), -1); +expect(__builtin_dynamic_object_size(array_annotated->c, 1), + array_annotated->b * sizeof (int)); +expect(__builtin_dynamic_object_size(array_nested_annotated->c, 1), + array_nested_annotated->b * sizeof (int)); +} Maybe another test where the allocation, size assignment and __bdos call happen in the same function, where the allocator is not recognized by gcc: void * __attribute__ ((noinline)) alloc (size_t sz) { return __builtin_malloc (sz); } void test (size_t sz) { array_annotated = alloc (sz); array_annotated->b = sz; return __builtin_dynamic_object_size (array_annotated->c, 1); } The interesting thing to test (and ensure in the codegen) is that the assignment to array_annotated->b does not get reordered to below the __builtin_dynamic_object_size call since technically there is no data dependency between the two. + +int main(int argc, char *argv[]) +{ + setup (10,10); + test (); + DONE (); +} diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c new file mode 100644 index ..a0c3cb88ec71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c @@ -0,0 +1,210 @@ +/* test the attribute counted_by and its usage in +__builtin_dynamic_object_size: what's the correct behavior when the +allocation size mismatched with the value of counted_by attribute? */ If the behaviour is undefined, does it make sense to add tests for this? Maybe once you have a -Wmismatched-counted-by or similar, we could have tests for that. I guess the counter-argument is that we keep track of this behaviour but not necessarily guarantee it. +/* { dg-do run } */ +/* { dg-options "-O -fstrict-flex-arrays=3" } */ + +#include "builtin-object-size-common.h" + +struct annotated { + size_t foo; + char others; + char array[]
PING *2: [V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896]
Hi, I’d like to ping this patch set one more time. Thanks Qing > On Aug 25, 2023, at 11:24 AM, Qing Zhao wrote: > > Use the counted_by atribute info in builtin object size to compute the > subobject size for flexible array members. > > gcc/ChangeLog: > > PR C/108896 > * tree-object-size.cc (addr_object_size): Use the counted_by > attribute info. > * tree.cc (component_ref_has_counted_by_p): New function. > (component_ref_get_counted_by): New function. > * tree.h (component_ref_has_counted_by_p): New prototype. > (component_ref_get_counted_by): New prototype. > > gcc/testsuite/ChangeLog: > > PR C/108896 > * gcc.dg/flex-array-counted-by-2.c: New test. > * gcc.dg/flex-array-counted-by-3.c: New test. > --- > .../gcc.dg/flex-array-counted-by-2.c | 74 ++ > .../gcc.dg/flex-array-counted-by-3.c | 210 ++ > gcc/tree-object-size.cc | 37 ++- > gcc/tree.cc | 95 +++- > gcc/tree.h| 10 + > 5 files changed, 418 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > > diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > new file mode 100644 > index ..ec580c1f1f01 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > @@ -0,0 +1,74 @@ > +/* test the attribute counted_by and its usage in > + * __builtin_dynamic_object_size. */ > +/* { dg-do run } */ > +/* { dg-options "-O2" } */ > + > +#include "builtin-object-size-common.h" > + > +#define expect(p, _v) do { \ > +size_t v = _v; \ > +if (p == v) \ > + __builtin_printf ("ok: %s == %zd\n", #p, p); \ > +else \ > + { \ > + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ > + FAIL (); \ > + } \ > +} while (0); > + > +struct flex { > + int b; > + int c[]; > +} *array_flex; > + > +struct annotated { > + int b; > + int c[] __attribute__ ((counted_by (b))); > +} *array_annotated; > + > +struct nested_annotated { > + struct { > +union { > + int b; > + float f; > +}; > +int n; > + }; > + int c[] __attribute__ ((counted_by (b))); > +} *array_nested_annotated; > + > +void __attribute__((__noinline__)) setup (int normal_count, int attr_count) > +{ > + array_flex > += (struct flex *)malloc (sizeof (struct flex) > + + normal_count * sizeof (int)); > + array_flex->b = normal_count; > + > + array_annotated > += (struct annotated *)malloc (sizeof (struct annotated) > + + attr_count * sizeof (int)); > + array_annotated->b = attr_count; > + > + array_nested_annotated > += (struct nested_annotated *)malloc (sizeof (struct nested_annotated) > + + attr_count * sizeof (int)); > + array_nested_annotated->b = attr_count; > + > + return; > +} > + > +void __attribute__((__noinline__)) test () > +{ > +expect(__builtin_dynamic_object_size(array_flex->c, 1), -1); > +expect(__builtin_dynamic_object_size(array_annotated->c, 1), > +array_annotated->b * sizeof (int)); > +expect(__builtin_dynamic_object_size(array_nested_annotated->c, 1), > +array_nested_annotated->b * sizeof (int)); > +} > + > +int main(int argc, char *argv[]) > +{ > + setup (10,10); > + test (); > + DONE (); > +} > diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > new file mode 100644 > index ..a0c3cb88ec71 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > @@ -0,0 +1,210 @@ > +/* test the attribute counted_by and its usage in > +__builtin_dynamic_object_size: what's the correct behavior when the > +allocation size mismatched with the value of counted_by attribute? */ > +/* { dg-do run } */ > +/* { dg-options "-O -fstrict-flex-arrays=3" } */ > + > +#include "builtin-object-size-common.h" > + > +struct annotated { > + size_t foo; > + char others; > + char array[] __attribute__((counted_by (foo))); > +}; > + > +#define expect(p, _v) do { \ > +size_t v = _v; \ > +if (p == v) \ > +__builtin_printf ("ok: %s == %zd\n", #p, p); \ > +else \ > +{ \ > + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ > + FAIL (); \ > +} \ > +} while (0); > + > +#define noinline __attribute__((__noinline__)) > +#define SIZE_BUMP 10 > +#define MAX(a, b) ((a) > (b) ? (a) : (b)) > +#define MIN(a, b) ((a) < (b) ? (a) : (b)) > + > +/* In general, Due to type casting, the type for the pointee of a pointer > + does not say anything about the object it points to, > + So, __builtin_object_size can not directly use the type of the pointee > + to decide the size
Re: [V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896]
Ping. thanks. Qing > On Aug 25, 2023, at 11:24 AM, Qing Zhao wrote: > > Use the counted_by atribute info in builtin object size to compute the > subobject size for flexible array members. > > gcc/ChangeLog: > > PR C/108896 > * tree-object-size.cc (addr_object_size): Use the counted_by > attribute info. > * tree.cc (component_ref_has_counted_by_p): New function. > (component_ref_get_counted_by): New function. > * tree.h (component_ref_has_counted_by_p): New prototype. > (component_ref_get_counted_by): New prototype. > > gcc/testsuite/ChangeLog: > > PR C/108896 > * gcc.dg/flex-array-counted-by-2.c: New test. > * gcc.dg/flex-array-counted-by-3.c: New test. > --- > .../gcc.dg/flex-array-counted-by-2.c | 74 ++ > .../gcc.dg/flex-array-counted-by-3.c | 210 ++ > gcc/tree-object-size.cc | 37 ++- > gcc/tree.cc | 95 +++- > gcc/tree.h| 10 + > 5 files changed, 418 insertions(+), 8 deletions(-) > create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > > diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > new file mode 100644 > index ..ec580c1f1f01 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c > @@ -0,0 +1,74 @@ > +/* test the attribute counted_by and its usage in > + * __builtin_dynamic_object_size. */ > +/* { dg-do run } */ > +/* { dg-options "-O2" } */ > + > +#include "builtin-object-size-common.h" > + > +#define expect(p, _v) do { \ > +size_t v = _v; \ > +if (p == v) \ > + __builtin_printf ("ok: %s == %zd\n", #p, p); \ > +else \ > + { \ > + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ > + FAIL (); \ > + } \ > +} while (0); > + > +struct flex { > + int b; > + int c[]; > +} *array_flex; > + > +struct annotated { > + int b; > + int c[] __attribute__ ((counted_by (b))); > +} *array_annotated; > + > +struct nested_annotated { > + struct { > +union { > + int b; > + float f; > +}; > +int n; > + }; > + int c[] __attribute__ ((counted_by (b))); > +} *array_nested_annotated; > + > +void __attribute__((__noinline__)) setup (int normal_count, int attr_count) > +{ > + array_flex > += (struct flex *)malloc (sizeof (struct flex) > + + normal_count * sizeof (int)); > + array_flex->b = normal_count; > + > + array_annotated > += (struct annotated *)malloc (sizeof (struct annotated) > + + attr_count * sizeof (int)); > + array_annotated->b = attr_count; > + > + array_nested_annotated > += (struct nested_annotated *)malloc (sizeof (struct nested_annotated) > + + attr_count * sizeof (int)); > + array_nested_annotated->b = attr_count; > + > + return; > +} > + > +void __attribute__((__noinline__)) test () > +{ > +expect(__builtin_dynamic_object_size(array_flex->c, 1), -1); > +expect(__builtin_dynamic_object_size(array_annotated->c, 1), > +array_annotated->b * sizeof (int)); > +expect(__builtin_dynamic_object_size(array_nested_annotated->c, 1), > +array_nested_annotated->b * sizeof (int)); > +} > + > +int main(int argc, char *argv[]) > +{ > + setup (10,10); > + test (); > + DONE (); > +} > diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > new file mode 100644 > index ..a0c3cb88ec71 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c > @@ -0,0 +1,210 @@ > +/* test the attribute counted_by and its usage in > +__builtin_dynamic_object_size: what's the correct behavior when the > +allocation size mismatched with the value of counted_by attribute? */ > +/* { dg-do run } */ > +/* { dg-options "-O -fstrict-flex-arrays=3" } */ > + > +#include "builtin-object-size-common.h" > + > +struct annotated { > + size_t foo; > + char others; > + char array[] __attribute__((counted_by (foo))); > +}; > + > +#define expect(p, _v) do { \ > +size_t v = _v; \ > +if (p == v) \ > +__builtin_printf ("ok: %s == %zd\n", #p, p); \ > +else \ > +{ \ > + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ > + FAIL (); \ > +} \ > +} while (0); > + > +#define noinline __attribute__((__noinline__)) > +#define SIZE_BUMP 10 > +#define MAX(a, b) ((a) > (b) ? (a) : (b)) > +#define MIN(a, b) ((a) < (b) ? (a) : (b)) > + > +/* In general, Due to type casting, the type for the pointee of a pointer > + does not say anything about the object it points to, > + So, __builtin_object_size can not directly use the type of the pointee > + to decide the size of the object the pointer points to. > + > +
[V3][PATCH 2/3] Use the counted_by atribute info in builtin object size [PR108896]
Use the counted_by atribute info in builtin object size to compute the subobject size for flexible array members. gcc/ChangeLog: PR C/108896 * tree-object-size.cc (addr_object_size): Use the counted_by attribute info. * tree.cc (component_ref_has_counted_by_p): New function. (component_ref_get_counted_by): New function. * tree.h (component_ref_has_counted_by_p): New prototype. (component_ref_get_counted_by): New prototype. gcc/testsuite/ChangeLog: PR C/108896 * gcc.dg/flex-array-counted-by-2.c: New test. * gcc.dg/flex-array-counted-by-3.c: New test. --- .../gcc.dg/flex-array-counted-by-2.c | 74 ++ .../gcc.dg/flex-array-counted-by-3.c | 210 ++ gcc/tree-object-size.cc | 37 ++- gcc/tree.cc | 95 +++- gcc/tree.h| 10 + 5 files changed, 418 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-2.c create mode 100644 gcc/testsuite/gcc.dg/flex-array-counted-by-3.c diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c new file mode 100644 index ..ec580c1f1f01 --- /dev/null +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-2.c @@ -0,0 +1,74 @@ +/* test the attribute counted_by and its usage in + * __builtin_dynamic_object_size. */ +/* { dg-do run } */ +/* { dg-options "-O2" } */ + +#include "builtin-object-size-common.h" + +#define expect(p, _v) do { \ +size_t v = _v; \ +if (p == v) \ + __builtin_printf ("ok: %s == %zd\n", #p, p); \ +else \ + { \ + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + FAIL (); \ + } \ +} while (0); + +struct flex { + int b; + int c[]; +} *array_flex; + +struct annotated { + int b; + int c[] __attribute__ ((counted_by (b))); +} *array_annotated; + +struct nested_annotated { + struct { +union { + int b; + float f; +}; +int n; + }; + int c[] __attribute__ ((counted_by (b))); +} *array_nested_annotated; + +void __attribute__((__noinline__)) setup (int normal_count, int attr_count) +{ + array_flex += (struct flex *)malloc (sizeof (struct flex) ++ normal_count * sizeof (int)); + array_flex->b = normal_count; + + array_annotated += (struct annotated *)malloc (sizeof (struct annotated) + + attr_count * sizeof (int)); + array_annotated->b = attr_count; + + array_nested_annotated += (struct nested_annotated *)malloc (sizeof (struct nested_annotated) ++ attr_count * sizeof (int)); + array_nested_annotated->b = attr_count; + + return; +} + +void __attribute__((__noinline__)) test () +{ +expect(__builtin_dynamic_object_size(array_flex->c, 1), -1); +expect(__builtin_dynamic_object_size(array_annotated->c, 1), + array_annotated->b * sizeof (int)); +expect(__builtin_dynamic_object_size(array_nested_annotated->c, 1), + array_nested_annotated->b * sizeof (int)); +} + +int main(int argc, char *argv[]) +{ + setup (10,10); + test (); + DONE (); +} diff --git a/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c new file mode 100644 index ..a0c3cb88ec71 --- /dev/null +++ b/gcc/testsuite/gcc.dg/flex-array-counted-by-3.c @@ -0,0 +1,210 @@ +/* test the attribute counted_by and its usage in +__builtin_dynamic_object_size: what's the correct behavior when the +allocation size mismatched with the value of counted_by attribute? */ +/* { dg-do run } */ +/* { dg-options "-O -fstrict-flex-arrays=3" } */ + +#include "builtin-object-size-common.h" + +struct annotated { + size_t foo; + char others; + char array[] __attribute__((counted_by (foo))); +}; + +#define expect(p, _v) do { \ +size_t v = _v; \ +if (p == v) \ +__builtin_printf ("ok: %s == %zd\n", #p, p); \ +else \ +{ \ + __builtin_printf ("WAT: %s == %zd (expected %zd)\n", #p, p, v); \ + FAIL (); \ +} \ +} while (0); + +#define noinline __attribute__((__noinline__)) +#define SIZE_BUMP 10 +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +/* In general, Due to type casting, the type for the pointee of a pointer + does not say anything about the object it points to, + So, __builtin_object_size can not directly use the type of the pointee + to decide the size of the object the pointer points to. + + there are only two reliable ways: + A. observed allocations (call to the allocation functions in the routine) + B. observed accesses (read or write access to the location of the + pointer points to) + + that provide information about the type/existence of an object at + the corresponding