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