| 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 | |