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