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 };
15 typedef basic_string<char> string;
16 typedef basic_string<wchar_t> wstring;
17
18 template <typename C, typename T = std::char_traits<C>>
19 struct basic_string_view {
20 basic_string_view();
21 basic_string_view(const C *, unsigned int size);
22 basic_string_view(const C *);
23 };
24 typedef basic_string_view<char> string_view;
25 typedef basic_string_view<wchar_t> wstring_view;
26 }
27
28 const char* kText = "";
29 const char kText2[] = "";
30 extern const char kText3[];
31
Test()32 void Test() {
33 std::string str('x', 4);
34 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters are probably swapped; expecting string(count, character) [bugprone-string-constructor]
35 // CHECK-FIXES: std::string str(4, 'x');
36 std::wstring wstr(L'x', 4);
37 // CHECK-MESSAGES: [[@LINE-1]]:16: warning: string constructor parameters are probably swapped
38 // CHECK-FIXES: std::wstring wstr(4, L'x');
39 std::string s0(0, 'x');
40 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
41 std::string s1(-4, 'x');
42 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
43 std::string s2(0x1000000, 'x');
44 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
45
46 std::string q0("test", 0);
47 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
48 std::string q1(kText, -4);
49 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
50 std::string q2("test", 200);
51 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
52 std::string q3(kText, 200);
53 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
54 std::string q4(kText2, 200);
55 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
56 std::string q5(kText3, 0x1000000);
57 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
58 std::string q6(nullptr);
59 // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour
60 std::string q7 = 0;
61 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour
62 }
63
TestView()64 void TestView() {
65 std::string_view q0("test", 0);
66 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructor creating an empty string
67 std::string_view q1(kText, -4);
68 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: negative value used as length parameter
69 std::string_view q2("test", 200);
70 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size
71 std::string_view q3(kText, 200);
72 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size
73 std::string_view q4(kText2, 200);
74 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size
75 std::string_view q5(kText3, 0x1000000);
76 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: suspicious large length parameter
77 std::string_view q6(nullptr);
78 // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour
79 std::string_view q7 = 0;
80 // CHECK-MESSAGES: [[@LINE-1]]:25: warning: constructing string from nullptr is undefined behaviour
81 }
82
StringFromZero()83 std::string StringFromZero() {
84 return 0;
85 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
86 }
87
StringViewFromZero()88 std::string_view StringViewFromZero() {
89 return 0;
90 // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
91 }
92
Valid()93 void Valid() {
94 std::string empty();
95 std::string str(4, 'x');
96 std::wstring wstr(4, L'x');
97 std::string s1("test", 4);
98 std::string s2("test", 3);
99 std::string s3("test");
100
101 std::string_view emptyv();
102 std::string_view sv1("test", 4);
103 std::string_view sv2("test", 3);
104 std::string_view sv3("test");
105 }
106
107 namespace instantiation_dependent_exprs {
108 template<typename T>
109 struct S {
110 bool x;
finstantiation_dependent_exprs::S111 std::string f() { return x ? "a" : "b"; }
ginstantiation_dependent_exprs::S112 std::string_view g() { return x ? "a" : "b"; }
113 };
114 }
115