1 /* { dg-do compile } */
2 /* { dg-options "-std=c99 -Wformat -Wformat-length=1 -ftrack-macro-expansion=0" } */
3 /* { dg-require-effective-target int32plus } */
5 /* When debugging, define LINE to the line number of the test case to exercise
6 and avoid exercising any of the others. The buffer and objsize macros
7 below make use of LINE to avoid warnings for other lines. */
12 #define INT_MAX __INT_MAX__
17 /* Evaluate to an array of SIZE characters when non-negative and LINE
18 is not set or set to the line the macro is on, or to a pointer to
19 an unknown object otherwise. */
20 #define buffer(size) \
21 (0 <= size && (!LINE || __LINE__ == LINE) \
22 ? buffer + sizeof buffer - size : ptr)
24 /* Evaluate to SIZE when non-negative and LINE is not set or set to
25 the line the macro is on, or to SIZE_MAX otherise. */
26 #define objsize(size) \
27 (0 <= size && (!LINE || __LINE__ == LINE) \
28 ? size : __SIZE_MAX__)
30 typedef __SIZE_TYPE__
size_t;
33 typedef __WCHAR_TYPE__
wchar_t;
36 typedef __WINT_TYPE__
wint_t;
38 typedef unsigned char UChar
;
40 /* Constants used to verify the pass can determine their values even
41 without optimization. */
46 /* Initialized global variables used to verify that the pass doesn't
47 use their initial values (they could be modified by calls to other
53 const char s1
[] = "1";
54 const char s2
[] = "12";
55 const char s3
[] = "123";
56 const char s4
[] = "1234";
57 const char s5
[] = "12345";
58 const char s6
[] = "123456";
59 const char s7
[] = "1234567";
60 const char s8
[] = "12345678";
62 void sink (void*, ...);
64 /* Macro to verify that calls to __builtin_sprintf (i.e., with no size
65 argument) issue diagnostics by correctly determining the size of
66 the destination buffer. */
67 #define T(size, fmt, ...) \
68 __builtin_sprintf (buffer (size), fmt, __VA_ARGS__), \
71 /* Exercise the "%c" and "%lc" directive with constant arguments. */
73 void test_sprintf_c_const (void)
75 T (-1, "%c", 0); /* No warning for unknown destination size. */
76 T ( 0, "%c", 0); /* { dg-warning ".%c. directive writing 1 byte into a region of size 0" } */
77 T ( 1, "%c", 0); /* { dg-warning "writing a terminating nul past the end" } */
78 T ( 1, "%c", '1'); /* { dg-warning "nul past the end" } */
80 T ( 2, "%2c", '1'); /* { dg-warning "nul past the end" } */
81 T ( 2, "%3c", '1'); /* { dg-warning "into a region" } */
82 T ( 2, "%c%c", '1', '2'); /* { dg-warning "nul past the end" } */
83 T ( 3, "%c%c", '1', '2');
85 T ( 2, "%1$c%2$c", '1', '2'); /* { dg-warning "does not support %n.|nul past the end" } */
86 T ( 3, "%1$c%2$c", '1', '2');
88 /* Verify that a warning is issued for exceeding INT_MAX bytes and
90 T (-1, "%*c", INT_MAX
- 1, '1');
91 T (-1, "%*c", INT_MAX
, '1');
92 T (-1, "X%*c", INT_MAX
- 1, '1');
93 T (-1, "X%*c", INT_MAX
, '1'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
95 T (-1, "%*c%*c", INT_MAX
- 1, '1', INT_MAX
- 1, '2'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
97 T (-1, "%*cX", INT_MAX
- 2, '1');
98 T (-1, "%*cX", INT_MAX
- 1, '1');
99 T (-1, "%*cX", INT_MAX
, '1'); /* { dg-warning "output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
102 /* Verify that no warning is issued for calls that write into a flexible
103 array member whose size isn't known. Also verify that calls that use
104 a flexible array member as an argument to the "%s" directive do not
107 void test_sprintf_flexarray (void *p
, int i
)
115 __builtin_sprintf (s
->a
, "%c", 'x');
117 __builtin_sprintf (s
->a
, "%s", "");
118 __builtin_sprintf (s
->a
, "%s", "abc");
119 __builtin_sprintf (s
->a
, "abc%sghi", "def");
121 __builtin_sprintf (s
->a
, "%i", 1234);
123 __builtin_sprintf (buffer (1), "%s", s
->a
);
124 __builtin_sprintf (buffer (1), "%s", s
[i
].a
);
127 /* Same as above but for zero-length arrays. */
129 void test_sprintf_zero_length_array (void *p
, int i
)
137 __builtin_sprintf (s
->a
, "%c", 'x');
139 __builtin_sprintf (s
->a
, "%s", "");
140 __builtin_sprintf (s
->a
, "%s", "abc");
141 __builtin_sprintf (s
->a
, "abc%sghi", "def");
143 __builtin_sprintf (s
->a
, "%i", 1234);
145 __builtin_sprintf (buffer (1), "%s", s
->a
);
146 __builtin_sprintf (buffer (1), "%s", s
[i
].a
);
150 #define T(size, fmt, ...) \
151 __builtin___sprintf_chk (buffer (size), 0, objsize (size), fmt, \
152 __VA_ARGS__), sink (buffer, ptr)
154 /* Exercise the "%c" and "%lc" directive with constant arguments. */
156 void test_sprintf_chk_c_const (void)
158 T (-1, "%c", 0); /* No warning for unknown destination size. */
159 /* Verify the full text of the diagnostic for just the distinct messages
160 and use abbreviations in subsequent test cases. */
161 T (0, "%c", 0); /* { dg-warning ".%c. directive writing 1 byte into a region of size 0" } */
162 T (1, "%c", 0); /* { dg-warning "writing a terminating nul past the end" } */
163 T (1, "%c", '1'); /* { dg-warning "nul past the end" } */
165 T (2, "%2c", '1'); /* { dg-warning "nul past the end" } */
166 T (2, "%3c", '1'); /* { dg-warning "into a region" } */
167 T (2, "%c%c", '1', '2'); /* { dg-warning "nul past the end" } */
168 T (3, "%c%c", '1', '2');
170 /* Wide characters. */
171 T (0, "%lc", (wint_t)0); /* { dg-warning "nul past the end" } */
172 T (1, "%lc", (wint_t)0);
173 T (1, "%lc%lc", (wint_t)0, (wint_t)0);
174 T (2, "%lc", (wint_t)0);
175 T (2, "%lc%lc", (wint_t)0, (wint_t)0);
177 /* The following could result in as few as no bytes and in as many as
178 MB_CUR_MAX, but since the MB_CUR_MAX value is a runtime property
179 the write cannot be reliably diagnosed. */
180 T (2, "%lc", (wint_t)L
'1');
181 T (2, "%1lc", (wint_t)L
'1');
182 /* Writing some unknown number of bytes into a field two characters wide. */
183 T (2, "%2lc", (wint_t)L
'1'); /* { dg-warning "nul past the end" } */
185 T (3, "%lc%c", (wint_t)L
'1', '2');
186 /* Here in the best case each argument will format as single character,
187 causing the terminating NUL to be written past the end. */
188 T (3, "%lc%c%c", (wint_t)L
'1', '2', '3'); /* { dg-warning "nul past the end" } */
189 T (3, "%lc%lc%c", (wint_t)L
'1', (wint_t)L
'2', '3'); /* { dg-warning "nul past the end" } */
192 /* Exercise the "%s" and "%ls" directive with constant arguments. */
194 void test_sprintf_chk_s_const (void)
196 T (-1, "%*s", 0, ""); /* No warning for unknown destination size. */
197 T ( 0, "%*s", 0, ""); /* { dg-warning "nul past the end" } */
198 T ( 0, "%-s", ""); /* { dg-warning "nul past the end" } */
199 T ( 0, "%*s", 0, s0
); /* { dg-warning "nul past the end" } */
200 T ( 1, "%*s", 0, "");
201 T ( 1, "%*s", 0, s0
);
202 T ( 1, "%*s", 0, "\0");
203 T ( 1, "%*s", 0, "1"); /* { dg-warning "nul past the end" } */
204 T ( 1, "%*s", 0, s1
); /* { dg-warning "nul past the end" } */
205 T ( 1, "%1s", ""); /* { dg-warning "nul past the end" } */
206 T ( 1, "%1s", s0
); /* { dg-warning "nul past the end" } */
207 T (-1, "%1s", "1"); /* No warning for unknown destination size. */
208 T ( 1, "%*s", 1, ""); /* { dg-warning "nul past the end" } */
209 T ( 1, "%*s", 1, s0
); /* { dg-warning "nul past the end" } */
210 T (-1, "%*s", 1, s0
); /* No warning for unknown destination size. */
214 T (1, "%.0s", "123");
216 T (1, "%.*s", 0, "123");
217 T (1, "%.*s", 0, s3
);
218 T (1, "%.1s", "123"); /* { dg-warning "nul past the end" } */
219 T (1, "%.1s", s3
); /* { dg-warning "nul past the end" } */
220 T (1, "%.*s", 1, "123"); /* { dg-warning "nul past the end" } */
221 T (1, "%.*s", 1, s3
); /* { dg-warning "nul past the end" } */
223 T (2, "%.*s", 0, "");
224 T (2, "%.*s", 0, "1");
225 T (2, "%.*s", 0, s1
);
226 T (2, "%.*s", 0, "1\0");
227 T (2, "%.*s", 0, "12");
228 T (2, "%.*s", 0, s2
);
230 T (2, "%.*s", 1, "");
231 T (2, "%.*s", 1, "1");
232 T (2, "%.*s", 1, s1
);
233 T (2, "%.*s", 1, "1\0");
234 T (2, "%.*s", 1, "12");
235 T (2, "%.*s", 1, s2
);
237 T (2, "%.*s", 2, "");
238 T (2, "%.*s", 2, "1");
239 T (2, "%.*s", 2, s1
);
240 T (2, "%.*s", 2, "1\0");
241 T (2, "%.*s", 2, "12"); /* { dg-warning "nul past the end" } */
242 T (2, "%.*s", 2, s2
); /* { dg-warning "nul past the end" } */
244 T (2, "%.*s", 3, "");
245 T (2, "%.*s", 3, "1");
246 T (2, "%.*s", 3, s1
);
247 T (2, "%.*s", 3, "1\0");
248 T (2, "%.*s", 3, "12"); /* { dg-warning "nul past the end" } */
249 T (2, "%.*s", 3, "123"); /* { dg-warning "into a region" } */
250 T (2, "%.*s", 3, s2
); /* { dg-warning "nul past the end" } */
251 T (2, "%.*s", 3, s3
); /* { dg-warning "into a region" } */
254 T (2, "%*s", 0, "1");
256 T (2, "%*s", 0, "1\0");
257 T (2, "%*s", 0, "12"); /* { dg-warning "nul past the end" } */
258 T (2, "%*s", 0, s2
); /* { dg-warning "nul past the end" } */
260 /* Verify that output in excess of INT_MAX bytes is diagnosed even
261 when the size of the destination object is unknown. */
262 T (-1, "%*s", INT_MAX
- 1, "");
263 T (-1, "%*s", INT_MAX
, "");
264 T (-1, "X%*s", INT_MAX
, ""); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
266 /* Multiple directives. */
268 T (1, "%s%s", "", "");
269 T (1, "%s%s", s0
, s0
);
270 T (1, "%s%s", "", "1"); /* { dg-warning "nul past the end" } */
271 T (1, "%s%s", s0
, s1
); /* { dg-warning "nul past the end" } */
272 T (1, "%s%s", "1", ""); /* { dg-warning "nul past the end" } */
273 T (1, "%s%s", s1
, s0
); /* { dg-warning "nul past the end" } */
274 T (1, "%s%s", "1", "2"); /* { dg-warning "into a region" } */
275 T (1, "%s%s", s1
, s1
); /* { dg-warning "into a region" } */
277 T (2, "%s%s", "", "");
278 T (2, "%s%s", "", "1");
279 T (2, "%s%s", "1", "");
280 T (2, "%s%s", "", "12"); /* { dg-warning "nul past the end" } */
281 T (2, "%s%s", "1", "2"); /* { dg-warning "nul past the end" } */
282 T (2, "%s%s", "12", "2"); /* { dg-warning "into a region" } */
283 T (2, "%s%s", "1", "23"); /* { dg-warning "into a region" } */
284 T (2, "%s%s", "12", "3"); /* { dg-warning "into a region" } */
285 T (2, "%s%s", "12", "34"); /* { dg-warning "into a region" } */
290 T (2, "_%s", "1"); /* { dg-warning "nul past the end" } */
291 T (2, "%%%s", "1"); /* { dg-warning "nul past the end" } */
292 T (2, "%s%%", "1"); /* { dg-warning "nul past the end" } */
293 T (2, "_%s", "12"); /* { dg-warning "into a region" } */
294 T (2, "__%s", "1"); /* { dg-warning "into a region" } */
296 T (2, "%1$s%2$s", "12", "3"); /* { dg-warning ".%2.s. directive writing 1 byte into a region of size 0" } */
297 T (2, "%1$s%1$s", "12"); /* { dg-warning "does not support|.%1.s. directive writing 2 bytes into a region of size 0" } */
298 T (2, "%2$s%1$s", "1", "23"); /* { dg-warning ".%1.s. directive writing 1 byte into a region of size 0" } */
299 T (2, "%2$s%2$s", "1", "23"); /* { dg-warning "unused|%2.s. directive writing 2 bytes into a region of size 0" } */
302 T (3, "__%s", "1"); /* { dg-warning "nul past the end" } */
303 T (3, "%s_%s", "", "");
304 T (3, "%s_%s", "1", "");
305 T (3, "%s_%s", "", "1");
306 T (3, "%s_%s", "1", "2"); /* { dg-warning "nul past the end" } */
310 T ( 0, "%ls", L
""); /* { dg-warning "nul past the end" } */
312 T ( 1, "%ls", L
"\0");
313 T ( 1, "%1ls", L
""); /* { dg-warning "nul past the end" } */
315 T (0, "%*ls", 0, L
""); /* { dg-warning "nul past the end" } */
316 T (1, "%*ls", 0, L
"");
317 T (1, "%*ls", 0, L
"\0");
318 T (1, "%*ls", 1, L
""); /* { dg-warning "nul past the end" } */
320 T (1, "%ls", L
"1"); /* { dg-warning "nul past the end" } */
321 T (1, "%.0ls", L
"1");
322 T (2, "%.0ls", L
"1");
323 T (2, "%.1ls", L
"1");
324 T (2, "%.*ls", 1, L
"1");
326 /* The "%.2ls" directive below will write at a minimum 1 byte (because
327 L"1" is known and can be assumed to convert to at least one multibyte
328 character), and at most 2 bytes because of the precision. Since its
329 output is explicitly bounded it is diagnosed. */
330 T (2, "%.2ls", L
"1"); /* { dg-warning "nul past the end" } */
331 T (2, "%.*ls", 2, L
"1"); /* { dg-warning "nul past the end" } */
333 T (3, "%.0ls", L
"1");
334 T (3, "%.1ls", L
"1");
335 T (3, "%.2ls", L
"1");
338 T (3, "%ls", L
"123"); /* { dg-warning "nul past the end" } */
339 T (3, "%.0ls", L
"123");
340 T (3, "%.1ls", L
"123");
341 T (3, "%.2ls", L
"123");
342 T (3, "%.3ls", L
"123"); /* { dg-warning "nul past the end" } */
345 /* Exercise the "%hhd", "%hhi", "%hho", "%hhu", and "%hhx" directives
346 with constant arguments. */
348 void test_sprintf_chk_hh_const (void)
352 T (1, "%hhd", 0); /* { dg-warning "nul past the end" } */
353 T (1, "%hhd", cst0
); /* { dg-warning "nul past the end" } */
354 T (1, "%hhd", 1); /* { dg-warning "nul past the end" } */
355 T (1, "%hhd", cst1
); /* { dg-warning "nul past the end" } */
356 T (1, "%hhd", -1); /* { dg-warning "into a region" } */
357 T (1, "%+hhd", 0); /* { dg-warning "into a region" } */
358 T (1, "%+hhd", 1); /* { dg-warning "into a region" } */
359 T (1, "%-hhd", 0); /* { dg-warning "nul past the end" } */
361 T (1, "%hhi", 0); /* { dg-warning "nul past the end" } */
362 T (1, "%hhi", 1); /* { dg-warning "nul past the end" } */
363 T (1, "%hhi", -1); /* { dg-warning "into a region" } */
364 T (1, "%+hhi", 0); /* { dg-warning "into a region" } */
365 T (1, "%+hhi", 1); /* { dg-warning "into a region" } */
366 T (1, "%-hhi", 0); /* { dg-warning "nul past the end" } */
371 T (2, "% hhi", 9); /* { dg-warning "nul past the end" } */
372 T (2, "%+hhi", 9); /* { dg-warning "nul past the end" } */
374 T (2, "%hhi", 10); /* { dg-warning "nul past the end" } */
375 T (2, "%hhi", cst10
); /* { dg-warning "nul past the end" } */
376 T (2, "%hhi", -1); /* { dg-warning "nul past the end" } */
377 T (2, "% hhi", -1); /* { dg-warning "nul past the end" } */
378 T (2, "%+hhi", -1); /* { dg-warning "nul past the end" } */
379 T (2, "%-hhi", -1); /* { dg-warning "nul past the end" } */
384 T (2, "%hho", 010); /* { dg-warning "nul past the end" } */
385 T (2, "%hho", 077); /* { dg-warning "nul past the end" } */
386 T (2, "%hho", -1); /* { dg-warning "into a region" } */
392 T (2, "%hhx", -1); /* { dg-warning "nul past the end" } */
394 T (2, "%hhx", 0x10); /* { dg-warning "nul past the end" } */
395 T (2, "%hhX", 0xff); /* { dg-warning "nul past the end" } */
397 T (1, "%#hhx", 0); /* { dg-warning "nul past the end" } */
399 T (3, "%#hhx", 1); /* { dg-warning "nul past the end" } */
403 T (4, "%hhd", 0xfff);
404 T (4, "%hhd", 0xffff);
408 T (4, "%hhi", 0xfff);
409 T (4, "%hhi", 0xffff);
414 T (4, "%hhu", 0xfff);
415 T (4, "%hhu", 0xffff);
419 T (4, "%#hhx", -1); /* { dg-warning "nul past the end" } */
421 T (4, "%#hhx", 0x10); /* { dg-warning "nul past the end" } */
422 T (4, "%#hhx", 0xff); /* { dg-warning "nul past the end" } */
423 T (4, "%#hhx", 0xfff); /* { dg-warning "nul past the end" } */
425 T (4, "%hhi %hhi", 0, 0);
426 T (4, "%hhi %hhi", 9, 9);
427 T (4, "%hhi %hhi", 1, 10); /* { dg-warning "nul past the end" } */
428 T (4, "%hhi %hhi", 10, 1); /* { dg-warning "nul past the end" } */
429 T (4, "%hhi %hhi", 11, 12); /* { dg-warning "into a region" } */
431 /* As a special case, a precision of zero with an argument of zero
432 results in zero bytes (unless modified by width). */
437 T (1, "%0.0hhd", 0); /* { dg-warning ".0. flag ignored with precision" } */
438 T (1, "%00.0hhd", 0); /* { dg-warning "repeated .0. flag in format" } */
439 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
440 T (1, "%-0.0hhd", 0); /* { dg-warning ".0. flag ignored with .-. flag" } */
441 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
449 T (5, "%0*hhd %0*hhi", 0, 7, 0, 9);
450 T (5, "%0*hhd %0*hhi", 1, 7, 1, 9);
451 T (5, "%0*hhd %0*hhi", 1, 7, 2, 9);
452 T (5, "%0*hhd %0*hhi", 2, 7, 1, 9);
453 T (5, "%0*hhd %0*hhi", 2, 7, 2, 9); /* { dg-warning "nul past the end" } */
454 T (5, "%0*hhd %0*hhi", 0, 12, 0, 123); /* { dg-warning ".%0\\*hhi. directive writing 3 bytes into a region of size 2" } */
455 T (5, "%0*hhd %0*hhi", 1, 12, 1, 123); /* { dg-warning ".%0\\*hhi. directive writing 3 bytes into a region of size 2" } */
456 T (5, "%0*hhd %0*hhi", 2, 12, 3, 123); /* { dg-warning ".%0\\*hhi. directive writing 3 bytes into a region of size 2" } */
458 /* FIXME: Move the boundary test cases into a file of their own that's
459 exercised only on targets with the matching type limits (otherwise
465 #define MIN (-MAX -1)
467 T (1, "%hhi", MAX
); /* { dg-warning "into a region" } */
468 T (1, "%hhi", MIN
); /* { dg-warning "into a region" } */
469 T (1, "%hhi", MAX
+ 1); /* { dg-warning "into a region" } */
471 T (2, "%hhi", MAX
+ 1); /* { dg-warning "into a region" } */
472 T (2, "%hhi", MAX
+ 10); /* { dg-warning "into a region" } */
473 T (2, "%hhi", MAX
+ 100); /* { dg-warning "into a region" } */
476 /* Exercise the "%hhd", "%hi", "%ho", "%hu", and "%hx" directives
477 with constant arguments. */
479 void test_sprintf_chk_h_const (void)
481 T (1, "%hu", 0); /* { dg-warning "nul past the end" } */
482 T (1, "%hu", 1); /* { dg-warning "nul past the end" } */
483 T (1, "%hu", -1); /* { dg-warning "into a region" } */
488 T (2, "% hi", 9); /* { dg-warning "nul past the end" } */
489 T (2, "%+hi", 9); /* { dg-warning "nul past the end" } */
491 T (2, "%hi", 10); /* { dg-warning "nul past the end" } */
492 T (2, "%hi", -1); /* { dg-warning "nul past the end" } */
493 T (2, "% hi", -2); /* { dg-warning "nul past the end" } */
494 T (2, "%+hi", -3); /* { dg-warning "nul past the end" } */
495 T (2, "%-hi", -4); /* { dg-warning "nul past the end" } */
500 T (2, "%hu", 10); /* { dg-warning "nul past the end" } */
501 T (2, "%hu", -1); /* { dg-warning "into a region" } */
506 T (2, "%ho", 010); /* { dg-warning "nul past the end" } */
507 T (2, "%ho", 077); /* { dg-warning "nul past the end" } */
508 T (2, "%ho", 0100); /* { dg-warning "into a region" } */
509 T (2, "%ho", -1); /* { dg-warning "into a region" } */
515 T (2, "%hx", 0x10); /* { dg-warning "nul past the end" } */
516 T (2, "%hx", 0xff); /* { dg-warning "nul past the end" } */
517 T (2, "%hx", 0x100); /* { dg-warning "into a region" } */
518 T (2, "%hx", -1); /* { dg-warning "into a region" } */
530 T (5, "%hu", 10000); /* { dg-warning "nul past the end" } */
531 T (5, "%hu", 65535); /* { dg-warning "nul past the end" } */
533 T (1, "%#hx", 0); /* { dg-warning "nul past the end" } */
535 T (3, "%#hx", 1); /* { dg-warning "nul past the end" } */
540 T (4, "%#hx", 0x10); /* { dg-warning "nul past the end" } */
541 T (4, "%#hx", 0xff); /* { dg-warning "nul past the end" } */
542 T (4, "%#hx", 0x100); /* { dg-warning "into a region" } */
543 T (4, "%#hx", -1); /* { dg-warning "into a region" } */
545 /* As a special case, a precision of zero with an argument of zero
546 results in zero bytes (unless modified by width). */
551 T (1, "%0.0hd", 0); /* { dg-warning ".0. flag ignored with precision" } */
552 T (1, "%00.0hd", 0); /* { dg-warning "repeated .0. flag in format" } */
553 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
554 T (1, "%-0.0hd", 0); /* { dg-warning ".0. flag ignored with .-. flag" } */
555 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
566 T (1, "%hu", 0); /* { dg-warning "nul past the end" } */
567 T (1, "%hu", 1); /* { dg-warning "nul past the end" } */
568 T (1, "%hu", -1); /* { dg-warning "into a region" } */
569 T (1, "%hu", MAX
); /* { dg-warning "into a region" } */
570 T (1, "%hu", MAX
+ 1); /* { dg-warning "nul past the end" } */
573 /* Exercise the "%d", "%i", "%o", "%u", and "%x" directives with
574 constant arguments. */
576 void test_sprintf_chk_integer_const (void)
578 T ( 1, "%i", 0); /* { dg-warning "nul past the end" } */
579 T ( 1, "%i", 1); /* { dg-warning "nul past the end" } */
580 T ( 1, "%i", -1); /* { dg-warning "into a region" } */
581 T ( 1, "%i_", 1); /* { dg-warning "character ._. at offset 2 past the end" } */
582 T ( 1, "_%i", 1); /* { dg-warning "into a region" } */
583 T ( 1, "_%i_", 1); /* { dg-warning "into a region" } */
584 T ( 1, "%o", 0); /* { dg-warning "nul past the end" } */
585 T ( 1, "%u", 0); /* { dg-warning "nul past the end" } */
586 T ( 1, "%x", 0); /* { dg-warning "nul past the end" } */
587 T ( 1, "%#x", 0); /* { dg-warning "nul past the end" } */
588 T ( 1, "%x", 1); /* { dg-warning "nul past the end" } */
589 T ( 1, "%#x", 1); /* { dg-warning "into a region" } */
594 T ( 2, "%i", -1); /* { dg-warning "nul past the end" } */
595 T ( 2, "%i", 10); /* { dg-warning "nul past the end" } */
596 T ( 2, "%i_", 0); /* { dg-warning "nul past the end" } */
597 T ( 2, "_%i", 0); /* { dg-warning "nul past the end" } */
598 T ( 2, "_%i_", 0); /* { dg-warning "character ._. at offset 3 past the end" } */
601 T ( 2, "%o", 010); /* { dg-warning "nul past the end" } */
602 T ( 2, "%o", 0100); /* { dg-warning "into a region" } */
604 T ( 2, "%#x", 1); /* { dg-warning "into a region" } */
607 T ( 2, "%x", 0x10); /* { dg-warning "nul past the end" } */
608 T ( 2, "%x", 0xff); /* { dg-warning "nul past the end" } */
609 T ( 2, "%x", 0x1ff); /* { dg-warning "into a region" } */
617 T ( 3, "%i", -99); /* { dg-warning "nul past the end" } */
619 /* ~0U is formatted into exactly three bytes as "-1" followed by
620 the terminating NUL character. */
625 T ( 8, "%8u", 1); /* { dg-warning "nul past the end" } */
628 /* As a special case, a precision of zero with an argument of zero
629 results in zero bytes (unless modified by width). */
634 T (1, "%0.0d", 0); /* { dg-warning ".0. flag ignored with precision" } */
635 T (1, "%00.0d", 0); /* { dg-warning "repeated .0. flag in format" } */
636 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
637 T (1, "%-0.0d", 0); /* { dg-warning ".0. flag ignored with .-. flag" } */
638 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
646 T ( 7, "%1$i%2$i%3$i", 1, 23, 456);
647 T ( 8, "%1$i%2$i%3$i%1$i", 1, 23, 456);
648 T ( 8, "%1$i%2$i%3$i%2$i", 1, 23, 456); /* { dg-warning "nul past the end" } */
649 T ( 8, "%1$i%2$i%3$i%3$i", 1, 23, 456); /* { dg-warning "into a region" } */
652 #define MAX 2147483647 /* 10 digits. */
654 #define MIN (-MAX -1) /* Sign plus 10 digits. */
656 T ( 1, "%i", MAX
); /* { dg-warning "into a region" } */
657 T ( 1, "%i", MIN
); /* { dg-warning "into a region" } */
658 T ( 2, "%i", MAX
); /* { dg-warning "into a region" } */
659 T ( 2, "%i", MIN
); /* { dg-warning "into a region" } */
660 T (10, "%i", 123456789);
661 T (10, "%i", -123456789); /* { dg-warning "nul past the end" } */
662 T (10, "%i", MAX
); /* { dg-warning "nul past the end" } */
663 T (10, "%i", MIN
); /* { dg-warning "into a region" } */
666 T (11, "%i", MIN
); /* { dg-warning "nul past the end" } */
669 /* Exercise the "%jd", "%ji", "%jo", "%ju", and "%jx" directives
670 for the formatting of intmax_t and uintmax_t values with constant
673 void test_sprintf_chk_j_const (void)
675 #define I(x) ((__INTMAX_TYPE__)x)
677 T ( 1, "%ji", I ( 0)); /* { dg-warning "nul past the end" } */
678 T ( 1, "%ji", I ( 1)); /* { dg-warning "nul past the end" } */
679 T ( 1, "%ji", I ( -1)); /* { dg-warning "into a region" } */
680 T ( 1, "%ji_", I ( 1)); /* { dg-warning "character ._. at offset 3 past the end" } */
681 T ( 1, "_%ji", I ( 1)); /* { dg-warning "into a region" } */
682 T ( 1, "_%ji_",I ( 1)); /* { dg-warning "into a region" } */
683 T ( 1, "%jo", I ( 0)); /* { dg-warning "nul past the end" } */
684 T ( 1, "%ju", I ( 0)); /* { dg-warning "nul past the end" } */
685 T ( 1, "%jx", I ( 0)); /* { dg-warning "nul past the end" } */
686 T ( 1, "%#jx", I ( 0)); /* { dg-warning "nul past the end" } */
687 T ( 1, "%jx", I ( 1)); /* { dg-warning "nul past the end" } */
688 T ( 1, "%#jx", I ( 1)); /* { dg-warning "into a region" } */
690 T ( 2, "%ji", I ( 0));
691 T ( 2, "%ji", I ( 1));
692 T ( 2, "%ji", I ( 9));
693 T ( 2, "%ji", I ( -1)); /* { dg-warning "nul past the end" } */
694 T ( 2, "%ji", I ( 10)); /* { dg-warning "nul past the end" } */
695 T ( 2, "%ji_", I ( 0)); /* { dg-warning "nul past the end" } */
696 T ( 2, "_%ji", I ( 0)); /* { dg-warning "nul past the end" } */
697 T ( 2, "_%ji_",I ( 0)); /* { dg-warning "character ._. at offset 4 past the end" } */
698 T ( 2, "%jo", I ( 1));
699 T ( 2, "%jo", I ( 7));
700 T ( 2, "%jo", I ( 010)); /* { dg-warning "nul past the end" } */
701 T ( 2, "%jo", I ( 0100)); /* { dg-warning "into a region" } */
702 T ( 2, "%jx", I ( 1));
703 T ( 2, "%#jx", I ( 1)); /* { dg-warning "into a region" } */
704 T ( 2, "%jx", I ( 0xa));
705 T ( 2, "%jx", I ( 0xf));
706 T ( 2, "%jx", I ( 0x10)); /* { dg-warning "nul past the end" } */
707 T ( 2, "%jx", I ( 0xff)); /* { dg-warning "nul past the end" } */
708 T ( 2, "%jx", I (0x1ff)); /* { dg-warning "into a region" } */
710 T ( 3, "%ji", I ( 0));
711 T ( 3, "%ji", I ( 1));
712 T ( 3, "%ji", I ( 9));
713 T ( 3, "%ji", I ( -9));
714 T ( 3, "%ji", I ( 10));
715 T ( 3, "%ji", I ( 99));
716 T ( 3, "%ji", I ( -99)); /* { dg-warning "nul past the end" } */
718 /* ~0 is formatted into exactly three bytes as "-1" followed by
719 the terminating NUL character. */
720 T ( 3, "%+ji", ~I (0));
721 T ( 3, "%-ji", ~I (0));
722 T ( 3, "% ji", ~I (0));
724 T ( 8, "%8ju", I (1)); /* { dg-warning "nul past the end" } */
725 T ( 9, "%8ju", I (1));
727 /* As a special case, a precision of zero with an argument of zero
728 results in zero bytes (unless modified by width). */
729 T (1, "%.0jd", I (0));
730 T (1, "%+.0jd", I (0));
731 T (1, "%-.0jd", I (0));
732 T (1, "% .0jd", I (0));
733 T (1, "%0.0jd", I (0)); /* { dg-warning ".0. flag ignored with precision" } */
734 T (1, "%00.0jd", I (0)); /* { dg-warning "repeated .0. flag in format" } */
735 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
736 T (1, "%-0.0jd", I (0)); /* { dg-warning ".0. flag ignored with .-. flag" } */
737 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
738 T (1, "%.0ji", I (0));
739 T (1, "%.0jo", I (0));
740 T (1, "%#.0jo", I (0));
741 T (1, "%.0jx", I (0));
742 T (1, "%.0jX", I (0));
743 T (1, "%#.0jX", I (0));
746 /* Exercise the "%ld", "%li", "%lo", "%lu", and "%lx" directives
747 with constant arguments. */
749 void test_sprintf_chk_l_const (void)
751 T ( 1, "%li", 0L); /* { dg-warning "nul past the end" } */
752 T ( 1, "%li", 1L); /* { dg-warning "nul past the end" } */
753 T ( 1, "%li", -1L); /* { dg-warning "into a region" } */
754 T ( 1, "%li_", 1L); /* { dg-warning "character ._. at offset 3 past the end" } */
755 T ( 1, "_%li", 1L); /* { dg-warning "into a region" } */
756 T ( 1, "_%li_", 1L); /* { dg-warning "into a region" } */
757 T ( 1, "%lo", 0L); /* { dg-warning "nul past the end" } */
758 T ( 1, "%lu", 0L); /* { dg-warning "nul past the end" } */
759 T ( 1, "%lx", 0L); /* { dg-warning "nul past the end" } */
760 T ( 1, "%#lx", 0L); /* { dg-warning "nul past the end" } */
761 T ( 1, "%lx", 1L); /* { dg-warning "nul past the end" } */
762 T ( 1, "%#lx", 1L); /* { dg-warning "into a region" } */
767 T ( 2, "%li", -1L); /* { dg-warning "nul past the end" } */
768 T ( 2, "%li", 10L); /* { dg-warning "nul past the end" } */
769 T ( 2, "%li_", 0L); /* { dg-warning "nul past the end" } */
770 T ( 2, "_%li", 0L); /* { dg-warning "nul past the end" } */
771 T ( 2, "_%li_", 0L); /* { dg-warning "character ._. at offset 4 past the end" } */
774 T ( 2, "%lo", 010L); /* { dg-warning "nul past the end" } */
775 T ( 2, "%lo", 0100L); /* { dg-warning "into a region" } */
777 T ( 2, "%#lx", 1L); /* { dg-warning "into a region" } */
780 T ( 2, "%lx", 0x10L
); /* { dg-warning "nul past the end" } */
781 T ( 2, "%lx", 0xffL
); /* { dg-warning "nul past the end" } */
782 T ( 2, "%lx", 0x1ffL
); /* { dg-warning "into a region" } */
790 T ( 3, "%li", -99L); /* { dg-warning "nul past the end" } */
792 /* ~0U is formatted into exactly three bytes as "-1" followed by
793 the terminating NUL character. */
794 T ( 3, "%+li", ~0LU);
795 T ( 3, "%-li", ~0LU);
796 T ( 3, "% li", ~0LU);
798 T ( 8, "%8lu", 1L); /* { dg-warning "nul past the end" } */
801 /* As a special case, a precision of zero with an argument of zero
802 results in zero bytes (unless modified by width). */
807 T (1, "%0.0ld", 0L); /* { dg-warning ".0. flag ignored with precision" } */
808 T (1, "%00.0ld", 0L); /* { dg-warning "repeated .0. flag in format" } */
809 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
810 T (1, "%-0.0ld", 0L); /* { dg-warning ".0. flag ignored with .-. flag" } */
811 /* { dg-warning ".0. flag ignored with precision" "" { target *-*-* } .-1 } */
820 /* Exercise the "%lld", "%lli", "%llo", "%llu", and "%llx" directives
821 with constant arguments. */
823 void test_sprintf_chk_ll_const (void)
825 T ( 1, "%lli", 0LL); /* { dg-warning "nul past the end" } */
826 T ( 1, "%lli", 1LL); /* { dg-warning "nul past the end" } */
827 T ( 1, "%lli", -1LL); /* { dg-warning "into a region" } */
828 T ( 1, "%lli_", 1LL); /* { dg-warning "character ._. at offset 4 past the end" } */
829 T ( 1, "_%lli", 1LL); /* { dg-warning "into a region" } */
830 T ( 1, "_%lli_", 1LL); /* { dg-warning "into a region" } */
831 T ( 1, "%llo", 0LL); /* { dg-warning "nul past the end" } */
832 T ( 1, "%llu", 0LL); /* { dg-warning "nul past the end" } */
833 T ( 1, "%llx", 0LL); /* { dg-warning "nul past the end" } */
834 T ( 1, "%#llx", 0LL); /* { dg-warning "nul past the end" } */
835 T ( 1, "%llx", 1LL); /* { dg-warning "nul past the end" } */
836 T ( 1, "%#llx", 1LL); /* { dg-warning "into a region" } */
841 T ( 2, "%lli", -1LL); /* { dg-warning "nul past the end" } */
842 T ( 2, "%lli", 10LL); /* { dg-warning "nul past the end" } */
843 T ( 2, "%lli_", 0LL); /* { dg-warning "nul past the end" } */
844 T ( 2, "_%lli", 0LL); /* { dg-warning "nul past the end" } */
845 T ( 2, "_%lli_", 0LL); /* { dg-warning "character ._. at offset 5 past the end" } */
848 T ( 2, "%llo", 010LL); /* { dg-warning "nul past the end" } */
849 T ( 2, "%llo", 0100LL); /* { dg-warning "into a region" } */
851 T ( 2, "%#llx", 1LL); /* { dg-warning "into a region" } */
852 T ( 2, "%llx", 0xaLL
);
853 T ( 2, "%llx", 0xfLL
);
854 T ( 2, "%llx", 0x10LL
); /* { dg-warning "nul past the end" } */
855 T ( 2, "%llx", 0xffLL
); /* { dg-warning "nul past the end" } */
856 T ( 2, "%llx", 0x1ffLL
); /* { dg-warning "into a region" } */
861 T ( 3, "%lli", -9LL);
862 T ( 3, "%lli", 10LL);
863 T ( 3, "%lli", 99LL);
864 T ( 3, "%lli", -99LL); /* { dg-warning "nul past the end" } */
866 /* ~0U is formatted into exactly three bytes as "-1" followed by
867 the terminating NUL character. */
868 T ( 3, "%+lli", ~0LLU);
869 T ( 3, "%-lli", ~0LLU);
870 T ( 3, "% lli", ~0LLU);
872 T ( 8, "%8llu", 1LL); /* { dg-warning "nul past the end" } */
873 T ( 9, "%8llu", 1LL);
875 /* assume 64-bit long long. */
876 #define LLONG_MAX 9223372036854775807LL /* 19 bytes */
877 #define LLONG_MIN (-LLONG_MAX - 1) /* 20 bytes */
879 T (18, "%lli", LLONG_MIN
); /* { dg-warning "into a region" } */
880 T (19, "%lli", LLONG_MIN
); /* { dg-warning "into a region" } */
881 T (20, "%lli", LLONG_MIN
); /* { dg-warning "nul past the end" } */
882 T (21, "%lli", LLONG_MIN
);
884 T (18, "%lli", LLONG_MAX
); /* { dg-warning "into a region" } */
885 T (19, "%lli", LLONG_MAX
); /* { dg-warning "nul past the end" } */
886 T (20, "%lli", LLONG_MAX
);
888 T (21, "%llo", -1LL); /* { dg-warning "into a region" } */
889 T (22, "%llo", -1LL); /* { dg-warning "nul past the end" } */
890 T (23, "%llo", -1LL);
892 T (19, "%llu", -1LL); /* { dg-warning "into a region" } */
893 T (20, "%llu", -1LL); /* { dg-warning "nul past the end" } */
894 T (21, "%llu", -1LL);
896 T (15, "%llx", -1LL); /* { dg-warning "into a region" } */
897 T (16, "%llx", -1LL); /* { dg-warning "nul past the end" } */
898 T (17, "%llx", -1LL);
901 void test_sprintf_chk_L_const (void)
904 T ( 1, "%Li", 0LL); /* { dg-warning "nul past the end" } */
905 T ( 1, "%Li", 1LL); /* { dg-warning "nul past the end" } */
906 T ( 1, "%Li", -1LL); /* { dg-warning "into a region" } */
907 T ( 1, "%Li_", 1LL); /* { dg-warning "character ._. at offset 3 past the end" } */
908 T ( 1, "_%Li", 1LL); /* { dg-warning "into a region" } */
909 T ( 1, "_%Li_", 1LL); /* { dg-warning "into a region" } */
912 void test_sprintf_chk_z_const (void)
914 T (-1, "%zi", (size_t)0);
915 T ( 1, "%zi", (size_t)0); /* { dg-warning "nul past the end" } */
916 T ( 1, "%zi", (size_t)1); /* { dg-warning "nul past the end" } */
917 T ( 1, "%zi", (size_t)-1L);/* { dg-warning "into a region" } */
918 T ( 1, "%zi_", (size_t)1); /* { dg-warning "character ._. at offset 3 past the end" } */
919 T ( 1, "_%zi", (size_t)1); /* { dg-warning "into a region" } */
920 T ( 1, "_%zi_", (size_t)1); /* { dg-warning "into a region" } */
922 T ( 2, "%zu", (size_t)1);
923 T ( 2, "%zu", (size_t)9);
924 T ( 2, "%zu", (size_t)10); /* { dg-warning "nul past the end" } */
927 void test_sprintf_chk_a_const (void)
933 T (-1, "%123.a", 0.0);
934 T (-1, "%234.la", 0.0);
935 T (-1, "%.345a", 0.0);
936 T (-1, "%456.567la", 0.0);
938 /* The least number of bytes on output is 6 for "0x0p+0". When precision
939 is missing the number of digits after the decimal point isn't fully
940 specified by C (it seems like a defect). */
941 T (0, "%a", 0.0); /* { dg-warning "into a region" } */
942 T (0, "%la", 0.0); /* { dg-warning "into a region" } */
943 T (1, "%a", 0.0); /* { dg-warning "into a region" } */
944 T (2, "%a", 0.0); /* { dg-warning "into a region" } */
945 T (3, "%a", 0.0); /* { dg-warning "into a region" } */
946 T (4, "%a", 0.0); /* { dg-warning "into a region" } */
947 T (5, "%a", 0.0); /* { dg-warning "into a region" } */
948 T (6, "%a", 0.0); /* { dg-warning "writing a terminating nul" } */
951 T (0, "%.a", 0.0); /* { dg-warning "into a region" } */
952 T (0, "%.0a", 0.0); /* { dg-warning "into a region" } */
953 T (0, "%.0la", 0.0); /* { dg-warning "into a region" } */
954 T (1, "%.0a", 0.0); /* { dg-warning "into a region" } */
955 T (2, "%.0a", 0.0); /* { dg-warning "into a region" } */
956 T (3, "%.0a", 0.0); /* { dg-warning "into a region" } */
957 T (4, "%.0a", 0.0); /* { dg-warning "into a region" } */
958 T (5, "%.0a", 0.0); /* { dg-warning "into a region" } */
959 T (6, "%.0a", 0.0); /* { dg-warning "writing a terminating nul" } */
962 T (7, "%7.a", 0.0); /* { dg-warning "writing a terminating nul" } */
963 T (7, "%7.1a", 0.0); /* { dg-warning "writing 8 bytes into a region of size 7" } */
969 void test_sprintf_chk_e_const (void)
975 T (-1, "%123.E", 0.0);
976 T (-1, "%234.lE", 0.0);
977 T (-1, "%.345E", 0.0);
978 T (-1, "%.456lE", 0.0);
980 T ( 0, "%E", 0.0); /* { dg-warning "into a region" } */
981 T ( 0, "%e", 0.0); /* { dg-warning "into a region" } */
982 T ( 1, "%E", 1.0); /* { dg-warning "into a region" } */
983 T ( 1, "%e", 1.0); /* { dg-warning "into a region" } */
984 T ( 2, "%e", 2.0); /* { dg-warning "into a region" } */
985 T ( 3, "%e", 3.0); /* { dg-warning "into a region" } */
986 T (12, "%e", 1.2); /* { dg-warning "nul past the end" } */
987 T (12, "%e", 12.0); /* { dg-warning "nul past the end" } */
988 T (13, "%e", 1.3); /* 1.300000e+00 */
989 T (13, "%E", 13.0); /* 1.300000e+01 */
991 T (13, "%E", 1.4e+99); /* 1.400000e+99 */
992 T (13, "%e", 1.5e+100); /* { dg-warning "nul past the end" } */
993 T (14, "%E", 1.6e+101); /* 1.600000E+101 */
994 T (14, "%e", -1.7e+102); /* { dg-warning "nul past the end" } */
995 T (15, "%E", -1.8e+103); /* -1.800000E+103 */
997 T (16, "%.8e", -1.9e+104); /* { dg-warning "nul past the end" } */
998 T (17, "%.8e", -2.0e+105); /* -2.00000000e+105 */
1000 T ( 5, "%.e", 0.0); /* { dg-warning "nul past the end" } */
1001 T ( 5, "%.0e", 0.0); /* { dg-warning "nul past the end" } */
1002 T ( 5, "%.0e", 1.0); /* { dg-warning "nul past the end" } */
1004 T ( 6, "%.0e", 1.0);
1006 /* The actual output of the following directives depends on the rounding
1007 mode. Verify that the warning correctly reflects that. At level 1,
1008 since the minimum number of bytes output by the directive fits the
1009 space the directive itself isn't diagnosed but the terminating nul
1010 is. The directive is diagnosed at level 2. */
1011 T (12, "%e", 9.999999e+99); /* { dg-warning "terminating nul" } */
1012 T (12, "%e", 9.9999994e+99); /* { dg-warning "terminating nul" } */
1013 T (12, "%e", 9.9999995e+99); /* { dg-warning "terminating nul" } */
1014 T (12, "%e", 9.9999996e+99); /* { dg-warning "terminating nul" } */
1015 T (12, "%e", 9.9999997e+99); /* { dg-warning "terminating nul" } */
1016 T (12, "%e", 9.9999998e+99); /* { dg-warning "terminating nul" } */
1018 T (12, "%Le", 9.9999994e+99L);/* { dg-warning "terminating nul" } */
1019 T (12, "%Le", 9.9999995e+99L);/* { dg-warning "terminating nul" } */
1020 T (12, "%Le", 9.9999996e+99L);/* { dg-warning "terminating nul" } */
1021 T (12, "%Le", 9.9999997e+99L);/* { dg-warning "terminating nul" } */
1022 T (12, "%Le", 9.9999998e+99L);/* { dg-warning "terminating nul" } */
1023 T (12, "%Le", 9.9999999e+99L);/* { dg-warning "terminating nul" } */
1026 /* At -Wformat-length level 1 unknown numbers are assumed to have
1027 the value one, and unknown strings are assumed to have a zero
1030 void test_sprintf_chk_s_nonconst (int w
, int p
, const char *s
)
1033 T ( 0, "%s", s
); /* { dg-warning "nul past the end" } */
1036 T ( 1, "%.1s", s
); /* { dg-warning "nul past the end" } */
1038 /* The string argument is constant but the width and/or precision
1040 T ( 1, "%*s", w
, "");
1041 T ( 1, "%*s", w
, "1"); /* { dg-warning "nul past the end" } */
1042 T ( 1, "%.*s", w
, "");
1043 T ( 1, "%.*s", w
, "1"); /* { dg-warning "may write a terminating nul" } */
1044 T ( 1, "%.*s", w
, "123"); /* { dg-warning "writing between 0 and 3 bytes into a region of size 1" } */
1046 T ( 1, "%*s", w
, "123"); /* { dg-warning "writing 3 or more bytes into a region of size 1" } */
1047 T ( 2, "%*s", w
, "123"); /* { dg-warning "writing 3 or more bytes into a region of size 2" } */
1048 T ( 3, "%*s", w
, "123"); /* { dg-warning "writing a terminating nul past the end" } */
1049 T ( 4, "%*s", w
, "123");
1051 /* The following will definitely write past the end of the buffer,
1052 but since at level 1 the length of an unknown string argument
1053 is assumed to be zero, it will write the terminating nul past
1054 the end (we don't print "past the end" when we're not
1055 sure which we can't be with an unknown string. */
1056 T (1, "%1s", s
); /* { dg-warning "writing a terminating nul past the end" } */
1059 /* Exercise the hh length modifier with all integer specifiers and
1060 a non-constant argument. */
1062 void test_sprintf_chk_hh_nonconst (int w
, int p
, int a
)
1066 T (0, "%hhd", a
); /* { dg-warning ".%hhd. directive writing between 1 and . bytes into a region of size 0" } */
1067 T (0, "%hhi", var0
); /* { dg-warning "into a region" } */
1068 T (0, "%hhi", a
); /* { dg-warning "into a region" } */
1069 T (0, "%hhu", a
); /* { dg-warning "into a region" } */
1070 T (0, "%hhx", a
); /* { dg-warning "into a region" } */
1072 T (1, "%hhd", a
); /* { dg-warning "nul past the end" } */
1073 T (1, "%hhd", var0
); /* { dg-warning "nul past the end" } */
1074 T (1, "%hhi", a
); /* { dg-warning "nul past the end" } */
1075 T (1, "%hhu", a
); /* { dg-warning "nul past the end" } */
1076 T (1, "%hhx", a
); /* { dg-warning "nul past the end" } */
1078 T (1, "% hhd", a
); /* { dg-warning "into a region" } */
1079 T (1, "% hhi", a
); /* { dg-warning "into a region" } */
1080 T (1, "%+hhd", a
); /* { dg-warning "into a region" } */
1081 T (1, "%+hhi", a
); /* { dg-warning "into a region" } */
1082 T (1, "%-hhd", a
); /* { dg-warning "nul past the end" } */
1083 T (1, "%-hhi", a
); /* { dg-warning "nul past the end" } */
1086 T (2, "%hhd", var0
);
1087 T (2, "%hhd", var10
);
1093 T (2, "% hhd", a
); /* { dg-warning "nul past the end" } */
1094 T (2, "% hhd", var0
); /* { dg-warning "nul past the end" } */
1095 T (2, "% hhd", var10
); /* { dg-warning "nul past the end" } */
1096 T (2, "% hhi", a
); /* { dg-warning "nul past the end" } */
1097 T (2, "% hho", a
); /* { dg-warning ". . flag used with .%o." } */
1098 T (2, "% hhu", a
); /* { dg-warning ". . flag used with .%u." } */
1099 T (2, "% hhx", a
); /* { dg-warning ". . flag used with .%x." } */
1101 T (2, "%#hho", a
); /* { dg-warning "nul past the end" } */
1102 T (2, "%#hhx", a
); /* { dg-warning ".%#hhx. directive writing between 3 and . bytes into a region of size 2" } */
1113 T (3, "%3hhd", a
); /* { dg-warning "nul past the end" } */
1114 T (3, "%3hhi", a
); /* { dg-warning "nul past the end" } */
1115 T (3, "%3hho", a
); /* { dg-warning "nul past the end" } */
1116 T (3, "%3hhu", a
); /* { dg-warning "nul past the end" } */
1117 T (3, "%3hhx", a
); /* { dg-warning "nul past the end" } */
1118 T (3, "%3.hhx", a
); /* { dg-warning "nul past the end" } */
1120 T (4, "%5hhd", a
); /* { dg-warning "into a region" } */
1121 T (4, "%6hhi", a
); /* { dg-warning "into a region" } */
1122 T (4, "%7hho", a
); /* { dg-warning "into a region" } */
1123 T (4, "%8hhu", a
); /* { dg-warning "into a region" } */
1124 T (4, "%9hhx", a
); /* { dg-warning "into a region" } */
1135 T (3, "%.3hhd", a
); /* { dg-warning "nul past the end" } */
1136 T (3, "%.3hhi", a
); /* { dg-warning "nul past the end" } */
1137 T (3, "%.3hho", a
); /* { dg-warning "nul past the end" } */
1138 T (3, "%.3hhu", a
); /* { dg-warning "nul past the end" } */
1139 T (3, "%.3hhx", a
); /* { dg-warning "nul past the end" } */
1141 T (4, "%.5hhd", a
); /* { dg-warning "into a region" } */
1142 T (4, "%.6hhi", a
); /* { dg-warning "into a region" } */
1143 T (4, "%.7hho", a
); /* { dg-warning "into a region" } */
1144 T (4, "%.8hhu", a
); /* { dg-warning "into a region" } */
1145 T (4, "%.9hhx", a
); /* { dg-warning "into a region" } */
1147 /* Exercise cases where the type of the actual argument (whose value
1148 and range are unknown) constrain the size of the output and so
1149 can be used to avoid what would otherwise be false positives. */
1151 T (2, "%hhd", (UChar
)a
);
1152 T (2, "%hhi", (UChar
)a
);
1153 T (2, "%-hhi", (UChar
)a
);
1155 /* Exercise cases where the argument is known but width isn't. */
1156 T (0, "%*hhi", w
, 0); /* { dg-warning "into a region" } */
1157 T (1, "%*hhi", w
, 0); /* { dg-warning "nul past the end" } */
1158 T (2, "%*hhi", w
, 0);
1159 T (2, "%*hhi", w
, 12); /* { dg-warning "nul past the end" } */
1160 T (2, "%*hhi", w
, 123); /* { dg-warning "into a region" } */
1162 /* The argument is known but precision isn't. When the argument
1163 is zero only the first call can be diagnosed since a zero
1164 precision would result in no bytes on output. */
1165 T (0, "%.*hhi", p
, 0); /* { dg-warning "nul past the end" } */
1166 T (1, "%.*hhi", p
, 0);
1167 T (2, "%.*hhi", p
, 0);
1168 T (2, "%.*hhi", p
, 12); /* { dg-warning "nul past the end" } */
1169 T (2, "%.*hhi", p
, 123); /* { dg-warning "into a region" } */
1171 /* The argument is known but neither width nor precision is. */
1172 T (0, "%*.*hhi", w
, p
, 0); /* { dg-warning "nul past the end" } */
1173 T (1, "%*.*hhi", w
, p
, 0);
1174 T (2, "%*.*hhi", w
, p
, 0);
1175 T (2, "%*.*hhi", w
, p
, 12); /* { dg-warning "nul past the end" } */
1176 T (2, "%*.*hhi", w
, p
, 123); /* { dg-warning "into a region" } */
1178 /* The argument and width are known but precision isn't. */
1179 T (0, "%1.*hhi", p
, 0); /* { dg-warning "into a region" } */
1180 T (0, "%-1.*hhi", p
, 0); /* { dg-warning "into a region" } */
1181 T (1, "%1.*hhi", p
, 0); /* { dg-warning "nul past the end" } */
1182 T (2, "%1.*hhi", p
, 0);
1183 T (2, "%2.*hhi", p
, 0); /* { dg-warning "nul past the end" } */
1184 T (2, "%1.*hhi", p
, 12); /* { dg-warning "nul past the end" } */
1185 T (2, "%2.*hhi", p
, 12); /* { dg-warning "nul past the end" } */
1187 T (2, "%1.*hhi", p
, 123); /* { dg-warning "into a region" } */
1188 T (2, "%2.*hhi", p
, 123); /* { dg-warning "into a region" } */
1189 T (2, "%3.*hhi", p
, 123); /* { dg-warning "into a region" } */
1191 /* The argument and precision are known but width isn't. */
1192 T (0, "%*.1hhi", w
, 0); /* { dg-warning "into a region" } */
1193 T (1, "%*.1hhi", w
, 0); /* { dg-warning "nul past the end" } */
1194 T (2, "%*.1hhi", w
, 0);
1195 T (2, "%*.2hhi", w
, 0); /* { dg-warning "nul past the end" } */
1196 T (2, "%*.1hhi", w
, 12); /* { dg-warning "nul past the end" } */
1197 T (2, "%*.2hhi", w
, 12); /* { dg-warning "nul past the end" } */
1198 T (2, "%*.3hhi", w
, 12); /* { dg-warning "into a region" } */
1200 T (2, "%*.1hhi", w
, 123); /* { dg-warning "into a region" } */
1201 T (2, "%*.2hhi", w
, 123); /* { dg-warning "into a region" } */
1202 T (2, "%*.3hhi", w
, 123); /* { dg-warning "into a region" } */
1205 /* Exercise the h length modifier with all integer specifiers and
1206 a non-constant argument. */
1208 void test_sprintf_chk_h_nonconst (int a
)
1212 T (0, "%hd", a
); /* { dg-warning "into a region" } */
1213 T (0, "%hi", a
); /* { dg-warning "into a region" } */
1214 T (0, "%hu", a
); /* { dg-warning "into a region" } */
1215 T (0, "%hx", a
); /* { dg-warning "into a region" } */
1217 T (1, "%hd", a
); /* { dg-warning "nul past the end" } */
1218 T (1, "%hi", a
); /* { dg-warning "nul past the end" } */
1219 T (1, "%hu", a
); /* { dg-warning "nul past the end" } */
1220 T (1, "%hx", a
); /* { dg-warning "nul past the end" } */
1222 T (1, "% hd", a
); /* { dg-warning "into a region" } */
1223 T (1, "% hi", a
); /* { dg-warning "into a region" } */
1224 T (1, "%+hd", a
); /* { dg-warning "into a region" } */
1225 T (1, "%+hi", a
); /* { dg-warning "into a region" } */
1226 T (1, "%-hd", a
); /* { dg-warning "nul past the end" } */
1227 T (1, "%-hi", a
); /* { dg-warning "nul past the end" } */
1235 T (2, "% hd", a
); /* { dg-warning "nul past the end" } */
1236 T (2, "% hi", a
); /* { dg-warning "nul past the end" } */
1237 T (2, "% ho", a
); /* { dg-warning ". . flag used with .%o." } */
1238 T (2, "% hu", a
); /* { dg-warning ". . flag used with .%u." } */
1239 T (2, "% hx", a
); /* { dg-warning ". . flag used with .%x." } */
1241 T (2, "#%ho", a
); /* { dg-warning "nul past the end" } */
1242 T (2, "#%hx", a
); /* { dg-warning "nul past the end" } */
1251 /* Exercise all integer specifiers with no modifier and a non-constant
1254 void test_sprintf_chk_int_nonconst (int w
, int p
, int a
)
1258 T (0, "%d", a
); /* { dg-warning "into a region" } */
1259 T (0, "%i", a
); /* { dg-warning "into a region" } */
1260 T (0, "%u", a
); /* { dg-warning "into a region" } */
1261 T (0, "%x", a
); /* { dg-warning "into a region" } */
1263 T (1, "%d", a
); /* { dg-warning "nul past the end" } */
1264 T (1, "%i", a
); /* { dg-warning "nul past the end" } */
1265 T (1, "%u", a
); /* { dg-warning "nul past the end" } */
1266 T (1, "%x", a
); /* { dg-warning "nul past the end" } */
1268 T (1, "% d", a
); /* { dg-warning "into a region" } */
1269 T (1, "% i", a
); /* { dg-warning "into a region" } */
1270 T (1, "%+d", a
); /* { dg-warning "into a region" } */
1271 T (1, "%+i", a
); /* { dg-warning "into a region" } */
1272 T (1, "%-d", a
); /* { dg-warning "nul past the end" } */
1273 T (1, "%-i", a
); /* { dg-warning "nul past the end" } */
1281 T (2, "% d", a
); /* { dg-warning "nul past the end" } */
1282 T (2, "% i", a
); /* { dg-warning "nul past the end" } */
1283 T (2, "% o", a
); /* { dg-warning ". . flag used with .%o." } */
1284 T (2, "% u", a
); /* { dg-warning ". . flag used with .%u." } */
1285 T (2, "% x", a
); /* { dg-warning ". . flag used with .%x." } */
1287 T (2, "#%o", a
); /* { dg-warning "nul past the end" } */
1288 T (2, "#%x", a
); /* { dg-warning "nul past the end" } */
1296 T (1, "%.*d", p
, a
);
1299 void test_sprintf_chk_e_nonconst (int w
, int p
, double d
)
1305 T (-1, "%*E", w
, d
);
1306 T (-1, "%*lE", w
, d
);
1307 T (-1, "%.*E", p
, d
);
1308 T (-1, "%.*lE", p
, d
);
1309 T (-1, "%*.*E", w
, p
, d
);
1310 T (-1, "%*.*lE", w
, p
, d
);
1312 T ( 0, "%E", d
); /* { dg-warning "writing between 12 and 14 bytes into a region of size 0" } */
1313 T ( 0, "%e", d
); /* { dg-warning "into a region" } */
1314 T ( 1, "%E", d
); /* { dg-warning "into a region" } */
1315 T ( 1, "%e", d
); /* { dg-warning "into a region" } */
1316 T ( 2, "%e", d
); /* { dg-warning "into a region" } */
1317 T ( 3, "%e", d
); /* { dg-warning "into a region" } */
1318 T (12, "%e", d
); /* { dg-warning "nul past the end" } */
1319 T (13, "%E", d
); /* 1.000000E+00 */
1324 T ( 0, "%+E", d
); /* { dg-warning "writing between 13 and 14 bytes into a region of size 0" } */
1325 T ( 0, "%-e", d
); /* { dg-warning "writing between 12 and 14 bytes into a region of size 0" } */
1326 T ( 0, "% E", d
); /* { dg-warning "writing between 13 and 14 bytes into a region of size 0" } */
1328 /* The range of output of "%.0e" is between 5 and 7 bytes (not counting
1329 the terminating NUL. */
1330 T ( 5, "%.0e", d
); /* { dg-warning "writing a terminating nul past the end" } */
1331 T ( 6, "%.0e", d
); /* 1e+00 */
1333 /* The range of output of "%.1e" is between 7 and 9 bytes (not counting
1334 the terminating NUL. */
1335 T ( 7, "%.1e", d
); /* { dg-warning "writing a terminating nul past the end" } */
1338 T ( 0, "%*e", 0, d
); /* { dg-warning "writing between 12 and 14 bytes into a region of size 0" } */
1339 T ( 0, "%*e", w
, d
); /* { dg-warning "writing 12 or more bytes into a region of size 0" } */
1342 void test_sprintf_chk_f_nonconst (double d
)
1347 T ( 0, "%F", d
); /* { dg-warning "into a region" } */
1348 T ( 0, "%f", d
); /* { dg-warning "into a region" } */
1349 T ( 1, "%F", d
); /* { dg-warning "into a region" } */
1350 T ( 1, "%f", d
); /* { dg-warning "into a region" } */
1351 T ( 2, "%F", d
); /* { dg-warning "into a region" } */
1352 T ( 2, "%f", d
); /* { dg-warning "into a region" } */
1353 T ( 3, "%F", d
); /* { dg-warning "into a region" } */
1354 T ( 3, "%f", d
); /* { dg-warning "into a region" } */
1355 T ( 4, "%F", d
); /* { dg-warning "into a region" } */
1356 T ( 4, "%f", d
); /* { dg-warning "into a region" } */
1357 T ( 5, "%F", d
); /* { dg-warning "into a region" } */
1358 T ( 5, "%f", d
); /* { dg-warning "into a region" } */
1359 T ( 6, "%F", d
); /* { dg-warning "into a region" } */
1360 T ( 6, "%f", d
); /* { dg-warning "into a region" } */
1361 T ( 7, "%F", d
); /* { dg-warning "into a region" } */
1362 T ( 7, "%f", d
); /* { dg-warning "into a region" } */
1363 T ( 8, "%F", d
); /* { dg-warning "nul past the end" } */
1364 T ( 8, "%f", d
); /* { dg-warning "nul past the end" } */
1369 /* Tests for __builtin_vsprintf_chk are the same as those for
1370 __builtin_sprintf_chk with non-constant arguments. */
1372 #define T(size, fmt) \
1373 __builtin___vsprintf_chk (buffer (size), 0, objsize (size), fmt, va)
1375 void test_vsprintf_chk_c (__builtin_va_list va
)
1379 /* Verify the full text of the diagnostic for just the distinct messages
1380 and use abbreviations in subsequent test cases. */
1381 T (0, "%c"); /* { dg-warning ".%c. directive writing 1 byte into a region of size 0" } */
1382 T (1, "%c"); /* { dg-warning "writing a terminating nul past the end" } */
1383 T (1, "%c"); /* { dg-warning "nul past the end" } */
1385 T (2, "%2c"); /* { dg-warning "nul past the end" } */
1386 T (2, "%3c"); /* { dg-warning "into a region" } */
1387 T (2, "%c%c"); /* { dg-warning "nul past the end" } */
1390 /* Wide characters. */
1391 T (0, "%lc"); /* { dg-warning "nul past the end" } */
1395 /* The following could result in as few as a single byte and in as many
1396 as MB_CUR_MAX, but since the MB_CUR_MAX value is a runtime property
1397 the write cannot be reliably diagnosed. */
1400 /* Writing some unknown number of bytes into a field two characters wide. */
1401 T (2, "%2lc"); /* { dg-warning "nul past the end" } */
1405 /* Here in the best case each argument will format as single character,
1406 causing the terminating NUL to be written past the end. */
1410 void test_vsprintf_chk_int (__builtin_va_list va
)
1414 T (0, "%d"); /* { dg-warning "into a region" } */
1415 T (0, "%i"); /* { dg-warning "into a region" } */
1416 T (0, "%u"); /* { dg-warning "into a region" } */
1417 T (0, "%x"); /* { dg-warning "into a region" } */
1419 T (1, "%d"); /* { dg-warning "nul past the end" } */
1420 T (1, "%i"); /* { dg-warning "nul past the end" } */
1421 T (1, "%u"); /* { dg-warning "nul past the end" } */
1422 T (1, "%x"); /* { dg-warning "nul past the end" } */
1424 T (1, "% d"); /* { dg-warning "into a region" } */
1425 T (1, "% i"); /* { dg-warning "into a region" } */
1426 T (1, "%+d"); /* { dg-warning "into a region" } */
1427 T (1, "%+i"); /* { dg-warning "into a region" } */
1428 T (1, "%-d"); /* { dg-warning "nul past the end" } */
1429 T (1, "%-i"); /* { dg-warning "nul past the end" } */
1437 T (2, "% d"); /* { dg-warning "nul past the end" } */
1438 T (2, "% i"); /* { dg-warning "nul past the end" } */
1439 T (2, "% o"); /* { dg-warning ". . flag used with .%o." } */
1440 T (2, "% u"); /* { dg-warning ". . flag used with .%u." } */
1441 T (2, "% x"); /* { dg-warning ". . flag used with .%x." } */
1443 T (2, "#%o"); /* { dg-warning "nul past the end" } */
1444 T (2, "#%x"); /* { dg-warning "nul past the end" } */
1454 #define T(size, fmt, ...) \
1455 __builtin_snprintf (buffer (size), objsize (size), fmt, __VA_ARGS__)
1457 void test_snprintf_c_const (char *d
)
1459 T (-1, "%c", 0); /* { dg-warning "specified destination size \[0-9\]+ is too large" } */
1461 __builtin_snprintf (d
, INT_MAX
, "%c", 0);
1463 /* Verify the full text of the diagnostic for just the distinct messages
1464 and use abbreviations in subsequent test cases. */
1466 /* A call to snprintf with a buffer of zero size is a request to determine
1467 the size of output without writing anything into the destination. No
1468 warning must be issued. */
1470 T (1, "%c", 0); /* { dg-warning "output truncated before the last format character" } */
1471 T (1, "%c", '1'); /* { dg-warning "output truncated" } */
1473 T (2, "%2c", '1'); /* { dg-warning "output truncated" } */
1474 T (2, "%3c", '1'); /* { dg-warning "directive output truncated" } */
1475 T (2, "%c%c", '1', '2'); /* { dg-warning "output truncated" } */
1476 T (3, "%c%c", '1', '2');
1478 /* Wide characters. */
1479 T (0, "%lc", (wint_t)0);
1480 T (1, "%lc", (wint_t)0);
1481 T (2, "%lc", (wint_t)0);
1483 /* The following could result in as few as a single byte and in as many
1484 as MB_CUR_MAX, but since the MB_CUR_MAX value is a runtime property
1485 the write cannot be reliably diagnosed. */
1486 T (2, "%lc", (wint_t)L
'1');
1487 T (2, "%1lc", (wint_t)L
'1');
1488 /* Writing at least 1 characted into a field two characters wide. */
1489 T (2, "%2lc", (wint_t)L
'1'); /* { dg-warning "output truncated before the last format character" } */
1491 T (3, "%lc%c", (wint_t)'1', '2');
1492 /* Here in the best case each argument will format as single character,
1493 causing the output to be truncated just before the terminating NUL
1494 (i.e., cutting off the '3'). */
1495 T (3, "%lc%c%c", (wint_t)'1', '2', '3'); /* { dg-warning "output truncated" } */
1496 T (3, "%lc%lc%c", (wint_t)'1', (wint_t)'2', '3'); /* { dg-warning "output truncated" } */
1500 #define T(size, fmt, ...) \
1501 __builtin___snprintf_chk (buffer (size), objsize (size), \
1502 0, objsize (size), fmt, __VA_ARGS__)
1504 void test_snprintf_chk_c_const (void)
1506 /* Verify that specifying a size of the destination buffer that's
1507 bigger than its actual size (normally determined and passed to
1508 the function by __builtin_object_size) is diagnosed. */
1509 __builtin___snprintf_chk (buffer
, 3, 0, 2, " "); /* { dg-warning "always overflow|specified size 3 exceeds the size 2 of the destination" } */
1511 T (-1, "%c", 0); /* { dg-warning "specified destination size \[^ \]* is too large" } */
1514 T (0, "%c%c", 0, 0);
1515 T (0, "%c_%c", 0, 0);
1516 T (0, "_%c_%c", 0, 0);
1518 T (1, "%c", 0); /* { dg-warning "output truncated before the last format character" } */
1519 T (1, "%c", '1'); /* { dg-warning "output truncated" } */
1521 T (2, "%2c", '1'); /* { dg-warning "output truncated" } */
1522 T (2, "%3c", '1'); /* { dg-warning "directive output truncated" } */
1523 T (2, "%c%c", '1', '2'); /* { dg-warning "output truncated before the last format character" } */
1524 T (3, "%c%c", '1', '2');
1525 T (3, "%c_%c", '1', '2'); /* { dg-warning "output truncated" } */
1527 /* Wide characters. */
1528 T (0, "%lc", (wint_t)0);
1529 T (1, "%lc", (wint_t)0);
1530 T (2, "%lc", (wint_t)0);
1532 /* The following could result in as few as a single byte and in as many
1533 as MB_CUR_MAX, but since the MB_CUR_MAX value is a runtime property
1534 the write cannot be reliably diagnosed. */
1535 T (2, "%lc", (wint_t)L
'1');
1536 T (2, "%1lc", (wint_t)L
'1');
1537 /* Writing at least 1 characted into a field two characters wide. */
1538 T (2, "%2lc", (wint_t)'1'); /* { dg-warning "output truncated before the last format character" } */
1540 T (3, "%lc%c", (wint_t)'1', '2');
1541 /* Here in the best case each argument will format as single character,
1542 causing the output to be truncated just before the terminating NUL
1543 (i.e., cutting off the '3'). */
1544 T (3, "%lc%c%c", (wint_t)'1', '2', '3'); /* { dg-warning "output truncated" } */
1545 T (3, "%lc%lc%c", (wint_t)'1', (wint_t)'2', '3'); /* { dg-warning "output truncated" } */
1548 /* Macro to verify that calls to __builtin_vsprintf (i.e., with no size
1549 argument) issue diagnostics by correctly determining the size of
1550 the destination buffer. */
1552 #define T(size, fmt) \
1553 __builtin_vsprintf (buffer (size), fmt, va)
1555 void test_vsprintf_s (__builtin_va_list va
)
1559 T (0, "%s"); /* { dg-warning "writing a terminating nul past the end" } */
1561 T (1, "%1s"); /* { dg-warning "writing a terminating nul past the end" } */
1567 T (2, "_%s_%s"); /* { dg-warning "writing a terminating nul past the end" } */
1570 /* Exercise all integer specifiers with no modifier and a non-constant
1573 void test_vsprintf_int (__builtin_va_list va
)
1577 T (0, "%d"); /* { dg-warning "into a region" } */
1578 T (0, "%i"); /* { dg-warning "into a region" } */
1579 T (0, "%u"); /* { dg-warning "into a region" } */
1580 T (0, "%x"); /* { dg-warning "into a region" } */
1582 T (1, "%d"); /* { dg-warning "nul past the end" } */
1583 T (1, "%i"); /* { dg-warning "nul past the end" } */
1584 T (1, "%u"); /* { dg-warning "nul past the end" } */
1585 T (1, "%x"); /* { dg-warning "nul past the end" } */
1587 T (1, "% d"); /* { dg-warning "into a region" } */
1588 T (1, "% i"); /* { dg-warning "into a region" } */
1589 T (1, "%+d"); /* { dg-warning "into a region" } */
1590 T (1, "%+i"); /* { dg-warning "into a region" } */
1591 T (1, "%-d"); /* { dg-warning "nul past the end" } */
1592 T (1, "%-i"); /* { dg-warning "nul past the end" } */
1600 T (2, "% d"); /* { dg-warning "nul past the end" } */
1601 T (2, "% i"); /* { dg-warning "nul past the end" } */
1602 T (2, "% o"); /* { dg-warning ". . flag used with .%o." } */
1603 T (2, "% u"); /* { dg-warning ". . flag used with .%u." } */
1604 T (2, "% x"); /* { dg-warning ". . flag used with .%x." } */
1606 T (2, "#%o"); /* { dg-warning "nul past the end" } */
1607 T (2, "#%x"); /* { dg-warning "nul past the end" } */
1617 #define T(size, fmt) \
1618 __builtin_vsnprintf (buffer (size), objsize (size), fmt, va)
1620 void test_vsnprintf_s (__builtin_va_list va
)
1622 T (-1, "%s"); /* { dg-warning "specified destination size \[^ \]* is too large" } */
1626 T (1, "%1s"); /* { dg-warning "output truncated before the last format character" } */
1632 T (2, "_%s_%s"); /* { dg-warning "output truncated before the last format character" } */
1636 #define T(size, fmt) \
1637 __builtin___vsnprintf_chk (buffer (size), objsize (size), \
1638 0, objsize (size), fmt, va)
1640 void test_vsnprintf_chk_s (__builtin_va_list va
)
1642 /* Verify that specifying a size of the destination buffer that's
1643 bigger than its actual size (normally determined and passed to
1644 the function by __builtin_object_size) is diagnosed. */
1645 __builtin___vsnprintf_chk (buffer
, 123, 0, 122, "%-s", va
); /* { dg-warning "always overflow|specified size 123 exceeds the size 122 of the destination object" } */
1647 __builtin___vsnprintf_chk (buffer
, __SIZE_MAX__
, 0, 2, "%-s", va
); /* { dg-warning "always overflow|destination size .\[0-9\]+. is too large" } */
1651 T (1, "%1s"); /* { dg-warning "output truncated before the last format character" } */
1657 T (2, "_%s_%s"); /* { dg-warning "output truncated before the last format character" } */