xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/bugprone/string-integer-assignment.cpp (revision 89a1d03e2b379e325daa5249411e414bbd995b5e)
1*89a1d03eSRichard // RUN: %check_clang_tidy %s bugprone-string-integer-assignment %t -- -- -fno-delayed-template-parsing
2*89a1d03eSRichard 
3*89a1d03eSRichard namespace std {
4*89a1d03eSRichard template<typename T>
5*89a1d03eSRichard struct basic_string {
6*89a1d03eSRichard   basic_string& operator=(T);
7*89a1d03eSRichard   basic_string& operator=(basic_string);
8*89a1d03eSRichard   basic_string& operator+=(T);
9*89a1d03eSRichard   basic_string& operator+=(basic_string);
10*89a1d03eSRichard   const T &operator[](int i) const;
11*89a1d03eSRichard   T &operator[](int i);
12*89a1d03eSRichard };
13*89a1d03eSRichard 
14*89a1d03eSRichard typedef basic_string<char> string;
15*89a1d03eSRichard typedef basic_string<wchar_t> wstring;
16*89a1d03eSRichard 
17*89a1d03eSRichard int tolower(int i);
18*89a1d03eSRichard int toupper(int i);
19*89a1d03eSRichard }
20*89a1d03eSRichard 
21*89a1d03eSRichard int tolower(int i);
22*89a1d03eSRichard int toupper(int i);
23*89a1d03eSRichard 
24*89a1d03eSRichard typedef int MyArcaneChar;
25*89a1d03eSRichard 
26*89a1d03eSRichard constexpr char kCharConstant = 'a';
27*89a1d03eSRichard 
main()28*89a1d03eSRichard int main() {
29*89a1d03eSRichard   std::string s;
30*89a1d03eSRichard   std::wstring ws;
31*89a1d03eSRichard   int x = 5;
32*89a1d03eSRichard   const char c = 'c';
33*89a1d03eSRichard 
34*89a1d03eSRichard   s = 6;
35*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a character code when assigning {{.*}} [bugprone-string-integer-assignment]
36*89a1d03eSRichard // CHECK-FIXES: {{^}}  s = '6';{{$}}
37*89a1d03eSRichard   s = 66;
38*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a chara
39*89a1d03eSRichard // CHECK-FIXES: {{^}}  s = "66";{{$}}
40*89a1d03eSRichard   s = x;
41*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a chara
42*89a1d03eSRichard // CHECK-FIXES: {{^}}  s = std::to_string(x);{{$}}
43*89a1d03eSRichard   s = 'c';
44*89a1d03eSRichard   s = static_cast<char>(6);
45*89a1d03eSRichard 
46*89a1d03eSRichard // +=
47*89a1d03eSRichard   ws += 6;
48*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
49*89a1d03eSRichard // CHECK-FIXES: {{^}}  ws += L'6';{{$}}
50*89a1d03eSRichard   ws += 66;
51*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
52*89a1d03eSRichard // CHECK-FIXES: {{^}}  ws += L"66";{{$}}
53*89a1d03eSRichard   ws += x;
54*89a1d03eSRichard // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
55*89a1d03eSRichard // CHECK-FIXES: {{^}}  ws += std::to_wstring(x);{{$}}
56*89a1d03eSRichard   ws += L'c';
57*89a1d03eSRichard   ws += (wchar_t)6;
58*89a1d03eSRichard 
59*89a1d03eSRichard   std::basic_string<MyArcaneChar> as;
60*89a1d03eSRichard   as = 6;
61*89a1d03eSRichard   as = static_cast<MyArcaneChar>(6);
62*89a1d03eSRichard   as = 'a';
63*89a1d03eSRichard 
64*89a1d03eSRichard   s += toupper(x);
65*89a1d03eSRichard   s += tolower(x);
66*89a1d03eSRichard   s += (std::tolower(x));
67*89a1d03eSRichard 
68*89a1d03eSRichard   s += c & s[1];
69*89a1d03eSRichard   s += c ^ s[1];
70*89a1d03eSRichard   s += c | s[1];
71*89a1d03eSRichard 
72*89a1d03eSRichard   s[x] += 1;
73*89a1d03eSRichard   s += s[x];
74*89a1d03eSRichard   as += as[x];
75*89a1d03eSRichard 
76*89a1d03eSRichard   // Likely character expressions.
77*89a1d03eSRichard   s += x & 0xff;
78*89a1d03eSRichard   s += 0xff & x;
79*89a1d03eSRichard   s += x % 26;
80*89a1d03eSRichard   s += 26 % x;
81*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
82*89a1d03eSRichard   // CHECK-FIXES: {{^}}  s += std::to_string(26 % x);{{$}}
83*89a1d03eSRichard   s += c | 0x80;
84*89a1d03eSRichard   s += c | 0x8000;
85*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
86*89a1d03eSRichard   // CHECK-FIXES: {{^}}  s += std::to_string(c | 0x8000);{{$}}
87*89a1d03eSRichard   as += c | 0x8000;
88*89a1d03eSRichard 
89*89a1d03eSRichard   s += 'a' + (x % 26);
90*89a1d03eSRichard   s += kCharConstant + (x % 26);
91*89a1d03eSRichard   s += 'a' + (s[x] & 0xf);
92*89a1d03eSRichard   s += (x % 10) + 'b';
93*89a1d03eSRichard 
94*89a1d03eSRichard   s += x > 255 ? c : x;
95*89a1d03eSRichard   s += x > 255 ? 12 : x;
96*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
97*89a1d03eSRichard   // CHECK-FIXES: {{^}}  s += std::to_string(x > 255 ? 12 : x);{{$}}
98*89a1d03eSRichard }
99*89a1d03eSRichard 
100*89a1d03eSRichard namespace instantiation_dependent_exprs {
101*89a1d03eSRichard template<typename T>
102*89a1d03eSRichard struct S {
103*89a1d03eSRichard   static constexpr T t = 0x8000;
104*89a1d03eSRichard   std::string s;
finstantiation_dependent_exprs::S105*89a1d03eSRichard   void f(char c) { s += c | static_cast<int>(t); }
106*89a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: an integer is interpreted as a chara
107*89a1d03eSRichard   // CHECK-FIXES: {{^}}  void f(char c) { s += std::to_string(c | static_cast<int>(t)); }
108*89a1d03eSRichard };
109*89a1d03eSRichard 
110*89a1d03eSRichard template struct S<int>;
111*89a1d03eSRichard }
112