xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/hicpp/signed-bitwise.cpp (revision fa8f8616028abbc10aa5a3ad4641e8a40ec20cc8)
189a1d03eSRichard // RUN: %check_clang_tidy %s hicpp-signed-bitwise %t -- -- --target=x86_64-linux
289a1d03eSRichard 
389a1d03eSRichard // These could cause false positives and should not be considered.
489a1d03eSRichard struct StreamClass {
589a1d03eSRichard };
operator <<(StreamClass & os,unsigned int i)689a1d03eSRichard StreamClass &operator<<(StreamClass &os, unsigned int i) {
789a1d03eSRichard   return os;
889a1d03eSRichard }
operator <<(StreamClass & os,int i)989a1d03eSRichard StreamClass &operator<<(StreamClass &os, int i) {
1089a1d03eSRichard   return os;
1189a1d03eSRichard }
operator >>(StreamClass & os,unsigned int i)1289a1d03eSRichard StreamClass &operator>>(StreamClass &os, unsigned int i) {
1389a1d03eSRichard   return os;
1489a1d03eSRichard }
operator >>(StreamClass & os,int i)1589a1d03eSRichard StreamClass &operator>>(StreamClass &os, int i) {
1689a1d03eSRichard   return os;
1789a1d03eSRichard }
1889a1d03eSRichard struct AnotherStream {
operator <<AnotherStream1989a1d03eSRichard   AnotherStream &operator<<(unsigned char c) { return *this; }
operator <<AnotherStream2089a1d03eSRichard   AnotherStream &operator<<(signed char c) { return *this; }
2189a1d03eSRichard 
operator >>AnotherStream2289a1d03eSRichard   AnotherStream &operator>>(unsigned char c) { return *this; }
operator >>AnotherStream2389a1d03eSRichard   AnotherStream &operator>>(signed char c) { return *this; }
2489a1d03eSRichard };
2589a1d03eSRichard 
binary_bitwise()2689a1d03eSRichard void binary_bitwise() {
2789a1d03eSRichard   int SValue = 42;
2889a1d03eSRichard   int SResult;
2989a1d03eSRichard 
3089a1d03eSRichard   unsigned int UValue = 42;
3189a1d03eSRichard   unsigned int UResult;
3289a1d03eSRichard 
3389a1d03eSRichard   SResult = SValue & 1;
3489a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
3589a1d03eSRichard   SResult = SValue & -1;
3689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
3789a1d03eSRichard   SResult = SValue & SValue;
3889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
3989a1d03eSRichard 
4089a1d03eSRichard   UResult = SValue & 1;
4189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
4289a1d03eSRichard   UResult = SValue & -1;
4389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
4489a1d03eSRichard   UResult&= 1;
45*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
4689a1d03eSRichard 
4789a1d03eSRichard   UResult = UValue & 1u;     // Ok
4889a1d03eSRichard   UResult = UValue & UValue; // Ok
4989a1d03eSRichard   UResult&= 2u;              // Ok
5089a1d03eSRichard 
5189a1d03eSRichard   unsigned char UByte1 = 0u;
5289a1d03eSRichard   unsigned char UByte2 = 16u;
5389a1d03eSRichard   signed char SByte1 = 0;
5489a1d03eSRichard   signed char SByte2 = 16;
5589a1d03eSRichard 
5689a1d03eSRichard   UByte1 = UByte1 & UByte2; // Ok
5789a1d03eSRichard   UByte1 = SByte1 & UByte2;
5889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
5989a1d03eSRichard   UByte1 = SByte1 & SByte2;
6089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
6189a1d03eSRichard   SByte1 = SByte1 & SByte2;
6289a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
6389a1d03eSRichard 
6489a1d03eSRichard   // More complex expressions.
6589a1d03eSRichard   UResult = UValue & (SByte1 + (SByte1 | SByte2));
66*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
6789a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator
6889a1d03eSRichard 
6989a1d03eSRichard   // The rest is to demonstrate functionality but all operators are matched equally.
7089a1d03eSRichard   // Therefore functionality is the same for all binary operations.
7189a1d03eSRichard   UByte1 = UByte1 | UByte2; // Ok
7289a1d03eSRichard   UByte1 = UByte1 | SByte2;
73*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use of a signed integer operand with a binary bitwise operator
7489a1d03eSRichard   UByte1|= SByte2;
75*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
7689a1d03eSRichard   UByte1|= UByte2; // Ok
7789a1d03eSRichard 
7889a1d03eSRichard   UByte1 = UByte1 ^ UByte2; // Ok
7989a1d03eSRichard   UByte1 = UByte1 ^ SByte2;
80*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use of a signed integer operand with a binary bitwise operator
8189a1d03eSRichard   UByte1^= SByte2;
82*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
8389a1d03eSRichard   UByte1^= UByte2; // Ok
8489a1d03eSRichard 
8589a1d03eSRichard   UByte1 = UByte1 >> UByte2; // Ok
8689a1d03eSRichard   UByte1 = UByte1 >> SByte2;
87*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
8889a1d03eSRichard   UByte1>>= SByte2;
89*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
9089a1d03eSRichard   UByte1>>= UByte2; // Ok
9189a1d03eSRichard 
9289a1d03eSRichard   UByte1 = UByte1 << UByte2; // Ok
9389a1d03eSRichard   UByte1 = UByte1 << SByte2;
94*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
9589a1d03eSRichard   UByte1<<= SByte2;
96*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
9789a1d03eSRichard   UByte1<<= UByte2; // Ok
9889a1d03eSRichard 
9989a1d03eSRichard   int SignedInt1 = 1 << 12;
10089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
10189a1d03eSRichard   int SignedInt2 = 1u << 12;
102*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use of a signed integer operand with a binary bitwise operator
10389a1d03eSRichard }
10489a1d03eSRichard 
f1(unsigned char c)10589a1d03eSRichard void f1(unsigned char c) {}
f2(signed char c)10689a1d03eSRichard void f2(signed char c) {}
f3(int c)10789a1d03eSRichard void f3(int c) {}
10889a1d03eSRichard 
unary_bitwise()10989a1d03eSRichard void unary_bitwise() {
11089a1d03eSRichard   unsigned char UByte1 = 0u;
11189a1d03eSRichard   signed char SByte1 = 0;
11289a1d03eSRichard 
11389a1d03eSRichard   UByte1 = ~UByte1; // Ok
11489a1d03eSRichard   SByte1 = ~UByte1;
11589a1d03eSRichard   SByte1 = ~SByte1;
116*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
11789a1d03eSRichard   UByte1 = ~SByte1;
118*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
11989a1d03eSRichard 
12089a1d03eSRichard   unsigned int UInt = 0u;
12189a1d03eSRichard   int SInt = 0;
12289a1d03eSRichard 
12389a1d03eSRichard   f1(~UByte1); // Ok
12489a1d03eSRichard   f1(~SByte1);
125*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
12689a1d03eSRichard   f1(~UInt);
12789a1d03eSRichard   f1(~SInt);
128*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
12989a1d03eSRichard   f2(~UByte1);
13089a1d03eSRichard   f2(~SByte1);
131*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
13289a1d03eSRichard   f2(~UInt);
13389a1d03eSRichard   f2(~SInt);
134*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
13589a1d03eSRichard   f3(~UByte1); // Ok
13689a1d03eSRichard   f3(~SByte1);
137*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
13889a1d03eSRichard }
13989a1d03eSRichard 
14089a1d03eSRichard /// HICPP uses these examples to demonstrate the rule.
standard_examples()14189a1d03eSRichard void standard_examples() {
14289a1d03eSRichard   int i = 3;
14389a1d03eSRichard   unsigned int k = 0u;
14489a1d03eSRichard 
14589a1d03eSRichard   int r = i << -1; // Emits -Wshift-count-negative from clang
14689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
14789a1d03eSRichard   r = i << 1;
14889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
14989a1d03eSRichard 
15089a1d03eSRichard   r = -1 >> -1; // Emits -Wshift-count-negative from clang
15189a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
15289a1d03eSRichard   r = -1 >> 1;
15389a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
15489a1d03eSRichard 
15589a1d03eSRichard   r = -1 >> i;
15689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
15789a1d03eSRichard   r = -1 >> -i;
15889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
15989a1d03eSRichard 
16089a1d03eSRichard   r = ~0;
161*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use of a signed integer operand with a unary bitwise operator
16289a1d03eSRichard   r = ~0u; // Ok
16389a1d03eSRichard   k = ~k;  // Ok
16489a1d03eSRichard 
16589a1d03eSRichard   unsigned int u = (-1) & 2u;
16689a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
16789a1d03eSRichard   u = (-1) | 1u;
16889a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
16989a1d03eSRichard   u = (-1) ^ 1u;
17089a1d03eSRichard   // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
17189a1d03eSRichard }
17289a1d03eSRichard 
streams_should_work()17389a1d03eSRichard void streams_should_work() {
17489a1d03eSRichard   StreamClass s;
17589a1d03eSRichard   s << 1u; // Ok
17689a1d03eSRichard   s << 1;  // Ok
17789a1d03eSRichard   s >> 1;  // Ok
17889a1d03eSRichard   s >> 1u; // Ok
17989a1d03eSRichard 
18089a1d03eSRichard   AnotherStream as;
18189a1d03eSRichard   unsigned char uc = 1u;
18289a1d03eSRichard   signed char sc = 1;
18389a1d03eSRichard   as << uc; // Ok
18489a1d03eSRichard   as << sc; // Ok
18589a1d03eSRichard   as >> uc; // Ok
18689a1d03eSRichard   as >> sc; // Ok
18789a1d03eSRichard }
18889a1d03eSRichard 
18989a1d03eSRichard enum OldEnum {
19089a1d03eSRichard   ValueOne,
19189a1d03eSRichard   ValueTwo,
19289a1d03eSRichard };
19389a1d03eSRichard 
19489a1d03eSRichard enum OldSigned : int {
19589a1d03eSRichard   IntOne,
19689a1d03eSRichard   IntTwo,
19789a1d03eSRichard };
19889a1d03eSRichard 
classicEnums()19989a1d03eSRichard void classicEnums() {
20089a1d03eSRichard   OldEnum e1 = ValueOne, e2 = ValueTwo;
20189a1d03eSRichard   int e3;                   // Using the enum type, results in an error.
20289a1d03eSRichard   e3 = ValueOne | ValueTwo; // Ok
20389a1d03eSRichard   e3 = ValueOne & ValueTwo; // Ok
20489a1d03eSRichard   e3 = ValueOne ^ ValueTwo; // Ok
20589a1d03eSRichard   e3 = e1 | e2;             // Ok
20689a1d03eSRichard   e3 = e1 & e2;             // Ok
20789a1d03eSRichard   e3 = e1 ^ e2;             // Ok
20889a1d03eSRichard 
20989a1d03eSRichard   OldSigned s1 = IntOne, s2 = IntTwo;
21089a1d03eSRichard   int s3;
21189a1d03eSRichard   s3 = IntOne | IntTwo; // Signed
21289a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
21389a1d03eSRichard   s3|= IntTwo; // Signed
21489a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
21589a1d03eSRichard   s3 = IntOne & IntTwo; // Signed
21689a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
21789a1d03eSRichard   s3&= IntTwo; // Signed
21889a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
21989a1d03eSRichard   s3 = IntOne ^ IntTwo; // Signed
22089a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
22189a1d03eSRichard   s3^= IntTwo; // Signed
22289a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
22389a1d03eSRichard   s3 = s1 | s2; // Signed
22489a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
22589a1d03eSRichard   s3 = s1 & s2; // Signed
22689a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
22789a1d03eSRichard   s3 = s1 ^ s2; // Signed
22889a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
22989a1d03eSRichard }
23089a1d03eSRichard 
23189a1d03eSRichard enum EnumConstruction {
23289a1d03eSRichard   one = 1,
23389a1d03eSRichard   two = 2,
23489a1d03eSRichard   test1 = 1 << 12,
23589a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
23689a1d03eSRichard   test2 = one << two,
23789a1d03eSRichard   // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
23889a1d03eSRichard   test3 = 1u << 12,
239*fa8f8616SVladimir Plyashkun   // CHECK-MESSAGES: [[@LINE-1]]:17: warning: use of a signed integer operand with a binary bitwise operator
24089a1d03eSRichard };
241