/* Test the code generation for the new attribute counted_by. And also the offsetof operator on such array. */ /* { dg-do run } */ /* { dg-options "-O2 -fdump-tree-original" } */ #include struct annotated { int b; char c[] __attribute__ ((counted_by (b))); } *array_annotated; static struct annotated static_annotated = { sizeof "hello", "hello" }; static char *y = static_annotated.c; struct flex { int b; char c[]; }; struct nested_annotated { struct { union { int b; float f; }; int n; }; char c[] __attribute__ ((counted_by (b))); } *array_nested_annotated; static struct nested_annotated nested_static_annotated = { sizeof "hello1", 0, "hello1" }; static char *nested_y = nested_static_annotated.c; struct nested_flex { struct { union { int b; float f; }; int n; }; char c[]; }; void __attribute__((__noinline__)) setup (int normal_count, int attr_count) { array_annotated = (struct annotated *)malloc (sizeof (struct annotated) + attr_count * sizeof (char)); array_annotated->b = attr_count; array_nested_annotated = (struct nested_annotated *)malloc (sizeof (struct nested_annotated) + attr_count * sizeof (char)); array_nested_annotated->b = attr_count; return; } void __attribute__((__noinline__)) test (char a, char b) { if (__builtin_offsetof (struct annotated, c[0]) != __builtin_offsetof (struct flex, c[0])) abort (); if (__builtin_offsetof (struct annotated, c[1]) != __builtin_offsetof (struct flex, c[1])) abort (); if (__builtin_offsetof (struct nested_annotated, c[0]) != __builtin_offsetof (struct nested_flex, c[0])) abort (); if (__builtin_offsetof (struct nested_annotated, c[1]) != __builtin_offsetof (struct nested_flex, c[1])) abort (); if (__builtin_types_compatible_p (typeof (array_annotated->c), typeof (&(array_annotated->c)[0]))) abort (); if (__builtin_types_compatible_p (typeof (array_nested_annotated->c), typeof (&(array_nested_annotated->c)[0]))) abort (); if (__alignof (array_annotated->c) != __alignof (char)) abort (); if (__alignof (array_nested_annotated->c) != __alignof (char)) abort (); if ((unsigned long) array_annotated->c != (unsigned long) &array_annotated->c) abort (); if ((unsigned long) array_nested_annotated->c != (unsigned long) &array_nested_annotated->c) abort (); array_annotated->c[2] = a; array_nested_annotated->c[3] = b; if (y[2] != 'l') abort (); if (nested_y[4] !='o') abort (); } int main(int argc, char *argv[]) { setup (10,10); test ('A', 'B'); if (array_annotated->c[2] != 'A') abort (); if (array_nested_annotated->c[3] != 'B') abort (); return 0; } /* { dg-final { scan-tree-dump-times "ACCESS_WITH_SIZE" 8 "original" } } */