1 /* PR tree-optimization/77671 - missing -Wformat-overflow warning
2    on sprintf overflow with "%s"
3    { dg-compile }
4    { dg-options "-O2 -Wformat -Wno-format-zero-length -fdump-tree-optimized" } */
5 
6 void sink (char*);
7 
8 extern char buffer[];
9 
10 /* String exactly 4100 characters long (plus the terminating NUL).  */
11 extern const char s4100[4101];
12 
test_sprintf(const char * s)13 void test_sprintf (const char *s)
14 {
15 #define IGN(...) __builtin_sprintf (buffer, __VA_ARGS__); sink (buffer)
16 
17   /* Each of the following calls is expected to be transformed into
18      one of memcpy or strcpy.  */
19   IGN ("");
20   IGN ("a");
21   IGN ("ab");
22   /* FIXME: Transform to strcpy/memcpy.  */
23   /* IGN (s4100 + 5); */
24 
25   IGN ("%s", "");
26   IGN ("%s", "a");
27   IGN ("%s", "ab");
28 
29   IGN ("%s", s4100 + 5);
30 
31   /* FIXME: This can be transformed into strcpy.  */
32   /* IGN (s); */
33   IGN ("%s", s);
34 }
35 
36 
test_snprintf(void)37 void test_snprintf (void)
38 {
39 #undef IGN
40 #define IGN(N, ...) __builtin_snprintf (buffer, N, __VA_ARGS__); sink (buffer)
41 
42   /* Each of the following calls is expected to be transformed into
43      one of memcpy or strcpy.  */
44   IGN (1, "");
45   IGN (2, "1");
46   IGN (8, "1234567");
47 
48   /* FIXME: Transform to strcpy/memcpy.  */
49   /* IGN (4096, s4100 + 5); */
50 
51   IGN (1, "%s", "");
52   IGN (2, "%s", "1");
53   IGN (8, "%s", "1234567");
54 
55   IGN (4096, "%s", s4100 + 5);
56 }
57 
58 #if 0   /* FIXME: Implement vs{,n}printf optimization.  */
59 
60 void test_vsprintf (__builtin_va_list va)
61 {
62 #undef IGN
63 #define IGN(fmt) __builtin_vsprintf (buffer, fmt, va); sink (buffer)
64 
65   /* Each of the following calls is expected to be transformed into
66      one of memcpy or strcpy.  */
67   IGN ("");
68   IGN ("a");
69   IGN ("ab");
70   IGN (s4100 + 5);
71 
72   IGN ("%s");
73 }
74 
75 void test_vsnprintf (__builtin_va_list va)
76 {
77 #undef IGN
78 #define IGN(N, fmt) __builtin_vsnprintf (buffer, N, fmt, va); sink (buffer)
79 
80   /* Each of the following calls is expected to be transformed into
81      one of memcpy or strcpy.  */
82   IGN (   1, "");
83   IGN (   2, "1");
84   IGN (   8, "1234567");
85   IGN (4096, s4100 + 5);
86 }
87 
88 #endif
89 
90 /* { dg-final { scan-tree-dump-not "builtin_sprintf" "optimized" } }
91    { dg-final { scan-tree-dump-not "builtin_snprintf" "optimized" } }
92    { dg-final { scan-tree-dump-not "builtin_vsprintf" "optimized" } }
93    { dg-final { scan-tree-dump-not "builtin_vsnprintf" "optimized" } } */
94 
95 #define S10    "0123456789"
96 #define S100   S10 S10 S10 S10 S10  S10 S10 S10 S10 S10
97 #define S1000  S100 S100 S100 S100 S100  S100 S100 S100 S100 S100
98 
99 const char s4100[4101] = S1000 S1000 S1000 S1000 S100;
100