PR middle-end/77735 - FAIL: gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
[official-gcc.git] / gcc / testsuite / gcc.dg / tree-ssa / builtin-sprintf.c
blob916df79bb9b3e554e573f0d69e98d6a258aa9dcc
1 /* Test to verify that the return value of calls to __builtin_sprintf
2 that produce a known number of bytes on output is available for
3 constant folding. With optimization enabled the test will fail to
4 link if any of the assertions fails. Without optimization the test
5 aborts at runtime if any of the assertions fails. */
6 /* { dg-do run } */
7 /* { dg-additional-options "-O2 -Wall -Wno-pedantic -fprintf-return-value" } */
9 #ifndef LINE
10 # define LINE 0
11 #endif
13 #if __STDC_VERSION__ < 199901L
14 # define __func__ __FUNCTION__
15 #endif
17 typedef __SIZE_TYPE__ size_t;
19 unsigned ntests;
20 unsigned nfails;
22 void __attribute__ ((noclone, noinline))
23 checkv (const char *func, int line, int res, int min, int max,
24 char *dst, const char *fmt, __builtin_va_list va)
26 int n = __builtin_vsprintf (dst, fmt, va);
27 int len = __builtin_strlen (dst);
29 ++ntests;
31 int fail = 0;
32 if (n != res)
34 __builtin_printf ("FAIL: %s:%i: \"%s\" expected result for \"%s\" "
35 "doesn't match function call return value: ",
36 func, line, fmt, dst);
37 if (min == max)
38 __builtin_printf ("%i != %i\n", n, min);
39 else
40 __builtin_printf ("%i not in [%i, %i]\n", n, min, max);
42 fail = 1;
44 else
46 if (len < min || max < len)
48 __builtin_printf ("FAIL: %s:%i: \"%s\" expected result for \"%s\" "
49 "doesn't match output length: ",
50 func, line, fmt, dst);
52 if (min == max)
53 __builtin_printf ("%i != %i\n", len, min);
54 else
55 __builtin_printf ("%i not in [%i, %i]\n", len, min, max);
57 fail = 1;
59 else
60 __builtin_printf ("PASS: %s:%i: \"%s\" result %i: \"%s\"\n",
61 func, line, fmt, n, dst);
64 if (fail)
65 ++nfails;
68 void __attribute__ ((noclone, noinline))
69 check (const char *func, int line, int res, int min, int max,
70 char *dst, const char *fmt, ...)
72 __builtin_va_list va;
73 __builtin_va_start (va, fmt);
74 checkv (func, line, res, min, max, dst, fmt, va);
75 __builtin_va_end (va);
78 char buffer[256];
79 char* volatile dst = buffer;
80 char* ptr = buffer;
82 #define concat(a, b) a ## b
83 #define CAT(a, b) concat (a, b)
85 #if __OPTIMIZE__
86 /* With optimization references to the following undefined symbol which
87 is unique for each test case are expected to be eliminated. */
88 # define TEST_FAILURE(line, ignore1, ignore2, ignore3) \
89 do { \
90 extern void CAT (failure_on_line_, line)(void); \
91 CAT (failure_on_line_, line)(); \
92 } while (0)
93 #else
94 /* The test is run by DejaGnu with optimization enabled. When it's run
95 with it disabled (i.e., at -O0) each test case is verified at runtime
96 and the test aborts just before exiting if any of them failed. */
97 # define TEST_FAILURE(line, result, min, max) \
98 if (min == max) \
99 __builtin_printf ("FAIL: %s:%i: expected %i, got %i\n", \
100 __func__, line, min, result); \
101 else \
102 __builtin_printf ("FAIL: %s:%i: expected range [%i, %i], got %i\n", \
103 __func__, line, min, max, result);
104 #endif
106 /* Verify that the result is exactly equal to RES. */
107 #define EQL(expect, size, fmt, ...) \
108 if (!LINE || LINE == __LINE__) \
109 do { \
110 char *buf = (size) < 0 ? ptr : buffer + sizeof buffer - (size); \
111 int result = __builtin_sprintf (buf, fmt, __VA_ARGS__); \
112 if (result != expect) \
114 TEST_FAILURE (__LINE__, expect, expect, result); \
116 check (__func__, __LINE__, result, expect, expect, dst, fmt, \
117 __VA_ARGS__); \
118 } while (0)
120 /* Verify that the result is in the range [MIN, MAX]. */
121 #define RNG(min, max, size, fmt, ...) \
122 if (!LINE || LINE == __LINE__) \
123 do { \
124 char *buf = (size) < 0 ? ptr : buffer + sizeof buffer - (size); \
125 int result = __builtin_sprintf (buf, fmt, __VA_ARGS__); \
126 if (result < min || max < result) \
128 TEST_FAILURE (__LINE__, min, max, result); \
130 check (__func__, __LINE__, result, min, max, dst, fmt, \
131 __VA_ARGS__); \
132 } while (0)
134 static void __attribute__ ((noinline, noclone))
135 test_c (char c)
137 EQL (1, 2, "%c", c);
138 EQL (1, -1, "%c", c);
139 EQL (1, 2, "%1c", c);
140 EQL (1, -1, "%1c", c);
141 EQL (1, 2, "%*c", 1, c);
142 EQL (1, -1, "%*c", 1, c);
143 EQL (2, 3, "%c%c", '1', '2');
144 EQL (2, -1, "%c%c", '1', '2');
145 EQL (3, 4, "%3c", c);
146 EQL (3, -1, "%3c", c);
147 EQL (3, 4, "%*c", 3, c);
148 EQL (3, -1, "%*c", 3, c);
150 EQL (3, 4, "%*c%*c", 2, c, 1, c);
151 EQL (3, 4, "%*c%*c", 1, c, 2, c);
152 EQL (3, 4, "%c%c%c", '1', '2', '3');
153 EQL (3, 4, "%*c%c%c", 1, '1', '2', '3');
154 EQL (3, 4, "%*c%*c%c", 1, '1', 1, '2', '3');
155 EQL (3, 4, "%*c%*c%*c", 1, '1', 1, '2', 1, '3');
157 EQL (3, -1, "%*c%*c", 2, c, 1, c);
158 EQL (3, -1, "%*c%*c", 1, c, 2, c);
159 EQL (3, -1, "%c%c%c", '1', '2', '3');
160 EQL (3, -1, "%*c%c%c", 1, '1', '2', '3');
161 EQL (3, -1, "%*c%*c%c", 1, '1', 1, '2', '3');
162 EQL (3, -1, "%*c%*c%*c", 1, '1', 1, '2', 1, '3');
164 EQL (4, 5, "%c%c %c", '1', '2', '3');
165 EQL (5, 6, "%c %c %c", '1', '2', '3');
166 EQL (5, 6, "%c %c %c", c, c, c);
169 /* Generate a pseudo-random value in the specified range. The return
170 value must be unsigned char to work around limitations in the GCC
171 range information. Similarly for the declaration of rand() whose
172 correct return value should be int, but that also prevents the range
173 information from making it to the printf pass. */
175 unsigned char uchar_range (unsigned min, unsigned max)
177 extern unsigned rand (void);
179 unsigned x;
180 x = rand ();
182 if (x < min)
183 x = min;
184 else if (max < x)
185 x = max;
187 return x;
190 static void __attribute__ ((noinline, noclone))
191 test_d_i (int i, long li)
193 /* +-------------------------- expected return value */
194 /* | +---------------------- destination size */
195 /* | | +------------------- format string */
196 /* | | | +-- variable argument(s) */
197 /* | | | | */
198 /* V V V V */
199 EQL ( 1, 2, "%d", 0);
200 EQL ( 2, 3, "%d%d", 0, 1);
201 EQL ( 3, 4, "%d%d", 9, 10);
202 EQL ( 4, 5, "%d%d", 11, 12);
203 EQL ( 5, 6, "%d:%d", 12, 34);
204 EQL ( 5, 6, "%d", 12345);
205 EQL ( 6, 7, "%d", -12345);
206 EQL (15, 16, "%d:%d:%d:%d", 123, 124, 125, 126);
208 EQL ( 1, 2, "%i", uchar_range (0, 9));
209 EQL ( 1, -1, "%i", uchar_range (0, 9));
211 /* The range information available to passes other than the Value
212 Range Propoagation pass itself is so bad that the following two
213 tests fail (the range seen in the test below is [0, 99] rather
214 than [10, 99].
215 EQL ( 2, 3, "%i", uchar_range (10, 99));
216 EQL ( 3, 4, "%i", uchar_range (100, 199));
219 /* Verify that the width allows the return value in the following
220 calls can be folded despite the unknown value of the argument. */
221 #if __SIZEOF_INT__ == 2
222 EQL ( 6, 7, "%6d", i);
223 EQL ( 6, 7, "%+6d", i);
224 EQL ( 6, 7, "%-6d", i);
225 EQL ( 6, 7, "%06d", i);
226 #elif __SIZEOF_INT__ == 4
227 EQL (11, 12, "%11d", i);
228 EQL (11, 12, "%+11d", i);
229 EQL (11, 12, "%-11d", i);
230 EQL (11, 12, "%011d", i);
231 #elif __SIZEOF_INT__ == 8
232 EQL (20, 21, "%20d", i);
233 EQL (20, 21, "%+20d", i);
234 EQL (20, 21, "%-29d", i);
235 EQL (20, 21, "%020d", i);
236 #endif
238 #if __SIZEOF_LONG__ == 2
239 EQL ( 6, 7, "%6ld", li);
240 EQL ( 6, 7, "%+6ld", li);
241 EQL ( 6, 7, "%-6ld", li);
242 EQL ( 6, 7, "%06ld", li);
243 #elif __SIZEOF_LONG__ == 4
244 EQL (11, 12, "%11ld", li);
245 EQL (11, 12, "%+11ld", li);
246 EQL (11, 12, "%-11ld", li);
247 EQL (11, 12, "%011ld", li);
248 #elif __SIZEOF_LONG__ == 8
249 EQL (20, 21, "%20ld", li);
250 EQL (20, 21, "%+20ld", li);
251 EQL (20, 21, "%-20ld", li);
252 EQL (20, 21, "%020ld", li);
253 #endif
255 /* Verify that the output of a directive with an unknown argument
256 is correctly determined at compile time to be in the expected
257 range. */
259 /* +---------------------------- expected minimum return value */
260 /* | +------------------------ expected maximum return value */
261 /* | | +-------------------- destination size */
262 /* | | | +----------------- format string */
263 /* | | | | +----- variable argument(s) */
264 /* | | | | | */
265 /* V V V V V */
266 RNG ( 1, 4, 5, "%hhi", i);
267 RNG ( 1, 3, 4, "%hhu", i);
269 #if __SIZEOF_SHORT__ == 2
270 RNG ( 1, 6, 7, "%hi", i);
271 RNG ( 1, 5, 6, "%hu", i);
272 #elif __SIZEOF_SHORT__ == 4
273 RNG ( 1, 11, 12, "%hi", i);
274 RNG ( 1, 10, 11, "%hu", i);
275 #endif
277 #if __SIZEOF_INT__ == 2
278 RNG ( 1, 6, 7, "%i", i);
279 RNG ( 1, 5, 6, "%u", i);
280 #elif __SIZEOF_INT__ == 4
281 RNG ( 1, 11, 12, "%i", i);
282 RNG ( 1, 10, 11, "%u", i);
283 #elif __SIZEOF_INT__ == 8
284 RNG ( 1, 20, 21, "%i", i);
285 RNG ( 1, 19, 20, "%u", i);
286 #endif
288 #if __SIZEOF_LONG__ == 4
289 RNG ( 1, 11, 12, "%li", li);
290 RNG ( 1, 10, 11, "%lu", li);
291 #elif __SIZEOF_LONG__ == 8
292 RNG ( 1, 20, 21, "%li", li);
293 RNG ( 1, 19, 20, "%lu", li);
294 #endif
297 static void __attribute__ ((noinline, noclone))
298 test_x (unsigned char uc, unsigned short us, unsigned ui)
300 EQL ( 1, 2, "%hhx", 0);
301 EQL ( 2, 3, "%2hhx", 0);
302 EQL ( 2, 3, "%02hhx", 0);
303 EQL ( 2, 3, "%#02hhx", 0);
305 EQL ( 1, 2, "%hhx", 1);
306 EQL ( 2, 3, "%2hhx", 1);
307 EQL ( 2, 3, "%02hhx", 1);
308 EQL ( 3, 4, "%#02hhx", 1);
310 EQL ( 2, 3, "%2hhx", uc);
311 EQL ( 2, 3, "%02hhx", uc);
312 EQL ( 5, 6, "%#05hhx", uc);
314 EQL ( 2, 3, "%2hhx", us);
315 EQL ( 2, 3, "%02hhx", us);
316 EQL ( 5, 6, "%#05hhx", us);
318 EQL ( 2, 3, "%2hhx", ui);
319 EQL ( 2, 3, "%02hhx", ui);
320 EQL ( 5, 6, "%#05hhx", ui);
322 EQL ( 1, 2, "%x", 0);
323 EQL ( 1, 2, "%#x", 0);
324 EQL ( 1, 2, "%#0x", 0);
325 EQL ( 1, 2, "%x", 1);
326 EQL ( 1, 2, "%x", 0xf);
327 EQL ( 2, 3, "%x", 0x10);
328 EQL ( 2, 3, "%x", 0xff);
329 EQL ( 3, 4, "%x", 0x100);
331 EQL (11, 12, "%02x:%02x:%02x:%02x", 0xde, 0xad, 0xbe, 0xef);
333 /* The following would be optimized if the range information of
334 the variable's type was made available. Alas, it's lost due
335 to the promotion of the actual argument (unsined char) to
336 the type of the "formal" argument (int in the case of the
337 ellipsis).
338 EQL (11, 12, "%02x:%02x:%02x:%02x", uc, uc, uc, uc);
340 EQL (11, 12, "%02hhx:%02hhx:%02hhx:%02hhx", uc, uc, uc, uc);
342 #if __SIZEOF_SHORT__ == 2
343 EQL ( 4, 5, "%04hx", us);
344 EQL ( 9, 10, "%04hx:%04hx", us, us);
345 EQL (14, 15, "%04hx:%04hx:%04hx", us, us, us);
346 EQL (19, 20, "%04hx:%04hx:%04hx:%04hx", us, us, us, us);
347 #endif
349 #if __SIZEOF_INT__ == 2
350 EQL ( 4, 5, "%04x", ui);
351 EQL ( 6, 7, "%#06x", ui);
352 #elif __SIZEOF_INT__ == 4
353 EQL ( 8, 9, "%08x", ui);
354 EQL (10, 10 + 1, "%#010x", ui);
355 #elif __SIZEOF_INT__ == 8
356 EQL (16, 17, "%016x", ui);
357 EQL (18, 19, "%#018x", ui);
358 #endif
361 static void __attribute__ ((noinline, noclone))
362 test_a_double (double d)
364 EQL ( 6, 7, "%.0a", 0.0); /* 0x0p+0 */
365 EQL ( 6, 7, "%.0a", 1.0); /* 0x8p-3 */
366 EQL ( 6, 7, "%.0a", 2.0); /* 0x8p-2 */
367 EQL ( 8, 9, "%.1a", 3.0); /* 0xc.0p-2 */
368 EQL ( 9, 10, "%.2a", 4.0); /* 0x8.00p-1 */
369 EQL (10, 11, "%.3a", 5.0); /* 0xa.000p-1 */
371 /* d is in [ 0, -DBL_MAX ] */
372 RNG ( 6, 10, 11, "%.0a", d); /* 0x0p+0 ... -0x2p+1023 */
373 RNG ( 6, 12, 13, "%.1a", d); /* 0x0p+0 ... -0x2.0p+1023 */
374 RNG ( 6, 13, 14, "%.2a", d); /* 0x0p+0 ... -0x2.00p+1023 */
377 static void __attribute__ ((noinline, noclone))
378 test_a_long_double (void)
380 EQL ( 6, 7, "%.0La", 0.0L); /* 0x0p+0 */
381 EQL ( 6, 7, "%.0La", 1.0L); /* 0x8p-3 */
382 EQL ( 6, 7, "%.0La", 2.0L); /* 0x8p-2 */
383 EQL ( 8, 9, "%.1La", 3.0L); /* 0xc.0p-2 */
384 EQL ( 9, 10, "%.2La", 4.0L); /* 0xa.00p-1 */
387 static void __attribute__ ((noinline, noclone))
388 test_e_double (void)
390 EQL (12, 13, "%e", 1.0e0);
391 EQL (13, 14, "%e", -1.0e0);
392 EQL (12, 13, "%e", 1.0e+1);
393 EQL (13, 14, "%e", -1.0e+1);
394 EQL (12, 13, "%e", 1.0e+12);
395 EQL (13, 14, "%e", -1.0e+12);
396 EQL (13, 14, "%e", 1.0e+123);
397 EQL (14, 15, "%e", -1.0e+123);
399 EQL (12, 13, "%e", 9.999e+99);
400 EQL (12, 13, "%e", 9.9999e+99);
401 EQL (12, 13, "%e", 9.99999e+99);
403 /* The actual output of the following directive depends on the rounding
404 mode. */
405 /* EQL (12, "%e", 9.9999994e+99); */
407 EQL (12, 13, "%e", 1.0e-1);
408 EQL (12, 13, "%e", 1.0e-12);
409 EQL (13, 14, "%e", 1.0e-123);
412 static void __attribute__ ((noinline, noclone))
413 test_e_long_double (void)
415 EQL (12, 13, "%Le", 1.0e0L);
416 EQL (13, 14, "%Le", -1.0e0L);
417 EQL (12, 13, "%Le", 1.0e+1L);
418 EQL (13, 14, "%Le", -1.0e+1L);
419 EQL (12, 13, "%Le", 1.0e+12L);
420 EQL (13, 14, "%Le", -1.0e+12L);
421 EQL (13, 14, "%Le", 1.0e+123L);
422 EQL (14, 15, "%Le", -1.0e+123L);
424 EQL (12, 13, "%Le", 9.999e+99L);
425 EQL (12, 13, "%Le", 9.9999e+99L);
426 EQL (12, 13, "%Le", 9.99999e+99L);
428 #if __DBL_DIG__ < __LDBL_DIG__
429 EQL (12, 13, "%Le", 9.999999e+99L);
430 #else
431 RNG (12, 13, 14, "%Le", 9.999999e+99L);
432 #endif
434 /* The actual output of the following directive depends on the rounding
435 mode. */
436 /* EQL (12, "%Le", 9.9999994e+99L); */
438 EQL (12, 13, "%Le", 1.0e-1L);
439 EQL (12, 13, "%Le", 1.0e-12L);
440 EQL (13, 14, "%Le", 1.0e-123L);
442 EQL ( 6, 7, "%.0Le", 1.0e-111L);
443 EQL ( 8, 9, "%.1Le", 1.0e-111L);
444 EQL (19, 20, "%.12Le", 1.0e-112L);
445 EQL (20, 21, "%.13Le", 1.0e-113L);
448 static void __attribute__ ((noinline, noclone))
449 test_f_double (void)
451 EQL ( 8, 9, "%f", 0.0e0);
452 EQL ( 8, 9, "%f", 0.1e0);
453 EQL ( 8, 9, "%f", 0.12e0);
454 EQL ( 8, 9, "%f", 0.123e0);
455 EQL ( 8, 9, "%f", 0.1234e0);
456 EQL ( 8, 9, "%f", 0.12345e0);
457 EQL ( 8, 9, "%f", 0.123456e0);
458 EQL ( 8, 9, "%f", 1.234567e0);
460 EQL ( 9, 10, "%f", 1.0e+1);
461 EQL ( 20, 21, "%f", 1.0e+12);
462 EQL (130, 131, "%f", 1.0e+123);
464 EQL ( 8, 9, "%f", 1.0e-1);
465 EQL ( 8, 9, "%f", 1.0e-12);
466 EQL ( 8, 9, "%f", 1.0e-123);
469 static void __attribute__ ((noinline, noclone))
470 test_f_long_double (void)
472 EQL ( 8, 9, "%Lf", 0.0e0L);
473 EQL ( 8, 9, "%Lf", 0.1e0L);
474 EQL ( 8, 9, "%Lf", 0.12e0L);
475 EQL ( 8, 9, "%Lf", 0.123e0L);
476 EQL ( 8, 9, "%Lf", 0.1234e0L);
477 EQL ( 8, 9, "%Lf", 0.12345e0L);
478 EQL ( 8, 9, "%Lf", 0.123456e0L);
479 EQL ( 8, 9, "%Lf", 1.234567e0L);
481 EQL ( 9, 10, "%Lf", 1.0e+1L);
482 EQL ( 20, 21, "%Lf", 1.0e+12L);
483 EQL (130, 131, "%Lf", 1.0e+123L);
485 EQL ( 8, 9, "%Lf", 1.0e-1L);
486 EQL ( 8, 9, "%Lf", 1.0e-12L);
487 EQL ( 8, 9, "%Lf", 1.0e-123L);
490 static void __attribute__ ((noinline, noclone))
491 test_s (int i)
493 EQL ( 0, 1, "%s", "");
494 EQL ( 0, 1, "%s", "\0");
495 EQL ( 1, 2, "%1s", "");
496 EQL ( 1, 2, "%s", "1");
497 EQL ( 2, 3, "%2s", "");
498 EQL ( 2, 3, "%s", "12");
499 EQL ( 2, 3, "%s%s", "12", "");
500 EQL ( 2, 3, "%s%s", "", "12");
501 EQL ( 2, 3, "%s%s", "1", "2");
502 EQL ( 3, 4, "%3s", "");
503 EQL ( 3, 4, "%3s", "1");
504 EQL ( 3, 4, "%3s", "12");
505 EQL ( 3, 4, "%3s", "123");
506 EQL ( 3, 4, "%3.3s", "1");
507 EQL ( 3, 4, "%3.3s", "12");
508 EQL ( 3, 4, "%3.3s", "123");
509 EQL ( 3, 4, "%3.3s", "1234");
510 EQL ( 3, 4, "%3.3s", "12345");
511 EQL ( 3, 4, "%s %s", "1", "2");
512 EQL ( 4, 5, "%s %s", "12", "3");
513 EQL ( 5, 6, "%s %s", "12", "34");
514 EQL ( 5, 6, "[%s %s]", "1", "2");
515 EQL ( 6, 7, "[%s %s]", "12", "3");
516 EQL ( 7, 8, "[%s %s]", "12", "34");
518 /* Verify the result of a conditional expression involving string
519 literals is in the expected range of their lengths. */
520 RNG ( 0, 3, 4, "%-s", i ? "" : "123");
521 RNG ( 1, 4, 5, "%-s", i ? "1" : "1234");
522 RNG ( 2, 5, 6, "%-s", i ? "12" : "12345");
523 RNG ( 3, 6, 7, "%-s", i ? "123" : "123456");
526 int main (void)
528 test_c ('?');
529 test_d_i (0xdeadbeef, 0xdeadbeefL);
530 test_x ('?', 0xdead, 0xdeadbeef);
532 test_a_double (0.0);
533 test_e_double ();
534 test_f_double ();
536 test_a_long_double ();
537 test_e_long_double ();
538 test_f_long_double ();
540 test_s (0);
542 if (nfails)
544 __builtin_printf ("%u out of %u tests failed\n", nfails, ntests);
545 __builtin_abort ();
548 return 0;