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 initialization
43 // CHECK-FIXES: std::string b;
44 std::string c = R"()";
45 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
46 // CHECK-FIXES: std::string c;
47 std::string d(R"()");
48 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
49 // CHECK-FIXES: std::string d;
50 std::string e{""};
51 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
52 // CHECK-FIXES: std::string e;
53 std::string f = {""};
54 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
55 // 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 initialization
70 // CHECK-FIXES: std::string_view b;
71 std::string_view c = R"()";
72 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization
73 // CHECK-FIXES: std::string_view c;
74 std::string_view d(R"()");
75 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization
76 // CHECK-FIXES: std::string_view d;
77 std::string_view e{""};
78 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization
79 // CHECK-FIXES: std::string_view e;
80 std::string_view f = {""};
81 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: redundant string initialization
82 // 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 initialization
94 // CHECK-FIXES: std::wstring a;
95 std::wstring b(L"");
96 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
97 // CHECK-FIXES: std::wstring b;
98 std::wstring c = LR"()";
99 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
100 // CHECK-FIXES: std::wstring c;
101 std::wstring d(LR"()");
102 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
103 // 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 initialization
118 // CHECK-FIXES: std::wstring_view b;
119 std::wstring_view c = L"";
120 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
121 // CHECK-FIXES: std::wstring_view c;
122 std::wstring_view d(L"");
123 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
124 // CHECK-FIXES: std::wstring_view d;
125 std::wstring_view e{L""};
126 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
127 // CHECK-FIXES: std::wstring_view e;
128 std::wstring_view f = {L""};
129 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
130 // 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 initialization
143 // CHECK-FIXES: std::string s;
144}
145
146#define M(x) x
147#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 initialization
156 // CHECK-FIXES: M({ std::string s; })
157
158 N
159 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
160 // CHECK-FIXES: N
161 N
162 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: redundant string initialization
163 // CHECK-FIXES: N
164}
165
166typedef std::string MyString;
167#define STRING MyString
168#define DECL_STRING(name, val) STRING name = val
169
170void i() {
171 MyString a = "";
172 // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization
173 // CHECK-FIXES: MyString a;
174 STRING b = "";
175 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization
176 // CHECK-FIXES: STRING b;
177 MyString c = "" "" "";
178 // CHECK-MESSAGES: [[@LINE-1]]:12: warning: redundant string initialization
179 // CHECK-FIXES: MyString c;
180 STRING d = "" "" "";
181 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization
182 // CHECK-FIXES: STRING d;
183 DECL_STRING(e, "");
184 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
185
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 initialization
195 // CHECK-FIXES: std::string a;
196 std::string b = (EMPTY_STR);
197 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
198 // 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 initialization
206 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: redundant string initialization
207 // CHECK-MESSAGES: [[@LINE-3]]:31: warning: redundant string initialization
208 // 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 initialization
214 // CHECK-MESSAGES: [[@LINE-2]]:43: warning: redundant string initialization
215 // 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 initialization
236 // CHECK-FIXES: our::TestString a;
237 our::TestString b("");
238 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
239 // CHECK-FIXES: our::TestString b;
240 our::TestString c = R"()";
241 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
242 // CHECK-FIXES: our::TestString c;
243 our::TestString d(R"()");
244 // CHECK-MESSAGES: [[@LINE-1]]:19: warning: redundant string initialization
245 // 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 / fix
259void theirTestStringTests() {
260 their::TestString a = "";
261 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
262 // CHECK-FIXES: their::TestString a;
263 their::TestString b("");
264 // CHECK-MESSAGES: [[@LINE-1]]:21: warning: redundant string initialization
265 // CHECK-FIXES: their::TestString b;
266}
267
268namespace other {
269// Identical declarations to above but different type
270struct TestString {
271 TestString();
272 TestString(const TestString &);
273 TestString(const char *);
274 ~TestString();
275};
276
277// Identical declarations to above but different type
278template <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 types
294// 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 initialization
307 // 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 initialization
317 // 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 initialization
322 // 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 initialization
327 // 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 initialization
332 // CHECK-MESSAGES: [[@LINE-2]]:21: warning: redundant string initialization
333 // CHECK-FIXES: Foo(int) : E() {}
334
335 Foo(short) : B{""} {}
336 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
337 // CHECK-FIXES: Foo(short) {}
338
339 Foo(float) : A{""}, B{""} {}
340 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: redundant string initialization
341 // CHECK-MESSAGES: [[@LINE-2]]:23: warning: redundant string initialization
342 // CHECK-FIXES: Foo(float) {}
343
344 // Check how it handles removing some redundant initializers while leaving
345 // 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 initialization
348 // CHECK-MESSAGES: [[@LINE-2]]:56: warning: redundant string initialization
349 // CHECK-MESSAGES: [[@LINE-3]]:66: warning: redundant string initialization
350 // CHECK-FIXES: Foo(std::string Arg) : A(Arg), C("NonEmpty"), E() {}
351};
352

source code of clang-tools-extra/test/clang-tidy/checkers/readability/redundant-string-init.cpp