1// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t -- -- --target=x86_64-linux
2
3// These could cause false positives and should not be considered.
4struct StreamClass {
5};
6StreamClass &operator<<(StreamClass &os, unsigned int i) {
7 return os;
8}
9StreamClass &operator<<(StreamClass &os, int i) {
10 return os;
11}
12StreamClass &operator>>(StreamClass &os, unsigned int i) {
13 return os;
14}
15StreamClass &operator>>(StreamClass &os, int i) {
16 return os;
17}
18struct AnotherStream {
19 AnotherStream &operator<<(unsigned char c) { return *this; }
20 AnotherStream &operator<<(signed char c) { return *this; }
21
22 AnotherStream &operator>>(unsigned char c) { return *this; }
23 AnotherStream &operator>>(signed char c) { return *this; }
24};
25
26void binary_bitwise() {
27 int SValue = 42;
28 int SResult;
29
30 unsigned int UValue = 42;
31 unsigned int UResult;
32
33 SResult = SValue & 1;
34 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
35 SResult = SValue & -1;
36 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
37 SResult = SValue & SValue;
38 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
39
40 UResult = SValue & 1;
41 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
42 UResult = SValue & -1;
43 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
44 UResult&= 1;
45 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
46
47 UResult = UValue & 1u; // Ok
48 UResult = UValue & UValue; // Ok
49 UResult&= 2u; // Ok
50
51 unsigned char UByte1 = 0u;
52 unsigned char UByte2 = 16u;
53 signed char SByte1 = 0;
54 signed char SByte2 = 16;
55
56 UByte1 = UByte1 & UByte2; // Ok
57 UByte1 = SByte1 & UByte2;
58 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
59 UByte1 = SByte1 & SByte2;
60 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
61 SByte1 = SByte1 & SByte2;
62 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
63
64 // More complex expressions.
65 UResult = UValue & (SByte1 + (SByte1 | SByte2));
66 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
67 // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator
68
69 // The rest is to demonstrate functionality but all operators are matched equally.
70 // Therefore functionality is the same for all binary operations.
71 UByte1 = UByte1 | UByte2; // Ok
72 UByte1 = UByte1 | SByte2;
73 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use of a signed integer operand with a binary bitwise operator
74 UByte1|= SByte2;
75 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
76 UByte1|= UByte2; // Ok
77
78 UByte1 = UByte1 ^ UByte2; // Ok
79 UByte1 = UByte1 ^ SByte2;
80 // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use of a signed integer operand with a binary bitwise operator
81 UByte1^= SByte2;
82 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
83 UByte1^= UByte2; // Ok
84
85 UByte1 = UByte1 >> UByte2; // Ok
86 UByte1 = UByte1 >> SByte2;
87 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
88 UByte1>>= SByte2;
89 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
90 UByte1>>= UByte2; // Ok
91
92 UByte1 = UByte1 << UByte2; // Ok
93 UByte1 = UByte1 << SByte2;
94 // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
95 UByte1<<= SByte2;
96 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
97 UByte1<<= UByte2; // Ok
98
99 int SignedInt1 = 1 << 12;
100 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
101 int SignedInt2 = 1u << 12;
102 // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use of a signed integer operand with a binary bitwise operator
103}
104
105void f1(unsigned char c) {}
106void f2(signed char c) {}
107void f3(int c) {}
108
109void unary_bitwise() {
110 unsigned char UByte1 = 0u;
111 signed char SByte1 = 0;
112
113 UByte1 = ~UByte1; // Ok
114 SByte1 = ~UByte1;
115 SByte1 = ~SByte1;
116 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
117 UByte1 = ~SByte1;
118 // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
119
120 unsigned int UInt = 0u;
121 int SInt = 0;
122
123 f1(c: ~UByte1); // Ok
124 f1(c: ~SByte1);
125 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
126 f1(c: ~UInt);
127 f1(c: ~SInt);
128 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
129 f2(c: ~UByte1);
130 f2(c: ~SByte1);
131 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
132 f2(c: ~UInt);
133 f2(c: ~SInt);
134 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
135 f3(c: ~UByte1); // Ok
136 f3(c: ~SByte1);
137 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
138}
139
140/// HICPP uses these examples to demonstrate the rule.
141void standard_examples() {
142 int i = 3;
143 unsigned int k = 0u;
144
145 int r = i << -1; // Emits -Wshift-count-negative from clang
146 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
147 r = i << 1;
148 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
149
150 r = -1 >> -1; // Emits -Wshift-count-negative from clang
151 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
152 r = -1 >> 1;
153 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
154
155 r = -1 >> i;
156 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
157 r = -1 >> -i;
158 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
159
160 r = ~0;
161 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use of a signed integer operand with a unary bitwise operator
162 r = ~0u; // Ok
163 k = ~k; // Ok
164
165 unsigned int u = (-1) & 2u;
166 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
167 u = (-1) | 1u;
168 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
169 u = (-1) ^ 1u;
170 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
171}
172
173void streams_should_work() {
174 StreamClass s;
175 s << 1u; // Ok
176 s << 1; // Ok
177 s >> 1; // Ok
178 s >> 1u; // Ok
179
180 AnotherStream as;
181 unsigned char uc = 1u;
182 signed char sc = 1;
183 as << uc; // Ok
184 as << sc; // Ok
185 as >> uc; // Ok
186 as >> sc; // Ok
187}
188
189enum OldEnum {
190 ValueOne,
191 ValueTwo,
192};
193
194enum OldSigned : int {
195 IntOne,
196 IntTwo,
197};
198
199void classicEnums() {
200 OldEnum e1 = ValueOne, e2 = ValueTwo;
201 int e3; // Using the enum type, results in an error.
202 e3 = ValueOne | ValueTwo; // Ok
203 e3 = ValueOne & ValueTwo; // Ok
204 e3 = ValueOne ^ ValueTwo; // Ok
205 e3 = e1 | e2; // Ok
206 e3 = e1 & e2; // Ok
207 e3 = e1 ^ e2; // Ok
208
209 OldSigned s1 = IntOne, s2 = IntTwo;
210 int s3;
211 s3 = IntOne | IntTwo; // Signed
212 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
213 s3|= IntTwo; // Signed
214 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
215 s3 = IntOne & IntTwo; // Signed
216 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
217 s3&= IntTwo; // Signed
218 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
219 s3 = IntOne ^ IntTwo; // Signed
220 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
221 s3^= IntTwo; // Signed
222 // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
223 s3 = s1 | s2; // Signed
224 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
225 s3 = s1 & s2; // Signed
226 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
227 s3 = s1 ^ s2; // Signed
228 // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
229}
230
231enum EnumConstruction {
232 one = 1,
233 two = 2,
234 test1 = 1 << 12,
235 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
236 test2 = one << two,
237 // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
238 test3 = 1u << 12,
239 // CHECK-MESSAGES: [[@LINE-1]]:17: warning: use of a signed integer operand with a binary bitwise operator
240};
241

source code of clang-tools-extra/test/clang-tidy/checkers/hicpp/signed-bitwise.cpp