73 lines · cpp
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; any_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_headers10// 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; any_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_headers18 19#include <cstdio>20#include <string>21// CHECK-FIXES: #include <fmt/core.h>22 23std::string strprintf(const char *, ...);24 25namespace mynamespace {26 std::string strprintf2(const char *, ...);27}28 29std::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 39std::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 a48// NamedDecl that has no name when we're trying to match unqualified_strprintf.49std::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 is55// promoted to something that isn't a string.56struct S {57 S(...);58};59std::string any_format_type_strprintf(const S &, ...);60 61void unsupported_format_parameter_types()62{63 // No fixes here because the format parameter of the function called is not a64 // string.65 auto s1 = any_format_type_strprintf(L"");66 auto s2 = any_format_type_strprintf(42);67 68 // But if we do pass a character string then that ought to be acceptable.69 auto s3 = any_format_type_strprintf("Hello %s", "world");70 // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use 'fmt::format' instead of 'any_format_type_strprintf' [modernize-use-std-format]71 // CHECK-FIXES: auto s3 = fmt::format("Hello {}", "world");72}73