[clang] [analyzer] Loop should contain CXXForRangeStmt (PR #70190)

Qizhi Hu via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 25 03:20:11 PDT 2023


https://github.com/jcsxky created https://github.com/llvm/llvm-project/pull/70190

Static analyze can't report diagnose when statement after a CXXForRangeStmt and enable widen, because `ExprEngine::processCFGBlockEntrance` lacks of CXXForRangeStmt and when `AMgr.options.maxBlockVisitOnPath - 1` equals to `blockCount`, it can't widen. After next iteration, `BlockCount >= AMgr.options.maxBlockVisitOnPath` holds and generate a sink node. Add `CXXForRangeStmt` makes it work.

>From dcd607df487ea04d2f1b6be9621b6a35ac7c2900 Mon Sep 17 00:00:00 2001
From: huqizhi <huqizhi at feysh.com>
Date: Wed, 25 Oct 2023 18:13:21 +0800
Subject: [PATCH] [analyzer] Loop should contain CXXForRangeStmt

---
 clang/lib/StaticAnalyzer/Core/ExprEngine.cpp   |  2 +-
 clang/lib/StaticAnalyzer/Core/LoopWidening.cpp |  7 +++++--
 clang/test/Analysis/loop-widening-notes.cpp    | 12 ++++++++++++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 451ee91b94533d5..2e67fb953e45611 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2509,7 +2509,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
   if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
       AMgr.options.ShouldWidenLoops) {
     const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminatorStmt();
-    if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt>(Term))
+    if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
       return;
     // Widen.
     const LocationContext *LCtx = Pred->getLocationContext();
diff --git a/clang/lib/StaticAnalyzer/Core/LoopWidening.cpp b/clang/lib/StaticAnalyzer/Core/LoopWidening.cpp
index a3b29ff487e4edc..180c50cf3e0d20f 100644
--- a/clang/lib/StaticAnalyzer/Core/LoopWidening.cpp
+++ b/clang/lib/StaticAnalyzer/Core/LoopWidening.cpp
@@ -13,10 +13,11 @@
 ///
 //===----------------------------------------------------------------------===//
 
+#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
 #include "clang/AST/AST.h"
+#include "clang/AST/StmtCXX.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
 
 using namespace clang;
 using namespace ento;
@@ -35,6 +36,8 @@ static const Expr *getLoopCondition(const Stmt *LoopStmt) {
     return cast<WhileStmt>(LoopStmt)->getCond();
   case Stmt::DoStmtClass:
     return cast<DoStmt>(LoopStmt)->getCond();
+  case Stmt::CXXForRangeStmtClass:
+    return cast<CXXForRangeStmt>(LoopStmt)->getCond();
   }
 }
 
@@ -45,7 +48,7 @@ ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState,
                                     const LocationContext *LCtx,
                                     unsigned BlockCount, const Stmt *LoopStmt) {
 
-  assert((isa<ForStmt, WhileStmt, DoStmt>(LoopStmt)));
+  assert((isa<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(LoopStmt)));
 
   // Invalidate values in the current state.
   // TODO Make this more conservative by only invalidating values that might
diff --git a/clang/test/Analysis/loop-widening-notes.cpp b/clang/test/Analysis/loop-widening-notes.cpp
index 0ba71d030d058a6..a3f030dfe988261 100644
--- a/clang/test/Analysis/loop-widening-notes.cpp
+++ b/clang/test/Analysis/loop-widening-notes.cpp
@@ -70,3 +70,15 @@ int test_for_loop() {
   return flag_d / num; // no-crash expected-warning {{Division by zero}} 
                        // expected-note at -1 {{Division by zero}}
 }
+
+int test_for_range_loop() {
+  int arr[10] = {0};
+  for(auto x : arr) { // expected-note {{Assigning value}} 
+    ++x;
+  }
+  if (arr[0] == 0)   // expected-note {{Assuming the condition is true}} 
+                     // expected-note at -1 {{Taking true branch}}
+    return 1/arr[0]; // expected-warning {{Division by zero}}
+                     // expected-note at -1 {{Division by zero}}
+  return 0;
+}



More information about the cfe-commits mailing list