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