1 | // RUN: %check_clang_tidy %s bugprone-string-constructor %t |
2 | |
3 | namespace std { |
4 | template <typename T> |
5 | class allocator {}; |
6 | template <typename T> |
7 | class char_traits {}; |
8 | template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C> > |
9 | struct basic_string { |
10 | basic_string(); |
11 | basic_string(const C*, unsigned int size); |
12 | basic_string(const C *, const A &allocator = A()); |
13 | basic_string(unsigned int size, C c); |
14 | basic_string(const C*, unsigned int pos, unsigned int size); |
15 | }; |
16 | typedef basic_string<char> string; |
17 | typedef basic_string<wchar_t> wstring; |
18 | |
19 | template <typename C, typename T = std::char_traits<C>> |
20 | struct basic_string_view { |
21 | basic_string_view(); |
22 | basic_string_view(const C *, unsigned int size); |
23 | basic_string_view(const C *); |
24 | }; |
25 | typedef basic_string_view<char> string_view; |
26 | typedef basic_string_view<wchar_t> wstring_view; |
27 | } |
28 | |
29 | const char* kText = "" ; |
30 | const char kText2[] = "" ; |
31 | extern const char kText3[]; |
32 | |
33 | void Test() { |
34 | std::string str('x', 4); |
35 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters are probably swapped; expecting string(count, character) [bugprone-string-constructor] |
36 | // CHECK-FIXES: std::string str(4, 'x'); |
37 | std::wstring wstr(L'x', 4); |
38 | // CHECK-MESSAGES: [[@LINE-1]]:16: warning: string constructor parameters are probably swapped |
39 | // CHECK-FIXES: std::wstring wstr(4, L'x'); |
40 | std::string s0(0, 'x'); |
41 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string |
42 | std::string s1(-4, 'x'); |
43 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter |
44 | std::string s2(0x1000000, 'x'); |
45 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter |
46 | |
47 | std::string q0("test" , 0); |
48 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string |
49 | std::string q1(kText, -4); |
50 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter |
51 | std::string q2("test" , 200); |
52 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size |
53 | std::string t1("test" , 5); |
54 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size |
55 | std::string q3(kText, 200); |
56 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size |
57 | std::string q4(kText2, 200); |
58 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size |
59 | std::string q5(kText3, 0x1000000); |
60 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter |
61 | std::string q6(nullptr); |
62 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour |
63 | std::string q7 = 0; |
64 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour |
65 | |
66 | std::string r1("test" , 1, 0); |
67 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string |
68 | std::string r2("test" , 0, -4); |
69 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter |
70 | std::string r3("test" , -4, 1); |
71 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as position of the first character parameter |
72 | std::string r4("test" , 0, 0x1000000); |
73 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter |
74 | std::string r5("test" , 0, 5); |
75 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size |
76 | std::string r6("test" , 3, 2); |
77 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than remaining string literal size |
78 | std::string r7("test" , 4, 1); |
79 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: position of the first character parameter is bigger than string literal character range |
80 | } |
81 | |
82 | void TestView() { |
83 | std::string_view q0("test" , 0); |
84 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructor creating an empty string |
85 | std::string_view q1(kText, -4); |
86 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: negative value used as length parameter |
87 | std::string_view q2("test" , 200); |
88 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size |
89 | std::string_view q3(kText, 200); |
90 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size |
91 | std::string_view q4(kText2, 200); |
92 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size |
93 | std::string_view q5(kText3, 0x1000000); |
94 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: suspicious large length parameter |
95 | std::string_view q6(nullptr); |
96 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour |
97 | std::string_view q7 = 0; |
98 | // CHECK-MESSAGES: [[@LINE-1]]:25: warning: constructing string from nullptr is undefined behaviour |
99 | } |
100 | |
101 | void TestUnsignedArguments() { |
102 | std::string s0("test" , 0u); |
103 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string |
104 | std::string s1(0x1000000ull, 'x'); |
105 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter |
106 | std::string s2("test" , 3ull, 2u); |
107 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than remaining string literal size |
108 | std::string s3("test" , 0u, 5ll); |
109 | // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size |
110 | } |
111 | |
112 | std::string StringFromZero() { |
113 | return 0; |
114 | // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour |
115 | } |
116 | |
117 | std::string_view StringViewFromZero() { |
118 | return 0; |
119 | // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour |
120 | } |
121 | |
122 | void Valid() { |
123 | std::string empty(); |
124 | std::string str(4, 'x'); |
125 | std::wstring wstr(4, L'x'); |
126 | std::string s1("test" , 4); |
127 | std::string s2("test" , 3); |
128 | std::string s3("test" ); |
129 | std::string s4("test\000" , 5); |
130 | std::string s6("te" "st" , 4); |
131 | std::string s7("test" , 0, 4); |
132 | std::string s8("test" , 3, 1); |
133 | std::string s9("te" "st" , 1, 2); |
134 | |
135 | std::string_view emptyv(); |
136 | std::string_view sv1("test" , 4); |
137 | std::string_view sv2("test" , 3); |
138 | std::string_view sv3("test" ); |
139 | } |
140 | |
141 | namespace instantiation_dependent_exprs { |
142 | template<typename T> |
143 | struct S { |
144 | bool x; |
145 | std::string f() { return x ? "a" : "b" ; } |
146 | std::string_view g() { return x ? "a" : "b" ; } |
147 | }; |
148 | } |
149 | |