1 // RUN: %check_clang_tidy -check-suffixes=,STRICT \ 2 // RUN: -std=c++20 %s modernize-use-std-format %t -- \ 3 // RUN: -config="{CheckOptions: { \ 4 // RUN: modernize-use-std-format.StrictMode: true, \ 5 // RUN: modernize-use-std-format.StrFormatLikeFunctions: '::strprintf; mynamespace::strprintf2; bad_format_type_strprintf', \ 6 // RUN: modernize-use-std-format.ReplacementFormatFunction: 'fmt::format', \ 7 // RUN: modernize-use-std-format.FormatHeader: '<fmt/core.h>' \ 8 // RUN: }}" \ 9 // RUN: -- -isystem %clang_tidy_headers 10 // RUN: %check_clang_tidy -check-suffixes=,NOTSTRICT \ 11 // RUN: -std=c++20 %s modernize-use-std-format %t -- \ 12 // RUN: -config="{CheckOptions: { \ 13 // RUN: modernize-use-std-format.StrFormatLikeFunctions: '::strprintf; mynamespace::strprintf2; bad_format_type_strprintf', \ 14 // RUN: modernize-use-std-format.ReplacementFormatFunction: 'fmt::format', \ 15 // RUN: modernize-use-std-format.FormatHeader: '<fmt/core.h>' \ 16 // RUN: }}" \ 17 // RUN: -- -isystem %clang_tidy_headers 18 19 #include <cstdio> 20 #include <string> 21 // CHECK-FIXES: #include <fmt/core.h> 22 23 std::string strprintf(const char *, ...); 24 25 namespace mynamespace { 26 std::string strprintf2(const char *, ...); 27 } 28 29 std::string strprintf_test(const std::string &name, double value) { 30 return strprintf("'%s'='%f'\n", name.c_str(), value); 31 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'fmt::format' instead of 'strprintf' [modernize-use-std-format] 32 // CHECK-FIXES: return fmt::format("'{}'='{:f}'\n", name, value); 33 34 return mynamespace::strprintf2("'%s'='%f'\n", name.c_str(), value); 35 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'fmt::format' instead of 'strprintf2' [modernize-use-std-format] 36 // CHECK-FIXES: return fmt::format("'{}'='{:f}'\n", name, value); 37 } 38 39 std::string StrFormat_strict_conversion() { 40 const unsigned char uc = 'A'; 41 return strprintf("Integer %hhd from unsigned char\n", uc); 42 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: use 'fmt::format' instead of 'strprintf' [modernize-use-std-format] 43 // CHECK-FIXES-NOTSTRICT: return fmt::format("Integer {} from unsigned char\n", uc); 44 // CHECK-FIXES-STRICT: return fmt::format("Integer {} from unsigned char\n", static_cast<signed char>(uc)); 45 } 46 47 // Ensure that MatchesAnyListedNameMatcher::NameMatcher::match() can cope with a 48 // NamedDecl that has no name when we're trying to match unqualified_strprintf. 49 std::string A(const std::string &in) 50 { 51 return "_" + in; 52 } 53 54 // Issue #92896: Ensure that the check doesn't assert if the argument is 55 // promoted to something that isn't a string. 56 struct S { 57 S(...); 58 }; 59 std::string bad_format_type_strprintf(const S &, ...); 60 61 std::string unsupported_format_parameter_type() 62 { 63 // No fixes here because the format parameter of the function called is not a 64 // string. 65 return bad_format_type_strprintf(""); 66 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: unable to use 'fmt::format' instead of 'bad_format_type_strprintf' because first argument is not a narrow string literal [modernize-use-std-format] 67 } 68