Fix ICE in substring-handling building 502.gcc_r (PR 87562)
[official-gcc.git] / gcc / testsuite / c-c++-common / builtin-offsetof-2.c
blobf943dde05f705446810c38f0f8e55163f7fd313c
1 // { dg-options "-Warray-bounds" }
2 // { dg-do compile }
4 // Test case exercising pr c/67882 - surprising offsetof result
5 // on an invalid array member without diagnostic.
7 typedef struct A1 {
8 char a1[1];
9 char c;
10 } A1;
12 typedef struct A1_x_2 {
13 char a1[1];
14 char a[][2];
15 } A1_x_2;
17 typedef struct A1_1_x {
18 char a1_1[1][1];
19 char a[];
20 } A1_1_x;
22 typedef struct Ax_2_3 {
23 int i;
24 char a_x_2_3[][2][3];
25 } Ax_2_3;
27 typedef struct A1_1 {
28 char a1_1[1][1];
29 char c;
30 } A1_1;
32 typedef struct B {
33 A1_1 a2_3[2][3];
34 char a1_1[3][5];
35 char a[];
36 } B;
38 // Structures with members that contain flexible array members are
39 // an extension accepted by GCC.
40 typedef struct C {
41 A1_1_x a5_7 [5][7];
42 int a;
43 } C;
45 // Structs with a "fake" flexible array member (a GCC extension).
46 typedef struct FA0 {
47 int i;
48 char a0 [0];
49 } FA0;
51 typedef struct FA1 {
52 int i;
53 char a1 [1];
54 } FA1;
56 typedef struct FA3 {
57 int i;
58 char a3 [3];
59 } FA3;
61 // A "fake" multidimensional flexible array member.
62 typedef struct FA5_7 {
63 int i;
64 char a5_7 [5][7];
65 } FA5_7;
67 static void test (void)
69 // Verify that offsetof references to array elements past the end of
70 // the array member are diagnosed. As an extension, permit references
71 // to the element just past-the-end of the array.
73 int a[] = {
74 __builtin_offsetof (A1, a1), // valid
75 __builtin_offsetof (A1, a1 [0]), // valid
77 // The following expression is valid because it forms the equivalent
78 // of an address pointing just past the last element of the array.
79 __builtin_offsetof (A1, a1 [1]), // valid
81 __builtin_offsetof (A1, a1 [2]), // { dg-warning "index" }
83 __builtin_offsetof (A1_x_2, a1), // valid
84 __builtin_offsetof (A1_x_2, a1 [0]), // valid
85 __builtin_offsetof (A1_x_2, a1 [1]), // valid
86 __builtin_offsetof (A1_x_2, a1 [2]), // { dg-warning "index" }
88 __builtin_offsetof (A1_x_2, a), // valid
89 __builtin_offsetof (A1_x_2, a [0]), // valid
90 __builtin_offsetof (A1_x_2, a [1]), // valid
91 __builtin_offsetof (A1_x_2, a [99]), // valid
93 __builtin_offsetof (A1_x_2, a), // valid
94 __builtin_offsetof (A1_x_2, a [0][0]), // valid
95 __builtin_offsetof (A1_x_2, a [0][1]), // valid
97 // The following expression is valid because it forms the equivalent
98 // of an address pointing just past the last element of the first
99 // array.
100 __builtin_offsetof (A1_x_2, a [0][2]), // valid
102 // Unlike the case above, this is invalid since it refers to an element
103 // past one one just-past-the-end in A[][2].
104 __builtin_offsetof (A1_x_2, a [0][3]), // { dg-warning "index" }
106 __builtin_offsetof (A1_x_2, a [1][0]), // valid
107 __builtin_offsetof (A1_x_2, a [1][1]), // valid
108 __builtin_offsetof (A1_x_2, a [1][2]), // valid
109 __builtin_offsetof (A1_x_2, a [99][0]), // valid
110 __builtin_offsetof (A1_x_2, a [99][1]), // valid
111 __builtin_offsetof (A1_x_2, a [99][2]), // valid
113 __builtin_offsetof (A1_1_x, a), // valid
114 __builtin_offsetof (A1_1_x, a [0]), // valid
115 __builtin_offsetof (A1_1_x, a [1]), // valid
116 __builtin_offsetof (A1_1_x, a [99]), // valid
118 __builtin_offsetof (A1_1_x, a1_1 [0][0]), // valid
119 __builtin_offsetof (A1_1_x, a1_1 [0][1]), // valid
120 __builtin_offsetof (A1_1_x, a1_1 [0][2]), // { dg-warning "index" }
121 __builtin_offsetof (A1_1_x, a1_1 [1][0]), // { dg-warning "index" }
122 __builtin_offsetof (A1_1_x, a1_1 [1][1]), // { dg-warning "index" }
124 __builtin_offsetof (Ax_2_3, a_x_2_3 [0][1][3]), // valid
125 __builtin_offsetof (Ax_2_3, a_x_2_3 [0][1][4]), // { dg-warning "index" }
126 __builtin_offsetof (Ax_2_3, a_x_2_3 [0][2]), // valid
127 __builtin_offsetof (Ax_2_3, a_x_2_3 [0][2][0]), // { dg-warning "index" }
129 __builtin_offsetof (B, a2_3 [0][0].c), // valid
130 __builtin_offsetof (B, a2_3 [0][0].a1_1 [0][0]), // valid
131 __builtin_offsetof (B, a2_3 [1][3]), // valid
132 __builtin_offsetof (B, a2_3 [1][4]), // { dg-warning "index" }
133 __builtin_offsetof (B, a2_3 [0][0].a1_1 [0][1]), // valid
134 __builtin_offsetof (B, a2_3 [0][0].a1_1 [0][2]), // { dg-warning "index" }
136 __builtin_offsetof (B, a2_3 [0][0].a1_1 [1][0]), // { dg-warning "index" }
137 __builtin_offsetof (B, a2_3 [0][0].a1_1 [1][1]), // { dg-warning "index" }
139 __builtin_offsetof (B, a2_3 [1][2].a1_1 [0][0]), // valid
141 // Forming an offset to the just-past-end element is valid.
142 __builtin_offsetof (B, a2_3 [1][2].a1_1 [0][1]), // valid
143 __builtin_offsetof (B, a2_3 [1][2].a1_1 [1][0]), // { dg-warning "index" }
144 __builtin_offsetof (B, a2_3 [1][2].a1_1 [1][1]), // { dg-warning "index" }
146 // Forming an offset to the just-past-end element is valid.
147 __builtin_offsetof (B, a2_3 [1][3]), // valid
148 // ...but these are diagnosed because they dereference a just-past-the-end
149 // element.
150 __builtin_offsetof (B, a2_3 [1][3].a1_1 [0][0]), // { dg-warning "index" }
151 __builtin_offsetof (B, a2_3 [1][3].a1_1 [0][0]), // { dg-warning "index" }
152 __builtin_offsetof (B, a2_3 [1][3].a1_1 [0][1]), // { dg-warning "index" }
153 __builtin_offsetof (B, a2_3 [1][3].a1_1 [1][0]), // { dg-warning "index" }
154 __builtin_offsetof (B, a2_3 [1][3].a1_1 [1][1]), // { dg-warning "index" }
156 // Analogous to the case above, these are both diagnosed because they
157 // dereference just-past-the-end elements of the a2_3 array.
158 __builtin_offsetof (B, a2_3 [1][3].c), // { dg-warning "index" }
159 __builtin_offsetof (B, a2_3 [1][3].c), // { dg-warning "index" }
161 // The following are all invalid because of the reference to a2_3[2].
162 __builtin_offsetof (B, a2_3 [2][0].a1_1 [0][0]), // { dg-warning "index" }
163 __builtin_offsetof (B, a2_3 [2][0].a1_1 [0][1]), // { dg-warning "index" }
164 __builtin_offsetof (B, a2_3 [2][0].a1_1 [1][0]), // { dg-warning "index" }
165 __builtin_offsetof (B, a2_3 [2][0].a1_1 [1][1]), // { dg-warning "index" }
166 __builtin_offsetof (B, a2_3 [2][0].c), // { dg-warning "index" }
168 __builtin_offsetof (C, a5_7 [4][6]),
169 __builtin_offsetof (C, a5_7 [4][6].a),
170 __builtin_offsetof (C, a5_7 [4][6].a [0]),
171 __builtin_offsetof (C, a5_7 [4][6].a [99]),
173 __builtin_offsetof (C, a5_7 [4][7]), // valid
174 // Diagnose the following even though the object whose offset is
175 // computed is a flexible array member.
176 __builtin_offsetof (C, a5_7 [4][7].a), // { dg-warning "index" }
177 __builtin_offsetof (C, a5_7 [4][7].a [0]), // { dg-warning "index" }
178 __builtin_offsetof (C, a5_7 [4][7].a [99]), // { dg-warning "index" }
180 // Verify that no diagnostic is issued for offsetof expressions
181 // involving structs where the array has a rank of 1 and is the last
182 // member (e.g., those are treated as flexible array members).
183 __builtin_offsetof (FA0, a0 [0]),
184 __builtin_offsetof (FA0, a0 [1]),
185 __builtin_offsetof (FA0, a0 [99]),
187 __builtin_offsetof (FA1, a1 [0]),
188 __builtin_offsetof (FA1, a1 [1]),
189 __builtin_offsetof (FA1, a1 [99]),
191 __builtin_offsetof (FA3, a3 [0]),
192 __builtin_offsetof (FA3, a3 [3]),
193 __builtin_offsetof (FA3, a3 [99]),
195 __builtin_offsetof (FA5_7, a5_7 [0][0]),
197 // Unlike one-dimensional arrays, verify that out-of-bounds references
198 // to "fake" flexible arrays with rank of 2 and greater are diagnosed.
200 // The following are valid because they compute the offset of just past
201 // the end of each of the a5_7[0] and a5_7[1] arrays.
202 __builtin_offsetof (FA5_7, a5_7 [0][7]), // valid
203 __builtin_offsetof (FA5_7, a5_7 [1][7]), // valid
205 // The following two are accepted as an extesion (because a5_7 is
206 // treated as a flexible array member).
207 __builtin_offsetof (FA5_7, a5_7 [5][0]), // extension
208 __builtin_offsetof (FA5_7, a5_7 [5][7]), // extension
210 // The following are invalid since in both cases they denote an element
211 // that's beyond just-past-the-end of the array.
212 __builtin_offsetof (FA5_7, a5_7 [0][8]), // { dg-warning "index" }
213 __builtin_offsetof (FA5_7, a5_7 [6][8]) // { dg-warning "index" }
216 (void)&a;