[clang] 1b6b4d6 - [analyzer] Loop should contain CXXForRangeStmt (#70190)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 26 06:11:55 PDT 2023
Author: Qizhi Hu
Date: 2023-10-26T21:11:51+08:00
New Revision: 1b6b4d6a08321fb914127dadcd6677dcd9b1b222
URL: https://github.com/llvm/llvm-project/commit/1b6b4d6a08321fb914127dadcd6677dcd9b1b222
DIFF: https://github.com/llvm/llvm-project/commit/1b6b4d6a08321fb914127dadcd6677dcd9b1b222.diff
LOG: [analyzer] Loop should contain CXXForRangeStmt (#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.
Co-authored-by: huqizhi <836744285 at qq.com>
Added:
Modified:
clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
clang/lib/StaticAnalyzer/Core/LoopWidening.cpp
clang/test/Analysis/loop-widening-notes.cpp
Removed:
################################################################################
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..9e42801760622df 100644
--- a/clang/lib/StaticAnalyzer/Core/LoopWidening.cpp
+++ b/clang/lib/StaticAnalyzer/Core/LoopWidening.cpp
@@ -35,6 +35,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 +47,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