New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[analyzer] Loop should contain CXXForRangeStmt #70190
Conversation
@llvm/pr-subscribers-clang-static-analyzer-1 @llvm/pr-subscribers-clang Author: Qizhi Hu (jcsxky) ChangesStatic analyze can't report diagnose when statement after a CXXForRangeStmt and enable widen, because Full diff: https://github.com/llvm/llvm-project/pull/70190.diff 3 Files Affected:
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@-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@-1 {{Taking true branch}}
+ return 1/arr[0]; // expected-warning {{Division by zero}}
+ // expected-note@-1 {{Division by zero}}
+ return 0;
+}
|
dcd607d
to
f65ad22
Compare
f65ad22
to
b1b49db
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks
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@qq.com>
Static analyze can't report diagnose when statement after a CXXForRangeStmt and enable widen, because
ExprEngine::processCFGBlockEntrance
lacks of CXXForRangeStmt and whenAMgr.options.maxBlockVisitOnPath - 1
equals toblockCount
, it can't widen. After next iteration,BlockCount >= AMgr.options.maxBlockVisitOnPath
holds and generate a sink node. AddCXXForRangeStmt
makes it work.