No need to change anything in middle-end. Add the testing case for PR120929.
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/pr120929.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 | 56 ++++++++++++++ gcc/testsuite/gcc.dg/pointer-counted-by-7.c | 32 ++++++++ gcc/testsuite/gcc.dg/pr120929.c | 49 ++++++++++++ 9 files changed, 302 insertions(+) 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 create mode 100644 gcc/testsuite/gcc.dg/pr120929.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..c4b36311c70 --- /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..b43ffdf4df9 --- /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..355558cd161 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-6.c @@ -0,0 +1,56 @@ +/* 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..af1ab279400 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pointer-counted-by-7.c @@ -0,0 +1,32 @@ +/* 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)); + free (p); + free (x.c); + DONE (); +} diff --git a/gcc/testsuite/gcc.dg/pr120929.c b/gcc/testsuite/gcc.dg/pr120929.c new file mode 100644 index 00000000000..8bb6d5cb6c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr120929.c @@ -0,0 +1,49 @@ +/* PR120929, pointee's size should not be propagated to pointer for + __builtin_dynamic_object_size. */ + +/* { dg-do compile} */ +/* { dg-options "-O2" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void pin_pointer(void *); +extern int some_value(void); + +struct magic_ { + char unused[9]; // at least 9 +}; + +struct magic_map { + struct magic_ *magic; +}; + +static int +coalesce_entries(struct magic_ **ma) +{ + size_t slen; + + slen = sizeof (**ma); + *ma = __builtin_malloc (slen); + + for (unsigned i = 0; i < 1; i++) + { + char b[1024] = {}; + struct magic_ *ptr = *ma; + (void) __builtin___memcpy_chk (ptr, b, sizeof (*ptr), /* { dg-bogus "overflows the destination" } */ + __builtin_dynamic_object_size (ptr, 0)); + } + return 0; +} + +struct magic_map * +apprentice_load(void) +{ + char buf[128]; // did not shrink, but needs to be more than 100 + struct magic_map *map2; + + map2 = __builtin_malloc (sizeof (*map2)); + + pin_pointer(&buf); + coalesce_entries(&map2->magic); + pin_pointer(map2); +} -- 2.31.1