352 lines · cpp
1// RUN: %check_clang_tidy %s readability-redundant-string-init %t \2// RUN: -config="{CheckOptions: \3// RUN: {readability-redundant-string-init.StringNames: \4// RUN: '::std::basic_string;::std::basic_string_view;our::TestString'} \5// RUN: }"6 7namespace std {8template <typename T>9class allocator {};10template <typename T>11class char_traits {};12template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>13struct basic_string {14 basic_string();15 basic_string(const basic_string&);16 basic_string(const C *, const A &a = A());17 ~basic_string();18};19typedef basic_string<char> string;20typedef basic_string<wchar_t> wstring;21 22template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>23struct basic_string_view {24 using size_type = decltype(sizeof(0));25 26 basic_string_view();27 basic_string_view(const basic_string_view &);28 basic_string_view(const C *, size_type);29 basic_string_view(const C *);30 template <class It, class End>31 basic_string_view(It, End);32};33typedef basic_string_view<char> string_view;34typedef basic_string_view<wchar_t> wstring_view;35}36 37void f() {38 std::string a = "";39 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization [readability-redundant-string-init]40 // CHECK-FIXES: std::string a;41 std::string b("");42 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization43 // CHECK-FIXES: std::string b;44 std::string c = R"()";45 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization46 // CHECK-FIXES: std::string c;47 std::string d(R"()");48 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization49 // CHECK-FIXES: std::string d;50 std::string e{""};51 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization52 // CHECK-FIXES: std::string e;53 std::string f = {""};54 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization55 // CHECK-FIXES: std::string f;56 57 std::string u = "u";58 std::string w("w");59 std::string x = R"(x)";60 std::string y(R"(y)");61 std::string z;62}63 64void fview() {65 std::string_view a = "";66 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization [readability-redundant-string-init]67 // CHECK-FIXES: std::string_view a;68 std::string_view b("");69 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization70 // CHECK-FIXES: std::string_view b;71 std::string_view c = R"()";72 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization73 // CHECK-FIXES: std::string_view c;74 std::string_view d(R"()");75 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization76 // CHECK-FIXES: std::string_view d;77 std::string_view e{""};78 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization79 // CHECK-FIXES: std::string_view e;80 std::string_view f = {""};81 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization82 // CHECK-FIXES: std::string_view f;83 84 std::string_view u = "u";85 std::string_view w("w");86 std::string_view x = R"(x)";87 std::string_view y(R"(y)");88 std::string_view z;89}90 91void g() {92 std::wstring a = L"";93 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization94 // CHECK-FIXES: std::wstring a;95 std::wstring b(L"");96 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization97 // CHECK-FIXES: std::wstring b;98 std::wstring c = LR"()";99 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization100 // CHECK-FIXES: std::wstring c;101 std::wstring d(LR"()");102 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization103 // CHECK-FIXES: std::wstring d;104 105 std::wstring u = L"u";106 std::wstring w(L"w");107 std::wstring x = LR"(x)";108 std::wstring y(LR"(y)");109 std::wstring z;110}111 112void gview() {113 std::wstring_view a = L"";114 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization [readability-redundant-string-init]115 // CHECK-FIXES: std::wstring_view a;116 std::wstring_view b(L"");117 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization118 // CHECK-FIXES: std::wstring_view b;119 std::wstring_view c = L"";120 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization121 // CHECK-FIXES: std::wstring_view c;122 std::wstring_view d(L"");123 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization124 // CHECK-FIXES: std::wstring_view d;125 std::wstring_view e{L""};126 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization127 // CHECK-FIXES: std::wstring_view e;128 std::wstring_view f = {L""};129 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization130 // CHECK-FIXES: std::wstring_view f;131 132 std::wstring_view u = L"u";133 std::wstring_view w(L"w");134 std::wstring_view x = LR"(x)";135 std::wstring_view y(LR"(y)");136 std::wstring_view z;137}138 139template <typename T>140void templ() {141 std::string s = "";142 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization143 // CHECK-FIXES: std::string s;144}145 146#define M(x) x147#define N { std::string s = ""; }148// CHECK-FIXES: #define N { std::string s = ""; }149 150void h() {151 templ<int>();152 templ<double>();153 154 M({ std::string s = ""; })155 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization156 // CHECK-FIXES: M({ std::string s; })157 158 N159 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization160 // CHECK-FIXES: N161 N162 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization163 // CHECK-FIXES: N164}165 166typedef std::string MyString;167#define STRING MyString168#define DECL_STRING(name, val) STRING name = val169 170void i() {171 MyString a = "";172 // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization173 // CHECK-FIXES: MyString a;174 STRING b = "";175 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization176 // CHECK-FIXES: STRING b;177 MyString c = "" "" "";178 // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization179 // CHECK-FIXES: MyString c;180 STRING d = "" "" "";181 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization182 // CHECK-FIXES: STRING d;183 DECL_STRING(e, "");184 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization185 186 MyString f = "u";187 STRING g = "u";188 DECL_STRING(h, "u");189}190 191#define EMPTY_STR ""192void j() {193 std::string a(EMPTY_STR);194 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization195 // CHECK-FIXES: std::string a;196 std::string b = (EMPTY_STR);197 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization198 // CHECK-FIXES: std::string b;199 200 std::string c(EMPTY_STR "u" EMPTY_STR);201}202 203void k() {204 std::string a = "", b = "", c = "";205 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization206 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: redundant string initialization207 // CHECK-MESSAGES: [[@LINE-3]]:31: warning: redundant string initialization208 // CHECK-FIXES: std::string a, b, c;209 210 std::string d = "u", e = "u", f = "u";211 212 std::string g = "u", h = "", i = "uuu", j = "", k;213 // CHECK-MESSAGES: [[@LINE-1]]:24: warning: redundant string initialization214 // CHECK-MESSAGES: [[@LINE-2]]:43: warning: redundant string initialization215 // CHECK-FIXES: std::string g = "u", h, i = "uuu", j, k;216}217 218// These cases should not generate warnings.219extern void Param1(std::string param = "");220extern void Param2(const std::string& param = "");221void Param3(std::string param = "") {}222void Param4(STRING param = "") {}223 224namespace our {225struct TestString {226 TestString();227 TestString(const TestString &);228 TestString(const char *);229 ~TestString();230};231}232 233void ourTestStringTests() {234 our::TestString a = "";235 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization236 // CHECK-FIXES: our::TestString a;237 our::TestString b("");238 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization239 // CHECK-FIXES: our::TestString b;240 our::TestString c = R"()";241 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization242 // CHECK-FIXES: our::TestString c;243 our::TestString d(R"()");244 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization245 // CHECK-FIXES: our::TestString d;246 247 our::TestString u = "u";248 our::TestString w("w");249 our::TestString x = R"(x)";250 our::TestString y(R"(y)");251 our::TestString z;252}253 254namespace their {255using TestString = our::TestString;256}257 258// their::TestString is the same type so should warn / fix259void theirTestStringTests() {260 their::TestString a = "";261 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization262 // CHECK-FIXES: their::TestString a;263 their::TestString b("");264 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization265 // CHECK-FIXES: their::TestString b;266}267 268namespace other {269// Identical declarations to above but different type270struct TestString {271 TestString();272 TestString(const TestString &);273 TestString(const char *);274 ~TestString();275};276 277// Identical declarations to above but different type278template <typename T>279class allocator {};280template <typename T>281class char_traits {};282template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>283struct basic_string {284 basic_string();285 basic_string(const basic_string &);286 basic_string(const C *, const A &a = A());287 ~basic_string();288};289typedef basic_string<char> string;290typedef basic_string<wchar_t> wstring;291}292 293// other::TestString, other::string, other::wstring are unrelated to the types294// being checked. No warnings / fixes should be produced for these types.295void otherTestStringTests() {296 other::TestString a = "";297 other::TestString b("");298 other::string c = "";299 other::string d("");300 other::wstring e = L"";301 other::wstring f(L"");302}303 304class Foo {305 std::string A = "";306 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization307 // CHECK-FIXES: std::string A;308 std::string B;309 std::string C;310 std::string D;311 std::string E = "NotEmpty";312 313public:314 // Check redundant constructor where Field has a redundant initializer.315 Foo() : A("") {}316 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: redundant string initialization317 // CHECK-FIXES: Foo() {}318 319 // Check redundant constructor where Field has no initializer.320 Foo(char) : B("") {}321 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization322 // CHECK-FIXES: Foo(char) {}323 324 // Check redundant constructor where Field has a valid initializer.325 Foo(long) : E("") {}326 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization327 // CHECK-FIXES: Foo(long) : E() {}328 329 // Check how it handles removing 1 initializer, and defaulting the other.330 Foo(int) : B(""), E("") {}331 // CHECK-MESSAGES: [[@LINE-1]]:14: warning: redundant string initialization332 // CHECK-MESSAGES: [[@LINE-2]]:21: warning: redundant string initialization333 // CHECK-FIXES: Foo(int) : E() {}334 335 Foo(short) : B{""} {}336 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization337 // CHECK-FIXES: Foo(short) {}338 339 Foo(float) : A{""}, B{""} {}340 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization341 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: redundant string initialization342 // CHECK-FIXES: Foo(float) {}343 344 // Check how it handles removing some redundant initializers while leaving345 // valid initializers intact.346 Foo(std::string Arg) : A(Arg), B(""), C("NonEmpty"), D(R"()"), E("") {}347 // CHECK-MESSAGES: [[@LINE-1]]:34: warning: redundant string initialization348 // CHECK-MESSAGES: [[@LINE-2]]:56: warning: redundant string initialization349 // CHECK-MESSAGES: [[@LINE-3]]:66: warning: redundant string initialization350 // CHECK-FIXES: Foo(std::string Arg) : A(Arg), C("NonEmpty"), E() {}351};352