diff options
Diffstat (limited to 'gcc/testsuite/gcc.dg/pointer-counted-by-6.c')
-rw-r--r-- | gcc/testsuite/gcc.dg/pointer-counted-by-6.c | 56 |
1 files changed, 56 insertions, 0 deletions
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 0000000..355558c --- /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; +} |