This revision was automatically updated to reflect the committed changes.
Closed by commit rG030ff901f432: [clang-tidy] extend 
bugprone-signed-char-misuse check with array subscript case. (authored by 
ztamas).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78904/new/

https://reviews.llvm.org/D78904

Files:
  clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
  clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst
  clang-tools-extra/test/clang-tidy/checkers/bugprone-signed-char-misuse.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/bugprone-signed-char-misuse.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/bugprone-signed-char-misuse.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/bugprone-signed-char-misuse.cpp
@@ -3,6 +3,16 @@
 ///////////////////////////////////////////////////////////////////
 /// Test cases correctly caught by the check.
 
+typedef __SIZE_TYPE__ size_t;
+
+namespace std {
+template <typename T, size_t N>
+struct array {
+  T &operator[](size_t n);
+  T &at(size_t n);
+};
+} // namespace std
+
 int SimpleVarDeclaration() {
   signed char CCharacter = -5;
   int NCharacter = CCharacter;
@@ -90,6 +100,16 @@
   return 0;
 }
 
+int SignedCharCArraySubscript(signed char SCharacter) {
+  int Array[3] = {1, 2, 3};
+
+  return Array[static_cast<unsigned int>(SCharacter)]; // CHECK-MESSAGES: [[@LINE]]:42: warning: 'signed char' to 'unsigned int' conversion in array subscript; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
+}
+
+int SignedCharSTDArraySubscript(std::array<int, 3> Array, signed char SCharacter) {
+  return Array[static_cast<unsigned int>(SCharacter)]; // CHECK-MESSAGES: [[@LINE]]:42: warning: 'signed char' to 'unsigned int' conversion in array subscript; consider casting to 'unsigned char' first. [bugprone-signed-char-misuse]
+}
+
 ///////////////////////////////////////////////////////////////////
 /// Test cases correctly ignored by the check.
 
@@ -207,3 +227,23 @@
     return 1;
   return 0;
 }
+
+int UnsignedCharCArraySubscript(unsigned char USCharacter) {
+  int Array[3] = {1, 2, 3};
+
+  return Array[static_cast<unsigned int>(USCharacter)];
+}
+
+int CastedCArraySubscript(signed char SCharacter) {
+  int Array[3] = {1, 2, 3};
+
+  return Array[static_cast<unsigned char>(SCharacter)];
+}
+
+int UnsignedCharSTDArraySubscript(std::array<int, 3> Array, unsigned char USCharacter) {
+  return Array[static_cast<unsigned int>(USCharacter)];
+}
+
+int CastedSTDArraySubscript(std::array<int, 3> Array, signed char SCharacter) {
+  return Array[static_cast<unsigned char>(SCharacter)];
+}
Index: clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst
===================================================================
--- clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst
+++ clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst
@@ -31,11 +31,10 @@
 by default and so it is caught by this check or not. To change the default behavior
 you can use ``-funsigned-char`` and ``-fsigned-char`` compilation options.
 
-Currently, this check is limited to assignments and variable declarations,
-where a ``signed char`` is assigned to an integer variable and to
-equality/inequality comparisons between ``signed char`` and ``unsigned char``.
-There are other use cases where the unexpected value ranges might lead to
-similar bogus behavior.
+Currently, this check warns in the following cases:
+- ``signed char`` is assigned to an integer variable
+- ``signed char`` and ``unsigned char`` are compared with equality/inequality operator
+- ``signed char`` is converted to an integer in the array subscript
 
 See also:
 `STR34-C. Cast characters to unsigned char before converting to larger integer sizes
Index: clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp
@@ -102,11 +102,31 @@
           .bind("comparison");
 
   Finder->addMatcher(CompareOperator, this);
+
+  // Catch array subscripts with signed char -> integer conversion.
+  // Matcher for C arrays.
+  const auto CArraySubscript =
+      arraySubscriptExpr(hasIndex(SignedCharCastExpr)).bind("arraySubscript");
+
+  Finder->addMatcher(CArraySubscript, this);
+
+  // Matcher for std arrays.
+  const auto STDArraySubscript =
+      cxxOperatorCallExpr(
+          hasOverloadedOperatorName("[]"),
+          hasArgument(0, hasType(cxxRecordDecl(hasName("::std::array")))),
+          hasArgument(1, SignedCharCastExpr))
+          .bind("arraySubscript");
+
+  Finder->addMatcher(STDArraySubscript, this);
 }
 
 void SignedCharMisuseCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *SignedCastExpression =
       Result.Nodes.getNodeAs<ImplicitCastExpr>("signedCastExpression");
+  const auto *IntegerType = Result.Nodes.getNodeAs<QualType>("integerType");
+  assert(SignedCastExpression);
+  assert(IntegerType);
 
   // Ignore the match if we know that the signed char's value is not negative.
   // The potential misinterpretation happens for negative values only.
@@ -135,14 +155,17 @@
 
     diag(Comparison->getBeginLoc(),
          "comparison between 'signed char' and 'unsigned char'");
-  } else if (const auto *IntegerType =
-                 Result.Nodes.getNodeAs<QualType>("integerType")) {
+  } else if (Result.Nodes.getNodeAs<Expr>("arraySubscript")) {
+    diag(SignedCastExpression->getBeginLoc(),
+         "'signed char' to %0 conversion in array subscript; "
+         "consider casting to 'unsigned char' first.")
+        << *IntegerType;
+  } else {
     diag(SignedCastExpression->getBeginLoc(),
          "'signed char' to %0 conversion; "
          "consider casting to 'unsigned char' first.")
         << *IntegerType;
-  } else
-    llvm_unreachable("Unexpected match");
+  }
 }
 
 } // namespace bugprone
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to