1 // RUN: %check_clang_tidy \ 2 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 3 // RUN: -config="{CheckOptions: [{key: StrictMode, value: true}]}" \ 4 // RUN: -- -isystem %clang_tidy_headers 5 // RUN: %check_clang_tidy \ 6 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 7 // RUN: -config="{CheckOptions: [{key: StrictMode, value: false}]}" \ 8 // RUN: -- -isystem %clang_tidy_headers 9 10 #include <cstdio> 11 #include <string.h> 12 13 namespace absl 14 { 15 // Use const char * for the format since the real type is hard to mock up. 16 template <typename... Args> 17 int PrintF(const char *format, const Args&... args); 18 19 template <typename... Args> 20 int FPrintF(FILE* output, const char *format, const Args&... args); 21 } 22 23 void printf_simple() { 24 absl::PrintF("Hello %s %d", "world", 42); 25 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'PrintF' [modernize-use-std-print] 26 // CHECK-FIXES: std::print("Hello {} {}", "world", 42); 27 } 28 29 void printf_newline() { 30 absl::PrintF("Hello %s %d\n", "world", 42); 31 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'PrintF' [modernize-use-std-print] 32 // CHECK-FIXES: std::println("Hello {} {}", "world", 42); 33 34 using namespace absl; 35 PrintF("Hello %s %d\n", "world", 42); 36 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'PrintF' [modernize-use-std-print] 37 // CHECK-FIXES: std::println("Hello {} {}", "world", 42); 38 } 39 40 // absl uses the type of the argument rather than the format string, so unsigned 41 // types will be printed as unsigned even if the format string indicates signed 42 // and vice-versa. This is exactly what std::print will do too, so no casts are 43 // required. 44 void printf_no_casts_in_strict_mode() { 45 using namespace absl; 46 47 const unsigned short us = 42U; 48 PrintF("Integer %hd from unsigned short\n", us); 49 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'PrintF' [modernize-use-std-print] 50 // CHECK-FIXES: std::println("Integer {} from unsigned short", us); 51 52 const short s = 42; 53 PrintF("Unsigned integer %hu from short\n", s); 54 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'PrintF' [modernize-use-std-print] 55 // CHECK-FIXES: std::println("Unsigned integer {} from short", s); 56 } 57 58 void fprintf_simple(FILE *fp) { 59 absl::FPrintF(fp, "Hello %s %d", "world", 42); 60 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'FPrintF' [modernize-use-std-print] 61 // CHECK-FIXES: std::print(fp, "Hello {} {}", "world", 42); 62 } 63 64 void fprintf_newline(FILE *fp) { 65 absl::FPrintF(fp, "Hello %s %d\n", "world", 42); 66 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 67 // CHECK-FIXES: std::println(fp, "Hello {} {}", "world", 42); 68 69 using namespace absl; 70 FPrintF(fp, "Hello %s %d\n", "world", 42); 71 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 72 // CHECK-FIXES: std::println(fp, "Hello {} {}", "world", 42); 73 } 74 75 void fprintf_no_casts_in_strict_mode(FILE *fp) { 76 using namespace absl; 77 78 const unsigned short us = 42U; 79 FPrintF(fp, "Integer %hd from unsigned short\n", us); 80 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 81 // CHECK-FIXES: std::println(fp, "Integer {} from unsigned short", us); 82 83 const short s = 42; 84 FPrintF(fp, "Unsigned integer %hu from short\n", s); 85 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 86 // CHECK-FIXES: std::println(fp, "Unsigned integer {} from short", s); 87 } 88