forked from OSchip/llvm-project
[clang-tidy] add missing assignment operations in hicpp-signed-bitwise
This patch resolves the bug https://bugs.llvm.org/show_bug.cgi?id=36963. - implement missing assignment operators for hicpp-signed-bitwise - mention fix in release notes Reviewers: aaron.ballman, hokein, alexfh Differential: https://reviews.llvm.org/D45414 llvm-svn: 329789
This commit is contained in:
parent
ac96d7c4b3
commit
0f5f41df93
|
@ -36,7 +36,8 @@ void SignedBitwiseCheck::registerMatchers(MatchFinder *Finder) {
|
|||
Finder->addMatcher(
|
||||
binaryOperator(
|
||||
allOf(anyOf(hasOperatorName("^"), hasOperatorName("|"),
|
||||
hasOperatorName("&")),
|
||||
hasOperatorName("&"), hasOperatorName("^="),
|
||||
hasOperatorName("|="), hasOperatorName("&=")),
|
||||
|
||||
unless(allOf(hasLHS(IsStdBitmask), hasRHS(IsStdBitmask))),
|
||||
|
||||
|
@ -48,10 +49,11 @@ void SignedBitwiseCheck::registerMatchers(MatchFinder *Finder) {
|
|||
// Shifting and complement is not allowed for any signed integer type because
|
||||
// the sign bit may corrupt the result.
|
||||
Finder->addMatcher(
|
||||
binaryOperator(allOf(anyOf(hasOperatorName("<<"), hasOperatorName(">>")),
|
||||
hasEitherOperand(SignedIntegerOperand),
|
||||
hasLHS(hasType(isInteger())),
|
||||
hasRHS(hasType(isInteger()))))
|
||||
binaryOperator(
|
||||
allOf(anyOf(hasOperatorName("<<"), hasOperatorName(">>"),
|
||||
hasOperatorName("<<="), hasOperatorName(">>=")),
|
||||
hasEitherOperand(SignedIntegerOperand),
|
||||
hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger()))))
|
||||
.bind("binary-sign-interference"),
|
||||
this);
|
||||
|
||||
|
@ -84,10 +86,8 @@ void SignedBitwiseCheck::check(const MatchFinder::MatchResult &Result) {
|
|||
else
|
||||
llvm_unreachable("unexpected matcher result");
|
||||
}
|
||||
|
||||
diag(Location,
|
||||
"use of a signed integer operand with a %select{binary|unary}0 bitwise "
|
||||
"operator")
|
||||
diag(Location, "use of a signed integer operand with a "
|
||||
"%select{binary|unary}0 bitwise operator")
|
||||
<< IsUnary << SignedOperand->getSourceRange();
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,9 @@ Improvements to clang-tidy
|
|||
<clang-tidy/checks/cppcoreguidelines-avoid-goto>`
|
||||
added.
|
||||
|
||||
- Adding the missing bitwise assignment operations to
|
||||
:doc:`hicpp-signed-bitwise <clang-tidy/checks/hicpp-signed-bitwise>`.
|
||||
|
||||
- The 'misc-forwarding-reference-overload' check was renamed to :doc:`bugprone-forwarding-reference-overload
|
||||
<clang-tidy/checks/bugprone-forwarding-reference-overload>`
|
||||
|
||||
|
|
|
@ -8,13 +8,19 @@ void pure_bitmask_types() {
|
|||
std::locale::category C = std::locale::category::ctype;
|
||||
|
||||
SResult = std::locale::category::none | std::locale::category::collate;
|
||||
SResult|= std::locale::category::collate;
|
||||
SResult = std::locale::category::ctype & std::locale::category::monetary;
|
||||
SResult&= std::locale::category::monetary;
|
||||
SResult = std::locale::category::numeric ^ std::locale::category::time;
|
||||
SResult^= std::locale::category::time;
|
||||
SResult = std::locale::category::messages | std::locale::category::all;
|
||||
|
||||
SResult = std::locale::category::all & C;
|
||||
SResult&= std::locale::category::all;
|
||||
SResult = std::locale::category::all | C;
|
||||
SResult|= std::locale::category::all;
|
||||
SResult = std::locale::category::all ^ C;
|
||||
SResult^= std::locale::category::all;
|
||||
|
||||
// std::ctype_base::mask
|
||||
std::ctype_base::mask M = std::ctype_base::mask::punct;
|
||||
|
@ -22,13 +28,13 @@ void pure_bitmask_types() {
|
|||
SResult = std::ctype_base::mask::space | std::ctype_base::mask::print;
|
||||
SResult = std::ctype_base::mask::cntrl & std::ctype_base::mask::upper;
|
||||
SResult = std::ctype_base::mask::lower ^ std::ctype_base::mask::alpha;
|
||||
SResult = std::ctype_base::mask::digit | std::ctype_base::mask::punct;
|
||||
SResult = std::ctype_base::mask::xdigit & std::ctype_base::mask::alnum;
|
||||
SResult = std::ctype_base::mask::alnum ^ std::ctype_base::mask::graph;
|
||||
SResult|= std::ctype_base::mask::digit | std::ctype_base::mask::punct;
|
||||
SResult&= std::ctype_base::mask::xdigit & std::ctype_base::mask::alnum;
|
||||
SResult^= std::ctype_base::mask::alnum ^ std::ctype_base::mask::graph;
|
||||
|
||||
SResult = std::ctype_base::mask::space & M;
|
||||
SResult = std::ctype_base::mask::space | M;
|
||||
SResult = std::ctype_base::mask::space ^ M;
|
||||
SResult&= std::ctype_base::mask::space & M;
|
||||
SResult|= std::ctype_base::mask::space | M;
|
||||
SResult^= std::ctype_base::mask::space ^ M;
|
||||
|
||||
// std::ios_base::fmtflags
|
||||
std::ios_base::fmtflags F = std::ios_base::fmtflags::floatfield;
|
||||
|
@ -36,23 +42,23 @@ void pure_bitmask_types() {
|
|||
SResult = std::ios_base::fmtflags::dec | std::ios_base::fmtflags::oct;
|
||||
SResult = std::ios_base::fmtflags::hex & std::ios_base::fmtflags::basefield;
|
||||
SResult = std::ios_base::fmtflags::left ^ std::ios_base::fmtflags::right;
|
||||
SResult = std::ios_base::fmtflags::internal | std::ios_base::fmtflags::adjustfield;
|
||||
SResult = std::ios_base::fmtflags::scientific & std::ios_base::fmtflags::fixed;
|
||||
SResult = std::ios_base::fmtflags::floatfield ^ std::ios_base::fmtflags::boolalpha;
|
||||
SResult|= std::ios_base::fmtflags::internal | std::ios_base::fmtflags::adjustfield;
|
||||
SResult&= std::ios_base::fmtflags::scientific & std::ios_base::fmtflags::fixed;
|
||||
SResult^= std::ios_base::fmtflags::floatfield ^ std::ios_base::fmtflags::boolalpha;
|
||||
SResult = std::ios_base::fmtflags::showbase | std::ios_base::fmtflags::showpoint;
|
||||
SResult = std::ios_base::fmtflags::showpos & std::ios_base::fmtflags::skipws;
|
||||
SResult = std::ios_base::fmtflags::unitbuf ^ std::ios_base::fmtflags::uppercase;
|
||||
|
||||
SResult = std::ios_base::fmtflags::unitbuf | F;
|
||||
SResult = std::ios_base::fmtflags::unitbuf & F;
|
||||
SResult = std::ios_base::fmtflags::unitbuf ^ F;
|
||||
SResult|= std::ios_base::fmtflags::unitbuf | F;
|
||||
SResult&= std::ios_base::fmtflags::unitbuf & F;
|
||||
SResult^= std::ios_base::fmtflags::unitbuf ^ F;
|
||||
|
||||
// std::ios_base::iostate
|
||||
std::ios_base::iostate S = std::ios_base::iostate::goodbit;
|
||||
|
||||
SResult = std::ios_base::iostate::goodbit | std::ios_base::iostate::badbit;
|
||||
SResult = std::ios_base::iostate::failbit & std::ios_base::iostate::eofbit;
|
||||
SResult = std::ios_base::iostate::failbit ^ std::ios_base::iostate::eofbit;
|
||||
SResult^= std::ios_base::iostate::goodbit | std::ios_base::iostate::badbit;
|
||||
SResult|= std::ios_base::iostate::failbit & std::ios_base::iostate::eofbit;
|
||||
SResult&= std::ios_base::iostate::failbit ^ std::ios_base::iostate::eofbit;
|
||||
|
||||
SResult = std::ios_base::iostate::goodbit | S;
|
||||
SResult = std::ios_base::iostate::goodbit & S;
|
||||
|
@ -65,9 +71,9 @@ void pure_bitmask_types() {
|
|||
SResult = std::ios_base::openmode::in & std::ios_base::openmode::out;
|
||||
SResult = std::ios_base::openmode::trunc ^ std::ios_base::openmode::ate;
|
||||
|
||||
SResult = std::ios_base::openmode::trunc | B;
|
||||
SResult = std::ios_base::openmode::trunc & B;
|
||||
SResult = std::ios_base::openmode::trunc ^ B;
|
||||
SResult&= std::ios_base::openmode::trunc | B;
|
||||
SResult^= std::ios_base::openmode::trunc & B;
|
||||
SResult|= std::ios_base::openmode::trunc ^ B;
|
||||
}
|
||||
|
||||
void still_forbidden() {
|
||||
|
@ -83,13 +89,20 @@ void still_forbidden() {
|
|||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
SResult = std::ctype_base::mask::lower ^ -8;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
|
||||
// Staying within the allowed standard types is ok for bitwise assignment
|
||||
// operations.
|
||||
std::ctype_base::mask var = std::ctype_base::mask::print;
|
||||
var<<= std::ctype_base::mask::upper;
|
||||
var>>= std::ctype_base::mask::upper;
|
||||
var &= std::ctype_base::mask::upper;
|
||||
var |= std::ctype_base::mask::upper;
|
||||
var ^= std::ctype_base::mask::upper;
|
||||
|
||||
UResult = std::locale::category::collate << 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::locale::category::ctype << 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::locale::category::monetary >> 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::locale::category::numeric >> 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
|
||||
|
@ -109,11 +122,8 @@ void still_forbidden() {
|
|||
UResult = std::ctype_base::mask::upper << 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ctype_base::mask::lower << 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ctype_base::mask::alpha >> 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ctype_base::mask::digit >> 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
|
||||
UResult = ~std::ctype_base::mask::punct;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
|
||||
|
@ -131,11 +141,9 @@ void still_forbidden() {
|
|||
UResult = std::ios_base::fmtflags::basefield >> 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::fmtflags::left >> 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::fmtflags::right << 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::fmtflags::internal << 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
|
||||
UResult = ~std::ios_base::fmtflags::adjustfield;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
|
||||
|
@ -153,11 +161,9 @@ void still_forbidden() {
|
|||
UResult = std::ios_base::iostate::eofbit << 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::iostate::goodbit << 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::iostate::badbit >> 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::iostate::failbit >> 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
|
||||
UResult = ~std::ios_base::iostate::eofbit;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
|
||||
|
@ -175,11 +181,9 @@ void still_forbidden() {
|
|||
UResult = std::ios_base::out >> 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::trunc >> 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::ate << 1;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UResult = std::ios_base::ate << 1u;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
|
||||
|
||||
UResult = ~std::ios_base::openmode::app;
|
||||
// CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
|
||||
|
|
|
@ -41,9 +41,12 @@ void binary_bitwise() {
|
|||
// 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]]:3: 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;
|
||||
|
@ -68,18 +71,30 @@ void binary_bitwise() {
|
|||
UByte1 = UByte1 | UByte2; // Ok
|
||||
UByte1 = UByte1 | SByte2;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UByte1|= SByte2;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:12: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UByte1^= SByte2;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:12: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UByte1>>= SByte2;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:3: 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]]:12: warning: use of a signed integer operand with a binary bitwise operator
|
||||
UByte1<<= SByte2;
|
||||
// CHECK-MESSAGES: :[[@LINE-1]]:3: 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
|
||||
|
@ -195,10 +210,16 @@ void classicEnums() {
|
|||
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
|
||||
|
|
Loading…
Reference in New Issue