1 /* PR middle-end/88993 - GCC 9 -Wformat-overflow=2 should reflect real
2 libc limits
3 Verify that -Wformat-overflow=2 "may exceed" warnings are not issued
4 for printf family of functions.
5 { dg-do compile }
6 { dg-options "-O -Wformat -Wformat-overflow=2 -ftrack-macro-expansion=0" }
7 { dg-require-effective-target int32plus } */
8
9
10 #define INT_MAX __INT_MAX__
11
12 typedef __SIZE_TYPE__ size_t;
13
14 #if !__cplusplus
15 typedef __WCHAR_TYPE__ wchar_t;
16 #endif
17
18 #define T(...) __builtin_printf (__VA_ARGS__)
19
20 /* Exercise the "%c" directive with constant arguments. */
21
test_printf_c_const(int width)22 void test_printf_c_const (int width)
23 {
24 /* Verify that a warning is only issued when the output is definitely
25 exceeded but not when exceeding it is possible but not inevitable. */
26 T ("%2147483647c", '1');
27 T ("X%2147483647c", '2'); /* { dg-warning ".%*c. directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
28 T ("%2147483647cY", '3'); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
29
30 T ("%2147483648c", '1'); /* { dg-warning ".%2147483648c. directive output of 2147483648 bytes exceeds .INT_MAX." } */
31 T ("X%2147483649c", '2'); /* { dg-warning ".%2147483649c. directive output of 2147483649 bytes exceeds .INT_MAX." } */
32 T ("%2147483650cY", '3'); /* { dg-warning ".%2147483650c. directive output of 2147483650 bytes exceeds .INT_MAX." } */
33
34 T ("%*c", INT_MAX, '1');
35 T ("X%*c", INT_MAX, '1'); /* { dg-warning ".%*c. directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
36 T ("%*cY", INT_MAX, '1'); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
37
38 T ("X%*c", INT_MAX - 1, '1');
39 T ("%*cY", INT_MAX - 1, '1');
40
41 T ("%*cY", INT_MAX, '1'); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
42 T ("X%*c", INT_MAX, '1'); /* { dg-warning ".%*c. directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
43
44 if (width > INT_MAX - 1)
45 width = INT_MAX - 1;
46
47 T ("%*c", width, '1');
48 T ("X%*c", width, '1');
49 T ("%*cY", width, '1');
50
51 T ("%*c", width, '1');
52 T ("X%*c", width, '1');
53 T ("%*cY", width, '1');
54
55 T ("%*c%*c", width, '1', width, '2');
56 T ("X%*cY%*cZ", width, '1', width, '2');
57
58 if (width < 4096)
59 width = 4096;
60
61 T ("%*c", width, '1');
62 T ("X%*c", width, '1');
63 T ("%*cY", width, '1');
64
65 if (width < INT_MAX - 1)
66 width = INT_MAX - 1;
67
68 T ("%*c", width, '1');
69 T ("X%*c", width, '2');
70 T ("%*cY", width, '3');
71 T ("X%*cY", width, '4'); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
72 }
73
74
75 /* Exercise the "%s" directive with constant arguments. */
76
test_printf_s_const(int width,const char * s)77 void test_printf_s_const (int width, const char *s)
78 {
79 T ("%2147483647s", s);
80 T ("X%2147483647s", s); /* { dg-warning ".%2147483647s. directive output between 2147483647 and \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
81 T ("%2147483647sY", s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
82
83 T ("%2147483648s", s); /* { dg-warning "%2147483648s. directive output between 2147483648 and \[0-9\]+ bytes exceeds .INT_MAX." } */
84 T ("X%2147483649s", s); /* { dg-warning "%2147483649s. directive output between 2147483649 and \[0-9\]+ bytes exceeds .INT_MAX." } */
85 T ("%2147483650sY", s); /* { dg-warning ".%2147483650s. directive output between 2147483650 and \[0-9\]+ bytes exceeds .INT_MAX." } */
86
87 T ("%*s", INT_MAX, s);
88 T ("X%*s", INT_MAX, s); /* { dg-warning ".%\\\*s. directive output between 2147483647 and \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
89 T ("%*sY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
90
91 T ("X%*s", INT_MAX - 1, s);
92 T ("%*sY", INT_MAX - 1, s);
93
94 T ("%*sY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
95 T ("X%*s", INT_MAX, s); /* { dg-warning ".%\\\*s. directive output between 2147483647 and \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
96
97 if (width > INT_MAX - 1)
98 width = INT_MAX - 1;
99
100 T ("%*s", width, s);
101 T ("X%*s", width, s);
102 T ("%*sY", width, s);
103
104 T ("%*s", width, s);
105 T ("X%*s", width, s);
106 T ("%*sY", width, s);
107
108 T ("%*s%*s", width, s, width, s);
109 T ("X%*sY%*sZ", width, s, width, s);
110
111 if (width < 4096)
112 width = 4096;
113
114 T ("%*s", width, s);
115 T ("X%*s", width, s);
116 T ("%*sY", width, s);
117
118 if (width < INT_MAX - 1)
119 width = INT_MAX - 1;
120
121 T ("%*s", width, s);
122 T ("X%*s", width, s);
123 T ("%*sY", width, s);
124 T ("X%*sY", width, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
125 }
126
127 /* Exercise the "%ls" directive with constant arguments. */
128
test_printf_ls_const(int width,const wchar_t * s)129 void test_printf_ls_const (int width, const wchar_t *s)
130 {
131 T ("%2147483647ls", s);
132 T ("X%2147483647ls", s); /* { dg-warning ".%2147483647ls. directive output between 2147483647 and \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
133 T ("%2147483647lsY", s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
134
135 T ("%2147483648ls", s); /* { dg-warning "%2147483648ls. directive output between 2147483648 and \[0-9\]+ bytes exceeds .INT_MAX." } */
136 T ("X%2147483649ls", s); /* { dg-warning "%2147483649ls. directive output between 2147483649 and \[0-9\]+ bytes exceeds .INT_MAX." } */
137 T ("%2147483650lsY", s); /* { dg-warning ".%2147483650ls. directive output between 2147483650 and \[0-9\]+ bytes exceeds .INT_MAX." } */
138
139 T ("%*ls", INT_MAX, s);
140 T ("X%*ls", INT_MAX, s); /* { dg-warning ".%\\\*ls. directive output between 2147483647 and \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
141 T ("%*lsY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
142
143 T ("X%*ls", INT_MAX - 1, s);
144 T ("%*lsY", INT_MAX - 1, s);
145
146 T ("%*lsY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
147 T ("X%*ls", INT_MAX, s); /* { dg-warning ".%\\\*ls. directive output between 2147483647 and \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
148
149 if (width > INT_MAX - 1)
150 width = INT_MAX - 1;
151
152 T ("%*ls", width, s);
153 T ("X%*ls", width, s);
154 T ("%*lsY", width, s);
155
156 T ("%*ls", width, s);
157 T ("X%*ls", width, s);
158 T ("%*lsY", width, s);
159
160 T ("%*ls%*ls", width, s, width, s);
161 T ("X%*lsY%*lsZ", width, s, width, s);
162
163 if (width < 4096)
164 width = 4096;
165
166 T ("%*ls", width, s);
167 T ("X%*ls", width, s);
168 T ("%*lsY", width, s);
169
170 if (width < INT_MAX - 1)
171 width = INT_MAX - 1;
172
173 T ("%*ls", width, s);
174 T ("X%*ls", width, s);
175 T ("%*lsY", width, s);
176 T ("X%*lsY", width, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
177 }
178
179
180 /* Also exercise printf_chk. */
181
182 #undef T
183 #define T(...) __builtin___printf_chk (__VA_ARGS__)
184
test_printf_chk_s_const(int width)185 void test_printf_chk_s_const (int width)
186 {
187 const char *s = "0123456789";
188
189 T (0, "%2147483647s", s);
190 T (0, "X%2147483647s", s); /* { dg-warning ".%2147483647s. directive output of 2147483647 bytes causes result to exceed .INT_MAX." } */
191 T (0, "%2147483647sY", s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
192
193 T (0, "%2147483648s", s); /* { dg-warning "%2147483648s. directive output of 2147483648 bytes exceeds .INT_MAX." } */
194 T (0, "X%2147483649s", s); /* { dg-warning "%2147483649s. directive output of 2147483649 bytes exceeds .INT_MAX." } */
195 T (0, "%2147483650sY", s); /* { dg-warning ".%2147483650s. directive output of 2147483650 bytes exceeds .INT_MAX." } */
196
197 T (0, "%*s", INT_MAX, s);
198 T (0, "X%*s", INT_MAX, s); /* { dg-warning ".%\\\*s. directive output of 2147483647 bytes causes result to exceed .INT_MAX." } */
199 T (0, "%*sY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
200
201 T (0, "X%*s", INT_MAX - 1, s);
202 T (0, "%*sY", INT_MAX - 1, s);
203
204 T (0, "%*sY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
205 T (0, "X%*s", INT_MAX, s); /* { dg-warning ".%\\\*s. directive output of 2147483647 bytes causes result to exceed .INT_MAX." } */
206
207 if (width > INT_MAX - 1)
208 width = INT_MAX - 1;
209
210 T (0, "%*s", width, s);
211 T (0, "X%*s", width, s);
212 T (0, "%*sY", width, s);
213
214 T (0, "%*s", width, s);
215 T (0, "X%*s", width, s);
216 T (0, "%*sY", width, s);
217
218 T (0, "%*s%*s", width, s, width, s);
219 T (0, "X%*sY%*sZ", width, s, width, s);
220
221 if (width < 4096)
222 width = 4096;
223
224 T (0, "%*s", width, s);
225 T (0, "X%*s", width, s);
226 T (0, "%*sY", width, s);
227
228 if (width < INT_MAX - 1)
229 width = INT_MAX - 1;
230
231 T (0, "%*s", width, s);
232 T (0, "X%*s", width, s);
233 T (0, "%*sY", width, s);
234 T (0, "X%*sY", width, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
235 }
236
237
238 /* And finally exercise printf_unlocked. */
239
240 #undef T
241 #define T(...) __builtin_printf_unlocked (__VA_ARGS__)
242
test_printf_unlocked_s_const(int width)243 void test_printf_unlocked_s_const (int width)
244 {
245 const char *s = "0123456789";
246
247 T ("%2147483647s", s);
248 T ("X%2147483647s", s); /* { dg-warning ".%2147483647s. directive output of 2147483647 bytes causes result to exceed .INT_MAX." } */
249 T ("%2147483647sY", s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
250
251 T ("%2147483648s", s); /* { dg-warning "%2147483648s. directive output of 2147483648 bytes exceeds .INT_MAX." } */
252 T ("X%2147483649s", s); /* { dg-warning "%2147483649s. directive output of 2147483649 bytes exceeds .INT_MAX." } */
253 T ("%2147483650sY", s); /* { dg-warning ".%2147483650s. directive output of 2147483650 bytes exceeds .INT_MAX." } */
254
255 T ("%*s", INT_MAX, s);
256 T ("X%*s", INT_MAX, s); /* { dg-warning ".%\\\*s. directive output of 2147483647 bytes causes result to exceed .INT_MAX." } */
257 T ("%*sY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
258
259 T ("X%*s", INT_MAX - 1, s);
260 T ("%*sY", INT_MAX - 1, s);
261
262 T ("%*sY", INT_MAX, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
263 T ("X%*s", INT_MAX, s); /* { dg-warning ".%\\\*s. directive output of 2147483647 bytes causes result to exceed .INT_MAX." } */
264
265 if (width > INT_MAX - 1)
266 width = INT_MAX - 1;
267
268 T ("%*s", width, s);
269 T ("X%*s", width, s);
270 T ("%*sY", width, s);
271
272 T ("%*s", width, s);
273 T ("X%*s", width, s);
274 T ("%*sY", width, s);
275
276 T ("%*s%*s", width, s, width, s);
277 T ("X%*sY%*sZ", width, s, width, s);
278
279 if (width < 4096)
280 width = 4096;
281
282 T ("%*s", width, s);
283 T ("X%*s", width, s);
284 T ("%*sY", width, s);
285
286 if (width < INT_MAX - 1)
287 width = INT_MAX - 1;
288
289 T ("%*s", width, s);
290 T ("X%*s", width, s);
291 T ("%*sY", width, s);
292 T ("X%*sY", width, s); /* { dg-warning ".Y. directive output of 1 bytes causes result to exceed .INT_MAX." } */
293 }
294