brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.0 KiB · a2bbd19 Raw
215 lines · cpp
1// RUN: %check_clang_tidy -check-suffix=STDFORMAT -std=c++20 %s readability-redundant-string-cstr %t -- --  -isystem %clang_tidy_headers -DTEST_STDFORMAT2// RUN: %check_clang_tidy -check-suffixes=STDFORMAT,STDPRINT -std=c++2b %s readability-redundant-string-cstr %t -- --  -isystem %clang_tidy_headers -DTEST_STDFORMAT -DTEST_STDPRINT3#include <string>4 5namespace std {6  template<typename T>7    struct type_identity { using type = T; };8  template<typename T>9    using type_identity_t = typename type_identity<T>::type;10 11  template <typename CharT, typename... Args>12  struct basic_format_string {13    consteval basic_format_string(const CharT *format) : str(format) {}14    basic_string_view<CharT, std::char_traits<CharT>> str;15  };16 17  template<typename... Args>18    using format_string = basic_format_string<char, type_identity_t<Args>...>;19 20  template<typename... Args>21    using wformat_string = basic_format_string<wchar_t, type_identity_t<Args>...>;22 23#if defined(TEST_STDFORMAT)24  template<typename ...Args>25  std::string format(format_string<Args...>, Args &&...);26  template<typename ...Args>27  std::string format(wformat_string<Args...>, Args &&...);28#endif // TEST_STDFORMAT29 30#if defined(TEST_STDPRINT)31  template<typename ...Args>32  void print(format_string<Args...>, Args &&...);33  template<typename ...Args>34  void print(wformat_string<Args...>, Args &&...);35#endif // TEST_STDPRINT36}37 38namespace notstd {39#if defined(TEST_STDFORMAT)40  template<typename ...Args>41  std::string format(const char *, Args &&...);42  template<typename ...Args>43  std::string format(const wchar_t *, Args &&...);44#endif // TEST_STDFORMAT45#if defined(TEST_STDPRINT)46  template<typename ...Args>47  void print(const char *, Args &&...);48  template<typename ...Args>49  void print(const wchar_t *, Args &&...);50#endif // TEST_STDPRINT51}52 53std::string return_temporary();54std::wstring return_wtemporary();55 56#if defined(TEST_STDFORMAT)57void std_format(const std::string &s1, const std::string &s2, const std::string &s3) {58  auto r1 = std::format("One:{}\n", s1.c_str());59  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-1]]:37: warning: redundant call to 'c_str' [readability-redundant-string-cstr]60  // CHECK-FIXES-STDFORMAT: auto r1 = std::format("One:{}\n", s1);61 62  auto r2 = std::format("One:{} Two:{} Three:{} Four:{}\n", s1.c_str(), s2, s3.c_str(), return_temporary().c_str());63  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-1]]:61: warning: redundant call to 'c_str' [readability-redundant-string-cstr]64  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-2]]:77: warning: redundant call to 'c_str' [readability-redundant-string-cstr]65  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-3]]:89: warning: redundant call to 'c_str' [readability-redundant-string-cstr]66  // CHECK-FIXES-STDFORMAT: auto r2 = std::format("One:{} Two:{} Three:{} Four:{}\n", s1, s2, s3, return_temporary());67 68  using namespace std;69  auto r3 = format("Four:{}\n", s1.c_str());70  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-1]]:33: warning: redundant call to 'c_str' [readability-redundant-string-cstr]71  // CHECK-FIXES-STDFORMAT: auto r3 = format("Four:{}\n", s1);72}73 74void std_format_wide(const std::wstring &s1, const std::wstring &s2, const std::wstring &s3) {75  auto r1 = std::format(L"One:{}\n", s1.c_str());76  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-1]]:38: warning: redundant call to 'c_str' [readability-redundant-string-cstr]77  // CHECK-FIXES-STDFORMAT: auto r1 = std::format(L"One:{}\n", s1);78 79  auto r2 = std::format(L"One:{} Two:{} Three:{} Four:{}\n", s1.c_str(), s2, s3.c_str(), return_wtemporary().c_str());80  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-1]]:62: warning: redundant call to 'c_str' [readability-redundant-string-cstr]81  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-2]]:78: warning: redundant call to 'c_str' [readability-redundant-string-cstr]82  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-3]]:90: warning: redundant call to 'c_str' [readability-redundant-string-cstr]83  // CHECK-FIXES-STDFORMAT: auto r2 = std::format(L"One:{} Two:{} Three:{} Four:{}\n", s1, s2, s3, return_wtemporary());84 85  using namespace std;86  auto r3 = format(L"Four:{}\n", s1.c_str());87  // CHECK-MESSAGES-STDFORMAT: :[[@LINE-1]]:34: warning: redundant call to 'c_str' [readability-redundant-string-cstr]88  // CHECK-FIXES-STDFORMAT: auto r3 = format(L"Four:{}\n", s1);89}90 91// There's are c_str() calls here, so it shouldn't be touched.92std::string std_format_no_cstr(const std::string &s1, const std::string &s2) {93  return std::format("One: {}, Two: {}\n", s1, s2);94}95 96// There's are c_str() calls here, so it shouldn't be touched.97std::string std_format_no_cstr_wide(const std::string &s1, const std::string &s2) {98  return std::format(L"One: {}, Two: {}\n", s1, s2);99}100 101// This is not std::format, so it shouldn't be fixed.102std::string not_std_format(const std::string &s1) {103  return notstd::format("One: {}\n", s1.c_str());104 105  using namespace notstd;106  format("One: {}\n", s1.c_str());107}108 109// This is not std::format, so it shouldn't be fixed.110std::string not_std_format_wide(const std::string &s1) {111  return notstd::format(L"One: {}\n", s1.c_str());112 113  using namespace notstd;114  format(L"One: {}\n", s1.c_str());115}116#endif // TEST_STDFORMAT117 118#if defined(TEST_STDPRINT)119void std_print(const std::string &s1, const std::string &s2, const std::string &s3) {120  std::print("One:{}\n", s1.c_str());121  // CHECK-MESSAGES-STDPRINT: :[[@LINE-1]]:26: warning: redundant call to 'c_str' [readability-redundant-string-cstr]122  // CHECK-FIXES-STDPRINT: std::print("One:{}\n", s1);123 124  std::print("One:{} Two:{} Three:{} Four:{}\n", s1.c_str(), s2, s3.c_str(), return_temporary().c_str());125  // CHECK-MESSAGES-STDPRINT: :[[@LINE-1]]:50: warning: redundant call to 'c_str' [readability-redundant-string-cstr]126  // CHECK-MESSAGES-STDPRINT: :[[@LINE-2]]:66: warning: redundant call to 'c_str' [readability-redundant-string-cstr]127  // CHECK-MESSAGES-STDPRINT: :[[@LINE-3]]:78: warning: redundant call to 'c_str' [readability-redundant-string-cstr]128  // CHECK-FIXES-STDPRINT: std::print("One:{} Two:{} Three:{} Four:{}\n", s1, s2, s3, return_temporary());129 130  using namespace std;131  print("Four:{}\n", s1.c_str());132  // CHECK-MESSAGES-STDPRINT: :[[@LINE-1]]:22: warning: redundant call to 'c_str' [readability-redundant-string-cstr]133  // CHECK-FIXES-STDPRINT: print("Four:{}\n", s1);134}135 136void std_print_wide(const std::wstring &s1, const std::wstring &s2, const std::wstring &s3) {137  std::print(L"One:{}\n", s1.c_str());138  // CHECK-MESSAGES-STDPRINT: :[[@LINE-1]]:27: warning: redundant call to 'c_str' [readability-redundant-string-cstr]139  // CHECK-FIXES-STDPRINT: std::print(L"One:{}\n", s1);140 141  std::print(L"One:{} Two:{} Three:{} Four:{}\n", s1.c_str(), s2, s3.c_str(), return_wtemporary().c_str());142  // CHECK-MESSAGES-STDPRINT: :[[@LINE-1]]:51: warning: redundant call to 'c_str' [readability-redundant-string-cstr]143  // CHECK-MESSAGES-STDPRINT: :[[@LINE-2]]:67: warning: redundant call to 'c_str' [readability-redundant-string-cstr]144  // CHECK-MESSAGES-STDPRINT: :[[@LINE-3]]:79: warning: redundant call to 'c_str' [readability-redundant-string-cstr]145  // CHECK-FIXES-STDPRINT: std::print(L"One:{} Two:{} Three:{} Four:{}\n", s1, s2, s3, return_wtemporary());146 147  using namespace std;148  print(L"Four:{}\n", s1.c_str());149  // CHECK-MESSAGES-STDPRINT: :[[@LINE-1]]:23: warning: redundant call to 'c_str' [readability-redundant-string-cstr]150  // CHECK-FIXES-STDPRINT: print(L"Four:{}\n", s1);151}152 153// There's no c_str() call here, so it shouldn't be touched.154void std_print_no_cstr(const std::string &s1, const std::string &s2) {155  std::print("One: {}, Two: {}\n", s1, s2);156}157 158// There's no c_str() call here, so it shouldn't be touched.159void std_print_no_cstr_wide(const std::wstring &s1, const std::wstring &s2) {160  std::print(L"One: {}, Two: {}\n", s1, s2);161}162 163// This isn't std::print, so it shouldn't be fixed.164void not_std_print(const std::string &s1) {165  notstd::print("One: {}\n", s1.c_str());166 167  using namespace notstd;168  print("One: {}\n", s1.c_str());169}170 171// This isn't std::print, so it shouldn't be fixed.172void not_std_print_wide(const std::string &s1) {173  notstd::print(L"One: {}\n", s1.c_str());174 175  using namespace notstd;176  print(L"One: {}\n", s1.c_str());177}178#endif // TEST_STDPRINT179 180#if defined(TEST_STDFORMAT)181// We can't declare these earlier since they make the "using namespace std"182// tests ambiguous.183template<typename ...Args>184std::string format(const char *, Args &&...);185template<typename ...Args>186std::string format(const wchar_t *, Args &&...);187 188// This is not std::format, so it shouldn't be fixed.189std::string not_std_format2(const std::wstring &s1) {190  return format("One: {}\n", s1.c_str());191}192 193// This is not std::format, so it shouldn't be fixed.194std::string not_std_format2_wide(const std::wstring &s1) {195  return format(L"One: {}\n", s1.c_str());196}197#endif // TEST_STDFORMAT198 199#if defined(TEST_STDPRINT)200template<typename ...Args>201void print(const char *, Args &&...);202template<typename ...Args>203void print(const wchar_t *, Args &&...);204 205// This isn't std::print, so it shouldn't be fixed.206void not_std_print2(const std::string &s1) {207  print("One: {}\n", s1.c_str());208}209 210// This isn't std::print, so it shouldn't be fixed.211void not_std_print2_wide(const std::string &s1) {212  print(L"One: {}\n", s1.c_str());213}214#endif // TEST_STDPRINT215