1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
/* 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 <stdlib.h>
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" } } */
|