1// RUN: %check_clang_tidy %s bugprone-signed-char-misuse %t
2
3///////////////////////////////////////////////////////////////////
4/// Test cases correctly caught by the check.
5
6typedef __SIZE_TYPE__ size_t;
7
8namespace std {
9template <typename T, size_t N>
10struct array {
11 T &operator[](size_t n);
12 T &at(size_t n);
13};
14} // namespace std
15
16int 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
24int 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
33int 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
42int 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
51int 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
60int 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
68int 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
75int 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
82int 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
89int 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
96int 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
103int 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
109int 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
116int UnsignedCharCast() {
117 unsigned char CCharacter = 'a';
118 int NCharacter = CCharacter;
119
120 return NCharacter;
121}
122
123int 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.
131int 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.
139int 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.
148bool 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.
156bool 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.
165unsigned char CharToCharCast() {
166 signed char SCCharacter = 'a';
167 unsigned char USCharacter;
168 USCharacter = SCCharacter;
169
170 return USCharacter;
171}
172
173int 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
180int 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.
188int 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.
196int 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.
204int CharIntComparison(signed char SCharacter) {
205 int ICharacter = 10;
206 if (SCharacter == ICharacter)
207 return 1;
208 return 0;
209}
210
211int CompareWithAsciiLiteral(unsigned char USCharacter) {
212 if (USCharacter == 'x') // no warning
213 return 1;
214 return 0;
215}
216
217int CompareWithAsciiConstant(unsigned char USCharacter) {
218 const signed char SCharacter = 'a';
219 if (USCharacter == SCharacter)
220 return 1;
221 return 0;
222}
223
224int CompareWithUnsignedAsciiConstant(signed char SCharacter) {
225 const unsigned char USCharacter = 'a';
226 if (USCharacter == SCharacter)
227 return 1;
228 return 0;
229}
230
231int UnsignedCharCArraySubscript(unsigned char USCharacter) {
232 int Array[3] = {1, 2, 3};
233
234 return Array[static_cast<unsigned int>(USCharacter)];
235}
236
237int CastedCArraySubscript(signed char SCharacter) {
238 int Array[3] = {1, 2, 3};
239
240 return Array[static_cast<unsigned char>(SCharacter)];
241}
242
243int UnsignedCharSTDArraySubscript(std::array<int, 3> Array, unsigned char USCharacter) {
244 return Array[static_cast<unsigned int>(USCharacter)];
245}
246
247int CastedSTDArraySubscript(std::array<int, 3> Array, signed char SCharacter) {
248 return Array[static_cast<unsigned char>(SCharacter)];
249}
250

source code of clang-tools-extra/test/clang-tidy/checkers/bugprone/signed-char-misuse.cpp