r311344 - [StaticAnalyzer] Handle LoopExit CFGElement in the analyzer
Peter Szecsi via cfe-commits
cfe-commits at lists.llvm.org
Mon Aug 21 09:10:20 PDT 2017
Author: szepet
Date: Mon Aug 21 09:10:19 2017
New Revision: 311344
URL: http://llvm.org/viewvc/llvm-project?rev=311344&view=rev
Log:
[StaticAnalyzer] Handle LoopExit CFGElement in the analyzer
This patch adds handling of the LoopExit CFGElements to the StaticAnalyzer.
This is reached by introducing a new ProgramPoint.
Tests will be added in a following commit.
Differential Revision: https://reviews.llvm.org/D35670
Modified:
cfe/trunk/include/clang/Analysis/ProgramPoint.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
Modified: cfe/trunk/include/clang/Analysis/ProgramPoint.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ProgramPoint.h?rev=311344&r1=311343&r2=311344&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/ProgramPoint.h (original)
+++ cfe/trunk/include/clang/Analysis/ProgramPoint.h Mon Aug 21 09:10:19 2017
@@ -83,6 +83,7 @@ public:
PostImplicitCallKind,
MinImplicitCallKind = PreImplicitCallKind,
MaxImplicitCallKind = PostImplicitCallKind,
+ LoopExitKind,
EpsilonKind};
private:
@@ -654,6 +655,29 @@ private:
}
};
+/// Represents a point when we exit a loop.
+/// When this ProgramPoint is encountered we can be sure that the symbolic
+/// execution of the corresponding LoopStmt is finished on the given path.
+/// Note: It is possible to encounter a LoopExit element when we haven't even
+/// encountered the loop itself. At the current state not all loop exits will
+/// result in a LoopExit program point.
+class LoopExit : public ProgramPoint {
+public:
+ LoopExit(const Stmt *LoopStmt, const LocationContext *LC)
+ : ProgramPoint(LoopStmt, nullptr, LoopExitKind, LC) {}
+
+ const Stmt *getLoopStmt() const {
+ return static_cast<const Stmt *>(getData1());
+ }
+
+private:
+ friend class ProgramPoint;
+ LoopExit() {}
+ static bool isKind(const ProgramPoint &Location) {
+ return Location.getKind() == LoopExitKind;
+ }
+};
+
/// This is a meta program point, which should be skipped by all the diagnostic
/// reasoning etc.
class EpsilonPoint : public ProgramPoint {
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=311344&r1=311343&r2=311344&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Mon Aug 21 09:10:19 2017
@@ -196,6 +196,8 @@ public:
void ProcessStmt(const CFGStmt S, ExplodedNode *Pred);
+ void ProcessLoopExit(const Stmt* S, ExplodedNode *Pred);
+
void ProcessInitializer(const CFGInitializer I, ExplodedNode *Pred);
void ProcessImplicitDtor(const CFGImplicitDtor D, ExplodedNode *Pred);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp?rev=311344&r1=311343&r2=311344&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CoreEngine.cpp Mon Aug 21 09:10:19 2017
@@ -274,7 +274,8 @@ void CoreEngine::dispatchWorkItem(Explod
assert(Loc.getAs<PostStmt>() ||
Loc.getAs<PostInitializer>() ||
Loc.getAs<PostImplicitCall>() ||
- Loc.getAs<CallExitEnd>());
+ Loc.getAs<CallExitEnd>() ||
+ Loc.getAs<LoopExit>());
HandlePostStmt(WU.getBlock(), WU.getIndex(), Pred);
break;
}
@@ -566,7 +567,8 @@ void CoreEngine::enqueueStmtNode(Explode
// Do not create extra nodes. Move to the next CFG element.
if (N->getLocation().getAs<PostInitializer>() ||
- N->getLocation().getAs<PostImplicitCall>()) {
+ N->getLocation().getAs<PostImplicitCall>()||
+ N->getLocation().getAs<LoopExit>()) {
WList->enqueue(N, Block, Idx+1);
return;
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=311344&r1=311343&r2=311344&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Mon Aug 21 09:10:19 2017
@@ -364,8 +364,10 @@ void ExprEngine::processCFGElement(const
case CFGElement::TemporaryDtor:
ProcessImplicitDtor(E.castAs<CFGImplicitDtor>(), Pred);
return;
- case CFGElement::LifetimeEnds:
case CFGElement::LoopExit:
+ ProcessLoopExit(E.castAs<CFGLoopExit>().getLoopStmt(), Pred);
+ return;
+ case CFGElement::LifetimeEnds:
return;
}
}
@@ -510,6 +512,21 @@ void ExprEngine::ProcessStmt(const CFGSt
Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
}
+void ExprEngine::ProcessLoopExit(const Stmt* S, ExplodedNode *Pred) {
+ PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),
+ S->getLocStart(),
+ "Error evaluating end of the loop");
+ ExplodedNodeSet Dst;
+ Dst.Add(Pred);
+ NodeBuilder Bldr(Pred, Dst, *currBldrCtx);
+
+ LoopExit PP(S, Pred->getLocationContext());
+ Bldr.generateNode(PP, Pred->getState(), Pred);
+
+ // Enqueue the new nodes onto the work list.
+ Engine.enqueue(Dst, currBldrCtx->getBlock(), currStmtIdx);
+}
+
void ExprEngine::ProcessInitializer(const CFGInitializer Init,
ExplodedNode *Pred) {
const CXXCtorInitializer *BMI = Init.getInitializer();
@@ -2689,6 +2706,12 @@ struct DOTGraphTraits<ExplodedNode*> :
Out << "Epsilon Point";
break;
+ case ProgramPoint::LoopExitKind: {
+ LoopExit LE = Loc.castAs<LoopExit>();
+ Out << "LoopExit: " << LE.getLoopStmt()->getStmtClassName();
+ break;
+ }
+
case ProgramPoint::PreImplicitCallKind: {
ImplicitCallPoint PC = Loc.castAs<ImplicitCallPoint>();
Out << "PreCall: ";
More information about the cfe-commits
mailing list