131
|
1 /* { dg-options "-Wformat -fdiagnostics-show-caret" } */
|
|
2
|
|
3 /* This is a copy of gcc.dg/format/diagnostic-ranges.c
|
|
4 with the following changes:
|
|
5 - removal of "format.h"
|
|
6 - "char \\*" -> "char\\*" (space removal)
|
|
7 - move of test_u8 to Wformat-ranges-c++11.C. */
|
|
8
|
|
9 #define printf __builtin_printf
|
|
10 typedef __SIZE_TYPE__ size_t;
|
|
11 typedef __SIZE_TYPE__ ssize_t;
|
|
12
|
|
13 extern ssize_t strfmon (char *__restrict __s, size_t __maxsize,
|
|
14 const char *__restrict, ...)
|
|
15 __attribute__ ((__format__ (__strfmon__, 3, 4)));
|
|
16
|
|
17 /* See PR 52952. */
|
|
18
|
|
19 void test_mismatching_types (const char *msg)
|
|
20 {
|
|
21 printf("hello %i", msg); /* { dg-warning "format '%i' expects argument of type 'int', but argument 2 has type 'const char\\*' " } */
|
|
22
|
|
23 /* { dg-begin-multiline-output "" }
|
|
24 printf("hello %i", msg);
|
|
25 ~^ ~~~
|
|
26 | |
|
|
27 int const char*
|
|
28 %s
|
|
29 { dg-end-multiline-output "" } */
|
|
30
|
|
31
|
|
32 printf("hello %s", 42); /* { dg-warning "format '%s' expects argument of type 'char\\*', but argument 2 has type 'int'" } */
|
|
33 /* { dg-begin-multiline-output "" }
|
|
34 printf("hello %s", 42);
|
|
35 ~^ ~~
|
|
36 | |
|
|
37 | int
|
|
38 char*
|
|
39 %d
|
|
40 { dg-end-multiline-output "" } */
|
|
41
|
|
42 printf("hello %i", (long)0); /* { dg-warning "format '%i' expects argument of type 'int', but argument 2 has type 'long int' " } */
|
|
43 /* { dg-begin-multiline-output "" }
|
|
44 printf("hello %i", (long)0);
|
|
45 ~^ ~~~~~~~
|
|
46 | |
|
|
47 int long int
|
|
48 %li
|
|
49 { dg-end-multiline-output "" } */
|
|
50 }
|
|
51
|
|
52 void test_multiple_arguments (void)
|
|
53 {
|
|
54 printf ("arg0: %i arg1: %s arg 2: %i", /* { dg-warning "29: format '%s'" } */
|
|
55 100, 101, 102);
|
|
56 /* { dg-begin-multiline-output "" }
|
|
57 printf ("arg0: %i arg1: %s arg 2: %i",
|
|
58 ~^
|
|
59 |
|
|
60 char*
|
|
61 %d
|
|
62 100, 101, 102);
|
|
63 ~~~
|
|
64 |
|
|
65 int
|
|
66 { dg-end-multiline-output "" } */
|
|
67 }
|
|
68
|
|
69 void test_multiple_arguments_2 (int i, int j)
|
|
70 {
|
|
71 printf ("arg0: %i arg1: %s arg 2: %i", /* { dg-warning "29: format '%s'" } */
|
|
72 100, i + j, 102);
|
|
73 /* { dg-begin-multiline-output "" }
|
|
74 printf ("arg0: %i arg1: %s arg 2: %i",
|
|
75 ~^
|
|
76 |
|
|
77 char*
|
|
78 %d
|
|
79 100, i + j, 102);
|
|
80 ~~~~~
|
|
81 |
|
|
82 int
|
|
83 { dg-end-multiline-output "" } */
|
|
84 }
|
|
85
|
|
86 void multiline_format_string (void) {
|
|
87 printf ("before the fmt specifier"
|
|
88 "%"
|
|
89 "d" /* { dg-warning "12: format '%d' expects a matching 'int' argument" } */
|
|
90 "after the fmt specifier");
|
|
91 /* { dg-begin-multiline-output "" }
|
|
92 "%"
|
|
93 ~~
|
|
94 "d"
|
|
95 ~^
|
|
96 |
|
|
97 int
|
|
98 { dg-end-multiline-output "" } */
|
|
99 }
|
|
100
|
|
101 void test_hex (const char *msg)
|
|
102 {
|
|
103 /* "%" is \x25
|
|
104 "i" is \x69 */
|
|
105 printf("hello \x25\x69", msg); /* { dg-warning "format '%i' expects argument of type 'int', but argument 2 has type 'const char\\*' " } */
|
|
106
|
|
107 /* { dg-begin-multiline-output "" }
|
|
108 printf("hello \x25\x69", msg);
|
|
109 ~~~~^~~~ ~~~
|
|
110 | |
|
|
111 int const char*
|
|
112 \x25s
|
|
113 { dg-end-multiline-output "" } */
|
|
114 }
|
|
115
|
|
116 void test_oct (const char *msg)
|
|
117 {
|
|
118 /* "%" is octal 045
|
|
119 "i" is octal 151. */
|
|
120 printf("hello \045\151", msg); /* { dg-warning "format '%i' expects argument of type 'int', but argument 2 has type 'const char\\*' " } */
|
|
121
|
|
122 /* { dg-begin-multiline-output "" }
|
|
123 printf("hello \045\151", msg);
|
|
124 ~~~~^~~~ ~~~
|
|
125 | |
|
|
126 int const char*
|
|
127 \045s
|
|
128 { dg-end-multiline-output "" } */
|
|
129 }
|
|
130
|
|
131 void test_multiple (const char *msg)
|
|
132 {
|
|
133 /* "%" is \x25 in hex
|
|
134 "i" is \151 in octal. */
|
|
135 printf("prefix" "\x25" "\151" "suffix", /* { dg-warning "format '%i'" } */
|
|
136 msg);
|
|
137 /* { dg-begin-multiline-output "" }
|
|
138 printf("prefix" "\x25" "\151" "suffix",
|
|
139 ~~~~~~~~^~~~
|
|
140 |
|
|
141 int
|
|
142 \x25" "s
|
|
143 msg);
|
|
144 ~~~
|
|
145 |
|
|
146 const char*
|
|
147 { dg-end-multiline-output "" } */
|
|
148 }
|
|
149
|
|
150 void test_param (long long_i, long long_j)
|
|
151 {
|
|
152 printf ("foo %s bar", long_i + long_j); /* { dg-warning "17: format '%s' expects argument of type 'char\\*', but argument 2 has type 'long int'" } */
|
|
153 /* { dg-begin-multiline-output "" }
|
|
154 printf ("foo %s bar", long_i + long_j);
|
|
155 ~^ ~~~~~~~~~~~~~~~
|
|
156 | |
|
|
157 char* long int
|
|
158 %ld
|
|
159 { dg-end-multiline-output "" } */
|
|
160 }
|
|
161
|
|
162 void test_field_width_specifier (long l, int i1, int i2)
|
|
163 {
|
|
164 printf (" %*.*d ", l, i1, i2); /* { dg-warning "14: field width specifier '\\*' expects argument of type 'int', but argument 2 has type 'long int'" } */
|
|
165 /* { dg-begin-multiline-output "" }
|
|
166 printf (" %*.*d ", l, i1, i2);
|
|
167 ~^~~~ ~
|
|
168 | |
|
|
169 int long int
|
|
170 { dg-end-multiline-output "" } */
|
|
171 }
|
|
172
|
|
173 /* PR c/72857. */
|
|
174
|
|
175 void test_field_width_specifier_2 (char *d, long foo, long bar)
|
|
176 {
|
|
177 __builtin_sprintf (d, " %*ld ", foo, foo); /* { dg-warning "28: field width specifier '\\*' expects argument of type 'int', but argument 3 has type 'long int'" } */
|
|
178 /* { dg-begin-multiline-output "" }
|
|
179 __builtin_sprintf (d, " %*ld ", foo, foo);
|
|
180 ~^~~ ~~~
|
|
181 | |
|
|
182 int long int
|
|
183 { dg-end-multiline-output "" } */
|
|
184
|
|
185 __builtin_sprintf (d, " %*ld ", foo + bar, foo); /* { dg-warning "28: field width specifier '\\*' expects argument of type 'int', but argument 3 has type 'long int'" } */
|
|
186 /* { dg-begin-multiline-output "" }
|
|
187 __builtin_sprintf (d, " %*ld ", foo + bar, foo);
|
|
188 ~^~~ ~~~~~~~~~
|
|
189 | |
|
|
190 int long int
|
|
191 { dg-end-multiline-output "" } */
|
|
192 }
|
|
193
|
|
194 void test_field_precision_specifier (char *d, long foo, long bar)
|
|
195 {
|
|
196 __builtin_sprintf (d, " %.*ld ", foo, foo); /* { dg-warning "29: field precision specifier '\\.\\*' expects argument of type 'int', but argument 3 has type 'long int'" } */
|
|
197 /* { dg-begin-multiline-output "" }
|
|
198 __builtin_sprintf (d, " %.*ld ", foo, foo);
|
|
199 ~~^~~ ~~~
|
|
200 | |
|
|
201 int long int
|
|
202 { dg-end-multiline-output "" } */
|
|
203
|
|
204 __builtin_sprintf (d, " %.*ld ", foo + bar, foo); /* { dg-warning "29: field precision specifier '\\.\\*' expects argument of type 'int', but argument 3 has type 'long int'" } */
|
|
205 /* { dg-begin-multiline-output "" }
|
|
206 __builtin_sprintf (d, " %.*ld ", foo + bar, foo);
|
|
207 ~~^~~ ~~~~~~~~~
|
|
208 | |
|
|
209 int long int
|
|
210 { dg-end-multiline-output "" } */
|
|
211 }
|
|
212
|
|
213 void test_spurious_percent (void)
|
|
214 {
|
|
215 printf("hello world %"); /* { dg-warning "23: spurious trailing" } */
|
|
216
|
|
217 /* { dg-begin-multiline-output "" }
|
|
218 printf("hello world %");
|
|
219 ^
|
|
220 { dg-end-multiline-output "" } */
|
|
221 }
|
|
222
|
|
223 void test_empty_precision (char *s, size_t m, double d)
|
|
224 {
|
|
225 strfmon (s, m, "%#.5n", d); /* { dg-warning "20: empty left precision in gnu_strfmon format" } */
|
|
226 /* { dg-begin-multiline-output "" }
|
|
227 strfmon (s, m, "%#.5n", d);
|
|
228 ^
|
|
229 { dg-end-multiline-output "" } */
|
|
230
|
|
231 strfmon (s, m, "%#5.n", d); /* { dg-warning "22: empty precision in gnu_strfmon format" } */
|
|
232 /* { dg-begin-multiline-output "" }
|
|
233 strfmon (s, m, "%#5.n", d);
|
|
234 ^
|
|
235 { dg-end-multiline-output "" } */
|
|
236 }
|
|
237
|
|
238 void test_repeated (int i)
|
|
239 {
|
|
240 printf ("%++d", i); /* { dg-warning "14: repeated '\\+' flag in format" } */
|
|
241 /* { dg-begin-multiline-output "" }
|
|
242 printf ("%++d", i);
|
|
243 ^
|
|
244 { dg-end-multiline-output "" } */
|
|
245 }
|
|
246
|
|
247 void test_conversion_lacks_type (void)
|
|
248 {
|
|
249 printf (" %h"); /* { dg-warning "14:conversion lacks type at end of format" } */
|
|
250 /* { dg-begin-multiline-output "" }
|
|
251 printf (" %h");
|
|
252 ^
|
|
253 { dg-end-multiline-output "" } */
|
|
254 }
|
|
255
|
|
256 void test_embedded_nul (void)
|
|
257 {
|
|
258 printf (" \0 "); /* { dg-warning "13:embedded" "warning for embedded NUL" } */
|
|
259 /* { dg-begin-multiline-output "" }
|
|
260 printf (" \0 ");
|
|
261 ^~
|
|
262 { dg-end-multiline-output "" } */
|
|
263 }
|
|
264
|
|
265 void test_macro (const char *msg)
|
|
266 {
|
|
267 #define INT_FMT "%i" /* { dg-message "19: format string is defined here" } */
|
|
268 printf("hello " INT_FMT " world", msg); /* { dg-warning "10: format '%i' expects argument of type 'int', but argument 2 has type 'const char\\*' " } */
|
|
269 /* { dg-begin-multiline-output "" }
|
|
270 printf("hello " INT_FMT " world", msg);
|
|
271 ^~~~~~~~~~~~~~~~~~~~~~~~~ ~~~
|
|
272 |
|
|
273 const char*
|
|
274 { dg-end-multiline-output "" } */
|
|
275 /* { dg-begin-multiline-output "" }
|
|
276 #define INT_FMT "%i"
|
|
277 ~^
|
|
278 |
|
|
279 int
|
|
280 %s
|
|
281 { dg-end-multiline-output "" } */
|
|
282 #undef INT_FMT
|
|
283 }
|
|
284
|
|
285 void test_macro_2 (const char *msg)
|
|
286 {
|
|
287 #define PRIu32 "u" /* { dg-message "17: format string is defined here" } */
|
|
288 printf("hello %" PRIu32 " world", msg); /* { dg-warning "10: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'const char\\*' " } */
|
|
289 /* { dg-begin-multiline-output "" }
|
|
290 printf("hello %" PRIu32 " world", msg);
|
|
291 ^~~~~~~~~~~~~~~~~~~~~~~~~ ~~~
|
|
292 |
|
|
293 const char*
|
|
294 { dg-end-multiline-output "" } */
|
|
295 /* { dg-begin-multiline-output "" }
|
|
296 #define PRIu32 "u"
|
|
297 ^
|
|
298 |
|
|
299 unsigned int
|
|
300 { dg-end-multiline-output "" } */
|
|
301 #undef PRIu32
|
|
302 }
|
|
303
|
|
304 void test_macro_3 (const char *msg)
|
|
305 {
|
|
306 #define FMT_STRING "hello %i world" // { dg-line test_macro_3_macro_line }
|
|
307 /* { dg-warning "20: format '%i' expects argument of type 'int', but argument 2 has type 'const char\\*'" "" { target *-*-* } .-1 } */
|
|
308 printf(FMT_STRING, msg); /* { dg-message "10: in expansion of macro 'FMT_STRING" } */
|
|
309 /* { dg-begin-multiline-output "" }
|
|
310 #define FMT_STRING "hello %i world"
|
|
311 ^~~~~~~~~~~~~~~~
|
|
312 { dg-end-multiline-output "" } */
|
|
313 /* { dg-begin-multiline-output "" }
|
|
314 printf(FMT_STRING, msg);
|
|
315 ^~~~~~~~~~
|
|
316 { dg-end-multiline-output "" } */
|
|
317 /* { dg-message "28: format string is defined here" "" { target *-*-* } test_macro_3_macro_line } */
|
|
318 /* { dg-begin-multiline-output "" }
|
|
319 #define FMT_STRING "hello %i world"
|
|
320 ~^
|
|
321 |
|
|
322 int
|
|
323 %s
|
|
324 { dg-end-multiline-output "" } */
|
|
325 #undef FMT_STRING
|
|
326 }
|
|
327
|
|
328 void test_macro_4 (const char *msg)
|
|
329 {
|
|
330 #define FMT_STRING "hello %i world" /* { dg-warning "20: format '%i' expects argument of type 'int', but argument 2 has type 'const char\\*' " } */
|
|
331 printf(FMT_STRING "\n", msg); /* { dg-message "10: in expansion of macro 'FMT_STRING" } */
|
|
332 /* { dg-begin-multiline-output "" }
|
|
333 #define FMT_STRING "hello %i world"
|
|
334 ^
|
|
335 { dg-end-multiline-output "" } */
|
|
336 /* { dg-begin-multiline-output "" }
|
|
337 printf(FMT_STRING "\n", msg);
|
|
338 ^~~~~~~~~~
|
|
339 { dg-end-multiline-output "" } */
|
|
340 /* { dg-begin-multiline-output "" }
|
|
341 #define FMT_STRING "hello %i world"
|
|
342 ~^
|
|
343 |
|
|
344 int
|
|
345 %s
|
|
346 { dg-end-multiline-output "" } */
|
|
347 #undef FMT_STRING
|
|
348 }
|
|
349
|
|
350 void test_non_contiguous_strings (void)
|
|
351 {
|
|
352 __builtin_printf(" %" "d ", 0.5); /* { dg-warning "26: format .%d. expects argument of type .int., but argument 2 has type .double." } */
|
|
353 /* { dg-begin-multiline-output "" }
|
|
354 __builtin_printf(" %" "d ", 0.5);
|
|
355 ~~~~^ ~~~
|
|
356 | |
|
|
357 int double
|
|
358 %" "f
|
|
359 { dg-end-multiline-output "" } */
|
|
360 }
|
|
361
|
|
362 void test_const_arrays (void)
|
|
363 {
|
|
364 /* TODO: ideally we'd highlight both the format string *and* the use of
|
|
365 it here. For now, just verify that we gracefully handle this case. */
|
|
366 const char a[] = " %d ";
|
|
367 __builtin_printf(a, 0.5); /* { dg-warning "20: format .%d. expects argument of type .int., but argument 2 has type .double." } */
|
|
368 /* { dg-begin-multiline-output "" }
|
|
369 __builtin_printf(a, 0.5);
|
|
370 ^ ~~~
|
|
371 |
|
|
372 double
|
|
373 { dg-end-multiline-output "" } */
|
|
374 }
|