JonasToth updated this revision to Diff 141547.
JonasToth added a comment.

- fix std bitmask type shifting issue


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D45414

Files:
  clang-tidy/hicpp/SignedBitwiseCheck.cpp
  docs/ReleaseNotes.rst
  test/clang-tidy/hicpp-signed-bitwise-standard-types.cpp
  test/clang-tidy/hicpp-signed-bitwise.cpp

Index: test/clang-tidy/hicpp-signed-bitwise.cpp
===================================================================
--- test/clang-tidy/hicpp-signed-bitwise.cpp
+++ test/clang-tidy/hicpp-signed-bitwise.cpp
@@ -41,9 +41,12 @@
   // 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 @@
   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 @@
   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
Index: test/clang-tidy/hicpp-signed-bitwise-standard-types.cpp
===================================================================
--- test/clang-tidy/hicpp-signed-bitwise-standard-types.cpp
+++ test/clang-tidy/hicpp-signed-bitwise-standard-types.cpp
@@ -8,51 +8,57 @@
   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;
 
   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;
 
   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 @@
   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,24 @@
   // 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;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: shifting a value of the standardized bitmask types
+  var>>= std::ctype_base::mask::upper;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: shifting a value of the standardized bitmask types
+  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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
   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 +126,11 @@
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
   UResult = std::ctype_base::mask::alpha >> 1u;
-  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
   UResult = std::ctype_base::mask::digit >> 1u;
-  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
 
   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 +148,11 @@
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
 
   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 +170,11 @@
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
 
   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 +192,11 @@
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
   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
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: shifting a value of the standardized bitmask types
 
   UResult = ~std::ios_base::openmode::app;
   // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
Index: docs/ReleaseNotes.rst
===================================================================
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -140,6 +140,9 @@
   <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>`
 
Index: clang-tidy/hicpp/SignedBitwiseCheck.cpp
===================================================================
--- clang-tidy/hicpp/SignedBitwiseCheck.cpp
+++ clang-tidy/hicpp/SignedBitwiseCheck.cpp
@@ -36,7 +36,8 @@
   Finder->addMatcher(
       binaryOperator(
           allOf(anyOf(hasOperatorName("^"), hasOperatorName("|"),
-                      hasOperatorName("&")),
+                      hasOperatorName("&"), hasOperatorName("^="),
+                      hasOperatorName("|="), hasOperatorName("&=")),
 
                 unless(allOf(hasLHS(IsStdBitmask), hasRHS(IsStdBitmask))),
 
@@ -48,10 +49,12 @@
   // 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(">>=")),
+                anyOf(hasEitherOperand(SignedIntegerOperand),
+                      hasEitherOperand(hasType(BitmaskType.bind("std_type")))),
+                hasLHS(hasType(isInteger())), hasRHS(hasType(isInteger()))))
           .bind("binary-sign-interference"),
       this);
 
@@ -85,10 +88,12 @@
       llvm_unreachable("unexpected matcher result");
   }
 
-  diag(Location,
-       "use of a signed integer operand with a %select{binary|unary}0 bitwise "
-       "operator")
-      << IsUnary << SignedOperand->getSourceRange();
+  if (N.getNodeAs<NamedDecl>("std_type"))
+    diag(Location, "shifting a value of the standardized bitmask types");
+  else
+    diag(Location, "use of a signed integer operand with a "
+                   "%select{binary|unary}0 bitwise operator")
+        << IsUnary << SignedOperand->getSourceRange();
 }
 
 } // namespace hicpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to