xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/modernize/use-std-print.cpp (revision 222dd235ffc39b3695a3c002593097bec216a8fa)
183f875dcSMike Crowe // RUN: %check_clang_tidy -check-suffixes=,STRICT \
283f875dcSMike Crowe // RUN:   -std=c++23 %s modernize-use-std-print %t -- \
3*222dd235SCongcong Cai // RUN:   -config="{CheckOptions: {modernize-use-std-print.StrictMode: true}}" \
4a199fb12SMike Crowe // RUN:   -- -isystem %clang_tidy_headers -fexceptions \
5a199fb12SMike Crowe // RUN:      -DPRI_CMDLINE_MACRO="\"s\"" \
6a199fb12SMike Crowe // RUN:      -D__PRI_CMDLINE_MACRO="\"s\""
783f875dcSMike Crowe // RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \
883f875dcSMike Crowe // RUN:   -std=c++23 %s modernize-use-std-print %t -- \
9*222dd235SCongcong Cai // RUN:   -config="{CheckOptions: {modernize-use-std-print.StrictMode: false}}" \
10a199fb12SMike Crowe // RUN:   -- -isystem %clang_tidy_headers -fexceptions \
11a199fb12SMike Crowe // RUN:      -DPRI_CMDLINE_MACRO="\"s\"" \
12a199fb12SMike Crowe // RUN:      -D__PRI_CMDLINE_MACRO="\"s\""
1383f875dcSMike Crowe #include <cstddef>
1483f875dcSMike Crowe #include <cstdint>
1583f875dcSMike Crowe #include <cstdio>
1683f875dcSMike Crowe // CHECK-FIXES: #include <print>
1783f875dcSMike Crowe #include <inttypes.h>
1883f875dcSMike Crowe #include <string.h>
1983f875dcSMike Crowe #include <string>
2083f875dcSMike Crowe 
21c6207f6eSMike Crowe template <typename T>
22c6207f6eSMike Crowe struct iterator {
23c6207f6eSMike Crowe   T *operator->();
24c6207f6eSMike Crowe   T &operator*();
25c6207f6eSMike Crowe };
26c6207f6eSMike Crowe 
2783f875dcSMike Crowe void printf_simple() {
2883f875dcSMike Crowe   printf("Hello");
2983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
3083f875dcSMike Crowe   // CHECK-FIXES: std::print("Hello");
3183f875dcSMike Crowe }
3283f875dcSMike Crowe 
3383f875dcSMike Crowe void printf_newline() {
3483f875dcSMike Crowe   printf("Hello\n");
3583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
3683f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello");
3783f875dcSMike Crowe 
3883f875dcSMike Crowe   printf("Split" "\n");
3983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
4083f875dcSMike Crowe   // CHECK-FIXES: std::println("Split");
4183f875dcSMike Crowe 
4283f875dcSMike Crowe   printf("Double\n\n");
4383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
4483f875dcSMike Crowe   // CHECK-FIXES: std::println("Double\n");
4583f875dcSMike Crowe }
4683f875dcSMike Crowe 
4783f875dcSMike Crowe void printf_deceptive_newline() {
4883f875dcSMike Crowe   printf("Hello\\n");
4983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
5083f875dcSMike Crowe   // CHECK-FIXES: std::print("Hello\\n");
5183f875dcSMike Crowe 
5283f875dcSMike Crowe   printf("Hello\x0a");
5383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
5483f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello");
5583f875dcSMike Crowe }
5683f875dcSMike Crowe 
572ce765ebSMike Crowe void printf_crlf_newline() {
582ce765ebSMike Crowe   printf("Hello\r\n");
592ce765ebSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
602ce765ebSMike Crowe   // CHECK-FIXES: std::print("Hello\r\n");
612ce765ebSMike Crowe 
622ce765ebSMike Crowe   printf("Hello\r\\n");
632ce765ebSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
642ce765ebSMike Crowe   // CHECK-FIXES: std::print("Hello\r\\n");
652ce765ebSMike Crowe }
662ce765ebSMike Crowe 
6709ed2102SMike Crowe // std::print returns nothing, so any callers that use the return
6809ed2102SMike Crowe // value cannot be automatically translated.
6909ed2102SMike Crowe int printf_uses_return_value(int choice) {
7009ed2102SMike Crowe   const int i = printf("Return value assigned to variable %d\n", 42);
7109ed2102SMike Crowe 
7209ed2102SMike Crowe   extern void accepts_int(int);
7309ed2102SMike Crowe   accepts_int(printf("Return value passed to function %d\n", 42));
7409ed2102SMike Crowe 
7509ed2102SMike Crowe   if (choice == 0)
7609ed2102SMike Crowe     printf("if body %d\n", i);
7709ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
7809ed2102SMike Crowe     // CHECK-FIXES: std::println("if body {}", i);
7909ed2102SMike Crowe   else if (choice == 1)
8009ed2102SMike Crowe     printf("else if body %d\n", i);
8109ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
8209ed2102SMike Crowe     // CHECK-FIXES: std::println("else if body {}", i);
8309ed2102SMike Crowe   else
8409ed2102SMike Crowe     printf("else body %d\n", i);
8509ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
8609ed2102SMike Crowe     // CHECK-FIXES: std::println("else body {}", i);
8709ed2102SMike Crowe 
8809ed2102SMike Crowe   if (printf("Return value used as boolean in if statement"))
8909ed2102SMike Crowe     if (printf("Return value used in expression if statement") == 44)
9009ed2102SMike Crowe       if (const int j = printf("Return value used in assignment in if statement"))
9109ed2102SMike Crowe         if (const int k = printf("Return value used with initializer in if statement"); k == 44)
9209ed2102SMike Crowe           ;
9309ed2102SMike Crowe 
9409ed2102SMike Crowe   int d = 0;
9509ed2102SMike Crowe   while (printf("%d", d) < 2)
9609ed2102SMike Crowe     ++d;
9709ed2102SMike Crowe 
9809ed2102SMike Crowe   while (true)
9909ed2102SMike Crowe     printf("while body %d\n", i);
10009ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
10109ed2102SMike Crowe     // CHECK-FIXES: std::println("while body {}", i);
10209ed2102SMike Crowe 
10309ed2102SMike Crowe   do
10409ed2102SMike Crowe     printf("do body %d\n", i);
10509ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
10609ed2102SMike Crowe     // CHECK-FIXES: std::println("do body {}", i);
10709ed2102SMike Crowe   while (true);
10809ed2102SMike Crowe 
10909ed2102SMike Crowe   for (;;)
11009ed2102SMike Crowe     printf("for body %d\n", i);
11109ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11209ed2102SMike Crowe     // CHECK-FIXES: std::println("for body {}", i);
11309ed2102SMike Crowe 
11409ed2102SMike Crowe   for (printf("for init statement %d\n", i);;)
11509ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11609ed2102SMike Crowe     // CHECK-FIXES: std::println("for init statement {}", i);
11709ed2102SMike Crowe     ;;
11809ed2102SMike Crowe 
11909ed2102SMike Crowe   for (int j = printf("for init statement %d\n", i);;)
12009ed2102SMike Crowe     ;;
12109ed2102SMike Crowe 
12209ed2102SMike Crowe   for (; printf("for condition %d\n", i);)
12309ed2102SMike Crowe     ;;
12409ed2102SMike Crowe 
12509ed2102SMike Crowe   for (;; printf("for expression %d\n", i))
12609ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
12709ed2102SMike Crowe     // CHECK-FIXES: std::println("for expression {}", i)
12809ed2102SMike Crowe     ;;
12909ed2102SMike Crowe 
13009ed2102SMike Crowe   for (auto C : "foo")
13109ed2102SMike Crowe     printf("ranged-for body %d\n", i);
13209ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
13309ed2102SMike Crowe     // CHECK-FIXES: std::println("ranged-for body {}", i);
13409ed2102SMike Crowe 
13509ed2102SMike Crowe   switch (1) {
13609ed2102SMike Crowe   case 1:
13709ed2102SMike Crowe     printf("switch case body %d\n", i);
13809ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
13909ed2102SMike Crowe     // CHECK-FIXES: std::println("switch case body {}", i);
14009ed2102SMike Crowe     break;
14109ed2102SMike Crowe   default:
14209ed2102SMike Crowe     printf("switch default body %d\n", i);
14309ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
14409ed2102SMike Crowe     // CHECK-FIXES: std::println("switch default body {}", i);
14509ed2102SMike Crowe     break;
14609ed2102SMike Crowe   }
14709ed2102SMike Crowe 
14809ed2102SMike Crowe   try {
14909ed2102SMike Crowe     printf("try body %d\n", i);
15009ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
15109ed2102SMike Crowe     // CHECK-FIXES: std::println("try body {}", i);
15209ed2102SMike Crowe   } catch (int) {
15309ed2102SMike Crowe     printf("catch body %d\n", i);
15409ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
15509ed2102SMike Crowe     // CHECK-FIXES: std::println("catch body {}", i);
15609ed2102SMike Crowe   }
15709ed2102SMike Crowe 
15809ed2102SMike Crowe   (printf("Parenthesised expression %d\n", i));
15909ed2102SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:4: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
16009ed2102SMike Crowe   // CHECK-FIXES: (std::println("Parenthesised expression {}", i));
16109ed2102SMike Crowe 
16209ed2102SMike Crowe   // Ideally we would convert these two, but the current check doesn't cope with
16309ed2102SMike Crowe   // that.
16409ed2102SMike Crowe   (void)printf("cast to void %d\n", i);
16509ed2102SMike Crowe   // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
16609ed2102SMike Crowe   // CHECK-FIXES-NOT: std::println("cast to void {}", i);
16709ed2102SMike Crowe 
16809ed2102SMike Crowe   static_cast<void>(printf("static_cast to void %d\n", i));
16909ed2102SMike Crowe   // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
17009ed2102SMike Crowe   // CHECK-FIXES-NOT: std::println("static cast to void {}", i);
17109ed2102SMike Crowe 
17209ed2102SMike Crowe   const int x = ({ printf("GCC statement expression using return value immediately %d\n", i); });
17309ed2102SMike Crowe   const int y = ({ const int y = printf("GCC statement expression using return value immediately %d\n", i); y; });
17409ed2102SMike Crowe 
17509ed2102SMike Crowe   // Ideally we would convert this one, but the current check doesn't cope with
17609ed2102SMike Crowe   // that.
17709ed2102SMike Crowe   ({ printf("GCC statement expression with unused result %d\n", i); });
17809ed2102SMike Crowe   // CHECK-MESSAGES-NOT: [[@LINE-1]]:6: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
17909ed2102SMike Crowe   // CHECK-FIXES-NOT: std::println("GCC statement expression with unused result {}", i);
18009ed2102SMike Crowe 
18109ed2102SMike Crowe   return printf("Return value used in return\n");
18209ed2102SMike Crowe }
18309ed2102SMike Crowe 
18409ed2102SMike Crowe int fprintf_uses_return_value(int choice) {
18509ed2102SMike Crowe   const int i = fprintf(stderr, "Return value assigned to variable %d\n", 42);
18609ed2102SMike Crowe 
18709ed2102SMike Crowe   extern void accepts_int(int);
18809ed2102SMike Crowe   accepts_int(fprintf(stderr, "Return value passed to function %d\n", 42));
18909ed2102SMike Crowe 
19009ed2102SMike Crowe   if (choice == 0)
19109ed2102SMike Crowe     fprintf(stderr, "if body %d\n", i);
19209ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
19309ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "if body {}", i);
19409ed2102SMike Crowe   else if (choice == 1)
19509ed2102SMike Crowe     fprintf(stderr, "else if body %d\n", i);
19609ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
19709ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "else if body {}", i);
19809ed2102SMike Crowe   else
19909ed2102SMike Crowe     fprintf(stderr, "else body %d\n", i);
20009ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
20109ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "else body {}", i);
20209ed2102SMike Crowe 
20309ed2102SMike Crowe   if (fprintf(stderr, "Return value used as boolean in if statement"))
20409ed2102SMike Crowe     if (fprintf(stderr, "Return value used in expression if statement") == 44)
20509ed2102SMike Crowe       if (const int j = fprintf(stderr, "Return value used in assignment in if statement"))
20609ed2102SMike Crowe         if (const int k = fprintf(stderr, "Return value used with initializer in if statement"); k == 44)
20709ed2102SMike Crowe           ;
20809ed2102SMike Crowe 
20909ed2102SMike Crowe   int d = 0;
21009ed2102SMike Crowe   while (fprintf(stderr, "%d", d) < 2)
21109ed2102SMike Crowe     ++d;
21209ed2102SMike Crowe 
21309ed2102SMike Crowe   while (true)
21409ed2102SMike Crowe     fprintf(stderr, "while body %d\n", i);
21509ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
21609ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "while body {}", i);
21709ed2102SMike Crowe 
21809ed2102SMike Crowe   do
21909ed2102SMike Crowe     fprintf(stderr, "do body %d\n", i);
22009ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
22109ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "do body {}", i);
22209ed2102SMike Crowe   while (true);
22309ed2102SMike Crowe 
22409ed2102SMike Crowe   for (;;)
22509ed2102SMike Crowe     fprintf(stderr, "for body %d\n", i);
22609ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
22709ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "for body {}", i);
22809ed2102SMike Crowe 
22909ed2102SMike Crowe   for (fprintf(stderr, "for init statement %d\n", i);;)
23009ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
23109ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "for init statement {}", i);
23209ed2102SMike Crowe     ;;
23309ed2102SMike Crowe 
23409ed2102SMike Crowe   for (int j = fprintf(stderr, "for init statement %d\n", i);;)
23509ed2102SMike Crowe     ;;
23609ed2102SMike Crowe 
23709ed2102SMike Crowe   for (; fprintf(stderr, "for condition %d\n", i);)
23809ed2102SMike Crowe     ;;
23909ed2102SMike Crowe 
24009ed2102SMike Crowe   for (;; fprintf(stderr, "for expression %d\n", i))
24109ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
24209ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "for expression {}", i)
24309ed2102SMike Crowe     ;;
24409ed2102SMike Crowe 
24509ed2102SMike Crowe   for (auto C : "foo")
24609ed2102SMike Crowe     fprintf(stderr, "ranged-for body %d\n", i);
24709ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
24809ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "ranged-for body {}", i);
24909ed2102SMike Crowe 
25009ed2102SMike Crowe   switch (1) {
25109ed2102SMike Crowe   case 1:
25209ed2102SMike Crowe     fprintf(stderr, "switch case body %d\n", i);
25309ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
25409ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "switch case body {}", i);
25509ed2102SMike Crowe     break;
25609ed2102SMike Crowe   default:
25709ed2102SMike Crowe     fprintf(stderr, "switch default body %d\n", i);
25809ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
25909ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "switch default body {}", i);
26009ed2102SMike Crowe     break;
26109ed2102SMike Crowe   }
26209ed2102SMike Crowe 
26309ed2102SMike Crowe   try {
26409ed2102SMike Crowe     fprintf(stderr, "try body %d\n", i);
26509ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
26609ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "try body {}", i);
26709ed2102SMike Crowe   } catch (int) {
26809ed2102SMike Crowe     fprintf(stderr, "catch body %d\n", i);
26909ed2102SMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
27009ed2102SMike Crowe     // CHECK-FIXES: std::println(stderr, "catch body {}", i);
27109ed2102SMike Crowe   }
27209ed2102SMike Crowe 
27309ed2102SMike Crowe 
27409ed2102SMike Crowe   (printf("Parenthesised expression %d\n", i));
27509ed2102SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:4: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
27609ed2102SMike Crowe   // CHECK-FIXES: (std::println("Parenthesised expression {}", i));
27709ed2102SMike Crowe 
27809ed2102SMike Crowe   // Ideally we would convert these two, but the current check doesn't cope with
27909ed2102SMike Crowe   // that.
28009ed2102SMike Crowe   (void)fprintf(stderr, "cast to void %d\n", i);
28109ed2102SMike Crowe   // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
28209ed2102SMike Crowe   // CHECK-FIXES-NOT: std::println(stderr, "cast to void {}", i);
28309ed2102SMike Crowe 
28409ed2102SMike Crowe   static_cast<void>(fprintf(stderr, "static_cast to void %d\n", i));
28509ed2102SMike Crowe   // CHECK-MESSAGES-NOT: [[@LINE-1]]:9: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
28609ed2102SMike Crowe   // CHECK-FIXES-NOT: std::println(stderr, "static cast to void {}", i);
28709ed2102SMike Crowe 
28809ed2102SMike Crowe   const int x = ({ fprintf(stderr, "GCC statement expression using return value immediately %d\n", i); });
28909ed2102SMike Crowe   const int y = ({ const int y = fprintf(stderr, "GCC statement expression using return value immediately %d\n", i); y; });
29009ed2102SMike Crowe 
29109ed2102SMike Crowe   // Ideally we would convert this one, but the current check doesn't cope with
29209ed2102SMike Crowe   // that.
29309ed2102SMike Crowe   ({ fprintf(stderr, "GCC statement expression with unused result %d\n", i); });
29409ed2102SMike Crowe   // CHECK-MESSAGES-NOT: [[@LINE-1]]:6: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
29509ed2102SMike Crowe   // CHECK-FIXES-NOT: std::println("GCC statement expression with unused result {}", i);
29609ed2102SMike Crowe 
29709ed2102SMike Crowe   return fprintf(stderr, "Return value used in return\n");
29809ed2102SMike Crowe }
29909ed2102SMike Crowe 
30083f875dcSMike Crowe void fprintf_simple() {
30183f875dcSMike Crowe   fprintf(stderr, "Hello");
30283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print]
30383f875dcSMike Crowe   // CHECK-FIXES: std::print(stderr, "Hello");
30483f875dcSMike Crowe }
30583f875dcSMike Crowe 
30683f875dcSMike Crowe void std_printf_simple() {
30783f875dcSMike Crowe   std::printf("std::Hello");
30883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
30983f875dcSMike Crowe   // CHECK-FIXES: std::print("std::Hello");
31083f875dcSMike Crowe }
31183f875dcSMike Crowe 
31283f875dcSMike Crowe void printf_escape() {
31383f875dcSMike Crowe   printf("before \t");
31483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
31583f875dcSMike Crowe   // CHECK-FIXES: std::print("before \t");
31683f875dcSMike Crowe 
31783f875dcSMike Crowe   printf("\n after");
31883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
31983f875dcSMike Crowe   // CHECK-FIXES: std::print("\n after");
32083f875dcSMike Crowe 
32183f875dcSMike Crowe   printf("before \a after");
32283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
32383f875dcSMike Crowe   // CHECK-FIXES: std::print("before \a after");
32483f875dcSMike Crowe 
32583f875dcSMike Crowe   printf("Bell\a%dBackspace\bFF%s\fNewline\nCR\rTab\tVT\vEscape\x1b\x07%d", 42, "string", 99);
32683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
32783f875dcSMike Crowe   // CHECK-FIXES: std::print("Bell\a{}Backspace\bFF{}\fNewline\nCR\rTab\tVT\vEscape\x1b\a{}", 42, "string", 99);
32883f875dcSMike Crowe 
32983f875dcSMike Crowe   printf("not special \x1b\x01\x7f");
33083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
33183f875dcSMike Crowe   // CHECK-FIXES: std::print("not special \x1b\x01\x7f");
33283f875dcSMike Crowe }
33383f875dcSMike Crowe 
33483f875dcSMike Crowe void printf_percent() {
33583f875dcSMike Crowe   printf("before %%");
33683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
33783f875dcSMike Crowe   // CHECK-FIXES: std::print("before %");
33883f875dcSMike Crowe 
33983f875dcSMike Crowe   printf("%% after");
34083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
34183f875dcSMike Crowe   // CHECK-FIXES: std::print("% after");
34283f875dcSMike Crowe 
34383f875dcSMike Crowe   printf("before %% after");
34483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
34583f875dcSMike Crowe   // CHECK-FIXES: std::print("before % after");
34683f875dcSMike Crowe 
34783f875dcSMike Crowe   printf("Hello %% and another %%");
34883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
34983f875dcSMike Crowe   // CHECK-FIXES: std::print("Hello % and another %");
35083f875dcSMike Crowe 
35183f875dcSMike Crowe   printf("Not a string %%s");
35283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
35383f875dcSMike Crowe   // CHECK-FIXES: std::print("Not a string %s");
35483f875dcSMike Crowe }
35583f875dcSMike Crowe 
35683f875dcSMike Crowe void printf_curlies() {
35783f875dcSMike Crowe   printf("%d {}", 42);
35883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
35983f875dcSMike Crowe   // CHECK-FIXES: std::print("{} {{[{][{]}}}}", 42);
36083f875dcSMike Crowe 
36183f875dcSMike Crowe   printf("{}");
36283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
36383f875dcSMike Crowe   // CHECK-FIXES: std::print("{{[{][{]}}}}");
36483f875dcSMike Crowe }
36583f875dcSMike Crowe 
36683f875dcSMike Crowe void printf_unsupported_format_specifiers() {
36783f875dcSMike Crowe   int pos;
36883f875dcSMike Crowe   printf("%d %n %d\n", 42, &pos, 72);
36983f875dcSMike Crowe   // 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]
37083f875dcSMike Crowe 
37183f875dcSMike Crowe   printf("Error %m\n");
37283f875dcSMike Crowe   // 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]
37383f875dcSMike Crowe }
37483f875dcSMike Crowe 
37583f875dcSMike Crowe void printf_not_string_literal(const char *fmt) {
37683f875dcSMike Crowe   // We can't convert the format string if it's not a literal
37783f875dcSMike Crowe   printf(fmt, 42);
37883f875dcSMike Crowe }
37983f875dcSMike Crowe 
38083f875dcSMike Crowe void printf_inttypes_ugliness() {
38183f875dcSMike Crowe   // The one advantage of the checker seeing the token pasted version of the
38283f875dcSMike Crowe   // format string is that we automatically cope with the horrendously-ugly
38383f875dcSMike Crowe   // inttypes.h macros!
38483f875dcSMike Crowe   int64_t u64 = 42;
38583f875dcSMike Crowe   uintmax_t umax = 4242;
38683f875dcSMike Crowe   printf("uint64:%" PRId64 " uintmax:%" PRIuMAX "\n", u64, umax);
38783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
38883f875dcSMike Crowe   // CHECK-FIXES: std::println("uint64:{} uintmax:{}", u64, umax);
38983f875dcSMike Crowe }
39083f875dcSMike Crowe 
39183f875dcSMike Crowe void printf_raw_string() {
39283f875dcSMike Crowe   // This one doesn't require the format string to be changed, so it stays intact
39383f875dcSMike Crowe   printf(R"(First\Second)");
39483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
39583f875dcSMike Crowe   // CHECK-FIXES: std::print(R"(First\Second)");
39683f875dcSMike Crowe 
39783f875dcSMike Crowe   // This one does require the format string to be changed, so unfortunately it
39883f875dcSMike Crowe   // gets reformatted as a normal string.
39983f875dcSMike Crowe   printf(R"(First %d\Second)", 42);
40083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
40183f875dcSMike Crowe   // CHECK-FIXES: std::print("First {}\\Second", 42);
40283f875dcSMike Crowe }
40383f875dcSMike Crowe 
40483f875dcSMike Crowe void printf_integer_d() {
40583f875dcSMike Crowe   const bool b = true;
40683f875dcSMike Crowe   // The "d" type is necessary here for compatibility with printf since
40783f875dcSMike Crowe   // std::print will print booleans as "true" or "false".
40883f875dcSMike Crowe   printf("Integer %d from bool\n", b);
40983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
41083f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {:d} from bool", b);
41183f875dcSMike Crowe 
41283f875dcSMike Crowe   // The "d" type is necessary here for compatibility with printf since
41383f875dcSMike Crowe   // std::print will print booleans as "true" or "false".
41483f875dcSMike Crowe   printf("Integer %i from bool\n", b);
41583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
41683f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {:d} from bool", b);
41783f875dcSMike Crowe 
41883f875dcSMike Crowe   // The 'd' is always necessary if we pass a char since otherwise the
41983f875dcSMike Crowe   // parameter will be formatted as a character. In StrictMode, the
42083f875dcSMike Crowe   // cast is always necessary to maintain the printf behaviour since
42183f875dcSMike Crowe   // char may be unsigned, but this also means that the 'd' is not
42283f875dcSMike Crowe   // necessary.
42383f875dcSMike Crowe   const char c = 'A';
42483f875dcSMike Crowe   printf("Integers %d %hhd from char\n", c, c);
42583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
42683f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integers {:d} {:d} from char", c, c);
42783f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integers {} {} from char", static_cast<signed char>(c), static_cast<signed char>(c));
42883f875dcSMike Crowe 
42983f875dcSMike Crowe   printf("Integers %i %hhi from char\n", c, c);
43083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
43183f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integers {:d} {:d} from char", c, c);
43283f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integers {} {} from char", static_cast<signed char>(c), static_cast<signed char>(c));
43383f875dcSMike Crowe 
43483f875dcSMike Crowe   const signed char sc = 'A';
43583f875dcSMike Crowe   printf("Integers %d %hhd from signed char\n", sc, sc);
43683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
43783f875dcSMike Crowe   // CHECK-FIXES: std::println("Integers {} {} from signed char", sc, sc);
43883f875dcSMike Crowe 
43983f875dcSMike Crowe   printf("Integers %i %hhi from signed char\n", sc, sc);
44083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
44183f875dcSMike Crowe   // CHECK-FIXES: std::println("Integers {} {} from signed char", sc, sc);
44283f875dcSMike Crowe 
44383f875dcSMike Crowe   const unsigned char uc = 'A';
44483f875dcSMike Crowe   printf("Integers %d %hhd from unsigned char\n", uc, uc);
44583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
44683f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integers {} {} from unsigned char", uc, uc);
44783f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integers {} {} from unsigned char", static_cast<signed char>(uc), static_cast<signed char>(uc));
44883f875dcSMike Crowe 
44983f875dcSMike Crowe   printf("Integers %i %hhi from unsigned char\n", uc, uc);
45083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
45183f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integers {} {} from unsigned char", uc, uc);
45283f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integers {} {} from unsigned char", static_cast<signed char>(uc), static_cast<signed char>(uc));
45383f875dcSMike Crowe 
45483f875dcSMike Crowe   const int8_t i8 = 42;
45583f875dcSMike Crowe   printf("Integer %" PRIi8 " from int8_t\n", i8);
45683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
45783f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from int8_t", i8);
45883f875dcSMike Crowe 
45983f875dcSMike Crowe   const int_fast8_t if8 = 42;
46083f875dcSMike Crowe   printf("Integer %" PRIiFAST8 " from int_fast8_t\n", if8);
46183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
46283f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from int_fast8_t", if8);
46383f875dcSMike Crowe 
46483f875dcSMike Crowe   const int_least8_t il8 = 42;
46583f875dcSMike Crowe   printf("Integer %" PRIiFAST8 " from int_least8_t\n", il8);
46683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
46783f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from int_least8_t", il8);
46883f875dcSMike Crowe 
46983f875dcSMike Crowe   const uint8_t u8 = 42U;
47083f875dcSMike Crowe   const std::uint8_t su8 = u8;
47183f875dcSMike Crowe   printf("Integers %" PRIi8 " and %" PRId8 " from uint8_t\n", u8, su8);
47283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
47383f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uint8_t", u8, su8);
47483f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uint8_t", static_cast<int8_t>(u8), static_cast<std::int8_t>(su8));
47583f875dcSMike Crowe 
47683f875dcSMike Crowe   const uint_fast8_t uf8 = 42U;
47783f875dcSMike Crowe   printf("Integer %" PRIiFAST8 " from uint_fast8_t\n", uf8);
47883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
47983f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_fast8_t", uf8);
48083f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from uint_fast8_t", static_cast<int_fast8_t>(uf8));
48183f875dcSMike Crowe 
48283f875dcSMike Crowe   const uint_least8_t ul8 = 42U;
48383f875dcSMike Crowe   printf("Integer %" PRIiLEAST8 " from uint_least8_t\n", ul8);
48483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
48583f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from uint_least8_t", ul8);
48683f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from uint_least8_t", static_cast<int_least8_t>(ul8));
48783f875dcSMike Crowe 
48883f875dcSMike Crowe   const short s = 42;
48983f875dcSMike Crowe   printf("Integer %hd from short\n", s);
49083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
49183f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from short", s);
49283f875dcSMike Crowe 
49383f875dcSMike Crowe   printf("Integer %hi from short\n", s);
49483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
49583f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from short", s);
49683f875dcSMike Crowe 
49783f875dcSMike Crowe   const unsigned short us = 42U;
49883f875dcSMike Crowe   printf("Integer %hd from unsigned short\n", us);
49983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
50083f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us);
50183f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us));
50283f875dcSMike Crowe 
50383f875dcSMike Crowe   printf("Integer %hi from unsigned short\n", us);
50483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
50583f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned short", us);
50683f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned short", static_cast<short>(us));
50783f875dcSMike Crowe 
50883f875dcSMike Crowe   const int i = 42;
50983f875dcSMike Crowe   printf("Integer %d from integer\n", i);
51083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
51183f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from integer", i);
51283f875dcSMike Crowe 
51383f875dcSMike Crowe   printf("Integer %i from integer\n", i);
51483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
51583f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from integer", i);
51683f875dcSMike Crowe 
51783f875dcSMike Crowe   const unsigned int ui = 42U;
51883f875dcSMike Crowe   printf("Integer %d from unsigned integer\n", ui);
51983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
52083f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui);
52183f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui));
52283f875dcSMike Crowe 
52383f875dcSMike Crowe   printf("Integer %i from unsigned integer\n", ui);
52483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
52583f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned integer", ui);
52683f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned integer", static_cast<int>(ui));
52783f875dcSMike Crowe 
52883f875dcSMike Crowe   const long l = 42L;
52983f875dcSMike Crowe   printf("Integer %ld from long\n", l);
53083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
53183f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from long", l);
53283f875dcSMike Crowe 
53383f875dcSMike Crowe   printf("Integer %li from long\n", l);
53483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
53583f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from long", l);
53683f875dcSMike Crowe 
53783f875dcSMike Crowe   const unsigned long ul = 42UL;
53883f875dcSMike Crowe   printf("Integer %ld from unsigned long\n", ul);
53983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
54083f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul);
54183f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul));
54283f875dcSMike Crowe 
54383f875dcSMike Crowe   printf("Integer %li from unsigned long\n", ul);
54483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
54583f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long", ul);
54683f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long", static_cast<long>(ul));
54783f875dcSMike Crowe 
54883f875dcSMike Crowe   const long long ll = 42LL;
54983f875dcSMike Crowe   printf("Integer %lld from long long\n", ll);
55083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
55183f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from long long", ll);
55283f875dcSMike Crowe 
55383f875dcSMike Crowe   printf("Integer %lli from long long\n", ll);
55483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
55583f875dcSMike Crowe   // CHECK-FIXES: std::println("Integer {} from long long", ll);
55683f875dcSMike Crowe 
55783f875dcSMike Crowe   const unsigned long long ull = 42ULL;
55883f875dcSMike Crowe   printf("Integer %lld from unsigned long long\n", ull);
55983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
56083f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull);
56183f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull));
56283f875dcSMike Crowe 
56383f875dcSMike Crowe   printf("Integer %lli from unsigned long long\n", ull);
56483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
56583f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from unsigned long long", ull);
56683f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from unsigned long long", static_cast<long long>(ull));
56783f875dcSMike Crowe 
56883f875dcSMike Crowe   const intmax_t im = 42;
56983f875dcSMike Crowe   const std::intmax_t sim = im;
57083f875dcSMike Crowe   printf("Integers %jd and %jd from intmax_t\n", im, sim);
57183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
57283f875dcSMike Crowe   // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim);
57383f875dcSMike Crowe 
57483f875dcSMike Crowe   printf("Integers %ji and %ji from intmax_t\n", im, sim);
57583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
57683f875dcSMike Crowe   // CHECK-FIXES: std::println("Integers {} and {} from intmax_t", im, sim);
57783f875dcSMike Crowe 
57883f875dcSMike Crowe   const uintmax_t uim = 42;
57983f875dcSMike Crowe   const std::uintmax_t suim = uim;
58083f875dcSMike Crowe   printf("Integers %jd and %jd from uintmax_t\n", uim, suim);
58183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
58283f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from uintmax_t", uim, suim);
58383f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integers {} and {} from uintmax_t", static_cast<intmax_t>(uim), static_cast<std::intmax_t>(suim));
58483f875dcSMike Crowe 
58583f875dcSMike Crowe   printf("Integer %ji from intmax_t\n", uim);
58683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
58783f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integer {} from intmax_t", uim);
58883f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integer {} from intmax_t", static_cast<intmax_t>(uim));
58983f875dcSMike Crowe 
59083f875dcSMike Crowe   const int ai[] = { 0, 1, 2, 3};
59183f875dcSMike Crowe   const ptrdiff_t pd = &ai[3] - &ai[0];
59283f875dcSMike Crowe   const std::ptrdiff_t spd = pd;
59383f875dcSMike Crowe   printf("Integers %td and %td from ptrdiff_t\n", pd, spd);
59483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
59583f875dcSMike Crowe   // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd);
59683f875dcSMike Crowe 
59783f875dcSMike Crowe   printf("Integers %ti and %ti from ptrdiff_t\n", pd, spd);
59883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
59983f875dcSMike Crowe   // CHECK-FIXES: std::println("Integers {} and {} from ptrdiff_t", pd, spd);
60083f875dcSMike Crowe 
60183f875dcSMike Crowe   const size_t z = 42UL;
60283f875dcSMike Crowe   const std::size_t sz = z;
60383f875dcSMike Crowe   printf("Integers %zd and %zd from size_t\n", z, sz);
60483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
60583f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Integers {} and {} from size_t", z, sz);
60683f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Integers {} and {} from size_t", static_cast<ssize_t>(z), static_cast<std::ssize_t>(sz));
60783f875dcSMike Crowe }
60883f875dcSMike Crowe 
60983f875dcSMike Crowe void printf_integer_u()
61083f875dcSMike Crowe {
61183f875dcSMike Crowe   const bool b = true;
61283f875dcSMike Crowe   // The "d" type is necessary here for compatibility with printf since
61383f875dcSMike Crowe   // std::print will print booleans as "true" or "false".
61483f875dcSMike Crowe   printf("Unsigned integer %u from bool\n", b);
61583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
61683f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {:d} from bool", b);
61783f875dcSMike Crowe 
61883f875dcSMike Crowe   const char c = 'A';
61983f875dcSMike Crowe   printf("Unsigned integer %hhu from char\n", c);
62083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
62183f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {:d} from char", c);
62283f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from char", static_cast<unsigned char>(c));
62383f875dcSMike Crowe 
62483f875dcSMike Crowe   const signed char sc = 'A';
62583f875dcSMike Crowe   printf("Unsigned integer %hhu from signed char\n", sc);
62683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
62783f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc);
62883f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc));
62983f875dcSMike Crowe 
63083f875dcSMike Crowe   printf("Unsigned integer %u from signed char\n", sc);
63183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
63283f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed char", sc);
63383f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed char", static_cast<unsigned char>(sc));
63483f875dcSMike Crowe 
63583f875dcSMike Crowe   const unsigned char uc = 'A';
63683f875dcSMike Crowe   printf("Unsigned integer %hhu from unsigned char\n", uc);
63783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
63883f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc);
63983f875dcSMike Crowe 
64083f875dcSMike Crowe   printf("Unsigned integer %u from unsigned char\n", uc);
64183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
64283f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from unsigned char", uc);
64383f875dcSMike Crowe 
64483f875dcSMike Crowe   const int8_t i8 = 42;
64583f875dcSMike Crowe   printf("Unsigned integer %" PRIu8 " from int8_t\n", i8);
64683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
64783f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int8_t", i8);
64883f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int8_t", static_cast<uint8_t>(i8));
64983f875dcSMike Crowe 
65083f875dcSMike Crowe   const int_fast8_t if8 = 42;
65183f875dcSMike Crowe   printf("Unsigned integer %" PRIuFAST8 " from int_fast8_t\n", if8);
65283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
65383f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_fast8_t", if8);
65483f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_fast8_t", static_cast<uint_fast8_t>(if8));
65583f875dcSMike Crowe 
65683f875dcSMike Crowe   const int_least8_t il8 = 42;
65783f875dcSMike Crowe   printf("Unsigned integer %" PRIuFAST8 " from int_least8_t\n", il8);
65883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
65983f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from int_least8_t", il8);
66083f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from int_least8_t", static_cast<uint_least8_t>(il8));
66183f875dcSMike Crowe 
66283f875dcSMike Crowe   const uint8_t u8 = 42U;
66383f875dcSMike Crowe   printf("Unsigned integer %" PRIu8 " from uint8_t\n", u8);
66483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
66583f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from uint8_t", u8);
66683f875dcSMike Crowe 
66783f875dcSMike Crowe   const uint_fast8_t uf8 = 42U;
66883f875dcSMike Crowe   printf("Unsigned integer %" PRIuFAST8 " from uint_fast8_t\n", uf8);
66983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
67083f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from uint_fast8_t", uf8);
67183f875dcSMike Crowe 
67283f875dcSMike Crowe   const uint_least8_t ul8 = 42U;
67383f875dcSMike Crowe   printf("Unsigned integer %" PRIuLEAST8 " from uint_least8_t\n", ul8);
67483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
67583f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from uint_least8_t", ul8);
67683f875dcSMike Crowe 
67783f875dcSMike Crowe   const short s = 42;
67883f875dcSMike Crowe   printf("Unsigned integer %hu from short\n", s);
67983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
68083f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from short", s);
68183f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from short", static_cast<unsigned short>(s));
68283f875dcSMike Crowe 
68383f875dcSMike Crowe   const unsigned short us = 42U;
68483f875dcSMike Crowe   printf("Unsigned integer %hu from unsigned short\n", us);
68583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
68683f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from unsigned short", us);
68783f875dcSMike Crowe 
68883f875dcSMike Crowe   const int i = 42;
68983f875dcSMike Crowe   printf("Unsigned integer %u from signed integer\n", i);
69083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
69183f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed integer", i);
69283f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed integer", static_cast<unsigned int>(i));
69383f875dcSMike Crowe 
69483f875dcSMike Crowe   const unsigned int ui = 42U;
69583f875dcSMike Crowe   printf("Unsigned integer %u from unsigned integer\n", ui);
69683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
69783f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from unsigned integer", ui);
69883f875dcSMike Crowe 
69983f875dcSMike Crowe   const long l = 42L;
70083f875dcSMike Crowe   printf("Unsigned integer %u from signed long\n", l);
70183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
70283f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from signed long", l);
70383f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from signed long", static_cast<unsigned long>(l));
70483f875dcSMike Crowe 
70583f875dcSMike Crowe   const unsigned long ul = 42UL;
70683f875dcSMike Crowe   printf("Unsigned integer %lu from unsigned long\n", ul);
70783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
70883f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long", ul);
70983f875dcSMike Crowe 
71083f875dcSMike Crowe   const long long ll = 42LL;
71183f875dcSMike Crowe   printf("Unsigned integer %llu from long long\n", ll);
71283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
71383f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integer {} from long long", ll);
71483f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integer {} from long long", static_cast<unsigned long long>(ll));
71583f875dcSMike Crowe 
71683f875dcSMike Crowe   const unsigned long long ull = 42ULL;
71783f875dcSMike Crowe   printf("Unsigned integer %llu from unsigned long long\n", ull);
71883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
71983f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integer {} from unsigned long long", ull);
72083f875dcSMike Crowe 
72183f875dcSMike Crowe   const intmax_t im = 42;
72283f875dcSMike Crowe   const std::intmax_t sim = im;
72383f875dcSMike Crowe   printf("Unsigned integers %ju and %ju from intmax_t\n", im, sim);
72483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
72583f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from intmax_t", im, sim);
72683f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from intmax_t", static_cast<uintmax_t>(im), static_cast<std::uintmax_t>(sim));
72783f875dcSMike Crowe 
72883f875dcSMike Crowe   const uintmax_t uim = 42U;
72983f875dcSMike Crowe   const std::uintmax_t suim = uim;
73083f875dcSMike Crowe   printf("Unsigned integers %ju and %ju from uintmax_t\n", uim, suim);
73183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
73283f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integers {} and {} from uintmax_t", uim, suim);
73383f875dcSMike Crowe 
73483f875dcSMike Crowe   const int ai[] = { 0, 1, 2, 3};
73583f875dcSMike Crowe   const ptrdiff_t pd = &ai[3] - &ai[0];
73683f875dcSMike Crowe   const std::ptrdiff_t spd = pd;
73783f875dcSMike Crowe   printf("Unsigned integers %tu and %tu from ptrdiff_t\n", pd, spd);
73883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
73983f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", pd, spd);
74083f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println("Unsigned integers {} and {} from ptrdiff_t", static_cast<size_t>(pd), static_cast<std::size_t>(spd));
74183f875dcSMike Crowe 
74283f875dcSMike Crowe   const size_t z = 42U;
74383f875dcSMike Crowe   const std::size_t sz = z;
74483f875dcSMike Crowe   printf("Unsigned integers %zu and %zu from size_t\n", z, sz);
74583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
74683f875dcSMike Crowe   // CHECK-FIXES: std::println("Unsigned integers {} and {} from size_t", z, sz);
74783f875dcSMike Crowe }
74883f875dcSMike Crowe 
74983f875dcSMike Crowe // This checks that we get the argument offset right with the extra FILE * argument
75083f875dcSMike Crowe void fprintf_integer() {
75183f875dcSMike Crowe   fprintf(stderr, "Integer %d from integer\n", 42);
75283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
75383f875dcSMike Crowe   // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 42);
75483f875dcSMike Crowe 
75583f875dcSMike Crowe   fprintf(stderr, "Integer %i from integer\n", 65);
75683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
75783f875dcSMike Crowe   // CHECK-FIXES: std::println(stderr, "Integer {} from integer", 65);
75883f875dcSMike Crowe 
75983f875dcSMike Crowe   fprintf(stderr, "Integer %i from char\n", 'A');
76083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
76183f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println(stderr, "Integer {:d} from char", 'A');
76283f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println(stderr, "Integer {} from char", static_cast<signed char>('A'));
76383f875dcSMike Crowe 
76483f875dcSMike Crowe   fprintf(stderr, "Integer %d from char\n", 'A');
76583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
76683f875dcSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println(stderr, "Integer {:d} from char", 'A');
76783f875dcSMike Crowe   // CHECK-FIXES-STRICT: std::println(stderr, "Integer {} from char", static_cast<signed char>('A'));
76883f875dcSMike Crowe }
76983f875dcSMike Crowe 
77083f875dcSMike Crowe void printf_char() {
77183f875dcSMike Crowe   const char c = 'A';
77283f875dcSMike Crowe   printf("Char %c from char\n", c);
77383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
77483f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {} from char", c);
77583f875dcSMike Crowe 
77683f875dcSMike Crowe   const signed char sc = 'A';
77783f875dcSMike Crowe   printf("Char %c from signed char\n", sc);
77883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
77983f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {:c} from signed char", sc);
78083f875dcSMike Crowe 
78183f875dcSMike Crowe   const unsigned char uc = 'A';
78283f875dcSMike Crowe   printf("Char %c from unsigned char\n", uc);
78383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
78483f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {:c} from unsigned char", uc);
78583f875dcSMike Crowe 
78683f875dcSMike Crowe   const int i = 65;
78783f875dcSMike Crowe   printf("Char %c from integer\n", i);
78883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
78983f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {:c} from integer", i);
79083f875dcSMike Crowe 
79183f875dcSMike Crowe   const unsigned int ui = 65;
79283f875dcSMike Crowe   printf("Char %c from unsigned integer\n", ui);
79383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
79483f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {:c} from unsigned integer", ui);
79583f875dcSMike Crowe 
79683f875dcSMike Crowe   const unsigned long long ull = 65;
79783f875dcSMike Crowe   printf("Char %c from unsigned long long\n", ull);
79883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
79983f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {:c} from unsigned long long", ull);
80083f875dcSMike Crowe }
80183f875dcSMike Crowe 
80283f875dcSMike Crowe void printf_bases() {
80383f875dcSMike Crowe   printf("Hex %lx\n", 42L);
80483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
80583f875dcSMike Crowe   // CHECK-FIXES: std::println("Hex {:x}", 42L);
80683f875dcSMike Crowe 
80783f875dcSMike Crowe   printf("HEX %X\n", 42);
80883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
80983f875dcSMike Crowe   // CHECK-FIXES: std::println("HEX {:X}", 42);
81083f875dcSMike Crowe 
81183f875dcSMike Crowe   printf("Oct %lo\n", 42L);
81283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
81383f875dcSMike Crowe   // CHECK-FIXES: std::println("Oct {:o}", 42L);
81483f875dcSMike Crowe }
81583f875dcSMike Crowe 
81683f875dcSMike Crowe void printf_alternative_forms() {
81783f875dcSMike Crowe   printf("Hex %#lx\n", 42L);
81883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
81983f875dcSMike Crowe   // CHECK-FIXES: std::println("Hex {:#x}", 42L);
82083f875dcSMike Crowe 
82183f875dcSMike Crowe   printf("HEX %#X\n", 42);
82283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
82383f875dcSMike Crowe   // CHECK-FIXES: std::println("HEX {:#X}", 42);
82483f875dcSMike Crowe 
82583f875dcSMike Crowe   printf("Oct %#lo\n", 42L);
82683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
82783f875dcSMike Crowe   // CHECK-FIXES: std::println("Oct {:#o}", 42L);
82883f875dcSMike Crowe 
82983f875dcSMike Crowe   printf("Double %#f %#F\n", -42.0, -42.0);
83083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
83183f875dcSMike Crowe   // CHECK-FIXES: std::println("Double {:#f} {:#F}", -42.0, -42.0);
83283f875dcSMike Crowe 
83383f875dcSMike Crowe   printf("Double %#g %#G\n", -42.0, -42.0);
83483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
83583f875dcSMike Crowe   // CHECK-FIXES: std::println("Double {:#g} {:#G}", -42.0, -42.0);
83683f875dcSMike Crowe 
83783f875dcSMike Crowe   printf("Double %#e %#E\n", -42.0, -42.0);
83883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
83983f875dcSMike Crowe   // CHECK-FIXES: std::println("Double {:#e} {:#E}", -42.0, -42.0);
84083f875dcSMike Crowe 
84183f875dcSMike Crowe   printf("Double %#a %#A\n", -42.0, -42.0);
84283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
84383f875dcSMike Crowe   // CHECK-FIXES: std::println("Double {:#a} {:#A}", -42.0, -42.0);
84483f875dcSMike Crowe 
84583f875dcSMike Crowe   // Characters don't have an alternate form
84683f875dcSMike Crowe   printf("Char %#c\n", 'A');
84783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
84883f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {}", 'A');
84983f875dcSMike Crowe 
85083f875dcSMike Crowe   // Strings don't have an alternate form
85183f875dcSMike Crowe   printf("Char %#c\n", 'A');
85283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
85383f875dcSMike Crowe   // CHECK-FIXES: std::println("Char {}", 'A');
85483f875dcSMike Crowe }
85583f875dcSMike Crowe 
85683f875dcSMike Crowe void printf_string() {
85783f875dcSMike Crowe   printf("Hello %s after\n", "Goodbye");
85883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
85983f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {} after", "Goodbye");
86083f875dcSMike Crowe 
86183f875dcSMike Crowe   // std::print can't print signed char strings.
86283f875dcSMike Crowe   const signed char *sstring = reinterpret_cast<const signed char *>("ustring");
86383f875dcSMike Crowe   printf("signed char string %s\n", sstring);
86483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
86583f875dcSMike Crowe   // CHECK-FIXES: std::println("signed char string {}", reinterpret_cast<const char *>(sstring));
86683f875dcSMike Crowe 
86783f875dcSMike Crowe   // std::print can't print unsigned char strings.
86883f875dcSMike Crowe   const unsigned char *ustring = reinterpret_cast<const unsigned char *>("ustring");
86983f875dcSMike Crowe   printf("unsigned char string %s\n", ustring);
87083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
87183f875dcSMike Crowe   // CHECK-FIXES: std::println("unsigned char string {}", reinterpret_cast<const char *>(ustring));
87283f875dcSMike Crowe }
87383f875dcSMike Crowe 
87483f875dcSMike Crowe void printf_float() {
87583f875dcSMike Crowe   // If the type is not specified then either f or e will be used depending on
87683f875dcSMike Crowe   // whichever is shorter. This means that it is necessary to be specific to
87783f875dcSMike Crowe   // maintain compatibility with printf.
87883f875dcSMike Crowe 
87983f875dcSMike Crowe   // TODO: Should we force a cast here, since printf will promote to double
88083f875dcSMike Crowe   // automatically, but std::format will not, which could result in different
88183f875dcSMike Crowe   // output?
88283f875dcSMike Crowe 
88383f875dcSMike Crowe   const float f = 42.0F;
88483f875dcSMike Crowe   printf("Hello %f after\n", f);
88583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
88683f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:f} after", f);
88783f875dcSMike Crowe 
88883f875dcSMike Crowe   printf("Hello %g after\n", f);
88983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
89083f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:g} after", f);
89183f875dcSMike Crowe 
89283f875dcSMike Crowe   printf("Hello %e after\n", f);
89383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
89483f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:e} after", f);
89583f875dcSMike Crowe }
89683f875dcSMike Crowe 
89783f875dcSMike Crowe void printf_double() {
89883f875dcSMike Crowe   // If the type is not specified then either f or e will be used depending on
89983f875dcSMike Crowe   // whichever is shorter. This means that it is necessary to be specific to
90083f875dcSMike Crowe   // maintain compatibility with printf.
90183f875dcSMike Crowe 
90283f875dcSMike Crowe   const double d = 42.0;
90383f875dcSMike Crowe   printf("Hello %f after\n", d);
90483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
90583f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:f} after", d);
90683f875dcSMike Crowe 
90783f875dcSMike Crowe   printf("Hello %g after\n", d);
90883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
90983f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:g} after", d);
91083f875dcSMike Crowe 
91183f875dcSMike Crowe   printf("Hello %e after\n", d);
91283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
91383f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:e} after", d);
91483f875dcSMike Crowe }
91583f875dcSMike Crowe 
91683f875dcSMike Crowe void printf_long_double() {
91783f875dcSMike Crowe   // If the type is not specified then either f or e will be used depending on
91883f875dcSMike Crowe   // whichever is shorter. This means that it is necessary to be specific to
91983f875dcSMike Crowe   // maintain compatibility with printf.
92083f875dcSMike Crowe 
92183f875dcSMike Crowe   const long double ld = 42.0L;
92283f875dcSMike Crowe   printf("Hello %Lf after\n", ld);
92383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
92483f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:f} after", ld);
92583f875dcSMike Crowe 
92683f875dcSMike Crowe   printf("Hello %g after\n", ld);
92783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
92883f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:g} after", ld);
92983f875dcSMike Crowe 
93083f875dcSMike Crowe   printf("Hello %e after\n", ld);
93183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
93283f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:e} after", ld);
93383f875dcSMike Crowe }
93483f875dcSMike Crowe 
93583f875dcSMike Crowe void printf_pointer() {
93683f875dcSMike Crowe   int i;
93783f875dcSMike Crowe   double j;
93883f875dcSMike Crowe   printf("Int* %p %s %p\n", &i, "Double*", &j);
93983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
94083f875dcSMike Crowe   // CHECK-FIXES: std::println("Int* {} {} {}", static_cast<const void *>(&i), "Double*", static_cast<const void *>(&j));
94183f875dcSMike Crowe 
94283f875dcSMike Crowe   printf("%p\n", nullptr);
94383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
94483f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", nullptr);
94583f875dcSMike Crowe 
94683f875dcSMike Crowe   const auto np = nullptr;
94783f875dcSMike Crowe   printf("%p\n", np);
94883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
94983f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", np);
95083f875dcSMike Crowe 
95183f875dcSMike Crowe   // NULL isn't a pointer, so std::print needs some help.
95283f875dcSMike Crowe   printf("%p\n", NULL);
95383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
95483f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", static_cast<const void *>(NULL));
95583f875dcSMike Crowe 
95683f875dcSMike Crowe   printf("%p\n", 42);
95783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
95883f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", static_cast<const void *>(42));
95983f875dcSMike Crowe 
96083f875dcSMike Crowe   // If we already have a void pointer then no cast is required.
96183f875dcSMike Crowe   printf("%p\n", reinterpret_cast<const void *>(44));
96283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
96383f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", reinterpret_cast<const void *>(44));
96483f875dcSMike Crowe 
96583f875dcSMike Crowe   const void *p;
96683f875dcSMike Crowe   printf("%p\n", p);
96783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
96883f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", p);
96983f875dcSMike Crowe 
97083f875dcSMike Crowe   // But a pointer to a pointer to void does need a cast
97183f875dcSMike Crowe   const void **pp;
97283f875dcSMike Crowe   printf("%p\n", pp);
97383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
97483f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", static_cast<const void *>(pp));
97583f875dcSMike Crowe 
97683f875dcSMike Crowe   printf("%p\n", printf_pointer);
97783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
97883f875dcSMike Crowe   // CHECK-FIXES: std::println("{}", static_cast<const void *>(printf_pointer));
97983f875dcSMike Crowe }
98083f875dcSMike Crowe 
98183f875dcSMike Crowe class AClass
98283f875dcSMike Crowe {
98383f875dcSMike Crowe   int member;
98483f875dcSMike Crowe 
98583f875dcSMike Crowe   void printf_this_pointer()
98683f875dcSMike Crowe   {
98783f875dcSMike Crowe     printf("%p\n", this);
98883f875dcSMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
98983f875dcSMike Crowe     // CHECK-FIXES: std::println("{}", static_cast<const void *>(this));
99083f875dcSMike Crowe   }
99183f875dcSMike Crowe 
99283f875dcSMike Crowe   void printf_pointer_to_member_function()
99383f875dcSMike Crowe   {
99483f875dcSMike Crowe     printf("%p\n", &AClass::printf_pointer_to_member_function);
99583f875dcSMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
99683f875dcSMike Crowe     // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::printf_pointer_to_member_function));
99783f875dcSMike Crowe   }
99883f875dcSMike Crowe 
99983f875dcSMike Crowe   void printf_pointer_to_member_variable()
100083f875dcSMike Crowe   {
100183f875dcSMike Crowe     printf("%p\n", &AClass::member);
100283f875dcSMike Crowe     // CHECK-MESSAGES: [[@LINE-1]]:5: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
100383f875dcSMike Crowe     // CHECK-FIXES: std::println("{}", static_cast<const void *>(&AClass::member));
100483f875dcSMike Crowe   }
100583f875dcSMike Crowe };
100683f875dcSMike Crowe 
100783f875dcSMike Crowe void printf_positional_arg() {
100883f875dcSMike Crowe   printf("%1$d", 42);
100983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
101083f875dcSMike Crowe   // CHECK-FIXES: std::print("{0}", 42);
101183f875dcSMike Crowe 
101283f875dcSMike Crowe   printf("before %1$d", 42);
101383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
101483f875dcSMike Crowe   // CHECK-FIXES: std::print("before {0}", 42);
101583f875dcSMike Crowe 
101683f875dcSMike Crowe   printf("%1$d after", 42);
101783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
101883f875dcSMike Crowe   // CHECK-FIXES: std::print("{0} after", 42);
101983f875dcSMike Crowe 
102083f875dcSMike Crowe   printf("before %1$d after", 42);
102183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
102283f875dcSMike Crowe   // CHECK-FIXES: std::print("before {0} after", 42);
102383f875dcSMike Crowe 
102483f875dcSMike Crowe   printf("before %2$d between %1$s after", "string", 42);
102583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
102683f875dcSMike Crowe   // CHECK-FIXES: std::print("before {1} between {0} after", "string", 42);
102783f875dcSMike Crowe }
102883f875dcSMike Crowe 
102983f875dcSMike Crowe // printf always defaults to right justification,, no matter what the type is of
103083f875dcSMike Crowe // the argument. std::format uses left justification by default for strings, and
103183f875dcSMike Crowe // right justification for numbers.
103283f875dcSMike Crowe void printf_right_justified() {
103383f875dcSMike Crowe   printf("Right-justified integer %4d after\n", 42);
103483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
103583f875dcSMike Crowe   // CHECK-FIXES: std::println("Right-justified integer {:4} after", 42);
103683f875dcSMike Crowe 
103783f875dcSMike Crowe   printf("Right-justified double %4f\n", 227.2);
103883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
103983f875dcSMike Crowe   // CHECK-FIXES: std::println("Right-justified double {:4f}", 227.2);
104083f875dcSMike Crowe 
104183f875dcSMike Crowe   printf("Right-justified double %4g\n", 227.4);
104283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
104383f875dcSMike Crowe   // CHECK-FIXES: std::println("Right-justified double {:4g}", 227.4);
104483f875dcSMike Crowe 
104583f875dcSMike Crowe   printf("Right-justified integer with field width argument %*d after\n", 5, 424242);
104683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
10472806cf4bSMike Crowe   // CHECK-FIXES: std::println("Right-justified integer with field width argument {:{}} after", 424242, 5);
104883f875dcSMike Crowe 
104983f875dcSMike Crowe   printf("Right-justified integer with field width argument %2$*1$d after\n", 5, 424242);
105083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
105183f875dcSMike Crowe   // CHECK-FIXES: std::println("Right-justified integer with field width argument {1:{0}} after", 5, 424242);
105283f875dcSMike Crowe 
105383f875dcSMike Crowe   printf("Right-justified string %20s\n", "Hello");
105483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
105583f875dcSMike Crowe   // CHECK-FIXES: std::println("Right-justified string {:>20}", "Hello");
105683f875dcSMike Crowe 
105783f875dcSMike Crowe   printf("Right-justified string with field width argument %2$*1$s after\n", 20, "wibble");
105883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
105983f875dcSMike Crowe   // CHECK-FIXES: std::println("Right-justified string with field width argument {1:>{0}} after", 20, "wibble");
106083f875dcSMike Crowe }
106183f875dcSMike Crowe 
106283f875dcSMike Crowe // printf always requires - for left justification, no matter what the type is
106383f875dcSMike Crowe // of the argument. std::format uses left justification by default for strings,
106483f875dcSMike Crowe // and right justification for numbers.
106583f875dcSMike Crowe void printf_left_justified() {
106683f875dcSMike Crowe   printf("Left-justified integer %-4d\n", 42);
106783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
106883f875dcSMike Crowe   // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42);
106983f875dcSMike Crowe 
107083f875dcSMike Crowe   printf("Left-justified integer %--4d\n", 42);
107183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
107283f875dcSMike Crowe   // CHECK-FIXES: std::println("Left-justified integer {:<4}", 42);
107383f875dcSMike Crowe 
107483f875dcSMike Crowe   printf("Left-justified double %-4f\n", 227.2);
107583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
107683f875dcSMike Crowe   // CHECK-FIXES: std::println("Left-justified double {:<4f}", 227.2);
107783f875dcSMike Crowe 
107883f875dcSMike Crowe   printf("Left-justified double %-4g\n", 227.4);
107983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
108083f875dcSMike Crowe   // CHECK-FIXES: std::println("Left-justified double {:<4g}", 227.4);
108183f875dcSMike Crowe 
108283f875dcSMike Crowe   printf("Left-justified integer with field width argument %-*d after\n", 5, 424242);
108383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
10842806cf4bSMike Crowe   // CHECK-FIXES: std::println("Left-justified integer with field width argument {:<{}} after", 424242, 5);
108583f875dcSMike Crowe 
108683f875dcSMike Crowe   printf("Left-justified integer with field width argument %2$-*1$d after\n", 5, 424242);
108783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
108883f875dcSMike Crowe   // CHECK-FIXES: std::println("Left-justified integer with field width argument {1:<{0}} after", 5, 424242);
108983f875dcSMike Crowe 
109083f875dcSMike Crowe   printf("Left-justified string %-20s\n", "Hello");
109183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
109283f875dcSMike Crowe   // CHECK-FIXES: std::println("Left-justified string {:20}", "Hello");
109383f875dcSMike Crowe 
109483f875dcSMike Crowe   printf("Left-justified string with field width argument %2$-*1$s after\n", 5, "wibble");
109583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
109683f875dcSMike Crowe   // CHECK-FIXES: std::println("Left-justified string with field width argument {1:{0}} after", 5, "wibble");
109783f875dcSMike Crowe }
109883f875dcSMike Crowe 
109983f875dcSMike Crowe void printf_precision() {
110083f875dcSMike Crowe   printf("Hello %.3f\n", 3.14159);
110183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
110283f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:.3f}", 3.14159);
110383f875dcSMike Crowe 
110483f875dcSMike Crowe   printf("Hello %10.3f\n", 3.14159);
110583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
110683f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:10.3f}", 3.14159);
110783f875dcSMike Crowe 
110883f875dcSMike Crowe   printf("Hello %.*f after\n", 10, 3.14159265358979323846);
110983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11102806cf4bSMike Crowe   // CHECK-FIXES: std::println("Hello {:.{}f} after", 3.14159265358979323846, 10);
111183f875dcSMike Crowe 
111283f875dcSMike Crowe   printf("Hello %10.*f after\n", 3, 3.14159265358979323846);
111383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11142806cf4bSMike Crowe   // CHECK-FIXES: std::println("Hello {:10.{}f} after", 3.14159265358979323846, 3);
111583f875dcSMike Crowe 
111683f875dcSMike Crowe   printf("Hello %*.*f after\n", 10, 4, 3.14159265358979323846);
111783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11182806cf4bSMike Crowe   // CHECK-FIXES: std::println("Hello {:{}.{}f} after", 3.14159265358979323846, 10, 4);
111983f875dcSMike Crowe 
112083f875dcSMike Crowe   printf("Hello %1$.*2$f after\n", 3.14159265358979323846, 4);
112183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
112283f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {0:.{1}f} after", 3.14159265358979323846, 4);
112383f875dcSMike Crowe 
112483f875dcSMike Crowe   // Precision is ignored, but maintained on non-numeric arguments
112583f875dcSMike Crowe   printf("Hello %.5s\n", "Goodbye");
112683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
112783f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:.5}", "Goodbye");
112883f875dcSMike Crowe 
112983f875dcSMike Crowe   printf("Hello %.5c\n", 'G');
113083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
113183f875dcSMike Crowe   // CHECK-FIXES: std::println("Hello {:.5}", 'G');
113283f875dcSMike Crowe }
113383f875dcSMike Crowe 
1134c6207f6eSMike Crowe void printf_field_width_and_precision(const std::string &s1, const std::string &s2, const std::string &s3)
1135c6207f6eSMike Crowe {
11362806cf4bSMike Crowe   printf("width only:%*d width and precision:%*.*f precision only:%.*f\n", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
113783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11382806cf4bSMike Crowe   // CHECK-FIXES: std::println("width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
11392806cf4bSMike Crowe 
1140c6207f6eSMike Crowe   const unsigned int ui1 = 42, ui2 = 43, ui3 = 44;
1141c6207f6eSMike Crowe   printf("casts width only:%*d width and precision:%*.*d precision only:%.*d\n", 3, ui1, 4, 2, ui2, 5, ui3);
1142c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1143c6207f6eSMike Crowe   // CHECK-FIXES-NOTSTRICT: std::println("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", ui1, 3, ui2, 4, 2, ui3, 5);
1144c6207f6eSMike Crowe   // CHECK-FIXES-STRICT: std::println("casts width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", static_cast<int>(ui1), 3, static_cast<int>(ui2), 4, 2, static_cast<int>(ui3), 5);
1145c6207f6eSMike Crowe 
1146c6207f6eSMike Crowe   printf("c_str removal width only:%*s width and precision:%*.*s precision only:%.*s\n", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str());
1147c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1148c6207f6eSMike Crowe   // CHECK-FIXES: std::println("c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
1149c6207f6eSMike Crowe 
1150c6207f6eSMike Crowe   const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3;
1151c6207f6eSMike Crowe   printf("c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str());
1152c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1153c6207f6eSMike Crowe   // CHECK-FIXES: std::println("c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5);
1154c6207f6eSMike Crowe 
1155c6207f6eSMike Crowe   iterator<std::string> is1, is2, is3;
1156c6207f6eSMike Crowe   printf("c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str());
1157c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1158c6207f6eSMike Crowe   // CHECK-FIXES: std::println("c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5);
1159c6207f6eSMike Crowe 
11602806cf4bSMike Crowe   printf("width and precision positional:%1$*2$.*3$f after\n", 3.14159265358979323846, 4, 2);
11612806cf4bSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11622806cf4bSMike Crowe   // CHECK-FIXES: std::println("width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2);
11632806cf4bSMike Crowe 
11642806cf4bSMike Crowe   const int width = 10, precision = 3;
11652806cf4bSMike Crowe   printf("width only:%3$*1$d width and precision:%4$*1$.*2$f precision only:%5$.*2$f\n", width, precision, 42, 3.1415926, 2.718);
11662806cf4bSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
11672806cf4bSMike Crowe   // CHECK-FIXES: std::println("width only:{2:{0}} width and precision:{3:{0}.{1}f} precision only:{4:.{1}f}", width, precision, 42, 3.1415926, 2.718);
1168c6207f6eSMike Crowe 
1169c6207f6eSMike Crowe   printf("c_str removal width only:%3$*1$s width and precision:%4$*1$.*2$s precision only:%5$.*2$s\n", width, precision, s1.c_str(), s2.c_str(), s3.c_str());
1170c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1171c6207f6eSMike Crowe   // CHECK-FIXES: std::println("c_str removal width only:{2:>{0}} width and precision:{3:>{0}.{1}} precision only:{4:.{1}}", width, precision, s1, s2, s3);
11722806cf4bSMike Crowe }
11732806cf4bSMike Crowe 
1174c6207f6eSMike Crowe void fprintf_field_width_and_precision(const std::string &s1, const std::string &s2, const std::string &s3) {
11752806cf4bSMike Crowe   fprintf(stderr, "width only:%*d width and precision:%*.*f precision only:%.*f\n", 3, 42, 4, 2, 3.14159265358979323846, 5, 2.718);
11762806cf4bSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
11772806cf4bSMike Crowe   // CHECK-FIXES: std::println(stderr, "width only:{:{}} width and precision:{:{}.{}f} precision only:{:.{}f}", 42, 3, 3.14159265358979323846, 4, 2, 2.718, 5);
11782806cf4bSMike Crowe 
11792806cf4bSMike Crowe   fprintf(stderr, "width and precision positional:%1$*2$.*3$f after\n", 3.14159265358979323846, 4, 2);
11802806cf4bSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
11812806cf4bSMike Crowe   // CHECK-FIXES: std::println(stderr, "width and precision positional:{0:{1}.{2}f} after", 3.14159265358979323846, 4, 2);
11822806cf4bSMike Crowe 
1183c6207f6eSMike Crowe   fprintf(stderr, "c_str removal width only:%*s width and precision:%*.*s precision only:%.*s\n", 3, s1.c_str(), 4, 2, s2.c_str(), 5, s3.c_str());
1184c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1185c6207f6eSMike Crowe   // CHECK-FIXES: std::println(stderr, "c_str removal width only:{:>{}} width and precision:{:>{}.{}} precision only:{:.{}}", s1, 3, s2, 4, 2, s3, 5);
1186c6207f6eSMike Crowe 
1187c6207f6eSMike Crowe   const std::string *ps1 = &s1, *ps2 = &s2, *ps3 = &s3;
1188c6207f6eSMike Crowe   fprintf(stderr, "c_str() removal pointer width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, ps1->c_str(), 4, 2, ps2->c_str(), 5, ps3->c_str());
1189c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1190c6207f6eSMike Crowe   // CHECK-FIXES: std::println(stderr, "c_str() removal pointer width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *ps1, 3, *ps2, 4, 2, *ps3, 5);
1191c6207f6eSMike Crowe 
1192c6207f6eSMike Crowe   iterator<std::string> is1, is2, is3;
1193c6207f6eSMike Crowe   fprintf(stderr, "c_str() removal iterator width only:%-*s width and precision:%-*.*s precision only:%-.*s\n", 3, is1->c_str(), 4, 2, is2->c_str(), 5, is3->c_str());
1194c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1195c6207f6eSMike Crowe   // CHECK-FIXES: std::println(stderr, "c_str() removal iterator width only:{:{}} width and precision:{:{}.{}} precision only:{:.{}}", *is1, 3, *is2, 4, 2, *is3, 5);
1196c6207f6eSMike Crowe 
11972806cf4bSMike Crowe   const int width = 10, precision = 3;
11982806cf4bSMike Crowe   fprintf(stderr, "width only:%3$*1$d width and precision:%4$*1$.*2$f precision only:%5$.*2$f\n", width, precision, 42, 3.1415926, 2.718);
11992806cf4bSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
12002806cf4bSMike Crowe   // CHECK-FIXES: std::println(stderr, "width only:{2:{0}} width and precision:{3:{0}.{1}f} precision only:{4:.{1}f}", width, precision, 42, 3.1415926, 2.718);
1201c6207f6eSMike Crowe 
1202c6207f6eSMike Crowe   fprintf(stderr, "c_str removal width only:%3$*1$s width and precision:%4$*1$.*2$s precision only:%5$.*2$s\n", width, precision, s1.c_str(), s2.c_str(), s3.c_str());
1203c6207f6eSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print]
1204c6207f6eSMike Crowe   // CHECK-FIXES: std::println(stderr, "c_str removal width only:{2:>{0}} width and precision:{3:>{0}.{1}} precision only:{4:.{1}}", width, precision, s1, s2, s3);
120583f875dcSMike Crowe }
120683f875dcSMike Crowe 
120783f875dcSMike Crowe void printf_alternative_form() {
120883f875dcSMike Crowe   printf("Wibble %#x\n", 42);
120983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
121083f875dcSMike Crowe   // CHECK-FIXES: std::println("Wibble {:#x}", 42);
121183f875dcSMike Crowe 
121283f875dcSMike Crowe   printf("Wibble %#20x\n", 42);
121383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
121483f875dcSMike Crowe   // CHECK-FIXES: std::println("Wibble {:#20x}", 42);
121583f875dcSMike Crowe 
121683f875dcSMike Crowe   printf("Wibble %#020x\n", 42);
121783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
121883f875dcSMike Crowe   // CHECK-FIXES: std::println("Wibble {:#020x}", 42);
121983f875dcSMike Crowe 
122083f875dcSMike Crowe   printf("Wibble %#-20x\n", 42);
122183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
122283f875dcSMike Crowe   // CHECK-FIXES: std::println("Wibble {:<#20x}", 42);
122383f875dcSMike Crowe }
122483f875dcSMike Crowe 
122583f875dcSMike Crowe void printf_leading_plus() {
122683f875dcSMike Crowe   printf("Positive integer %+d\n", 42);
122783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
122883f875dcSMike Crowe   // CHECK-FIXES: std::println("Positive integer {:+}", 42);
122983f875dcSMike Crowe 
123083f875dcSMike Crowe   printf("Positive double %+f\n", 42.2);
123183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
123283f875dcSMike Crowe   // CHECK-FIXES: std::println("Positive double {:+f}", 42.2);
123383f875dcSMike Crowe 
123483f875dcSMike Crowe   printf("Positive double %+g\n", 42.2);
123583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
123683f875dcSMike Crowe   // CHECK-FIXES: std::println("Positive double {:+g}", 42.2);
123783f875dcSMike Crowe 
123883f875dcSMike Crowe   // Ignore leading plus on strings to avoid potential runtime exception where
123983f875dcSMike Crowe   // printf would have just ignored it.
124083f875dcSMike Crowe   printf("Positive string %+s\n", "string");
124183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
124283f875dcSMike Crowe   // CHECK-FIXES: std::println("Positive string {}", "string");
124383f875dcSMike Crowe }
124483f875dcSMike Crowe 
124583f875dcSMike Crowe void printf_leading_space() {
124683f875dcSMike Crowe   printf("Spaced integer % d\n", 42);
124783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
124883f875dcSMike Crowe   // CHECK-FIXES: std::println("Spaced integer {: }", 42);
124983f875dcSMike Crowe 
125083f875dcSMike Crowe   printf("Spaced integer %- d\n", 42);
125183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
125283f875dcSMike Crowe   // CHECK-FIXES: std::println("Spaced integer {: }", 42);
125383f875dcSMike Crowe 
125483f875dcSMike Crowe   printf("Spaced double % f\n", 42.2);
125583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
125683f875dcSMike Crowe   // CHECK-FIXES: std::println("Spaced double {: f}", 42.2);
125783f875dcSMike Crowe 
125883f875dcSMike Crowe   printf("Spaced double % g\n", 42.2);
125983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
126083f875dcSMike Crowe   // CHECK-FIXES: std::println("Spaced double {: g}", 42.2);
126183f875dcSMike Crowe }
126283f875dcSMike Crowe 
126383f875dcSMike Crowe void printf_leading_zero() {
126483f875dcSMike Crowe   printf("Leading zero integer %03d\n", 42);
126583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
126683f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero integer {:03}", 42);
126783f875dcSMike Crowe 
126883f875dcSMike Crowe   printf("Leading minus and zero integer %-03d minus ignored\n", 42);
126983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
127083f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading minus and zero integer {:<03} minus ignored", 42);
127183f875dcSMike Crowe 
127283f875dcSMike Crowe   printf("Leading zero unsigned integer %03u\n", 42U);
127383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
127483f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero unsigned integer {:03}", 42U);
127583f875dcSMike Crowe 
127683f875dcSMike Crowe   printf("Leading zero double %03f\n", 42.2);
127783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
127883f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero double {:03f}", 42.2);
127983f875dcSMike Crowe 
128083f875dcSMike Crowe   printf("Leading zero double %03g\n", 42.2);
128183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
128283f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero double {:03g}", 42.2);
128383f875dcSMike Crowe }
128483f875dcSMike Crowe 
128583f875dcSMike Crowe void printf_leading_plus_and_space() {
128683f875dcSMike Crowe   // printf prefers plus to space. {fmt} will throw if both are present.
128783f875dcSMike Crowe   printf("Spaced integer % +d\n", 42);
128883f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
128983f875dcSMike Crowe   // CHECK-FIXES: std::println("Spaced integer {:+}", 42);
129083f875dcSMike Crowe 
129183f875dcSMike Crowe   printf("Spaced double %+ f\n", 42.2);
129283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
129383f875dcSMike Crowe   // CHECK-FIXES: std::println("Spaced double {:+f}", 42.2);
129483f875dcSMike Crowe 
129583f875dcSMike Crowe   printf("Spaced double % +g\n", 42.2);
129683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
129783f875dcSMike Crowe   // CHECK-FIXES: std::println("Spaced double {:+g}", 42.2);
129883f875dcSMike Crowe }
129983f875dcSMike Crowe 
130083f875dcSMike Crowe void printf_leading_zero_and_plus() {
130183f875dcSMike Crowe   printf("Leading zero integer %+03d\n", 42);
130283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
130383f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero integer {:+03}", 42);
130483f875dcSMike Crowe 
130583f875dcSMike Crowe   printf("Leading zero double %0+3f\n", 42.2);
130683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
130783f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero double {:+03f}", 42.2);
130883f875dcSMike Crowe 
130983f875dcSMike Crowe   printf("Leading zero double %0+3g\n", 42.2);
131083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
131183f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero double {:+03g}", 42.2);
131283f875dcSMike Crowe }
131383f875dcSMike Crowe 
131483f875dcSMike Crowe void printf_leading_zero_and_space() {
131583f875dcSMike Crowe   printf("Leading zero and space integer %0 3d\n", 42);
131683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
131783f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero and space integer {: 03}", 42);
131883f875dcSMike Crowe 
131983f875dcSMike Crowe   printf("Leading zero and space double %0 3f\n", 42.2);
132083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
132183f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero and space double {: 03f}", 42.2);
132283f875dcSMike Crowe 
132383f875dcSMike Crowe   printf("Leading zero and space double %0 3g\n", 42.2);
132483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
132583f875dcSMike Crowe   // CHECK-FIXES: std::println("Leading zero and space double {: 03g}", 42.2);
132683f875dcSMike Crowe }
132783f875dcSMike Crowe 
132883f875dcSMike Crowe // add signed plained enum too
132983f875dcSMike Crowe enum PlainEnum { red };
133083f875dcSMike Crowe enum SignedPlainEnum { black = -42 };
133183f875dcSMike Crowe enum BoolEnum : unsigned int { yellow };
133283f875dcSMike Crowe enum CharEnum : char { purple };
133383f875dcSMike Crowe enum SCharEnum : signed char  { aquamarine };
133483f875dcSMike Crowe enum UCharEnum : unsigned char  { pink };
133583f875dcSMike Crowe enum ShortEnum : short { beige };
133683f875dcSMike Crowe enum UShortEnum : unsigned short { grey };
133783f875dcSMike Crowe enum IntEnum : int { green };
133883f875dcSMike Crowe enum UIntEnum : unsigned int { blue };
133983f875dcSMike Crowe enum LongEnum : long { magenta };
134083f875dcSMike Crowe enum ULongEnum : unsigned long { cyan };
134183f875dcSMike Crowe enum LongLongEnum : long long { taupe };
134283f875dcSMike Crowe enum ULongLongEnum : unsigned long long { brown };
134383f875dcSMike Crowe 
134483f875dcSMike Crowe void printf_enum_d() {
134583f875dcSMike Crowe   PlainEnum plain_enum;
134683f875dcSMike Crowe   printf("%d", plain_enum);
134783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
134883f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<int>(plain_enum));
134983f875dcSMike Crowe 
135083f875dcSMike Crowe   SignedPlainEnum splain_enum;
135183f875dcSMike Crowe   printf("%d", splain_enum);
135283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
135383f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<int>(splain_enum));
135483f875dcSMike Crowe 
135583f875dcSMike Crowe   BoolEnum bool_enum;
135683f875dcSMike Crowe   printf("%d", bool_enum);
135783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
135883f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<int>(bool_enum));
135983f875dcSMike Crowe 
136083f875dcSMike Crowe   CharEnum char_enum;
136183f875dcSMike Crowe   printf("%d", char_enum);
136283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
136383f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<signed char>(char_enum));
136483f875dcSMike Crowe 
136583f875dcSMike Crowe   SCharEnum schar_enum;
136683f875dcSMike Crowe   printf("%d", schar_enum);
136783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
136883f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<signed char>(schar_enum));
136983f875dcSMike Crowe 
137083f875dcSMike Crowe   UCharEnum uchar_enum;
137183f875dcSMike Crowe   printf("%d", uchar_enum);
137283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
137383f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<signed char>(uchar_enum));
137483f875dcSMike Crowe 
137583f875dcSMike Crowe   ShortEnum short_enum;
137683f875dcSMike Crowe   printf("%d", short_enum);
137783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
137883f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<short>(short_enum));
137983f875dcSMike Crowe 
138083f875dcSMike Crowe   UShortEnum ushort_enum;
138183f875dcSMike Crowe   printf("%d", ushort_enum);
138283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
138383f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<short>(ushort_enum));
138483f875dcSMike Crowe 
138583f875dcSMike Crowe   IntEnum int_enum;
138683f875dcSMike Crowe   printf("%d", int_enum);
138783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
138883f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<int>(int_enum));
138983f875dcSMike Crowe 
139083f875dcSMike Crowe   UIntEnum uint_enum;
139183f875dcSMike Crowe   printf("%d", uint_enum);
139283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
139383f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<int>(uint_enum));
139483f875dcSMike Crowe 
139583f875dcSMike Crowe   LongEnum long_enum;
139683f875dcSMike Crowe   printf("%d", long_enum);
139783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
139883f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<long>(long_enum));
139983f875dcSMike Crowe 
140083f875dcSMike Crowe   ULongEnum ulong_enum;
140183f875dcSMike Crowe   printf("%d", ulong_enum);
140283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
140383f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<long>(ulong_enum));
140483f875dcSMike Crowe 
140583f875dcSMike Crowe   LongLongEnum longlong_enum;
140683f875dcSMike Crowe   printf("%d", longlong_enum);
140783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
140883f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<long long>(longlong_enum));
140983f875dcSMike Crowe 
141083f875dcSMike Crowe   ULongLongEnum ulonglong_enum;
141183f875dcSMike Crowe   printf("%d", ulonglong_enum);
141283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
141383f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<long long>(ulonglong_enum));
141483f875dcSMike Crowe }
141583f875dcSMike Crowe 
141683f875dcSMike Crowe void printf_enum_u() {
141783f875dcSMike Crowe   PlainEnum plain_enum;
141883f875dcSMike Crowe   printf("%u", plain_enum);
141983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
142083f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(plain_enum));
142183f875dcSMike Crowe 
142283f875dcSMike Crowe   SignedPlainEnum splain_enum;
142383f875dcSMike Crowe   printf("%u", splain_enum);
142483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
142583f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(splain_enum));
142683f875dcSMike Crowe 
142783f875dcSMike Crowe   BoolEnum bool_enum;
142883f875dcSMike Crowe   printf("%u", bool_enum);
142983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
143083f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(bool_enum));
143183f875dcSMike Crowe 
143283f875dcSMike Crowe   CharEnum char_enum;
143383f875dcSMike Crowe   printf("%u", char_enum);
143483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
143583f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(char_enum));
143683f875dcSMike Crowe 
143783f875dcSMike Crowe   SCharEnum schar_enum;
143883f875dcSMike Crowe   printf("%u", schar_enum);
143983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
144083f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(schar_enum));
144183f875dcSMike Crowe 
144283f875dcSMike Crowe   UCharEnum uchar_enum;
144383f875dcSMike Crowe   printf("%u", uchar_enum);
144483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
144583f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned char>(uchar_enum));
144683f875dcSMike Crowe 
144783f875dcSMike Crowe   ShortEnum short_enum;
144883f875dcSMike Crowe   printf("%u", short_enum);
144983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
145083f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(short_enum));
145183f875dcSMike Crowe 
145283f875dcSMike Crowe   UShortEnum ushort_enum;
145383f875dcSMike Crowe   printf("%u", ushort_enum);
145483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
145583f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned short>(ushort_enum));
145683f875dcSMike Crowe 
145783f875dcSMike Crowe   IntEnum int_enum;
145883f875dcSMike Crowe   printf("%u", int_enum);
145983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
146083f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(int_enum));
146183f875dcSMike Crowe 
146283f875dcSMike Crowe   UIntEnum uint_enum;
146383f875dcSMike Crowe   printf("%u", uint_enum);
146483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
146583f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned int>(uint_enum));
146683f875dcSMike Crowe 
146783f875dcSMike Crowe   LongEnum long_enum;
146883f875dcSMike Crowe   printf("%u", long_enum);
146983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
147083f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(long_enum));
147183f875dcSMike Crowe 
147283f875dcSMike Crowe   ULongEnum ulong_enum;
147383f875dcSMike Crowe   printf("%u", ulong_enum);
147483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
147583f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned long>(ulong_enum));
147683f875dcSMike Crowe 
147783f875dcSMike Crowe   LongLongEnum longlong_enum;
147883f875dcSMike Crowe   printf("%u", longlong_enum);
147983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
148083f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(longlong_enum));
148183f875dcSMike Crowe 
148283f875dcSMike Crowe   ULongLongEnum ulonglong_enum;
148383f875dcSMike Crowe   printf("%u", ulonglong_enum);
148483f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
148583f875dcSMike Crowe   // CHECK-FIXES: std::print("{}", static_cast<unsigned long long>(ulonglong_enum));
148683f875dcSMike Crowe }
148783f875dcSMike Crowe 
148883f875dcSMike Crowe void printf_string_function(const char *(*callback)()) {
148983f875dcSMike Crowe   printf("printf string from callback %s", callback());
149083f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
149183f875dcSMike Crowe   // CHECK-FIXES: std::print("printf string from callback {}", callback());
149283f875dcSMike Crowe }
149383f875dcSMike Crowe 
149483f875dcSMike Crowe template <typename CharType>
149583f875dcSMike Crowe struct X
149683f875dcSMike Crowe {
149783f875dcSMike Crowe   const CharType *str() const;
149883f875dcSMike Crowe };
149983f875dcSMike Crowe 
150083f875dcSMike Crowe void printf_string_member_function(const X<char> &x, const X<const char> &cx) {
150183f875dcSMike Crowe   printf("printf string from member function %s", x.str());
150283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
150383f875dcSMike Crowe   // CHECK-FIXES: std::print("printf string from member function {}", x.str());
150483f875dcSMike Crowe 
150583f875dcSMike Crowe   printf("printf string from member function on const %s", cx.str());
150683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
150783f875dcSMike Crowe   // CHECK-FIXES: std::print("printf string from member function on const {}", cx.str());
150883f875dcSMike Crowe }
150983f875dcSMike Crowe 
151083f875dcSMike Crowe void printf_string_cstr(const std::string &s1, const std::string &s2) {
151183f875dcSMike Crowe   printf("printf string one c_str %s", s1.c_str());
151283f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
151383f875dcSMike Crowe   // CHECK-FIXES: std::print("printf string one c_str {}", s1);
151483f875dcSMike Crowe 
151583f875dcSMike Crowe   printf("printf string two c_str %s %s\n", s1.c_str(), s2.data());
151683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
151783f875dcSMike Crowe   // CHECK-FIXES: std::println("printf string two c_str {} {}", s1, s2);
151883f875dcSMike Crowe }
151983f875dcSMike Crowe 
152083f875dcSMike Crowe void printf_not_char_string_cstr(const std::wstring &ws1) {
152183f875dcSMike Crowe   // This test is to check that we only remove
152283f875dcSMike Crowe   // std::basic_string<CharType>::c_str()/data() when CharType is char. I've
152383f875dcSMike Crowe   // been unable to come up with a genuine situation where someone would have
152483f875dcSMike Crowe   // actually successfully called those methods when this isn't the case without
152583f875dcSMike Crowe   // -Wformat warning, but it seems sensible to restrict removal regardless.
152683f875dcSMike Crowe   printf("printf bogus wstring c_str %s", ws1.c_str());
152783f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
152883f875dcSMike Crowe   // CHECK-FIXES: std::print("printf bogus wstring c_str {}", ws1.c_str());
152983f875dcSMike Crowe }
153083f875dcSMike Crowe 
153183f875dcSMike Crowe void fprintf_string_cstr(const std::string &s1) {
153283f875dcSMike Crowe   fprintf(stderr, "fprintf string c_str %s", s1.c_str());
153383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print]
153483f875dcSMike Crowe   // CHECK-FIXES: std::print(stderr, "fprintf string c_str {}", s1);
153583f875dcSMike Crowe }
153683f875dcSMike Crowe 
153783f875dcSMike Crowe void printf_string_pointer_cstr(const std::string *s1, const std::string *s2) {
153883f875dcSMike Crowe   printf("printf string pointer one c_str %s", s1->c_str());
153983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
154083f875dcSMike Crowe   // CHECK-FIXES: std::print("printf string pointer one c_str {}", *s1);
154183f875dcSMike Crowe 
154283f875dcSMike Crowe   printf("printf string pointer two c_str %s %s\n", s1->c_str(), s2->data());
154383f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
154483f875dcSMike Crowe   // CHECK-FIXES: std::println("printf string pointer two c_str {} {}", *s1, *s2);
154583f875dcSMike Crowe }
154683f875dcSMike Crowe 
154783f875dcSMike Crowe void fprintf_string_pointer_cstr(const std::string *s1) {
154883f875dcSMike Crowe   fprintf(stderr, "fprintf string pointer c_str %s", s1->c_str());
154983f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'fprintf' [modernize-use-std-print]
155083f875dcSMike Crowe   // CHECK-FIXES: std::print(stderr, "fprintf string pointer c_str {}", *s1);
155183f875dcSMike Crowe }
155283f875dcSMike Crowe 
155383f875dcSMike Crowe void printf_iterator_cstr(iterator<std::string> i1, iterator<std::string> i2)
155483f875dcSMike Crowe {
155583f875dcSMike Crowe   printf("printf iterator c_str %s %s\n", i1->c_str(), i2->data());
155683f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
155783f875dcSMike Crowe   // CHECK-FIXES: std::println("printf iterator c_str {} {}", *i1, *i2);
155883f875dcSMike Crowe }
155983f875dcSMike Crowe 
156083f875dcSMike Crowe // Something that isn't std::string, so the calls to c_str() and data() must not
156183f875dcSMike Crowe // be removed even though the printf call will be replaced.
156283f875dcSMike Crowe struct S
156383f875dcSMike Crowe {
156483f875dcSMike Crowe   const char *c_str() const;
156583f875dcSMike Crowe   const char *data() const;
156683f875dcSMike Crowe };
156783f875dcSMike Crowe 
156883f875dcSMike Crowe void p(S s1, S *s2)
156983f875dcSMike Crowe {
157083f875dcSMike Crowe   printf("Not std::string %s %s", s1.c_str(), s2->c_str());
157183f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
157283f875dcSMike Crowe   // CHECK-FIXES: std::print("Not std::string {} {}", s1.c_str(), s2->c_str());
157383f875dcSMike Crowe 
157483f875dcSMike Crowe   printf("Not std::string %s %s", s1.data(), s2->data());
157583f875dcSMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
157683f875dcSMike Crowe   // CHECK-FIXES: std::print("Not std::string {} {}", s1.data(), s2->data());
157783f875dcSMike Crowe }
1578a199fb12SMike Crowe 
1579a199fb12SMike Crowe // These need PRI and __PRI prefixes so that the check gets as far as looking
1580a199fb12SMike Crowe // for where the macro comes from.
1581a199fb12SMike Crowe #define PRI_FMT_MACRO "s"
1582a199fb12SMike Crowe #define __PRI_FMT_MACRO "s"
1583a199fb12SMike Crowe 
1584a199fb12SMike Crowe void macro_expansion(const char *s)
1585a199fb12SMike Crowe {
1586a199fb12SMike Crowe   const uint64_t u64 = 42;
1587a199fb12SMike Crowe   const uint32_t u32 = 32;
1588a199fb12SMike Crowe 
1589a199fb12SMike Crowe   printf("Replaceable macro at end %" PRIu64, u64);
1590a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1591a199fb12SMike Crowe   // CHECK-FIXES: std::print("Replaceable macro at end {}", u64);
1592a199fb12SMike Crowe 
1593a199fb12SMike Crowe   printf("Replaceable macros in middle %" PRIu64 " %" PRIu32 "\n", u64, u32);
1594a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print]
1595a199fb12SMike Crowe   // CHECK-FIXES: std::println("Replaceable macros in middle {} {}", u64, u32);
1596a199fb12SMike Crowe 
1597a199fb12SMike Crowe   printf("Unreplaceable macro at end %" PRI_FMT_MACRO, s);
1598a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print]
1599a199fb12SMike Crowe 
1600a199fb12SMike Crowe   printf(PRI_FMT_MACRO " Unreplaceable macro at beginning %s", s);
1601a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print]
1602a199fb12SMike Crowe 
1603a199fb12SMike Crowe   printf("Unreplacemable macro %" __PRI_FMT_MACRO " in the middle", s);
1604a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro '__PRI_FMT_MACRO' [modernize-use-std-print]
1605a199fb12SMike Crowe 
1606a199fb12SMike Crowe   printf("First macro is replaceable %" PRIu64 " but second one is not %" PRI_FMT_MACRO, u64, s);
1607a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print]
1608a199fb12SMike Crowe 
1609a199fb12SMike Crowe   // Needs a PRI prefix so that we get as far as looking for where the macro comes from
1610a199fb12SMike Crowe   printf(" macro from command line %" PRI_CMDLINE_MACRO, s);
1611a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_CMDLINE_MACRO' [modernize-use-std-print]
1612a199fb12SMike Crowe 
1613a199fb12SMike Crowe   // Needs a __PRI prefix so that we get as far as looking for where the macro comes from
1614a199fb12SMike Crowe   printf(" macro from command line %" __PRI_CMDLINE_MACRO, s);
1615a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro '__PRI_CMDLINE_MACRO' [modernize-use-std-print]
1616a199fb12SMike Crowe 
1617a199fb12SMike Crowe   // We ought to be able to fix this since the macro surrounds the whole call
1618a199fb12SMike Crowe   // and therefore can't change the format string independently. This is
1619a199fb12SMike Crowe   // required to be able to fix calls inside Catch2 macros for example.
1620a199fb12SMike Crowe #define SURROUND_ALL(x) x
1621a199fb12SMike Crowe   SURROUND_ALL(printf("Macro surrounding entire invocation %" PRIu64, u64));
1622a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:16: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1623a199fb12SMike Crowe   // CHECK-FIXES: SURROUND_ALL(std::print("Macro surrounding entire invocation {}", u64));
1624a199fb12SMike Crowe 
1625a199fb12SMike Crowe   // But having that surrounding macro shouldn't stop us ignoring an
1626a199fb12SMike Crowe   // unreplaceable macro elsewhere.
1627a199fb12SMike Crowe   SURROUND_ALL(printf("Macro surrounding entire invocation with unreplaceable macro %" PRI_FMT_MACRO, s));
1628a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:16: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'PRI_FMT_MACRO' [modernize-use-std-print]
1629a199fb12SMike Crowe 
1630a199fb12SMike Crowe   // At the moment at least the check will replace occurrences where the
1631a199fb12SMike Crowe   // function name is the result of expanding a macro.
1632a199fb12SMike Crowe #define SURROUND_FUNCTION_NAME(x) x
1633a199fb12SMike Crowe   SURROUND_FUNCTION_NAME(printf)("Hello %d", 4442);
1634a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:26: warning: use 'std::print' instead of 'printf' [modernize-use-std-print]
1635a199fb12SMike Crowe   // CHECK-FIXES: std::print("Hello {}", 4442);
1636a199fb12SMike Crowe 
1637a199fb12SMike Crowe   // We can't safely fix occurrences where the macro may affect the format
1638a199fb12SMike Crowe   // string differently in different builds.
1639a199fb12SMike Crowe #define SURROUND_FORMAT(x) "!" x
1640a199fb12SMike Crowe   printf(SURROUND_FORMAT("Hello %d"), 4443);
1641a199fb12SMike Crowe   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'printf' because format string contains unreplaceable macro 'SURROUND_FORMAT' [modernize-use-std-print]
1642a199fb12SMike Crowe }
1643