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.
4 struct StreamClass {
5 };
operator <<(StreamClass & os,unsigned int i)6 StreamClass &operator<<(StreamClass &os, unsigned int i) {
7   return os;
8 }
operator <<(StreamClass & os,int i)9 StreamClass &operator<<(StreamClass &os, int i) {
10   return os;
11 }
operator >>(StreamClass & os,unsigned int i)12 StreamClass &operator>>(StreamClass &os, unsigned int i) {
13   return os;
14 }
operator >>(StreamClass & os,int i)15 StreamClass &operator>>(StreamClass &os, int i) {
16   return os;
17 }
18 struct AnotherStream {
operator <<AnotherStream19   AnotherStream &operator<<(unsigned char c) { return *this; }
operator <<AnotherStream20   AnotherStream &operator<<(signed char c) { return *this; }
21 
operator >>AnotherStream22   AnotherStream &operator>>(unsigned char c) { return *this; }
operator >>AnotherStream23   AnotherStream &operator>>(signed char c) { return *this; }
24 };
25 
binary_bitwise()26 void 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]]:3: 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]]:13: 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]]:12: warning: use of a signed integer operand with a binary bitwise operator
74   UByte1|= SByte2;
75   // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:12: warning: use of a signed integer operand with a binary bitwise operator
81   UByte1^= SByte2;
82   // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:12: warning: use of a signed integer operand with a binary bitwise operator
88   UByte1>>= SByte2;
89   // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:12: warning: use of a signed integer operand with a binary bitwise operator
95   UByte1<<= SByte2;
96   // CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:20: warning: use of a signed integer operand with a binary bitwise operator
103 }
104 
f1(unsigned char c)105 void f1(unsigned char c) {}
f2(signed char c)106 void f2(signed char c) {}
f3(int c)107 void f3(int c) {}
108 
unary_bitwise()109 void 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]]:12: warning: use of a signed integer operand with a unary bitwise operator
117   UByte1 = ~SByte1;
118   // CHECK-MESSAGES: :[[@LINE-1]]:12: 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(~UByte1); // Ok
124   f1(~SByte1);
125   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
126   f1(~UInt);
127   f1(~SInt);
128   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
129   f2(~UByte1);
130   f2(~SByte1);
131   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
132   f2(~UInt);
133   f2(~SInt);
134   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
135   f3(~UByte1); // Ok
136   f3(~SByte1);
137   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
138 }
139 
140 /// HICPP uses these examples to demonstrate the rule.
standard_examples()141 void 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]]:7: 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 
streams_should_work()173 void 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 
189 enum OldEnum {
190   ValueOne,
191   ValueTwo,
192 };
193 
194 enum OldSigned : int {
195   IntOne,
196   IntTwo,
197 };
198 
classicEnums()199 void 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 
231 enum 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]]:11: warning: use of a signed integer operand with a binary bitwise operator
240 };
241