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