xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-constructor.cpp (revision 2463a0ed70754524efb6e05b09d632dcacf9b51f)
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 t1("test", 5);
53   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
54   std::string q3(kText, 200);
55   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
56   std::string q4(kText2, 200);
57   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
58   std::string q5(kText3,  0x1000000);
59   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
60   std::string q6(nullptr);
61   // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour
62   std::string q7 = 0;
63   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour
64 }
65 
TestView()66 void TestView() {
67   std::string_view q0("test", 0);
68   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructor creating an empty string
69   std::string_view q1(kText, -4);
70   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: negative value used as length parameter
71   std::string_view q2("test", 200);
72   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size
73   std::string_view q3(kText, 200);
74   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size
75   std::string_view q4(kText2, 200);
76   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: length is bigger than string literal size
77   std::string_view q5(kText3, 0x1000000);
78   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: suspicious large length parameter
79   std::string_view q6(nullptr);
80   // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour
81   std::string_view q7 = 0;
82   // CHECK-MESSAGES: [[@LINE-1]]:25: warning: constructing string from nullptr is undefined behaviour
83 }
84 
StringFromZero()85 std::string StringFromZero() {
86   return 0;
87   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
88 }
89 
StringViewFromZero()90 std::string_view StringViewFromZero() {
91   return 0;
92   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
93 }
94 
Valid()95 void Valid() {
96   std::string empty();
97   std::string str(4, 'x');
98   std::wstring wstr(4, L'x');
99   std::string s1("test", 4);
100   std::string s2("test", 3);
101   std::string s3("test");
102   std::string s4("test\000", 5);
103   std::string s6("te" "st", 4);
104 
105   std::string_view emptyv();
106   std::string_view sv1("test", 4);
107   std::string_view sv2("test", 3);
108   std::string_view sv3("test");
109 }
110 
111 namespace instantiation_dependent_exprs {
112 template<typename T>
113 struct S {
114   bool x;
finstantiation_dependent_exprs::S115   std::string f() { return x ? "a" : "b"; }
ginstantiation_dependent_exprs::S116   std::string_view g() { return x ? "a" : "b"; }
117 };
118 }
119