https://github.com/malavikasamak updated 
https://github.com/llvm/llvm-project/pull/143205

>From 52e4413ea1e701dfe0b24cf957a26bb72732f066 Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavi...@apple.com>
Date: Wed, 21 May 2025 16:06:44 -0700
Subject: [PATCH 1/2] Place holder message for sizeof operator in loops.

---
 .../bugprone/SizeofExpressionCheck.cpp        | 17 +++++++++-
 .../bugprone/SizeofExpressionCheck.h          |  1 +
 .../checkers/bugprone/sizeof-expression.cpp   | 31 +++++++++++++++++++
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index f3d4c2255d86e..ee66a880792b8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -72,7 +72,8 @@ SizeofExpressionCheck::SizeofExpressionCheck(StringRef Name,
           Options.get("WarnOnSizeOfPointerToAggregate", true)),
       WarnOnSizeOfPointer(Options.get("WarnOnSizeOfPointer", false)),
       WarnOnOffsetDividedBySizeOf(
-          Options.get("WarnOnOffsetDividedBySizeOf", true)) {}
+          Options.get("WarnOnOffsetDividedBySizeOf", true)),
+      WarnOnLoopExprSizeOf(Options.get("WarnOnLoopExprSizeOf", true)) {}
 
 void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "WarnOnSizeOfConstant", WarnOnSizeOfConstant);
@@ -86,6 +87,7 @@ void 
SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "WarnOnSizeOfPointer", WarnOnSizeOfPointer);
   Options.store(Opts, "WarnOnOffsetDividedBySizeOf",
                 WarnOnOffsetDividedBySizeOf);
+  Options.store(Opts, "WarnOnLoopExprSizeOf", WarnOnLoopExprSizeOf);
 }
 
 void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
@@ -93,6 +95,11 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
   // Some of the checks should not match in template code to avoid false
   // positives if sizeof is applied on template argument.
 
+  auto LoopExpr =
+      [](const ast_matchers::internal::Matcher<Stmt> &InnerMatcher) {
+        return stmt(anyOf(forStmt(InnerMatcher), whileStmt(InnerMatcher)));
+      };
+
   const auto IntegerExpr = ignoringParenImpCasts(integerLiteral());
   const auto ConstantExpr = ignoringParenImpCasts(
       anyOf(integerLiteral(), unaryOperator(hasUnaryOperand(IntegerExpr)),
@@ -130,6 +137,11 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
                        this);
   }
 
+  if (WarnOnLoopExprSizeOf) {
+    Finder->addMatcher(
+        LoopExpr(has(binaryOperator(has(SizeOfExpr)))).bind("loop-expr"), 
this);
+  }
+
   // Detect sizeof(kPtr) where kPtr is 'const char* kPtr = "abc"';
   const auto CharPtrType = pointerType(pointee(isAnyCharacter()));
   const auto ConstStrLiteralDecl =
@@ -353,6 +365,9 @@ void SizeofExpressionCheck::check(const 
MatchFinder::MatchResult &Result) {
     diag(E->getBeginLoc(),
          "suspicious usage of 'sizeof(char*)'; do you mean 'strlen'?")
         << E->getSourceRange();
+  } else if (const auto *E = Result.Nodes.getNodeAs<Stmt>("loop-expr")) {
+    diag(E->getBeginLoc(), "suspicious usage of 'sizeof' in the loop")
+        << E->getSourceRange();
   } else if (const auto *E = Result.Nodes.getNodeAs<Expr>("sizeof-pointer")) {
     if (Result.Nodes.getNodeAs<Type>("struct-type")) {
       diag(E->getBeginLoc(),
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h 
b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h
index fbd62cb80fb2d..f7dccf39687a5 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h
@@ -32,6 +32,7 @@ class SizeofExpressionCheck : public ClangTidyCheck {
   const bool WarnOnSizeOfPointerToAggregate;
   const bool WarnOnSizeOfPointer;
   const bool WarnOnOffsetDividedBySizeOf;
+  const bool WarnOnLoopExprSizeOf;
 };
 
 } // namespace clang::tidy::bugprone
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp
index 5e6f394152e9d..52b71277466b1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp
@@ -164,6 +164,37 @@ int Test2(MyConstChar* A) {
   return sum;
 }
 
+struct A {
+   int array[10];
+};
+
+struct B {
+  struct A a;
+};
+
+int square(int num, struct B b) {
+    struct A arr[10];
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' 
in the loop [bugprone-sizeof-expression]
+    for(int i = 0; i < sizeof(arr); i++) {
+       struct A a = arr[i];
+    }
+    // CHECK-MESSAGES: :[[@LINE+2]]:24: warning: suspicious usage of 
'sizeof(K)'; did you mean 'K'? [bugprone-sizeof-expression]
+    // CHECK-MESSAGES: :[[@LINE+1]]:34: warning: suspicious usage of 
'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator 
[bugprone-sizeof-expression] 
+    for(int i = 0; i < sizeof(10)/sizeof(A); i++) {
+       struct A a = arr[i];
+    }
+    
+    for(int i = 0; i < sizeof(arr)/sizeof(A); i++) {
+       struct A a = arr[i];
+    }
+
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' 
in the loop [bugprone-sizeof-expression]
+    for(int j = 0; j < sizeof(b.a); j++) {
+
+    }
+    return 2;
+}
+
 template <int T>
 int Foo() { int A[T]; return sizeof(T); }
 // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)'

>From b7677bbd0f6f687ac4c96614d22b3af74e11a601 Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavi...@apple.com>
Date: Fri, 6 Jun 2025 14:07:58 -0700
Subject: [PATCH 2/2] Add documentation for the newly introduced CheckOption
 for loop.

---
 .../clang-tidy/bugprone/SizeofExpressionCheck.cpp         | 8 ++++----
 .../clang-tidy/bugprone/SizeofExpressionCheck.h           | 2 +-
 .../docs/clang-tidy/checks/bugprone/sizeof-expression.rst | 8 ++++++++
 .../clang-tidy/checkers/bugprone/sizeof-expression.cpp    | 4 ++--
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index ee66a880792b8..6a0ecf6b1c460 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -73,7 +73,7 @@ SizeofExpressionCheck::SizeofExpressionCheck(StringRef Name,
       WarnOnSizeOfPointer(Options.get("WarnOnSizeOfPointer", false)),
       WarnOnOffsetDividedBySizeOf(
           Options.get("WarnOnOffsetDividedBySizeOf", true)),
-      WarnOnLoopExprSizeOf(Options.get("WarnOnLoopExprSizeOf", true)) {}
+      
WarnOnSizeOfInLoopTermination(Options.get("WarnOnSizeOfInLoopTermination", 
true)) {}
 
 void SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "WarnOnSizeOfConstant", WarnOnSizeOfConstant);
@@ -87,7 +87,7 @@ void 
SizeofExpressionCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "WarnOnSizeOfPointer", WarnOnSizeOfPointer);
   Options.store(Opts, "WarnOnOffsetDividedBySizeOf",
                 WarnOnOffsetDividedBySizeOf);
-  Options.store(Opts, "WarnOnLoopExprSizeOf", WarnOnLoopExprSizeOf);
+  Options.store(Opts, "WarnOnSizeOfInLoopTermination", 
WarnOnSizeOfInLoopTermination);
 }
 
 void SizeofExpressionCheck::registerMatchers(MatchFinder *Finder) {
@@ -137,9 +137,9 @@ void SizeofExpressionCheck::registerMatchers(MatchFinder 
*Finder) {
                        this);
   }
 
-  if (WarnOnLoopExprSizeOf) {
+  if (WarnOnSizeOfInLoopTermination) {
     Finder->addMatcher(
-        LoopExpr(has(binaryOperator(has(SizeOfExpr)))).bind("loop-expr"), 
this);
+        LoopExpr(has(binaryOperator(has(SizeOfExpr.bind("loop-expr"))))), 
this);
   }
 
   // Detect sizeof(kPtr) where kPtr is 'const char* kPtr = "abc"';
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h 
b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h
index f7dccf39687a5..e979b4723cf2e 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.h
@@ -32,7 +32,7 @@ class SizeofExpressionCheck : public ClangTidyCheck {
   const bool WarnOnSizeOfPointerToAggregate;
   const bool WarnOnSizeOfPointer;
   const bool WarnOnOffsetDividedBySizeOf;
-  const bool WarnOnLoopExprSizeOf;
+  const bool WarnOnSizeOfInLoopTermination;
 };
 
 } // namespace clang::tidy::bugprone
diff --git 
a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst 
b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst
index 29edb26ed7aa2..68340f04489fb 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/sizeof-expression.rst
@@ -316,3 +316,11 @@ Options
    When `true`, the check will warn on pointer arithmetic where the
    element count is obtained from a division with ``sizeof(...)``,
    e.g., ``Ptr + Bytes / sizeof(*T)``. Default is `true`.
+
+.. option:: WarnOnSizeOfInLoopTermination
+
+   When `true`, the check will warn about incorrect use of sizeof expression
+   in loop termination condition. The warning triggers if the sizeof expression
+   appears to be incorrectly used to determine the number of array/buffer 
elements.
+   e.g, ``long arr[10]; for(int i = 0; i < sizeof(arr); i++) { ... }. Default
+  is `true`.
diff --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp
index 52b71277466b1..82d1fba11872c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/sizeof-expression.cpp
@@ -174,7 +174,7 @@ struct B {
 
 int square(int num, struct B b) {
     struct A arr[10];
-    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' 
in the loop [bugprone-sizeof-expression]
+    // CHECK-MESSAGES: :[[@LINE+1]]:24: warning: suspicious usage of 'sizeof' 
in the loop [bugprone-sizeof-expression]
     for(int i = 0; i < sizeof(arr); i++) {
        struct A a = arr[i];
     }
@@ -188,7 +188,7 @@ int square(int num, struct B b) {
        struct A a = arr[i];
     }
 
-    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious usage of 'sizeof' 
in the loop [bugprone-sizeof-expression]
+    // CHECK-MESSAGES: :[[@LINE+1]]:24: warning: suspicious usage of 'sizeof' 
in the loop [bugprone-sizeof-expression]
     for(int j = 0; j < sizeof(b.a); j++) {
 
     }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to