1 // RUN: %check_clang_tidy \ 2 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 3 // RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: true}}" \ 4 // RUN: -- -isystem %clang_tidy_headers 5 // RUN: %check_clang_tidy \ 6 // RUN: -std=c++23 %s modernize-use-std-print %t -- \ 7 // RUN: -config="{CheckOptions: {modernize-use-std-print.StrictMode: 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 int printf_uses_return_value(int i) { 59 using namespace absl; 60 61 return PrintF("return value %d\n", i); 62 } 63 64 void fprintf_simple(FILE *fp) { 65 absl::FPrintF(fp, "Hello %s %d", "world", 42); 66 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'FPrintF' [modernize-use-std-print] 67 // CHECK-FIXES: std::print(fp, "Hello {} {}", "world", 42); 68 } 69 70 void fprintf_newline(FILE *fp) { 71 absl::FPrintF(fp, "Hello %s %d\n", "world", 42); 72 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 73 // CHECK-FIXES: std::println(fp, "Hello {} {}", "world", 42); 74 75 using namespace absl; 76 FPrintF(fp, "Hello %s %d\n", "world", 42); 77 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 78 // CHECK-FIXES: std::println(fp, "Hello {} {}", "world", 42); 79 } 80 81 void fprintf_no_casts_in_strict_mode(FILE *fp) { 82 using namespace absl; 83 84 const unsigned short us = 42U; 85 FPrintF(fp, "Integer %hd from unsigned short\n", us); 86 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 87 // CHECK-FIXES: std::println(fp, "Integer {} from unsigned short", us); 88 89 const short s = 42; 90 FPrintF(fp, "Unsigned integer %hu from short\n", s); 91 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'FPrintF' [modernize-use-std-print] 92 // CHECK-FIXES: std::println(fp, "Unsigned integer {} from short", s); 93 } 94 95 int fprintf_uses_return_value(FILE *fp, int i) { 96 using namespace absl; 97 98 return FPrintF(fp, "return value %d\n", i); 99 } 100