[cfe-commits] r128761 - in /cfe/trunk: include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/Analysis/idempotent-operations.cpp
Ted Kremenek
kremenek at apple.com
Fri Apr 1 19:56:23 PDT 2011
Author: kremenek
Date: Fri Apr 1 21:56:23 2011
New Revision: 128761
URL: http://llvm.org/viewvc/llvm-project?rev=128761&view=rev
Log:
Teach IdempotentOperationsChecker about paths aborted because ExprEngine didn't know how to handle a specific Expr type.
Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/test/Analysis/idempotent-operations.cpp
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h?rev=128761&r1=128760&r2=128761&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h Fri Apr 1 21:56:23 2011
@@ -48,6 +48,10 @@
public:
typedef std::vector<std::pair<BlockEdge, const ExplodedNode*> >
BlocksExhausted;
+
+ typedef std::vector<std::pair<const CFGBlock*, const ExplodedNode*> >
+ BlocksAborted;
+
private:
SubEngine& SubEng;
@@ -68,6 +72,10 @@
/// The locations where we stopped doing work because we visited a location
/// too many times.
BlocksExhausted blocksExhausted;
+
+ /// The locations where we stopped because the engine aborted analysis,
+ /// usually because it could not reason about something.
+ BlocksAborted blocksAborted;
void generateNode(const ProgramPoint& Loc, const GRState* State,
ExplodedNode* Pred);
@@ -122,17 +130,32 @@
ExplodedNodeSet &Dst);
// Functions for external checking of whether we have unfinished work
- bool wasBlockAborted() const { return !blocksExhausted.empty(); }
- bool hasWorkRemaining() const { return wasBlockAborted() || WList->hasWork(); }
-
+ bool wasBlockAborted() const { return !blocksAborted.empty(); }
+ bool wasBlocksExhausted() const { return !blocksExhausted.empty(); }
+ bool hasWorkRemaining() const { return wasBlocksExhausted() ||
+ WList->hasWork() ||
+ wasBlockAborted(); }
+
+ /// Inform the CoreEngine that a basic block was aborted because
+ /// it could not be completely analyzed.
+ void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) {
+ blocksAborted.push_back(std::make_pair(block, node));
+ }
+
WorkList *getWorkList() const { return WList; }
- BlocksExhausted::const_iterator blocks_aborted_begin() const {
+ BlocksExhausted::const_iterator blocks_exhausted_begin() const {
return blocksExhausted.begin();
}
- BlocksExhausted::const_iterator blocks_aborted_end() const {
+ BlocksExhausted::const_iterator blocks_exhausted_end() const {
return blocksExhausted.end();
}
+ BlocksAborted::const_iterator blocks_aborted_begin() const {
+ return blocksAborted.begin();
+ }
+ BlocksAborted::const_iterator blocks_aborted_end() const {
+ return blocksAborted.end();
+ }
};
class StmtNodeBuilder {
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=128761&r1=128760&r2=128761&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Fri Apr 1 21:56:23 2011
@@ -213,11 +213,9 @@
const SymbolManager& getSymbolManager() const { return SymMgr; }
// Functions for external checking of whether we have unfinished work
- bool wasBlockAborted() const { return Engine.wasBlockAborted(); }
+ bool wasBlocksExhausted() const { return Engine.wasBlocksExhausted(); }
bool hasEmptyWorkList() const { return !Engine.getWorkList()->hasWork(); }
- bool hasWorkRemaining() const {
- return wasBlockAborted() || Engine.getWorkList()->hasWork();
- }
+ bool hasWorkRemaining() const { return Engine.hasWorkRemaining(); }
const CoreEngine &getCoreEngine() const { return Engine; }
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp?rev=128761&r1=128760&r2=128761&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/AnalyzerStatsChecker.cpp Fri Apr 1 21:56:23 2011
@@ -88,8 +88,8 @@
}
output << " -> Total CFGBlocks: " << total << " | Unreachable CFGBlocks: "
- << unreachable << " | Aborted Block: "
- << (Eng.wasBlockAborted() ? "yes" : "no")
+ << unreachable << " | Exhausted Block: "
+ << (Eng.wasBlocksExhausted() ? "yes" : "no")
<< " | Empty WorkList: "
<< (Eng.hasEmptyWorkList() ? "yes" : "no");
@@ -97,10 +97,10 @@
D->getLocation());
// Emit warning for each block we bailed out on
- typedef CoreEngine::BlocksExhausted::const_iterator AbortedIterator;
+ typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
const CoreEngine &CE = Eng.getCoreEngine();
- for (AbortedIterator I = CE.blocks_aborted_begin(),
- E = CE.blocks_aborted_end(); I != E; ++I) {
+ for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
+ E = CE.blocks_exhausted_end(); I != E; ++I) {
const BlockEdge &BE = I->first;
const CFGBlock *Exit = BE.getDst();
const CFGElement &CE = Exit->front();
Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp?rev=128761&r1=128760&r2=128761&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/IdempotentOperationChecker.cpp Fri Apr 1 21:56:23 2011
@@ -534,9 +534,9 @@
CFGReverseBlockReachabilityAnalysis *CRA = AC->getCFGReachablityAnalysis();
// Test for reachability from any aborted blocks to this block
- typedef CoreEngine::BlocksExhausted::const_iterator AbortedIterator;
- for (AbortedIterator I = CE.blocks_aborted_begin(),
- E = CE.blocks_aborted_end(); I != E; ++I) {
+ typedef CoreEngine::BlocksExhausted::const_iterator ExhaustedIterator;
+ for (ExhaustedIterator I = CE.blocks_exhausted_begin(),
+ E = CE.blocks_exhausted_end(); I != E; ++I) {
const BlockEdge &BE = I->first;
// The destination block on the BlockEdge is the first block that was not
@@ -550,6 +550,15 @@
if (destBlock == CB || CRA->isReachable(destBlock, CB))
return false;
}
+
+ // Test for reachability from blocks we just gave up on.
+ typedef CoreEngine::BlocksAborted::const_iterator AbortedIterator;
+ for (AbortedIterator I = CE.blocks_aborted_begin(),
+ E = CE.blocks_aborted_end(); I != E; ++I) {
+ const CFGBlock *destBlock = I->first;
+ if (destBlock == CB || CRA->isReachable(destBlock, CB))
+ return false;
+ }
// For the items still on the worklist, see if they are in blocks that
// can eventually reach 'CB'.
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=128761&r1=128760&r2=128761&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Apr 1 21:56:23 2011
@@ -444,7 +444,8 @@
{
SaveAndRestore<bool> OldSink(Builder->BuildSinks);
Builder->BuildSinks = true;
- MakeNode(Dst, S, Pred, GetState(Pred));
+ const ExplodedNode *node = MakeNode(Dst, S, Pred, GetState(Pred));
+ Engine.addAbortedBlock(node, Builder->getBlock());
break;
}
Modified: cfe/trunk/test/Analysis/idempotent-operations.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/idempotent-operations.cpp?rev=128761&r1=128760&r2=128761&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/idempotent-operations.cpp (original)
+++ cfe/trunk/test/Analysis/idempotent-operations.cpp Fri Apr 1 21:56:23 2011
@@ -13,3 +13,22 @@
test(five * a); // expected-warning {{The right operand to '*' is always 0}}
b = 4;
}
+
+// Test not flagging idempotent operations because we aborted the analysis
+// of a path because of an unsupported construct.
+struct RDar9219143_Foo {
+ ~RDar9219143_Foo();
+ operator bool() const;
+};
+
+RDar9219143_Foo foo();
+unsigned RDar9219143_bar();
+void RDar9219143_test() {
+ unsigned i, e;
+ for (i = 0, e = RDar9219143_bar(); i != e; ++i)
+ if (foo())
+ break;
+ if (i == e) // no-warning
+ return;
+}
+
More information about the cfe-commits
mailing list