Skip to content

Commit 1b6b4d6

Browse files
authored
[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 <[email protected]>
1 parent 6282b74 commit 1b6b4d6

File tree

3 files changed

+16
-2
lines changed

3 files changed

+16
-2
lines changed

clang/lib/StaticAnalyzer/Core/ExprEngine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2509,7 +2509,7 @@ void ExprEngine::processCFGBlockEntrance(const BlockEdge &L,
25092509
if (BlockCount == AMgr.options.maxBlockVisitOnPath - 1 &&
25102510
AMgr.options.ShouldWidenLoops) {
25112511
const Stmt *Term = nodeBuilder.getContext().getBlock()->getTerminatorStmt();
2512-
if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt>(Term))
2512+
if (!isa_and_nonnull<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(Term))
25132513
return;
25142514
// Widen.
25152515
const LocationContext *LCtx = Pred->getLocationContext();

clang/lib/StaticAnalyzer/Core/LoopWidening.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ static const Expr *getLoopCondition(const Stmt *LoopStmt) {
3535
return cast<WhileStmt>(LoopStmt)->getCond();
3636
case Stmt::DoStmtClass:
3737
return cast<DoStmt>(LoopStmt)->getCond();
38+
case Stmt::CXXForRangeStmtClass:
39+
return cast<CXXForRangeStmt>(LoopStmt)->getCond();
3840
}
3941
}
4042

@@ -45,7 +47,7 @@ ProgramStateRef getWidenedLoopState(ProgramStateRef PrevState,
4547
const LocationContext *LCtx,
4648
unsigned BlockCount, const Stmt *LoopStmt) {
4749

48-
assert((isa<ForStmt, WhileStmt, DoStmt>(LoopStmt)));
50+
assert((isa<ForStmt, WhileStmt, DoStmt, CXXForRangeStmt>(LoopStmt)));
4951

5052
// Invalidate values in the current state.
5153
// TODO Make this more conservative by only invalidating values that might

clang/test/Analysis/loop-widening-notes.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,15 @@ int test_for_loop() {
7070
return flag_d / num; // no-crash expected-warning {{Division by zero}}
7171
// expected-note@-1 {{Division by zero}}
7272
}
73+
74+
int test_for_range_loop() {
75+
int arr[10] = {0};
76+
for(auto x : arr) { // expected-note {{Assigning value}}
77+
++x;
78+
}
79+
if (arr[0] == 0) // expected-note {{Assuming the condition is true}}
80+
// expected-note@-1 {{Taking true branch}}
81+
return 1/arr[0]; // expected-warning {{Division by zero}}
82+
// expected-note@-1 {{Division by zero}}
83+
return 0;
84+
}

0 commit comments

Comments
 (0)