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