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