1 | // RUN: %check_clang_tidy %s bugprone-signed-char-misuse %t |
2 | |
3 | /////////////////////////////////////////////////////////////////// |
4 | /// Test cases correctly caught by the check. |
5 | |
6 | typedef __SIZE_TYPE__ size_t; |
7 | |
8 | namespace std { |
9 | template <typename T, size_t N> |
10 | struct array { |
11 | T &operator[](size_t n); |
12 | T &at(size_t n); |
13 | }; |
14 | } // namespace std |
15 | |
16 | int SimpleVarDeclaration() { |
17 | signed char CCharacter = -5; |
18 | int NCharacter = CCharacter; |
19 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
20 | |
21 | return NCharacter; |
22 | } |
23 | |
24 | int SimpleAssignment() { |
25 | signed char CCharacter = -5; |
26 | int NCharacter; |
27 | NCharacter = CCharacter; |
28 | // CHECK-MESSAGES: [[@LINE-1]]:16: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
29 | |
30 | return NCharacter; |
31 | } |
32 | |
33 | int CStyleCast() { |
34 | signed char CCharacter = -5; |
35 | int NCharacter; |
36 | NCharacter = (int)CCharacter; |
37 | // CHECK-MESSAGES: [[@LINE-1]]:21: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
38 | |
39 | return NCharacter; |
40 | } |
41 | |
42 | int StaticCast() { |
43 | signed char CCharacter = -5; |
44 | int NCharacter; |
45 | NCharacter = static_cast<int>(CCharacter); |
46 | // CHECK-MESSAGES: [[@LINE-1]]:33: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
47 | |
48 | return NCharacter; |
49 | } |
50 | |
51 | int FunctionalCast() { |
52 | signed char CCharacter = -5; |
53 | int NCharacter; |
54 | NCharacter = int(CCharacter); |
55 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
56 | |
57 | return NCharacter; |
58 | } |
59 | |
60 | int NegativeConstValue() { |
61 | const signed char CCharacter = -5; |
62 | int NCharacter = CCharacter; |
63 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
64 | |
65 | return NCharacter; |
66 | } |
67 | |
68 | int CharPointer(signed char *CCharacter) { |
69 | int NCharacter = *CCharacter; |
70 | // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'signed char' to 'int' conversion; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
71 | |
72 | return NCharacter; |
73 | } |
74 | |
75 | int SignedUnsignedCharEquality(signed char SCharacter) { |
76 | unsigned char USCharacter = 'a'; |
77 | if (SCharacter == USCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] |
78 | return 1; |
79 | return 0; |
80 | } |
81 | |
82 | int SignedUnsignedCharIneqiality(signed char SCharacter) { |
83 | unsigned char USCharacter = 'a'; |
84 | if (SCharacter != USCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] |
85 | return 1; |
86 | return 0; |
87 | } |
88 | |
89 | int CompareWithNonAsciiConstant(unsigned char USCharacter) { |
90 | const signed char SCharacter = -5; |
91 | if (USCharacter == SCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] |
92 | return 1; |
93 | return 0; |
94 | } |
95 | |
96 | int CompareWithUnsignedNonAsciiConstant(signed char SCharacter) { |
97 | const unsigned char USCharacter = 128; |
98 | if (USCharacter == SCharacter) // CHECK-MESSAGES: [[@LINE]]:7: warning: comparison between 'signed char' and 'unsigned char' [bugprone-signed-char-misuse] |
99 | return 1; |
100 | return 0; |
101 | } |
102 | |
103 | int SignedCharCArraySubscript(signed char SCharacter) { |
104 | int Array[3] = {1, 2, 3}; |
105 | |
106 | return Array[static_cast<unsigned int>(SCharacter)]; // CHECK-MESSAGES: [[@LINE]]:42: warning: 'signed char' to 'unsigned int' conversion in array subscript; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
107 | } |
108 | |
109 | int SignedCharSTDArraySubscript(std::array<int, 3> Array, signed char SCharacter) { |
110 | return Array[static_cast<unsigned int>(SCharacter)]; // CHECK-MESSAGES: [[@LINE]]:42: warning: 'signed char' to 'unsigned int' conversion in array subscript; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse] |
111 | } |
112 | |
113 | /////////////////////////////////////////////////////////////////// |
114 | /// Test cases correctly ignored by the check. |
115 | |
116 | int UnsignedCharCast() { |
117 | unsigned char CCharacter = 'a'; |
118 | int NCharacter = CCharacter; |
119 | |
120 | return NCharacter; |
121 | } |
122 | |
123 | int PositiveConstValue() { |
124 | const signed char CCharacter = 5; |
125 | int NCharacter = CCharacter; |
126 | |
127 | return NCharacter; |
128 | } |
129 | |
130 | // singed char -> integer cast is not the direct child of declaration expression. |
131 | int DescendantCast() { |
132 | signed char CCharacter = 'a'; |
133 | int NCharacter = 10 + CCharacter; |
134 | |
135 | return NCharacter; |
136 | } |
137 | |
138 | // singed char -> integer cast is not the direct child of assignment expression. |
139 | int DescendantCastAssignment() { |
140 | signed char CCharacter = 'a'; |
141 | int NCharacter; |
142 | NCharacter = 10 + CCharacter; |
143 | |
144 | return NCharacter; |
145 | } |
146 | |
147 | // bool is an integer type in clang; make sure to ignore it. |
148 | bool BoolVarDeclaration() { |
149 | signed char CCharacter = 'a'; |
150 | bool BCharacter = CCharacter == 'b'; |
151 | |
152 | return BCharacter; |
153 | } |
154 | |
155 | // bool is an integer type in clang; make sure to ignore it. |
156 | bool BoolAssignment() { |
157 | signed char CCharacter = 'a'; |
158 | bool BCharacter; |
159 | BCharacter = CCharacter == 'b'; |
160 | |
161 | return BCharacter; |
162 | } |
163 | |
164 | // char is an integer type in clang; make sure to ignore it. |
165 | unsigned char CharToCharCast() { |
166 | signed char SCCharacter = 'a'; |
167 | unsigned char USCharacter; |
168 | USCharacter = SCCharacter; |
169 | |
170 | return USCharacter; |
171 | } |
172 | |
173 | int FixComparisonWithSignedCharCast(signed char SCharacter) { |
174 | unsigned char USCharacter = 'a'; |
175 | if (SCharacter == static_cast<signed char>(USCharacter)) |
176 | return 1; |
177 | return 0; |
178 | } |
179 | |
180 | int FixComparisonWithUnSignedCharCast(signed char SCharacter) { |
181 | unsigned char USCharacter = 'a'; |
182 | if (static_cast<unsigned char>(SCharacter) == USCharacter) |
183 | return 1; |
184 | return 0; |
185 | } |
186 | |
187 | // Make sure we don't catch other type of char comparison. |
188 | int SameCharTypeComparison(signed char SCharacter) { |
189 | signed char SCharacter2 = 'a'; |
190 | if (SCharacter == SCharacter2) |
191 | return 1; |
192 | return 0; |
193 | } |
194 | |
195 | // Make sure we don't catch other type of char comparison. |
196 | int SameCharTypeComparison2(unsigned char USCharacter) { |
197 | unsigned char USCharacter2 = 'a'; |
198 | if (USCharacter == USCharacter2) |
199 | return 1; |
200 | return 0; |
201 | } |
202 | |
203 | // Make sure we don't catch integer - char comparison. |
204 | int CharIntComparison(signed char SCharacter) { |
205 | int ICharacter = 10; |
206 | if (SCharacter == ICharacter) |
207 | return 1; |
208 | return 0; |
209 | } |
210 | |
211 | int CompareWithAsciiLiteral(unsigned char USCharacter) { |
212 | if (USCharacter == 'x') // no warning |
213 | return 1; |
214 | return 0; |
215 | } |
216 | |
217 | int CompareWithAsciiConstant(unsigned char USCharacter) { |
218 | const signed char SCharacter = 'a'; |
219 | if (USCharacter == SCharacter) |
220 | return 1; |
221 | return 0; |
222 | } |
223 | |
224 | int CompareWithUnsignedAsciiConstant(signed char SCharacter) { |
225 | const unsigned char USCharacter = 'a'; |
226 | if (USCharacter == SCharacter) |
227 | return 1; |
228 | return 0; |
229 | } |
230 | |
231 | int UnsignedCharCArraySubscript(unsigned char USCharacter) { |
232 | int Array[3] = {1, 2, 3}; |
233 | |
234 | return Array[static_cast<unsigned int>(USCharacter)]; |
235 | } |
236 | |
237 | int CastedCArraySubscript(signed char SCharacter) { |
238 | int Array[3] = {1, 2, 3}; |
239 | |
240 | return Array[static_cast<unsigned char>(SCharacter)]; |
241 | } |
242 | |
243 | int UnsignedCharSTDArraySubscript(std::array<int, 3> Array, unsigned char USCharacter) { |
244 | return Array[static_cast<unsigned int>(USCharacter)]; |
245 | } |
246 | |
247 | int CastedSTDArraySubscript(std::array<int, 3> Array, signed char SCharacter) { |
248 | return Array[static_cast<unsigned char>(SCharacter)]; |
249 | } |
250 | |