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
SimpleVarDeclaration()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
SimpleAssignment()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
CStyleCast()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
StaticCast()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
FunctionalCast()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
NegativeConstValue()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
CharPointer(signed char * CCharacter)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
SignedUnsignedCharEquality(signed char SCharacter)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
SignedUnsignedCharIneqiality(signed char SCharacter)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
CompareWithNonAsciiConstant(unsigned char USCharacter)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
CompareWithUnsignedNonAsciiConstant(signed char SCharacter)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
SignedCharCArraySubscript(signed char SCharacter)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
SignedCharSTDArraySubscript(std::array<int,3> Array,signed char SCharacter)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
UnsignedCharCast()116 int UnsignedCharCast() {
117 unsigned char CCharacter = 'a';
118 int NCharacter = CCharacter;
119
120 return NCharacter;
121 }
122
PositiveConstValue()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.
DescendantCast()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.
DescendantCastAssignment()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.
BoolVarDeclaration()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.
BoolAssignment()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.
CharToCharCast()165 unsigned char CharToCharCast() {
166 signed char SCCharacter = 'a';
167 unsigned char USCharacter;
168 USCharacter = SCCharacter;
169
170 return USCharacter;
171 }
172
FixComparisonWithSignedCharCast(signed char SCharacter)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
FixComparisonWithUnSignedCharCast(signed char SCharacter)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.
SameCharTypeComparison(signed char SCharacter)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.
SameCharTypeComparison2(unsigned char USCharacter)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.
CharIntComparison(signed char SCharacter)204 int CharIntComparison(signed char SCharacter) {
205 int ICharacter = 10;
206 if (SCharacter == ICharacter)
207 return 1;
208 return 0;
209 }
210
CompareWithAsciiLiteral(unsigned char USCharacter)211 int CompareWithAsciiLiteral(unsigned char USCharacter) {
212 if (USCharacter == 'x') // no warning
213 return 1;
214 return 0;
215 }
216
CompareWithAsciiConstant(unsigned char USCharacter)217 int CompareWithAsciiConstant(unsigned char USCharacter) {
218 const signed char SCharacter = 'a';
219 if (USCharacter == SCharacter)
220 return 1;
221 return 0;
222 }
223
CompareWithUnsignedAsciiConstant(signed char SCharacter)224 int CompareWithUnsignedAsciiConstant(signed char SCharacter) {
225 const unsigned char USCharacter = 'a';
226 if (USCharacter == SCharacter)
227 return 1;
228 return 0;
229 }
230
UnsignedCharCArraySubscript(unsigned char USCharacter)231 int UnsignedCharCArraySubscript(unsigned char USCharacter) {
232 int Array[3] = {1, 2, 3};
233
234 return Array[static_cast<unsigned int>(USCharacter)];
235 }
236
CastedCArraySubscript(signed char SCharacter)237 int CastedCArraySubscript(signed char SCharacter) {
238 int Array[3] = {1, 2, 3};
239
240 return Array[static_cast<unsigned char>(SCharacter)];
241 }
242
UnsignedCharSTDArraySubscript(std::array<int,3> Array,unsigned char USCharacter)243 int UnsignedCharSTDArraySubscript(std::array<int, 3> Array, unsigned char USCharacter) {
244 return Array[static_cast<unsigned int>(USCharacter)];
245 }
246
CastedSTDArraySubscript(std::array<int,3> Array,signed char SCharacter)247 int CastedSTDArraySubscript(std::array<int, 3> Array, signed char SCharacter) {
248 return Array[static_cast<unsigned char>(SCharacter)];
249 }
250