1 /* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length array
4 { dg-options "-O2 -Wall -fno-tree-vectorize" }
5 { dg-require-effective-target alloca } */
7 typedef __INT16_TYPE__
int16_t;
8 typedef __INT32_TYPE__
int32_t;
12 /* Exercise a true flexible member. */
17 int16_t ax
[]; // { dg-message "while referencing 'ax'" "member" }
20 static void warn_ax_local (struct AX
*p
)
22 p
->ax
[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
23 p
->ax
[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
26 static void nowarn_ax_extern (struct AX
*p
)
28 p
->ax
[0] = 0; p
->ax
[99] = 99; p
->ax
[999] = 999; p
->ax
[9999] = 9999;
31 static void warn_ax_local_buf (struct AX
*p
)
33 p
->ax
[0] = 4; p
->ax
[1] = 5;
35 p
->ax
[2] = 6; // { dg-warning "\\\[-Warray-bounds" }
36 p
->ax
[3] = 7; // { dg-warning "\\\[-Warray-bounds" }
37 p
->ax
[4] = 8; // { dg-warning "\\\[-Warray-bounds" }
40 static void warn_ax_extern_buf (struct AX
*p
)
42 p
->ax
[0] = 9; p
->ax
[1] = 10; p
->ax
[2] = 11;
44 p
->ax
[3] = 12; // { dg-warning "\\\[-Warray-bounds" }
45 p
->ax
[4] = 13; // { dg-warning "\\\[-Warray-bounds" }
46 p
->ax
[5] = 14; // { dg-warning "\\\[-Warray-bounds" }
49 static void nowarn_ax_extern_bufx (struct AX
*p
)
51 p
->ax
[0] = 0; p
->ax
[99] = 99; p
->ax
[999] = 999; p
->ax
[9999] = 9999;
54 static void nowarn_ax_ref (struct AX
*p
)
56 p
->ax
[0] = 0; p
->ax
[99] = 99; p
->ax
[999] = 999; p
->ax
[9999] = 9999;
59 void test_ax (struct AX
*p
, unsigned n
)
62 struct AX sax
; // { dg-message "defined here" "struct definition" }
70 nowarn_ax_extern (&xsax
);
75 /* Verify out-of-bounds access to the local BUF is diagnosed. */
76 char ax_buf_p2
[sizeof (struct AX
) + 2 * sizeof (int16_t)];
77 warn_ax_local_buf ((struct AX
*) ax_buf_p2
);
82 /* Verify out-of-bounds access to the extern BUF with a known
83 bound is diagnosed. */
84 extern char ax_buf_p3
[sizeof (struct AX
) + 3 * sizeof (int16_t)];
85 warn_ax_extern_buf ((struct AX
*) ax_buf_p3
);
90 /* Verify that accesses to BUFX with an unknown bound are not
93 nowarn_ax_extern_bufx ((struct AX
*) bufx
);
98 /* Verify that accesses to BUFN with a runtime bound are not
101 nowarn_ax_extern_bufx ((struct AX
*) bufn
);
109 /* Exercise a zero-length trailing member array. It's the same as above
110 except that extern declarations with no definitions are considered to
111 have zero elements (they can't be initialized to have any). */
116 int16_t a0
[0]; // { dg-message "while referencing 'a0'" "member" }
119 static void warn_a0_local (struct A0
*p
)
121 p
->a0
[0] = 0; // { dg-warning "\\\[-Warray-bounds" }
122 p
->a0
[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
125 static void warn_a0_extern (struct A0
*p
)
127 p
->a0
[0] = 2; // { dg-warning "\\\[-Warray-bounds" }
128 p
->a0
[1] = 3; // { dg-warning "\\\[-Warray-bounds" }
131 static void warn_a0_local_buf (struct A0
*p
)
133 p
->a0
[0] = 4; p
->a0
[1] = 5;
135 p
->a0
[2] = 6; // { dg-warning "\\\[-Warray-bounds" }
136 p
->a0
[3] = 7; // { dg-warning "\\\[-Warray-bounds" }
137 p
->a0
[4] = 8; // { dg-warning "\\\[-Warray-bounds" }
140 static void warn_a0_extern_buf (struct A0
*p
)
142 p
->a0
[0] = 9; p
->a0
[1] = 10; p
->a0
[2] = 11;
144 p
->a0
[3] = 12; // { dg-warning "\\\[-Warray-bounds" }
145 p
->a0
[4] = 13; // { dg-warning "\\\[-Warray-bounds" }
146 p
->a0
[5] = 14; // { dg-warning "\\\[-Warray-bounds" }
149 static void nowarn_a0_extern_bufx (struct A0
*p
)
151 p
->a0
[0] = 0; p
->a0
[99] = 99; p
->a0
[999] = 999; p
->a0
[9999] = 9999;
154 static void nowarn_a0_ref (struct A0
*p
)
156 p
->a0
[0] = 0; p
->a0
[99] = 99; p
->a0
[999] = 999; p
->a0
[9999] = 9999;
159 void test_a0 (struct A0
*p
, unsigned n
)
162 struct A0 sa0
; // { dg-message "defined here" "struct definition" }
163 warn_a0_local (&sa0
);
169 struct A0 xsa0
; // { dg-message "defined here" "struct definition" }
170 warn_a0_extern (&xsa0
);
175 /* Verify out-of-bounds access to the local BUF is diagnosed. */
176 char a0_buf_p2
[sizeof (struct A0
) + 2 * sizeof (int16_t)];
177 warn_a0_local_buf ((struct A0
*) a0_buf_p2
);
182 /* Verify out-of-bounds access to the extern BUF with a known
183 bound is diagnosed. */
184 extern char a0_buf_p3
[sizeof (struct A0
) + 3 * sizeof (int16_t)];
185 warn_a0_extern_buf ((struct A0
*) a0_buf_p3
);
190 /* Verify that accesses to BUFX with an unknown bound are not
193 nowarn_a0_extern_bufx ((struct A0
*) bufx
);
198 /* Verify that accesses to BUFN with a runtime bound are not
201 nowarn_a0_extern_bufx ((struct A0
*) bufn
);
209 /* Exercise a one-element trailing member array. It's the same as above
210 except that it has exactly one element. */
215 int16_t a1
[1]; // { dg-message "while referencing 'a1'" }
218 static void warn_a1_local_noinit (struct A1
*p
)
221 p
->a1
[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
222 p
->a1
[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
225 static void warn_a1_extern (struct A1
*p
)
228 p
->a1
[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
229 p
->a1
[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
232 static void warn_a1_init (struct A1
*p
)
235 p
->a1
[1] = 1; // { dg-warning "\\\[-Warray-bounds" }
236 p
->a1
[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
239 static void warn_a1_local_buf (struct A1
*p
)
241 p
->a1
[0] = 0; p
->a1
[1] = 1; p
->a1
[2] = 2;
243 p
->a1
[3] = 3; // { dg-warning "\\\[-Warray-bounds" "" { target default_packed } }
244 p
->a1
[4] = 4; // { dg-warning "\\\[-Warray-bounds" }
247 static void warn_a1_extern_buf (struct A1
*p
)
249 p
->a1
[0] = 0; p
->a1
[1] = 1; p
->a1
[2] = 2; p
->a1
[3] = 3;
251 p
->a1
[4] = 4; // { dg-warning "\\\[-Warray-bounds" "" { target default_packed } }
252 p
->a1
[5] = 5; // { dg-warning "\\\[-Warray-bounds" }
255 static void nowarn_a1_extern_bufx (struct A1
*p
)
257 p
->a1
[0] = 0; p
->a1
[99] = 99; p
->a1
[999] = 999; p
->a1
[9999] = 9999;
260 static void nowarn_a1_ref (struct A1
*p
)
262 p
->a1
[0] = 0; p
->a1
[99] = 99; p
->a1
[999] = 999; p
->a1
[9999] = 9999;
265 void test_a1 (struct A1
*p
, unsigned n
)
269 warn_a1_local_noinit (&a1
);
274 extern struct A1 a1x
;
275 warn_a1_extern (&a1x
);
279 struct A1 a1
= { 0, { 1 } };
285 /* Verify out-of-bounds access to the local BUF is diagnosed. */
286 char buf_p2
[sizeof (struct A1
) + 2 * sizeof (int16_t)];
287 warn_a1_local_buf ((struct A1
*) buf_p2
);
292 /* Verify out-of-bounds access to the extern BUF with a known
293 bound is diagnosed. */
294 extern char a1_buf_p3
[sizeof (struct A1
) + 3 * sizeof (int16_t)];
295 warn_a1_extern_buf ((struct A1
*) a1_buf_p3
);
300 /* Verify that accesses to BUFX with an unknown bound are not
303 nowarn_a1_extern_bufx ((struct A1
*) bufx
);
308 /* Verify that accesses to BUFN with a runtime bound are not
311 nowarn_a1_extern_bufx ((struct A1
*) bufn
);
319 /* Exercise a two-element trailing member array. It's treated
320 the same as an interior array member. */
325 int16_t a2
[2]; // { dg-message "while referencing 'a2'" }
328 static void warn_a2_noinit (struct A2
*p
)
330 p
->a2
[0] = 0; p
->a2
[1] = 1;
332 p
->a2
[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
335 static void warn_a2_init (struct A2
*p
)
337 p
->a2
[0] = 0; p
->a2
[1] = 1;
339 p
->a2
[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
340 p
->a2
[9] = 9; // { dg-warning "\\\[-Warray-bounds" }
343 static void warn_a2_ref (struct A2
*p
)
345 p
->a2
[0] = 0; p
->a2
[1] = 1;
347 p
->a2
[2] = 2; // { dg-warning "\\\[-Warray-bounds" }
348 p
->a2
[9] = 9; // { dg-warning "\\\[-Warray-bounds" }
351 void test_a2 (struct A2
*p
)
355 warn_a2_noinit (&a2
);
360 struct A2 a2
= { 0, { 1, 2 } };