183f875dcSMike Crowe // RUN: %check_clang_tidy -std=c++23 %s modernize-use-std-print %t -- \ 283f875dcSMike Crowe // RUN: -config="{CheckOptions: \ 383f875dcSMike Crowe // RUN: { \ 4*666d2242SMike Crowe // RUN: modernize-use-std-print.PrintfLikeFunctions: 'unqualified_printf;::myprintf; mynamespace::myprintf2; bad_format_type_printf; fmt::printf', \ 5*666d2242SMike Crowe // RUN: modernize-use-std-print.FprintfLikeFunctions: '::myfprintf; mynamespace::myfprintf2; bad_format_type_fprintf; fmt::fprintf' \ 683f875dcSMike Crowe // RUN: } \ 783f875dcSMike Crowe // RUN: }" \ 883f875dcSMike Crowe // RUN: -- -isystem %clang_tidy_headers 983f875dcSMike Crowe 1083f875dcSMike Crowe #include <cstdio> 11b389a625SMike Crowe #include <string> 1283f875dcSMike Crowe 1383f875dcSMike Crowe int myprintf(const char *, ...); 1483f875dcSMike Crowe int myfprintf(FILE *fp, const char *, ...); 1583f875dcSMike Crowe 1683f875dcSMike Crowe namespace mynamespace { 1783f875dcSMike Crowe int myprintf2(const char *, ...); 1883f875dcSMike Crowe int myfprintf2(FILE *fp, const char *, ...); 1983f875dcSMike Crowe } 2083f875dcSMike Crowe 2183f875dcSMike Crowe void printf_simple() { 2283f875dcSMike Crowe myprintf("Hello %s %d", "world", 42); 2383f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'myprintf' [modernize-use-std-print] 2483f875dcSMike Crowe // CHECK-FIXES: std::print("Hello {} {}", "world", 42); 2583f875dcSMike Crowe } 2683f875dcSMike Crowe 2783f875dcSMike Crowe void printf_newline() { 2883f875dcSMike Crowe myprintf("Hello %s %d\n", "world", 42); 2983f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'myprintf' [modernize-use-std-print] 3083f875dcSMike Crowe // CHECK-FIXES: std::println("Hello {} {}", "world", 42); 3183f875dcSMike Crowe 3283f875dcSMike Crowe mynamespace::myprintf2("Hello %s %d\n", "world", 42); 3383f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'myprintf2' [modernize-use-std-print] 3483f875dcSMike Crowe // CHECK-FIXES: std::println("Hello {} {}", "world", 42); 3583f875dcSMike Crowe 3683f875dcSMike Crowe using mynamespace::myprintf2; 3783f875dcSMike Crowe myprintf2("Hello %s %d\n", "world", 42); 3883f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'myprintf2' [modernize-use-std-print] 3983f875dcSMike Crowe // CHECK-FIXES: std::println("Hello {} {}", "world", 42); 4083f875dcSMike Crowe 4183f875dcSMike Crowe // When using custom options leave printf alone 4283f875dcSMike Crowe printf("Hello %s %d\n", "world", 42); 4383f875dcSMike Crowe } 4483f875dcSMike Crowe 4509ed2102SMike Crowe int printf_uses_return_value(int i) { 4609ed2102SMike Crowe return myprintf("return value %d\n", i); 4709ed2102SMike Crowe // CHECK-MESSAGES-NOT: [[@LINE-1]]:10: warning: use 'std::println' instead of 'myprintf' [modernize-use-std-print] 4809ed2102SMike Crowe // CHECK-FIXES-NOT: std::println("return value {}", i); 4909ed2102SMike Crowe } 5009ed2102SMike Crowe 5183f875dcSMike Crowe void fprintf_simple(FILE *fp) 5283f875dcSMike Crowe { 5383f875dcSMike Crowe myfprintf(stderr, "Hello %s %d", "world", 42); 5483f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::print' instead of 'myfprintf' [modernize-use-std-print] 5583f875dcSMike Crowe // CHECK-FIXES: std::print(stderr, "Hello {} {}", "world", 42); 5683f875dcSMike Crowe } 5783f875dcSMike Crowe 5883f875dcSMike Crowe void fprintf_newline(FILE *fp) 5983f875dcSMike Crowe { 6083f875dcSMike Crowe myfprintf(stderr, "Hello %s %d\n", "world", 42); 6183f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'myfprintf' [modernize-use-std-print] 6283f875dcSMike Crowe // CHECK-FIXES: std::println(stderr, "Hello {} {}", "world", 42); 6383f875dcSMike Crowe 6483f875dcSMike Crowe mynamespace::myfprintf2(stderr, "Hello %s %d\n", "world", 42); 6583f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'myfprintf2' [modernize-use-std-print] 6683f875dcSMike Crowe // CHECK-FIXES: std::println(stderr, "Hello {} {}", "world", 42); 6783f875dcSMike Crowe 6883f875dcSMike Crowe using mynamespace::myfprintf2; 6983f875dcSMike Crowe myfprintf2(stderr, "Hello %s %d\n", "world", 42); 7083f875dcSMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'myfprintf2' [modernize-use-std-print] 7183f875dcSMike Crowe // CHECK-FIXES: std::println(stderr, "Hello {} {}", "world", 42); 7283f875dcSMike Crowe 7383f875dcSMike Crowe // When using custom options leave fprintf alone 7483f875dcSMike Crowe fprintf(stderr, "Hello %s %d\n", "world", 42); 7583f875dcSMike Crowe } 7609ed2102SMike Crowe 7709ed2102SMike Crowe int fprintf_uses_return_value(int i) { 7809ed2102SMike Crowe return myfprintf(stderr, "return value %d\n", i); 7909ed2102SMike Crowe // CHECK-MESSAGES-NOT: [[@LINE-1]]:10: warning: use 'std::println' instead of 'myprintf' [modernize-use-std-print] 8009ed2102SMike Crowe // CHECK-FIXES-NOT: std::println(stderr, "return value {}", i); 8109ed2102SMike Crowe } 82b389a625SMike Crowe 83b389a625SMike Crowe // Ensure that MatchesAnyListedNameMatcher::NameMatcher::match() can cope with a 84b389a625SMike Crowe // NamedDecl that has no name when we're trying to match unqualified_printf. 85b389a625SMike Crowe void no_name(const std::string &in) 86b389a625SMike Crowe { 87b389a625SMike Crowe "A" + in; 88b389a625SMike Crowe } 890e62d5cfSMike Crowe 900e62d5cfSMike Crowe int myprintf(const wchar_t *, ...); 910e62d5cfSMike Crowe 920e62d5cfSMike Crowe void wide_string_not_supported() { 930e62d5cfSMike Crowe myprintf(L"wide string %s", L"string"); 940e62d5cfSMike Crowe } 950e62d5cfSMike Crowe 960e62d5cfSMike Crowe // Issue #92896: Ensure that the check doesn't assert if the argument is 970e62d5cfSMike Crowe // promoted to something that isn't a string. 980e62d5cfSMike Crowe struct S { 990e62d5cfSMike Crowe S(...) {} 1000e62d5cfSMike Crowe }; 1010e62d5cfSMike Crowe int bad_format_type_printf(const S &, ...); 1020e62d5cfSMike Crowe int bad_format_type_fprintf(FILE *, const S &, ...); 1030e62d5cfSMike Crowe 1040e62d5cfSMike Crowe void unsupported_format_parameter_type() 1050e62d5cfSMike Crowe { 1060e62d5cfSMike Crowe // No fixes here because the format parameter of the function called is not a 1070e62d5cfSMike Crowe // string. 1080e62d5cfSMike Crowe bad_format_type_printf("Hello %s", "world"); 109*666d2242SMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'bad_format_type_printf' because first argument is not a narrow string literal [modernize-use-std-print] 110*666d2242SMike Crowe 1110e62d5cfSMike Crowe bad_format_type_fprintf(stderr, "Hello %s", "world"); 112*666d2242SMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: unable to use 'std::print' instead of 'bad_format_type_fprintf' because first argument is not a narrow string literal [modernize-use-std-print] 113*666d2242SMike Crowe } 114*666d2242SMike Crowe 115*666d2242SMike Crowe namespace fmt { 116*666d2242SMike Crowe template <typename S, typename... T> 117*666d2242SMike Crowe inline int printf(const S& fmt, const T&... args); 118*666d2242SMike Crowe 119*666d2242SMike Crowe template <typename S, typename... T> 120*666d2242SMike Crowe inline int fprintf(std::FILE* f, const S& fmt, const T&... args); 121*666d2242SMike Crowe } 122*666d2242SMike Crowe 123*666d2242SMike Crowe void fmt_printf() 124*666d2242SMike Crowe { 125*666d2242SMike Crowe fmt::printf("fmt::printf templated %s argument %d\n", "format", 424); 126*666d2242SMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'printf' [modernize-use-std-print] 127*666d2242SMike Crowe // CHECK-FIXES: std::println("fmt::printf templated {} argument {}", "format", 424); 128*666d2242SMike Crowe 129*666d2242SMike Crowe fmt::fprintf(stderr, "fmt::fprintf templated %s argument %d\n", "format", 425); 130*666d2242SMike Crowe // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use 'std::println' instead of 'fprintf' [modernize-use-std-print] 131*666d2242SMike Crowe // CHECK-FIXES: std::println(stderr, "fmt::fprintf templated {} argument {}", "format", 425); 1320e62d5cfSMike Crowe } 133