// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t -- -- --target=x86_64-linux
// These could cause false positives and should not be considered.
struct StreamClass {
};
StreamClass &operator<<(StreamClass &os, unsigned int i) {
return os;
}
StreamClass &operator<<(StreamClass &os, int i) {
return os;
}
StreamClass &operator>>(StreamClass &os, unsigned int i) {
return os;
}
StreamClass &operator>>(StreamClass &os, int i) {
return os;
}
struct AnotherStream {
AnotherStream &operator<<(unsigned char c) { return *this; }
AnotherStream &operator<<(signed char c) { return *this; }
AnotherStream &operator>>(unsigned char c) { return *this; }
AnotherStream &operator>>(signed char c) { return *this; }
};
void binary_bitwise() {
int SValue = 42;
int SResult;
unsigned int UValue = 42;
unsigned int UResult;
SResult = SValue & 1;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
SResult = SValue & -1;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
SResult = SValue & SValue;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
UResult = SValue & 1;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
UResult = SValue & -1;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
UResult&= 1;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
UResult = UValue & 1u; // Ok
UResult = UValue & UValue; // Ok
UResult&= 2u; // Ok
unsigned char UByte1 = 0u;
unsigned char UByte2 = 16u;
signed char SByte1 = 0;
signed char SByte2 = 16;
UByte1 = UByte1 & UByte2; // Ok
UByte1 = SByte1 & UByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
UByte1 = SByte1 & SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
SByte1 = SByte1 & SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
// More complex expressions.
UResult = UValue & (SByte1 + (SByte1 | SByte2));
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
// CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator
// The rest is to demonstrate functionality but all operators are matched equally.
// Therefore functionality is the same for all binary operations.
UByte1 = UByte1 | UByte2; // Ok
UByte1 = UByte1 | SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use of a signed integer operand with a binary bitwise operator
UByte1|= SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
UByte1|= UByte2; // Ok
UByte1 = UByte1 ^ UByte2; // Ok
UByte1 = UByte1 ^ SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use of a signed integer operand with a binary bitwise operator
UByte1^= SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
UByte1^= UByte2; // Ok
UByte1 = UByte1 >> UByte2; // Ok
UByte1 = UByte1 >> SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
UByte1>>= SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
UByte1>>= UByte2; // Ok
UByte1 = UByte1 << UByte2; // Ok
UByte1 = UByte1 << SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use of a signed integer operand with a binary bitwise operator
UByte1<<= SByte2;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
UByte1<<= UByte2; // Ok
int SignedInt1 = 1 << 12;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
int SignedInt2 = 1u << 12;
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: use of a signed integer operand with a binary bitwise operator
}
void f1(unsigned char c) {}
void f2(signed char c) {}
void f3(int c) {}
void unary_bitwise() {
unsigned char UByte1 = 0u;
signed char SByte1 = 0;
UByte1 = ~UByte1; // Ok
SByte1 = ~UByte1;
SByte1 = ~SByte1;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
UByte1 = ~SByte1;
// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
unsigned int UInt = 0u;
int SInt = 0;
f1(~UByte1); // Ok
f1(~SByte1);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
f1(~UInt);
f1(~SInt);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
f2(~UByte1);
f2(~SByte1);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
f2(~UInt);
f2(~SInt);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
f3(~UByte1); // Ok
f3(~SByte1);
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
}
/// HICPP uses these examples to demonstrate the rule.
void standard_examples() {
int i = 3;
unsigned int k = 0u;
int r = i << -1; // Emits -Wshift-count-negative from clang
// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
r = i << 1;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
r = -1 >> -1; // Emits -Wshift-count-negative from clang
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
r = -1 >> 1;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
r = -1 >> i;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
r = -1 >> -i;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
r = ~0;
// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use of a signed integer operand with a unary bitwise operator
r = ~0u; // Ok
k = ~k; // Ok
unsigned int u = (-1) & 2u;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
u = (-1) | 1u;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
u = (-1) ^ 1u;
// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
}
void streams_should_work() {
StreamClass s;
s << 1u; // Ok
s << 1; // Ok
s >> 1; // Ok
s >> 1u; // Ok
AnotherStream as;
unsigned char uc = 1u;
signed char sc = 1;
as << uc; // Ok
as << sc; // Ok
as >> uc; // Ok
as >> sc; // Ok
}
enum OldEnum {
ValueOne,
ValueTwo,
};
enum OldSigned : int {
IntOne,
IntTwo,
};
void classicEnums() {
OldEnum e1 = ValueOne, e2 = ValueTwo;
int e3; // Using the enum type, results in an error.
e3 = ValueOne | ValueTwo; // Ok
e3 = ValueOne & ValueTwo; // Ok
e3 = ValueOne ^ ValueTwo; // Ok
e3 = e1 | e2; // Ok
e3 = e1 & e2; // Ok
e3 = e1 ^ e2; // Ok
OldSigned s1 = IntOne, s2 = IntTwo;
int s3;
s3 = IntOne | IntTwo; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
s3|= IntTwo; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
s3 = IntOne & IntTwo; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
s3&= IntTwo; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
s3 = IntOne ^ IntTwo; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
s3^= IntTwo; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
s3 = s1 | s2; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
s3 = s1 & s2; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
s3 = s1 ^ s2; // Signed
// CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
}
enum EnumConstruction {
one = 1,
two = 2,
test1 = 1 << 12,
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
test2 = one << two,
// CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
test3 = 1u << 12,
// CHECK-MESSAGES: [[@LINE-1]]:17: warning: use of a signed integer operand with a binary bitwise operator
};