1// RUN: %check_clang_tidy -check-suffixes=,STRICT \
2// RUN: -std=c++23 %s modernize-use-std-print %t -- \
3// RUN: -config="{CheckOptions: {StrictMode: true}}" \
4// RUN: -- -isystem %clang_tidy_headers -fexceptions
5// RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \
6// RUN: -std=c++23 %s modernize-use-std-print %t -- \
7// RUN: -config="{CheckOptions: {StrictMode: false}}" \
8// RUN: -- -isystem %clang_tidy_headers -fexceptions
9#include <cstddef>
10#include <cstdint>
11#include <cstdio>
12// CHECK-FIXES: #include <print>
13#include <inttypes.h>
14#include <string.h>
15#include <string>
16
17template <typename T>
18struct iterator {
19 T *operator->();
20 T &operator*();
21};
22
23void printf_simple() {
24 printf(format: "Hello");
25 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
26 // CHECK-FIXES: std::print("Hello");
27}
28
29void printf_newline() {
30 printf(format: "Hello\n");
31 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
32 // CHECK-FIXES: std::println("Hello");
33
34 printf(format: "Split" "\n");
35 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
36 // CHECK-FIXES: std::println("Split");
37
38 printf(format: "Double\n\n");
39 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
40 // CHECK-FIXES: std::println("Double\n");
41}
42
43void printf_deceptive_newline() {
44 printf(format: "Hello\\n");
45 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
46 // CHECK-FIXES: std::print("Hello\\n");
47
48 printf(format: "Hello\x0a");
49 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
50 // CHECK-FIXES: std::println("Hello");
51}
52
53void printf_crlf_newline() {
54 printf(format: "Hello\r\n");
55 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
56 // CHECK-FIXES: std::print("Hello\r\n");
57
58 printf(format: "Hello\r\\n");
59 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
60 // CHECK-FIXES: std::print("Hello\r\\n");
61}
62
63// std::print returns nothing, so any callers that use the return
64// value cannot be automatically translated.
65int printf_uses_return_value(int choice) {
66 const int i = printf(format: "Return value assigned to variable %d\n", 42);
67
68 extern void accepts_int(int);
69 accepts_int(printf(format: "Return value passed to function %d\n", 42));
70
71 if (choice == 0)
72 printf(format: "if body %d\n", i);
73 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
74 // CHECK-FIXES: std::println("if body {}", i);
75 else if (choice == 1)
76 printf(format: "else if body %d\n", i);
77 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
78 // CHECK-FIXES: std::println("else if body {}", i);
79 else
80 printf(format: "else body %d\n", i);
81 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
82 // CHECK-FIXES: std::println("else body {}", i);
83
84 if (printf(format: "Return value used as boolean in if statement"))
85 if (printf(format: "Return value used in expression if statement") == 44)
86 if (const int j = printf(format: "Return value used in assignment in if statement"))
87 if (const int k = printf(format: "Return value used with initializer in if statement"); k == 44)
88 ;
89
90 int d = 0;
91 while (printf(format: "%d", d) < 2)
92 ++d;
93
94 while (true)
95 printf(format: "while body %d\n", i);
96 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
97 // CHECK-FIXES: std::println("while body {}", i);
98
99 do
100 printf(format: "do body %d\n", i);
101 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
102 // CHECK-FIXES: std::println("do body {}", i);
103 while (true);
104
105 for (;;)
106 printf(format: "for body %d\n", i);
107 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
108 // CHECK-FIXES: std::println("for body {}", i);
109
110 for (printf(format: "for init statement %d\n", i);;)
111 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
112 // CHECK-FIXES: std::println("for init statement {}", i);
113 ;;
114
115 for (int j = printf(format: "for init statement %d\n", i);;)
116 ;;
117
118 for (; printf(format: "for condition %d\n", i);)
119 ;;
120
121 for (;; printf(format: "for expression %d\n", i))
122 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
123 // CHECK-FIXES: std::println("for expression {}", i)
124 ;;
125
126 for (auto C : "foo")
127 printf(format: "ranged-for body %d\n", i);
128 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
129 // CHECK-FIXES: std::println("ranged-for body {}", i);
130
131 switch (1) {
132 case 1:
133 printf(format: "switch case body %d\n", i);
134 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
135 // CHECK-FIXES: std::println("switch case body {}", i);
136 break;
137 default:
138 printf(format: "switch default body %d\n", i);
139 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
140 // CHECK-FIXES: std::println("switch default body {}", i);
141 break;
142 }
143
144 try {
145 printf(format: "try body %d\n", i);
146 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
147 // CHECK-FIXES: std::println("try body {}", i);
148 } catch (int) {
149 printf(format: "catch body %d\n", i);
150 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
151 // CHECK-FIXES: std::println("catch body {}", i);
152 }
153
154 (printf(format: "Parenthesised expression %d\n", i));
155 // CHECK-MESSAGES: [[@LINE-1]]:4: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
156 // CHECK-FIXES: (std::println("Parenthesised expression {}", i));
157
158 // Ideally we would convert these two, but the current check doesn't cope with
159 // that.
160 (void)printf(format: "cast to void %d\n", i);
161 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
162 // CHECK-FIXES-NOT: std::println("cast to void {}", i);
163
164 static_cast<void>(printf(format: "static_cast to void %d\n", i));
165 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
166 // CHECK-FIXES-NOT: std::println("static cast to void {}", i);
167
168 const int x = ({ printf(format: "GCC statement expression using return value immediately %d\n", i); });
169 const int y = ({ const int y = printf(format: "GCC statement expression using return value immediately %d\n", i); y; });
170
171 // Ideally we would convert this one, but the current check doesn't cope with
172 // that.
173 ({ printf(format: "GCC statement expression with unused result %d\n", i); });
174 // CHECK-MESSAGES-NOT: [[@LINE-1]]:6: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
175 // CHECK-FIXES-NOT: std::println("GCC statement expression with unused result {}", i);
176
177 return printf(format: "Return value used in return\n");
178}
179
180int fprintf_uses_return_value(int choice) {
181 const int i = fprintf(stderr, format: "Return value assigned to variable %d\n", 42);
182
183 extern void accepts_int(int);
184 accepts_int(fprintf(stderr, format: "Return value passed to function %d\n", 42));
185
186 if (choice == 0)
187 fprintf(stderr, format: "if body %d\n", i);
188 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
189 // CHECK-FIXES: std::println(stderr, "if body {}", i);
190 else if (choice == 1)
191 fprintf(stderr, format: "else if body %d\n", i);
192 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
193 // CHECK-FIXES: std::println(stderr, "else if body {}", i);
194 else
195 fprintf(stderr, format: "else body %d\n", i);
196 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
197 // CHECK-FIXES: std::println(stderr, "else body {}", i);
198
199 if (fprintf(stderr, format: "Return value used as boolean in if statement"))
200 if (fprintf(stderr, format: "Return value used in expression if statement") == 44)
201 if (const int j = fprintf(stderr, format: "Return value used in assignment in if statement"))
202 if (const int k = fprintf(stderr, format: "Return value used with initializer in if statement"); k == 44)
203 ;
204
205 int d = 0;
206 while (fprintf(stderr, format: "%d", d) < 2)
207 ++d;
208
209 while (true)
210 fprintf(stderr, format: "while body %d\n", i);
211 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
212 // CHECK-FIXES: std::println(stderr, "while body {}", i);
213
214 do
215 fprintf(stderr, format: "do body %d\n", i);
216 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
217 // CHECK-FIXES: std::println(stderr, "do body {}", i);
218 while (true);
219
220 for (;;)
221 fprintf(stderr, format: "for body %d\n", i);
222 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
223 // CHECK-FIXES: std::println(stderr, "for body {}", i);
224
225 for (fprintf(stderr, format: "for init statement %d\n", i);;)
226 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
227 // CHECK-FIXES: std::println(stderr, "for init statement {}", i);
228 ;;
229
230 for (int j = fprintf(stderr, format: "for init statement %d\n", i);;)
231 ;;
232
233 for (; fprintf(stderr, format: "for condition %d\n", i);)
234 ;;
235
236 for (;; fprintf(stderr, format: "for expression %d\n", i))
237 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
238 // CHECK-FIXES: std::println(stderr, "for expression {}", i)
239 ;;
240
241 for (auto C : "foo")
242 fprintf(stderr, format: "ranged-for body %d\n", i);
243 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
244 // CHECK-FIXES: std::println(stderr, "ranged-for body {}", i);
245
246 switch (1) {
247 case 1:
248 fprintf(stderr, format: "switch case body %d\n", i);
249 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
250 // CHECK-FIXES: std::println(stderr, "switch case body {}", i);
251 break;
252 default:
253 fprintf(stderr, format: "switch default body %d\n", i);
254 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
255 // CHECK-FIXES: std::println(stderr, "switch default body {}", i);
256 break;
257 }
258
259 try {
260 fprintf(stderr, format: "try body %d\n", i);
261 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
262 // CHECK-FIXES: std::println(stderr, "try body {}", i);
263 } catch (int) {
264 fprintf(stderr, format: "catch body %d\n", i);
265 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
266 // CHECK-FIXES: std::println(stderr, "catch body {}", i);
267 }
268
269
270 (printf(format: "Parenthesised expression %d\n", i));
271 // CHECK-MESSAGES: [[@LINE-1]]:4: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
272 // CHECK-FIXES: (std::println("Parenthesised expression {}", i));
273
274 // Ideally we would convert these two, but the current check doesn't cope with
275 // that.
276 (void)fprintf(stderr, format: "cast to void %d\n", i);
277 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
278 // CHECK-FIXES-NOT: std::println(stderr, "cast to void {}", i);
279
280 static_cast<void>(fprintf(stderr, format: "static_cast to void %d\n", i));
281 // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
282 // CHECK-FIXES-NOT: std::println(stderr, "static cast to void {}", i);
283
284 const int x = ({ fprintf(stderr, format: "GCC statement expression using return value immediately %d\n", i); });
285 const int y = ({ const int y = fprintf(stderr, format: "GCC statement expression using return value immediately %d\n", i); y; });
286
287 // Ideally we would convert this one, but the current check doesn't cope with
288 // that.
289 ({ fprintf(stderr, format: "GCC statement expression with unused result %d\n", i); });
290 // CHECK-MESSAGES-NOT: [[@LINE-1]]:6: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
291 // CHECK-FIXES-NOT: std::println("GCC statement expression with unused result {}", i);
292
293 return fprintf(stderr, format: "Return value used in return\n");
294}
295
296void fprintf_simple() {
297 fprintf(stderr, format: "Hello");
298 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print]
299 // CHECK-FIXES: std::print(stderr, "Hello");
300}
301
302void std_printf_simple() {
303 std::printf(format: "std::Hello");
304 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
305 // CHECK-FIXES: std::print("std::Hello");
306}
307
308void printf_escape() {
309 printf(format: "before \t");
310 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
311 // CHECK-FIXES: std::print("before \t");
312
313 printf(format: "\n after");
314 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
315 // CHECK-FIXES: std::print("\n after");
316
317 printf(format: "before \a after");
318 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
319 // CHECK-FIXES: std::print("before \a after");
320
321 printf(format: "Bell\a%dBackspace\bFF%s\fNewline\nCR\rTab\tVT\vEscape\x1b\x07%d", 42, "string", 99);
322 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
323 // CHECK-FIXES: std::print("Bell\a{}Backspace\bFF{}\fNewline\nCR\rTab\tVT\vEscape\x1b\a{}", 42, "string", 99);
324
325 printf(format: "not special \x1b\x01\x7f");
326 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
327 // CHECK-FIXES: std::print("not special \x1b\x01\x7f");
328}
329
330void printf_percent() {
331 printf(format: "before %%");
332 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
333 // CHECK-FIXES: std::print("before %");
334
335 printf(format: "%% after");
336 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
337 // CHECK-FIXES: std::print("% after");
338
339 printf(format: "before %% after");
340 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
341 // CHECK-FIXES: std::print("before % after");
342
343 printf(format: "Hello %% and another %%");
344 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
345 // CHECK-FIXES: std::print("Hello % and another %");
346
347 printf(format: "Not a string %%s");
348 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
349 // CHECK-FIXES: std::print("Not a string %s");
350}
351
352void printf_curlies() {
353 printf(format: "%d {}", 42);
354 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
355 // CHECK-FIXES: std::print("{} {{[{][{]}}}}", 42);
356
357 printf(format: "{}");
358 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
359 // CHECK-FIXES: std::print("{{[{][{]}}}}");
360}
361
362void printf_unsupported_format_specifiers() {
363 int pos;
364 printf(format: "%d %n %d\n", 42, &pos, 72);
365 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::println' instead of 'printf' because '%n' is not supported in format string [modernize-use-std-print]
366
367 printf(format: "Error %m\n");
368 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::println' instead of 'printf' because '%m' is not supported in format string [modernize-use-std-print]
369}
370
371void printf_not_string_literal(const char *fmt) {
372 // We can't convert the format string if it's not a literal
373 printf(format: fmt, 42);
374}
375
376void printf_inttypes_ugliness() {
377 // The one advantage of the checker seeing the token pasted version of the
378 // format string is that we automatically cope with the horrendously-ugly
379 // inttypes.h macros!
380 int64_t u64 = 42;
381 uintmax_t umax = 4242;
382 printf(format: "uint64:%" PRId64 " uintmax:%" PRIuMAX "\n", u64, umax);
383 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
384 // CHECK-FIXES: std::println("uint64:{} uintmax:{}", u64, umax);
385}
386
387void printf_raw_string() {
388 // This one doesn't require the format string to be changed, so it stays intact
389 printf(format: R"(First\Second)");
390 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
391 // CHECK-FIXES: std::print(R"(First\Second)");
392
393 // This one does require the format string to be changed, so unfortunately it
394 // gets reformatted as a normal string.
395 printf(format: R"(First %d\Second)", 42);
396 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
397 // CHECK-FIXES: std::print("First {}\\Second", 42);
398}
399
400void printf_integer_d() {
401 const bool b = true;
402 // The "d" type is necessary here for compatibility with printf since
403 // std::print will print booleans as "true" or "false".
404 printf(format: "Integer %d from bool\n", b);
405 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
406 // CHECK-FIXES: std::println("Integer {:d} from bool", b);
407
408 // The "d" type is necessary here for compatibility with printf since
409 // std::print will print booleans as "true" or "false".
410 printf(format: "Integer %i from bool\n", b);
411 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
412 // CHECK-FIXES: std::println("Integer {:d} from bool", b);
413
414 // The 'd' is always necessary if we pass a char since otherwise the
415 // parameter will be formatted as a character. In StrictMode, the
416 // cast is always necessary to maintain the printf behaviour since
417 // char may be unsigned, but this also means that the 'd' is not
418 // necessary.
419 const char c = 'A';
420 printf(format: "Integers %d %hhd from char\n", c, c);
421 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
422 // CHECK-FIXES-NOTSTRICT: std::println("Integers {:d} {:d} from char", c, c);
423 // CHECK-FIXES-STRICT: std::println("Integers {} {} from char", static_cast<signed char>(c), static_cast<signed char>(c));
424
425 printf(format: "Integers %i %hhi from char\n", c, c);
426 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
427 // CHECK-FIXES-NOTSTRICT: std::println("Integers {:d} {:d} from char", c, c);
428 // CHECK-FIXES-STRICT: std::println("Integers {} {} from char", static_cast<signed char>(c), static_cast<signed char>(c));
429
430 const signed char sc = 'A';
431 printf(format: "Integers %d %hhd from signed char\n", sc, sc);
432 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
433 // CHECK-FIXES: std::println("Integers {} {} from signed char", sc, sc);
434
435 printf(format: "Integers %i %hhi from signed char\n", sc, sc);
436 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
437 // CHECK-FIXES: std::println("Integers {} {} from signed char", sc, sc);
438
439 const unsigned char uc = 'A';
440 printf(format: "Integers %d %hhd from unsigned char\n", uc, uc);
441 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
442 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} {} from unsigned char", uc, uc);
443 // CHECK-FIXES-STRICT: std::println("Integers {} {} from unsigned char", static_cast<signed char>(uc), static_cast<signed char>(uc));
444
445 printf(format: "Integers %i %hhi from unsigned char\n", uc, uc);
446 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
447 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} {} from unsigned char", uc, uc);
448 // CHECK-FIXES-STRICT: std::println("Integers {} {} from unsigned char", static_cast<signed char>(uc), static_cast<signed char>(uc));
449
450 const int8_t i8 = 42;
451 printf(format: "Integer %" PRIi8 " from int8_t\n", i8);
452 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
453 // CHECK-FIXES: std::println("Integer {} from int8_t", i8);
454
455 const int_fast8_t if8 = 42;
456 printf(format: "Integer %" PRIiFAST8 " from int_fast8_t\n", if8);
457 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
458 // CHECK-FIXES: std::println("Integer {} from int_fast8_t", if8);
459
460 const int_least8_t il8 = 42;
461 printf(format: "Integer %" PRIiFAST8 " from int_least8_t\n", il8);
462 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
463 // CHECK-FIXES: std::println("Integer {} from int_least8_t", il8);
464
465 const uint8_t u8 = 42U;
466 const std::uint8_t su8 = u8;
467 printf(format: "Integers %" PRIi8 " and %" PRId8 " from uint8_t\n", u8, su8);
468 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
469 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uint8_t", u8, su8);
470 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uint8_t", static_cast<int8_t>(u8), static_cast<std::int8_t>(su8));
471
472 const uint_fast8_t uf8 = 42U;
473 printf(format: "Integer %" PRIiFAST8 " from uint_fast8_t\n", uf8);
474 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
475 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_fast8_t", uf8);
476 // CHECK-FIXES-STRICT: std::println("Integer {} from uint_fast8_t", static_cast<int_fast8_t>(uf8));
477
478 const uint_least8_t ul8 = 42U;
479 printf(format: "Integer %" PRIiLEAST8 " from uint_least8_t\n", ul8);
480 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
481 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_least8_t", ul8);
482 // CHECK-FIXES-STRICT: std::println("Integer {} from uint_least8_t", static_cast<int_least8_t>(ul8));
483
484 const short s = 42;
485 printf(format: "Integer %hd from short\n", s);
486 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
487 // CHECK-FIXES: std::println("Integer {} from short", s);
488
489 printf(format: "Integer %hi from short\n", s);
490 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
491 // CHECK-FIXES: std::println("Integer {} from short", s);
492
493 const unsigned short us = 42U;
494 printf(format: "Integer %hd from unsigned short\n", us);
495 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
496 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us);
497 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us));
498
499 printf(format: "Integer %hi from unsigned short\n", us);
500 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
501 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us);
502 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us));
503
504 const int i = 42;
505 printf(format: "Integer %d from integer\n", i);
506 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
507 // CHECK-FIXES: std::println("Integer {} from integer", i);
508
509 printf(format: "Integer %i from integer\n", i);
510 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
511 // CHECK-FIXES: std::println("Integer {} from integer", i);
512
513 const unsigned int ui = 42U;
514 printf(format: "Integer %d from unsigned integer\n", ui);
515 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
516 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui);
517 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui));
518
519 printf(format: "Integer %i from unsigned integer\n", ui);
520 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
521 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui);
522 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui));
523
524 const long l = 42L;
525 printf(format: "Integer %ld from long\n", l);
526 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
527 // CHECK-FIXES: std::println("Integer {} from long", l);
528
529 printf(format: "Integer %li from long\n", l);
530 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
531 // CHECK-FIXES: std::println("Integer {} from long", l);
532
533 const unsigned long ul = 42UL;
534 printf(format: "Integer %ld from unsigned long\n", ul);
535 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
536 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul);
537 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul));
538
539 printf(format: "Integer %li from unsigned long\n", ul);
540 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
541 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul);
542 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul));
543
544 const long long ll = 42LL;
545 printf(format: "Integer %lld from long long\n", ll);
546 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
547 // CHECK-FIXES: std::println("Integer {} from long long", ll);
548
549 printf(format: "Integer %lli from long long\n", ll);
550 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
551 // CHECK-FIXES: std::println("Integer {} from long long", ll);
552
553 const unsigned long long ull = 42ULL;
554 printf(format: "Integer %lld from unsigned long long\n", ull);
555 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
556 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull);
557 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull));
558
559 printf(format: "Integer %lli from unsigned long long\n", ull);
560 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
561 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull);
562 // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull));
563
564 const intmax_t im = 42;
565 const std::intmax_t sim = im;
566 printf(format: "Integers %jd and %jd from intmax_t\n", im, sim);
567 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
568 // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim);
569
570 printf(format: "Integers %ji and %ji from intmax_t\n", im, sim);
571 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
572 // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim);
573
574 const uintmax_t uim = 42;
575 const std::uintmax_t suim = uim;
576 printf(format: "Integers %jd and %jd from uintmax_t\n", uim, suim);
577 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
578 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uintmax_t", uim, suim);
579 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uintmax_t", static_cast<intmax_t>(uim), static_cast<std::intmax_t>(suim));
580
581 printf(format: "Integer %ji from intmax_t\n", uim);
582 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
583 // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from intmax_t", uim);
584 // CHECK-FIXES-STRICT: std::println("Integer {} from intmax_t", static_cast<intmax_t>(uim));
585
586 const int ai[] = { 0, 1, 2, 3};
587 const ptrdiff_t pd = &ai[3] - &ai[0];
588 const std::ptrdiff_t spd = pd;
589 printf(format: "Integers %td and %td from ptrdiff_t\n", pd, spd);
590 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
591 // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd);
592
593 printf(format: "Integers %ti and %ti from ptrdiff_t\n", pd, spd);
594 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
595 // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd);
596
597 const size_t z = 42UL;
598 const std::size_t sz = z;
599 printf(format: "Integers %zd and %zd from size_t\n", z, sz);
600 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
601 // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from size_t", z, sz);
602 // CHECK-FIXES-STRICT: std::println("Integers {} and {} from size_t", static_cast<ssize_t>(z), static_cast<std::ssize_t>(sz));
603}
604
605void printf_integer_u()
606{
607 const bool b = true;
608 // The "d" type is necessary here for compatibility with printf since
609 // std::print will print booleans as "true" or "false".
610 printf(format: "Unsigned integer %u from bool\n", b);
611 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
612 // CHECK-FIXES: std::println("Unsigned integer {:d} from bool", b);
613
614 const char c = 'A';
615 printf(format: "Unsigned integer %hhu from char\n", c);
616 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
617 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {:d} from char", c);
618 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from char", static_cast<unsigned char>(c));
619
620 const signed char sc = 'A';
621 printf(format: "Unsigned integer %hhu from signed char\n", sc);
622 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
623 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc);
624 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc));
625
626 printf(format: "Unsigned integer %u from signed char\n", sc);
627 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
628 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc);
629 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc));
630
631 const unsigned char uc = 'A';
632 printf(format: "Unsigned integer %hhu from unsigned char\n", uc);
633 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
634 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc);
635
636 printf(format: "Unsigned integer %u from unsigned char\n", uc);
637 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
638 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc);
639
640 const int8_t i8 = 42;
641 printf(format: "Unsigned integer %" PRIu8 " from int8_t\n", i8);
642 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
643 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int8_t", i8);
644 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int8_t", static_cast<uint8_t>(i8));
645
646 const int_fast8_t if8 = 42;
647 printf(format: "Unsigned integer %" PRIuFAST8 " from int_fast8_t\n", if8);
648 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
649 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_fast8_t", if8);
650 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_fast8_t", static_cast<uint_fast8_t>(if8));
651
652 const int_least8_t il8 = 42;
653 printf(format: "Unsigned integer %" PRIuFAST8 " from int_least8_t\n", il8);
654 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
655 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_least8_t", il8);
656 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_least8_t", static_cast<uint_least8_t>(il8));
657
658 const uint8_t u8 = 42U;
659 printf(format: "Unsigned integer %" PRIu8 " from uint8_t\n", u8);
660 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
661 // CHECK-FIXES: std::println("Unsigned integer {} from uint8_t", u8);
662
663 const uint_fast8_t uf8 = 42U;
664 printf(format: "Unsigned integer %" PRIuFAST8 " from uint_fast8_t\n", uf8);
665 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
666 // CHECK-FIXES: std::println("Unsigned integer {} from uint_fast8_t", uf8);
667
668 const uint_least8_t ul8 = 42U;
669 printf(format: "Unsigned integer %" PRIuLEAST8 " from uint_least8_t\n", ul8);
670 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
671 // CHECK-FIXES: std::println("Unsigned integer {} from uint_least8_t", ul8);
672
673 const short s = 42;
674 printf(format: "Unsigned integer %hu from short\n", s);
675 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
676 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from short", s);
677 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from short", static_cast<unsigned short>(s));
678
679 const unsigned short us = 42U;
680 printf(format: "Unsigned integer %hu from unsigned short\n", us);
681 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
682 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned short", us);
683
684 const int i = 42;
685 printf(format: "Unsigned integer %u from signed integer\n", i);
686 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
687 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed integer", i);
688 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed integer", static_cast<unsigned int>(i));
689
690 const unsigned int ui = 42U;
691 printf(format: "Unsigned integer %u from unsigned integer\n", ui);
692 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
693 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned integer", ui);
694
695 const long l = 42L;
696 printf(format: "Unsigned integer %u from signed long\n", l);
697 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
698 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed long", l);
699 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed long", static_cast<unsigned long>(l));
700
701 const unsigned long ul = 42UL;
702 printf(format: "Unsigned integer %lu from unsigned long\n", ul);
703 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
704 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long", ul);
705
706 const long long ll = 42LL;
707 printf(format: "Unsigned integer %llu from long long\n", ll);
708 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
709 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from long long", ll);
710 // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from long long", static_cast<unsigned long long>(ll));
711
712 const unsigned long long ull = 42ULL;
713 printf(format: "Unsigned integer %llu from unsigned long long\n", ull);
714 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
715 // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long long", ull);
716
717 const intmax_t im = 42;
718 const std::intmax_t sim = im;
719 printf(format: "Unsigned integers %ju and %ju from intmax_t\n", im, sim);
720 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
721 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from intmax_t", im, sim);
722 // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from intmax_t", static_cast<uintmax_t>(im), static_cast<std::uintmax_t>(sim));
723
724 const uintmax_t uim = 42U;
725 const std::uintmax_t suim = uim;
726 printf(format: "Unsigned integers %ju and %ju from uintmax_t\n", uim, suim);
727 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
728 // CHECK-FIXES: std::println("Unsigned integers {} and {} from uintmax_t", uim, suim);
729
730 const int ai[] = { 0, 1, 2, 3};
731 const ptrdiff_t pd = &ai[3] - &ai[0];
732 const std::ptrdiff_t spd = pd;
733 printf(format: "Unsigned integers %tu and %tu from ptrdiff_t\n", pd, spd);
734 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
735 // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", pd, spd);
736 // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", static_cast<size_t>(pd), static_cast<std::size_t>(spd));
737
738 const size_t z = 42U;
739 const std::size_t sz = z;
740 printf(format: "Unsigned integers %zu and %zu from size_t\n", z, sz);
741 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
742 // CHECK-FIXES: std::println("Unsigned integers {} and {} from size_t", z, sz);
743}
744
745// This checks that we get the argument offset right with the extra FILE * argument
746void fprintf_integer() {
747 fprintf(stderr, format: "Integer %d from integer\n", 42);
748 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
749 // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 42);
750
751 fprintf(stderr, format: "Integer %i from integer\n", 65);
752 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
753 // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 65);
754
755 fprintf(stderr, format: "Integer %i from char\n", 'A');
756 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
757 // CHECK-FIXES-NOTSTRICT: std::println(stderr, "Integer {:d} from char", 'A');
758 // CHECK-FIXES-STRICT: std::println(stderr, "Integer {} from char", static_cast<signed char>('A'));
759
760 fprintf(stderr, format: "Integer %d from char\n", 'A');
761 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
762 // CHECK-FIXES-NOTSTRICT: std::println(stderr, "Integer {:d} from char", 'A');
763 // CHECK-FIXES-STRICT: std::println(stderr, "Integer {} from char", static_cast<signed char>('A'));
764}
765
766void printf_char() {
767 const char c = 'A';
768 printf(format: "Char %c from char\n", c);
769 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
770 // CHECK-FIXES: std::println("Char {} from char", c);
771
772 const signed char sc = 'A';
773 printf(format: "Char %c from signed char\n", sc);
774 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
775 // CHECK-FIXES: std::println("Char {:c} from signed char", sc);
776
777 const unsigned char uc = 'A';
778 printf(format: "Char %c from unsigned char\n", uc);
779 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
780 // CHECK-FIXES: std::println("Char {:c} from unsigned char", uc);
781
782 const int i = 65;
783 printf(format: "Char %c from integer\n", i);
784 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
785 // CHECK-FIXES: std::println("Char {:c} from integer", i);
786
787 const unsigned int ui = 65;
788 printf(format: "Char %c from unsigned integer\n", ui);
789 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
790 // CHECK-FIXES: std::println("Char {:c} from unsigned integer", ui);
791
792 const unsigned long long ull = 65;
793 printf(format: "Char %c from unsigned long long\n", ull);
794 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
795 // CHECK-FIXES: std::println("Char {:c} from unsigned long long", ull);
796}
797
798void printf_bases() {
799 printf(format: "Hex %lx\n", 42L);
800 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
801 // CHECK-FIXES: std::println("Hex {:x}", 42L);
802
803 printf(format: "HEX %X\n", 42);
804 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
805 // CHECK-FIXES: std::println("HEX {:X}", 42);
806
807 printf(format: "Oct %lo\n", 42L);
808 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
809 // CHECK-FIXES: std::println("Oct {:o}", 42L);
810}
811
812void printf_alternative_forms() {
813 printf(format: "Hex %#lx\n", 42L);
814 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
815 // CHECK-FIXES: std::println("Hex {:#x}", 42L);
816
817 printf(format: "HEX %#X\n", 42);
818 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
819 // CHECK-FIXES: std::println("HEX {:#X}", 42);
820
821 printf(format: "Oct %#lo\n", 42L);
822 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
823 // CHECK-FIXES: std::println("Oct {:#o}", 42L);
824
825 printf(format: "Double %#f %#F\n", -42.0, -42.0);
826 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
827 // CHECK-FIXES: std::println("Double {:#f} {:#F}", -42.0, -42.0);
828
829 printf(format: "Double %#g %#G\n", -42.0, -42.0);
830 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
831 // CHECK-FIXES: std::println("Double {:#g} {:#G}", -42.0, -42.0);
832
833 printf(format: "Double %#e %#E\n", -42.0, -42.0);
834 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
835 // CHECK-FIXES: std::println("Double {:#e} {:#E}", -42.0, -42.0);
836
837 printf(format: "Double %#a %#A\n", -42.0, -42.0);
838 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
839 // CHECK-FIXES: std::println("Double {:#a} {:#A}", -42.0, -42.0);
840
841 // Characters don't have an alternate form
842 printf(format: "Char %#c\n", 'A');
843 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
844 // CHECK-FIXES: std::println("Char {}", 'A');
845
846 // Strings don't have an alternate form
847 printf(format: "Char %#c\n", 'A');
848 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
849 // CHECK-FIXES: std::println("Char {}", 'A');
850}
851
852void printf_string() {
853 printf(format: "Hello %s after\n", "Goodbye");
854 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
855 // CHECK-FIXES: std::println("Hello {} after", "Goodbye");
856
857 // std::print can't print signed char strings.
858 const signed char *sstring = reinterpret_cast<const signed char *>("ustring");
859 printf(format: "signed char string %s\n", sstring);
860 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
861 // CHECK-FIXES: std::println("signed char string {}", reinterpret_cast<const char *>(sstring));
862
863 // std::print can't print unsigned char strings.
864 const unsigned char *ustring = reinterpret_cast<const unsigned char *>("ustring");
865 printf(format: "unsigned char string %s\n", ustring);
866 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
867 // CHECK-FIXES: std::println("unsigned char string {}", reinterpret_cast<const char *>(ustring));
868}
869
870void printf_float() {
871 // If the type is not specified then either f or e will be used depending on
872 // whichever is shorter. This means that it is necessary to be specific to
873 // maintain compatibility with printf.
874
875 // TODO: Should we force a cast here, since printf will promote to double
876 // automatically, but std::format will not, which could result in different
877 // output?
878
879 const float f = 42.0F;
880 printf(format: "Hello %f after\n", f);
881 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
882 // CHECK-FIXES: std::println("Hello {:f} after", f);
883
884 printf(format: "Hello %g after\n", f);
885 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
886 // CHECK-FIXES: std::println("Hello {:g} after", f);
887
888 printf(format: "Hello %e after\n", f);
889 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
890 // CHECK-FIXES: std::println("Hello {:e} after", f);
891}
892
893void printf_double() {
894 // If the type is not specified then either f or e will be used depending on
895 // whichever is shorter. This means that it is necessary to be specific to
896 // maintain compatibility with printf.
897
898 const double d = 42.0;
899 printf(format: "Hello %f after\n", d);
900 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
901 // CHECK-FIXES: std::println("Hello {:f} after", d);
902
903 printf(format: "Hello %g after\n", d);
904 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
905 // CHECK-FIXES: std::println("Hello {:g} after", d);
906
907 printf(format: "Hello %e after\n", d);
908 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
909 // CHECK-FIXES: std::println("Hello {:e} after", d);
910}
911
912void printf_long_double() {
913 // If the type is not specified then either f or e will be used depending on
914 // whichever is shorter. This means that it is necessary to be specific to
915 // maintain compatibility with printf.
916
917 const long double ld = 42.0L;
918 printf(format: "Hello %Lf after\n", ld);
919 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
920 // CHECK-FIXES: std::println("Hello {:f} after", ld);
921
922 printf(format: "Hello %g after\n", ld);
923 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
924 // CHECK-FIXES: std::println("Hello {:g} after", ld);
925
926 printf(format: "Hello %e after\n", ld);
927 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
928 // CHECK-FIXES: std::println("Hello {:e} after", ld);
929}
930
931void printf_pointer() {
932 int i;
933 double j;
934 printf(format: "Int* %p %s %p\n", &i, "Double*", &j);
935 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
936 // CHECK-FIXES: std::println("Int* {} {} {}", static_cast<const void *>(&i), "Double*", static_cast<const void *>(&j));
937
938 printf(format: "%p\n", nullptr);
939 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
940 // CHECK-FIXES: std::println("{}", nullptr);
941
942 const auto np = nullptr;
943 printf(format: "%p\n", np);
944 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
945 // CHECK-FIXES: std::println("{}", np);
946
947 // NULL isn't a pointer, so std::print needs some help.
948 printf(format: "%p\n", NULL);
949 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
950 // CHECK-FIXES: std::println("{}", static_cast<const void *>(NULL));
951
952 printf(format: "%p\n", 42);
953 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
954 // CHECK-FIXES: std::println("{}", static_cast<const void *>(42));
955
956 // If we already have a void pointer then no cast is required.
957 printf(format: "%p\n", reinterpret_cast<const void *>(44));
958 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
959 // CHECK-FIXES: std::println("{}", reinterpret_cast<const void *>(44));
960
961 const void *p;
962 printf(format: "%p\n", p);
963 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
964 // CHECK-FIXES: std::println("{}", p);
965
966 // But a pointer to a pointer to void does need a cast
967 const void **pp;
968 printf(format: "%p\n", pp);
969 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
970 // CHECK-FIXES: std::println("{}", static_cast<const void *>(pp));
971
972 printf(format: "%p\n", printf_pointer);
973 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
974 // CHECK-FIXES: std::println("{}", static_cast<const void *>(printf_pointer));
975}
976
977class AClass
978{
979 int member;
980
981 void printf_this_pointer()
982 {
983 printf(format: "%p\n", this);
984 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
985 // CHECK-FIXES: std::println("{}", static_cast<const void *>(this));
986 }
987
988 void printf_pointer_to_member_function()
989 {
990 printf(format: "%p\n", &AClass::printf_pointer_to_member_function);
991 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
992 // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::printf_pointer_to_member_function));
993 }
994
995 void printf_pointer_to_member_variable()
996 {
997 printf(format: "%p\n", &AClass::member);
998 // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
999 // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::member));
1000 }
1001};
1002
1003void printf_positional_arg() {
1004 printf(format: "%1$d", 42);
1005 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1006 // CHECK-FIXES: std::print("{0}", 42);
1007
1008 printf(format: "before %1$d", 42);
1009 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1010 // CHECK-FIXES: std::print("before {0}", 42);
1011
1012 printf(format: "%1$d after", 42);
1013 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1014 // CHECK-FIXES: std::print("{0} after", 42);
1015
1016 printf(format: "before %1$d after", 42);
1017 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1018 // CHECK-FIXES: std::print("before {0} after", 42);
1019
1020 printf(format: "before %2$d between %1$s after", "string", 42);
1021 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1022 // CHECK-FIXES: std::print("before {1} between {0} after", "string", 42);
1023}
1024
1025// printf always defaults to right justification,, no matter what the type is of
1026// the argument. std::format uses left justification by default for strings, and
1027// right justification for numbers.
1028void printf_right_justified() {
1029 printf(format: "Right-justified integer %4d after\n", 42);
1030 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1031 // CHECK-FIXES: std::println("Right-justified integer {:4} after", 42);
1032
1033 printf(format: "Right-justified double %4f\n", 227.2);
1034 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1035 // CHECK-FIXES: std::println("Right-justified double {:4f}", 227.2);
1036
1037 printf(format: "Right-justified double %4g\n", 227.4);
1038 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1039 // CHECK-FIXES: std::println("Right-justified double {:4g}", 227.4);
1040
1041 printf(format: "Right-justified integer with field width argument %*d after\n", 5, 424242);
1042 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1043 // CHECK-FIXES: std::println("Right-justified integer with field width argument {:{}} after", 424242, 5);
1044
1045 printf(format: "Right-justified integer with field width argument %2$*1$d after\n", 5, 424242);
1046 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1047 // CHECK-FIXES: std::println("Right-justified integer with field width argument {1:{0}} after", 5, 424242);
1048
1049 printf(format: "Right-justified string %20s\n", "Hello");
1050 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1051 // CHECK-FIXES: std::println("Right-justified string {:>20}", "Hello");
1052
1053 printf(format: "Right-justified string with field width argument %2$*1$s after\n", 20, "wibble");
1054 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1055 // CHECK-FIXES: std::println("Right-justified string with field width argument {1:>{0}} after", 20, "wibble");
1056}
1057
1058// printf always requires - for left justification, no matter what the type is
1059// of the argument. std::format uses left justification by default for strings,
1060// and right justification for numbers.
1061void printf_left_justified() {
1062 printf(format: "Left-justified integer %-4d\n", 42);
1063 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1064 // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42);
1065
1066 printf(format: "Left-justified integer %--4d\n", 42);
1067 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1068 // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42);
1069
1070 printf(format: "Left-justified double %-4f\n", 227.2);
1071 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1072 // CHECK-FIXES: std::println("Left-justified double {:<4f}", 227.2);
1073
1074 printf(format: "Left-justified double %-4g\n", 227.4);
1075 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1076 // CHECK-FIXES: std::println("Left-justified double {:<4g}", 227.4);
1077
1078 printf(format: "Left-justified integer with field width argument %-*d after\n", 5, 424242);
1079 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1080 // CHECK-FIXES: std::println("Left-justified integer with field width argument {:<{}} after", 424242, 5);
1081
1082 printf(format: "Left-justified integer with field width argument %2$-*1$d after\n", 5, 424242);
1083 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1084 // CHECK-FIXES: std::println("Left-justified integer with field width argument {1:<{0}} after", 5, 424242);
1085
1086 printf(format: "Left-justified string %-20s\n", "Hello");
1087 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1088 // CHECK-FIXES: std::println("Left-justified string {:20}", "Hello");
1089
1090 printf(format: "Left-justified string with field width argument %2$-*1$s after\n", 5, "wibble");
1091 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1092 // CHECK-FIXES: std::println("Left-justified string with field width argument {1:{0}} after", 5, "wibble");
1093}
1094
1095void printf_precision() {
1096 printf(format: "Hello %.3f\n", 3.14159);
1097 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1098 // CHECK-FIXES: std::println("Hello {:.3f}", 3.14159);
1099
1100 printf(format: "Hello %10.3f\n", 3.14159);
1101 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1102 // CHECK-FIXES: std::println("Hello {:10.3f}", 3.14159);
1103
1104 printf(format: "Hello %.*f after\n", 10, 3.14159265358979323846);
1105 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1106 // CHECK-FIXES: std::println("Hello {:.{}f} after", 3.14159265358979323846, 10);
1107
1108 printf(format: "Hello %10.*f after\n", 3, 3.14159265358979323846);
1109 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1110 // CHECK-FIXES: std::println("Hello {:10.{}f} after", 3.14159265358979323846, 3);
1111
1112 printf(format: "Hello %*.*f after\n", 10, 4, 3.14159265358979323846);
1113 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1114 // CHECK-FIXES: std::println("Hello {:{}.{}f} after", 3.14159265358979323846, 10, 4);
1115
1116 printf(format: "Hello %1$.*2$f after\n", 3.14159265358979323846, 4);
1117 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1118 // CHECK-FIXES: std::println("Hello {0:.{1}f} after", 3.14159265358979323846, 4);
1119
1120 // Precision is ignored, but maintained on non-numeric arguments
1121 printf(format: "Hello %.5s\n", "Goodbye");
1122 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1123 // CHECK-FIXES: std::println("Hello {:.5}", "Goodbye");
1124
1125 printf(format: "Hello %.5c\n", 'G');
1126 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1127 // CHECK-FIXES: std::println("Hello {:.5}", 'G');
1128}
1129
1130void printf_field_width_and_precision(const std::string &s1, const std::string &s2, const std::string &s3)
1131{
1132 printf(format: "width only:%*d width and precision:%*.*f precision only:%.*f\n", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
1133 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1134 // CHECK-FIXES: std::println("width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
1135
1136 const unsigned int ui1 = 42, ui2 = 43, ui3 = 44;
1137 printf(format: "casts width only:%*d width and precision:%*.*d precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3);
1138 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1139 // CHECK-FIXES-NOTSTRICT: std::println("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
1140 // CHECK-FIXES-STRICT: std::println("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", static_cast<int>(ui1), 3, static_cast<int>(ui2), 4, 2, static_cast<int>(ui3), 5);
1141
1142 printf(format: "c_str removal width only:%*s width and precision:%*.*s precision only:%.*s\n", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str());
1143 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1144 // CHECK-FIXES: std::println("c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
1145
1146 const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3;
1147 printf(format: "c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str());
1148 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1149 // CHECK-FIXES: std::println("c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5);
1150
1151 iterator<std::string> is1, is2, is3;
1152 printf(format: "c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str());
1153 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1154 // CHECK-FIXES: std::println("c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5);
1155
1156 printf(format: "width and precision positional:%1$*2$.*3$f after\n", 3.14159265358979323846, 4, 2);
1157 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1158 // CHECK-FIXES: std::println("width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2);
1159
1160 const int width = 10, precision = 3;
1161 printf(format: "width only:%3$*1$d width and precision:%4$*1$.*2$f precision only:%5$.*2$f\n", width, precision, 42, 3.1415926, 2.718);
1162 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1163 // CHECK-FIXES: std::println("width only:{2:{0}} width and precision:{3:{0}.{1}f} precision only:{4:.{1}f}", width, precision, 42, 3.1415926, 2.718);
1164
1165 printf(format: "c_str removal width only:%3$*1$s width and precision:%4$*1$.*2$s precision only:%5$.*2$s\n", width, precision, s1.c_str(), s2.c_str(), s3.c_str());
1166 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1167 // CHECK-FIXES: std::println("c_str removal width only:{2:>{0}} width and precision:{3:>{0}.{1}} precision only:{4:.{1}}", width, precision, s1, s2, s3);
1168}
1169
1170void fprintf_field_width_and_precision(const std::string &s1, const std::string &s2, const std::string &s3) {
1171 fprintf(stderr, format: "width only:%*d width and precision:%*.*f precision only:%.*f\n", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
1172 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1173 // CHECK-FIXES: std::println(stderr, "width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
1174
1175 fprintf(stderr, format: "width and precision positional:%1$*2$.*3$f after\n", 3.14159265358979323846, 4, 2);
1176 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1177 // CHECK-FIXES: std::println(stderr, "width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2);
1178
1179 fprintf(stderr, format: "c_str removal width only:%*s width and precision:%*.*s precision only:%.*s\n", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str());
1180 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1181 // CHECK-FIXES: std::println(stderr, "c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
1182
1183 const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3;
1184 fprintf(stderr, format: "c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str());
1185 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1186 // CHECK-FIXES: std::println(stderr, "c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5);
1187
1188 iterator<std::string> is1, is2, is3;
1189 fprintf(stderr, format: "c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str());
1190 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1191 // CHECK-FIXES: std::println(stderr, "c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5);
1192
1193 const int width = 10, precision = 3;
1194 fprintf(stderr, format: "width only:%3$*1$d width and precision:%4$*1$.*2$f precision only:%5$.*2$f\n", width, precision, 42, 3.1415926, 2.718);
1195 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1196 // CHECK-FIXES: std::println(stderr, "width only:{2:{0}} width and precision:{3:{0}.{1}f} precision only:{4:.{1}f}", width, precision, 42, 3.1415926, 2.718);
1197
1198 fprintf(stderr, format: "c_str removal width only:%3$*1$s width and precision:%4$*1$.*2$s precision only:%5$.*2$s\n", width, precision, s1.c_str(), s2.c_str(), s3.c_str());
1199 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1200 // CHECK-FIXES: std::println(stderr, "c_str removal width only:{2:>{0}} width and precision:{3:>{0}.{1}} precision only:{4:.{1}}", width, precision, s1, s2, s3);
1201}
1202
1203void printf_alternative_form() {
1204 printf(format: "Wibble %#x\n", 42);
1205 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1206 // CHECK-FIXES: std::println("Wibble {:#x}", 42);
1207
1208 printf(format: "Wibble %#20x\n", 42);
1209 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1210 // CHECK-FIXES: std::println("Wibble {:#20x}", 42);
1211
1212 printf(format: "Wibble %#020x\n", 42);
1213 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1214 // CHECK-FIXES: std::println("Wibble {:#020x}", 42);
1215
1216 printf(format: "Wibble %#-20x\n", 42);
1217 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1218 // CHECK-FIXES: std::println("Wibble {:<#20x}", 42);
1219}
1220
1221void printf_leading_plus() {
1222 printf(format: "Positive integer %+d\n", 42);
1223 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1224 // CHECK-FIXES: std::println("Positive integer {:+}", 42);
1225
1226 printf(format: "Positive double %+f\n", 42.2);
1227 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1228 // CHECK-FIXES: std::println("Positive double {:+f}", 42.2);
1229
1230 printf(format: "Positive double %+g\n", 42.2);
1231 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1232 // CHECK-FIXES: std::println("Positive double {:+g}", 42.2);
1233
1234 // Ignore leading plus on strings to avoid potential runtime exception where
1235 // printf would have just ignored it.
1236 printf(format: "Positive string %+s\n", "string");
1237 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1238 // CHECK-FIXES: std::println("Positive string {}", "string");
1239}
1240
1241void printf_leading_space() {
1242 printf(format: "Spaced integer % d\n", 42);
1243 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1244 // CHECK-FIXES: std::println("Spaced integer {: }", 42);
1245
1246 printf(format: "Spaced integer %- d\n", 42);
1247 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1248 // CHECK-FIXES: std::println("Spaced integer {: }", 42);
1249
1250 printf(format: "Spaced double % f\n", 42.2);
1251 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1252 // CHECK-FIXES: std::println("Spaced double {: f}", 42.2);
1253
1254 printf(format: "Spaced double % g\n", 42.2);
1255 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1256 // CHECK-FIXES: std::println("Spaced double {: g}", 42.2);
1257}
1258
1259void printf_leading_zero() {
1260 printf(format: "Leading zero integer %03d\n", 42);
1261 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1262 // CHECK-FIXES: std::println("Leading zero integer {:03}", 42);
1263
1264 printf(format: "Leading minus and zero integer %-03d minus ignored\n", 42);
1265 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1266 // CHECK-FIXES: std::println("Leading minus and zero integer {:<03} minus ignored", 42);
1267
1268 printf(format: "Leading zero unsigned integer %03u\n", 42U);
1269 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1270 // CHECK-FIXES: std::println("Leading zero unsigned integer {:03}", 42U);
1271
1272 printf(format: "Leading zero double %03f\n", 42.2);
1273 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1274 // CHECK-FIXES: std::println("Leading zero double {:03f}", 42.2);
1275
1276 printf(format: "Leading zero double %03g\n", 42.2);
1277 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1278 // CHECK-FIXES: std::println("Leading zero double {:03g}", 42.2);
1279}
1280
1281void printf_leading_plus_and_space() {
1282 // printf prefers plus to space. {fmt} will throw if both are present.
1283 printf(format: "Spaced integer % +d\n", 42);
1284 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1285 // CHECK-FIXES: std::println("Spaced integer {:+}", 42);
1286
1287 printf(format: "Spaced double %+ f\n", 42.2);
1288 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1289 // CHECK-FIXES: std::println("Spaced double {:+f}", 42.2);
1290
1291 printf(format: "Spaced double % +g\n", 42.2);
1292 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1293 // CHECK-FIXES: std::println("Spaced double {:+g}", 42.2);
1294}
1295
1296void printf_leading_zero_and_plus() {
1297 printf(format: "Leading zero integer %+03d\n", 42);
1298 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1299 // CHECK-FIXES: std::println("Leading zero integer {:+03}", 42);
1300
1301 printf(format: "Leading zero double %0+3f\n", 42.2);
1302 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1303 // CHECK-FIXES: std::println("Leading zero double {:+03f}", 42.2);
1304
1305 printf(format: "Leading zero double %0+3g\n", 42.2);
1306 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1307 // CHECK-FIXES: std::println("Leading zero double {:+03g}", 42.2);
1308}
1309
1310void printf_leading_zero_and_space() {
1311 printf(format: "Leading zero and space integer %0 3d\n", 42);
1312 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1313 // CHECK-FIXES: std::println("Leading zero and space integer {: 03}", 42);
1314
1315 printf(format: "Leading zero and space double %0 3f\n", 42.2);
1316 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1317 // CHECK-FIXES: std::println("Leading zero and space double {: 03f}", 42.2);
1318
1319 printf(format: "Leading zero and space double %0 3g\n", 42.2);
1320 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1321 // CHECK-FIXES: std::println("Leading zero and space double {: 03g}", 42.2);
1322}
1323
1324// add signed plained enum too
1325enum PlainEnum { red };
1326enum SignedPlainEnum { black = -42 };
1327enum BoolEnum : unsigned int { yellow };
1328enum CharEnum : char { purple };
1329enum SCharEnum : signed char { aquamarine };
1330enum UCharEnum : unsigned char { pink };
1331enum ShortEnum : short { beige };
1332enum UShortEnum : unsigned short { grey };
1333enum IntEnum : int { green };
1334enum UIntEnum : unsigned int { blue };
1335enum LongEnum : long { magenta };
1336enum ULongEnum : unsigned long { cyan };
1337enum LongLongEnum : long long { taupe };
1338enum ULongLongEnum : unsigned long long { brown };
1339
1340void printf_enum_d() {
1341 PlainEnum plain_enum;
1342 printf(format: "%d", plain_enum);
1343 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1344 // CHECK-FIXES: std::print("{}", static_cast<int>(plain_enum));
1345
1346 SignedPlainEnum splain_enum;
1347 printf(format: "%d", splain_enum);
1348 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1349 // CHECK-FIXES: std::print("{}", static_cast<int>(splain_enum));
1350
1351 BoolEnum bool_enum;
1352 printf(format: "%d", bool_enum);
1353 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1354 // CHECK-FIXES: std::print("{}", static_cast<int>(bool_enum));
1355
1356 CharEnum char_enum;
1357 printf(format: "%d", char_enum);
1358 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1359 // CHECK-FIXES: std::print("{}", static_cast<signed char>(char_enum));
1360
1361 SCharEnum schar_enum;
1362 printf(format: "%d", schar_enum);
1363 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1364 // CHECK-FIXES: std::print("{}", static_cast<signed char>(schar_enum));
1365
1366 UCharEnum uchar_enum;
1367 printf(format: "%d", uchar_enum);
1368 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1369 // CHECK-FIXES: std::print("{}", static_cast<signed char>(uchar_enum));
1370
1371 ShortEnum short_enum;
1372 printf(format: "%d", short_enum);
1373 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1374 // CHECK-FIXES: std::print("{}", static_cast<short>(short_enum));
1375
1376 UShortEnum ushort_enum;
1377 printf(format: "%d", ushort_enum);
1378 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1379 // CHECK-FIXES: std::print("{}", static_cast<short>(ushort_enum));
1380
1381 IntEnum int_enum;
1382 printf(format: "%d", int_enum);
1383 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1384 // CHECK-FIXES: std::print("{}", static_cast<int>(int_enum));
1385
1386 UIntEnum uint_enum;
1387 printf(format: "%d", uint_enum);
1388 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1389 // CHECK-FIXES: std::print("{}", static_cast<int>(uint_enum));
1390
1391 LongEnum long_enum;
1392 printf(format: "%d", long_enum);
1393 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1394 // CHECK-FIXES: std::print("{}", static_cast<long>(long_enum));
1395
1396 ULongEnum ulong_enum;
1397 printf(format: "%d", ulong_enum);
1398 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1399 // CHECK-FIXES: std::print("{}", static_cast<long>(ulong_enum));
1400
1401 LongLongEnum longlong_enum;
1402 printf(format: "%d", longlong_enum);
1403 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1404 // CHECK-FIXES: std::print("{}", static_cast<long long>(longlong_enum));
1405
1406 ULongLongEnum ulonglong_enum;
1407 printf(format: "%d", ulonglong_enum);
1408 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1409 // CHECK-FIXES: std::print("{}", static_cast<long long>(ulonglong_enum));
1410}
1411
1412void printf_enum_u() {
1413 PlainEnum plain_enum;
1414 printf(format: "%u", plain_enum);
1415 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1416 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(plain_enum));
1417
1418 SignedPlainEnum splain_enum;
1419 printf(format: "%u", splain_enum);
1420 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1421 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(splain_enum));
1422
1423 BoolEnum bool_enum;
1424 printf(format: "%u", bool_enum);
1425 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1426 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(bool_enum));
1427
1428 CharEnum char_enum;
1429 printf(format: "%u", char_enum);
1430 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1431 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(char_enum));
1432
1433 SCharEnum schar_enum;
1434 printf(format: "%u", schar_enum);
1435 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1436 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(schar_enum));
1437
1438 UCharEnum uchar_enum;
1439 printf(format: "%u", uchar_enum);
1440 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1441 // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(uchar_enum));
1442
1443 ShortEnum short_enum;
1444 printf(format: "%u", short_enum);
1445 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1446 // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(short_enum));
1447
1448 UShortEnum ushort_enum;
1449 printf(format: "%u", ushort_enum);
1450 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1451 // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(ushort_enum));
1452
1453 IntEnum int_enum;
1454 printf(format: "%u", int_enum);
1455 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1456 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(int_enum));
1457
1458 UIntEnum uint_enum;
1459 printf(format: "%u", uint_enum);
1460 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1461 // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(uint_enum));
1462
1463 LongEnum long_enum;
1464 printf(format: "%u", long_enum);
1465 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1466 // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(long_enum));
1467
1468 ULongEnum ulong_enum;
1469 printf(format: "%u", ulong_enum);
1470 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1471 // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(ulong_enum));
1472
1473 LongLongEnum longlong_enum;
1474 printf(format: "%u", longlong_enum);
1475 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1476 // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(longlong_enum));
1477
1478 ULongLongEnum ulonglong_enum;
1479 printf(format: "%u", ulonglong_enum);
1480 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1481 // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(ulonglong_enum));
1482}
1483
1484void printf_string_function(const char *(*callback)()) {
1485 printf(format: "printf string from callback %s", callback());
1486 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1487 // CHECK-FIXES: std::print("printf string from callback {}", callback());
1488}
1489
1490template <typename CharType>
1491struct X
1492{
1493 const CharType *str() const;
1494};
1495
1496void printf_string_member_function(const X<char> &x, const X<const char> &cx) {
1497 printf(format: "printf string from member function %s", x.str());
1498 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1499 // CHECK-FIXES: std::print("printf string from member function {}", x.str());
1500
1501 printf(format: "printf string from member function on const %s", cx.str());
1502 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1503 // CHECK-FIXES: std::print("printf string from member function on const {}", cx.str());
1504}
1505
1506void printf_string_cstr(const std::string &s1, const std::string &s2) {
1507 printf(format: "printf string one c_str %s", s1.c_str());
1508 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1509 // CHECK-FIXES: std::print("printf string one c_str {}", s1);
1510
1511 printf(format: "printf string two c_str %s %s\n", s1.c_str(), s2.data());
1512 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1513 // CHECK-FIXES: std::println("printf string two c_str {} {}", s1, s2);
1514}
1515
1516void printf_not_char_string_cstr(const std::wstring &ws1) {
1517 // This test is to check that we only remove
1518 // std::basic_string<CharType>::c_str()/data() when CharType is char. I've
1519 // been unable to come up with a genuine situation where someone would have
1520 // actually successfully called those methods when this isn't the case without
1521 // -Wformat warning, but it seems sensible to restrict removal regardless.
1522 printf(format: "printf bogus wstring c_str %s", ws1.c_str());
1523 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1524 // CHECK-FIXES: std::print("printf bogus wstring c_str {}", ws1.c_str());
1525}
1526
1527void fprintf_string_cstr(const std::string &s1) {
1528 fprintf(stderr, format: "fprintf string c_str %s", s1.c_str());
1529 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print]
1530 // CHECK-FIXES: std::print(stderr, "fprintf string c_str {}", s1);
1531}
1532
1533void printf_string_pointer_cstr(const std::string *s1, const std::string *s2) {
1534 printf(format: "printf string pointer one c_str %s", s1->c_str());
1535 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1536 // CHECK-FIXES: std::print("printf string pointer one c_str {}", *s1);
1537
1538 printf(format: "printf string pointer two c_str %s %s\n", s1->c_str(), s2->data());
1539 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1540 // CHECK-FIXES: std::println("printf string pointer two c_str {} {}", *s1, *s2);
1541}
1542
1543void fprintf_string_pointer_cstr(const std::string *s1) {
1544 fprintf(stderr, format: "fprintf string pointer c_str %s", s1->c_str());
1545 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print]
1546 // CHECK-FIXES: std::print(stderr, "fprintf string pointer c_str {}", *s1);
1547}
1548
1549void printf_iterator_cstr(iterator<std::string> i1, iterator<std::string> i2)
1550{
1551 printf(format: "printf iterator c_str %s %s\n", i1->c_str(), i2->data());
1552 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1553 // CHECK-FIXES: std::println("printf iterator c_str {} {}", *i1, *i2);
1554}
1555
1556// Something that isn't std::string, so the calls to c_str() and data() must not
1557// be removed even though the printf call will be replaced.
1558struct S
1559{
1560 const char *c_str() const;
1561 const char *data() const;
1562};
1563
1564void p(S s1, S *s2)
1565{
1566 printf(format: "Not std::string %s %s", s1.c_str(), s2->c_str());
1567 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1568 // CHECK-FIXES: std::print("Not std::string {} {}", s1.c_str(), s2->c_str());
1569
1570 printf(format: "Not std::string %s %s", s1.data(), s2->data());
1571 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1572 // CHECK-FIXES: std::print("Not std::string {} {}", s1.data(), s2->data());
1573}
1574

source code of clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp