summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-06-29 00:33:10 +0000
committerJordan Rose <jordan_rose@apple.com>2012-06-29 00:33:10 +0000
commit42ee04d00a651a95337de6d83905fa81feb1767c (patch)
treef3b7cbffef30a9b04198925718841025adaa6f00 /clang/lib
parent33fd523df145e0e6f0f975ab2b9e727735a963f6 (diff)
downloadbcm5719-llvm-42ee04d00a651a95337de6d83905fa81feb1767c.tar.gz
bcm5719-llvm-42ee04d00a651a95337de6d83905fa81feb1767c.zip
[analyzer] Add a test that we are, in fact, doing a DFS on the ExplodedGraph.
Previously: ...the comment said DFS... ...the WorkList being instantiated said BFS... ...and the implementation was actually DFS... ...due to an unintentional change in 2010... ...and everything kept working anyway. This fixes our std::deque implementation of BFS, but switches back to a SmallVector-based implementation of DFS. We should probably still investigate the ramifications of DFS vs. BFS, especially for large functions (and especially when we hit our block path limit), since this might completely change our memory use. It can also mask some bugs and reveal others depending on when we halt analysis. But at least we will not have this kind of little mistake creep in again. llvm-svn: 159397
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt1
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/Checkers.td4
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp57
-rw-r--r--clang/lib/StaticAnalyzer/Core/CoreEngine.cpp2
4 files changed, 63 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
index f121dd57056..79b0539ba00 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
+++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
@@ -58,6 +58,7 @@ add_clang_library(clangStaticAnalyzerCheckers
StackAddrEscapeChecker.cpp
StreamChecker.cpp
TaintTesterChecker.cpp
+ TraversalChecker.cpp
UndefBranchChecker.cpp
UndefCapturedBlockVarChecker.cpp
UndefResultChecker.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/Checkers.td b/clang/lib/StaticAnalyzer/Checkers/Checkers.td
index 28b0679d359..0969053976b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/Checkers.td
+++ b/clang/lib/StaticAnalyzer/Checkers/Checkers.td
@@ -479,6 +479,10 @@ def CallGraphDumper : Checker<"DumpCallGraph">,
HelpText<"Display Call Graph">,
DescFile<"DebugCheckers.cpp">;
+def TraversalDumper : Checker<"DumpTraversal">,
+ HelpText<"Print branch conditions as they are traversed by the engine">,
+ DescFile<"TraversalChecker.cpp">;
+
def AnalyzerStatsChecker : Checker<"Stats">,
HelpText<"Emit warnings with analyzer statistics">,
DescFile<"AnalyzerStatsChecker.cpp">;
diff --git a/clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
new file mode 100644
index 00000000000..d0479d45194
--- /dev/null
+++ b/clang/lib/StaticAnalyzer/Checkers/TraversalChecker.cpp
@@ -0,0 +1,57 @@
+//== TraversalChecker.cpp -------------------------------------- -*- C++ -*--=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This checker prints branch statements to llvm::outs as they are encountered.
+// This lets us see exactly how the ExprEngine is traversing the graph.
+//
+//===----------------------------------------------------------------------===//
+#include "ClangSACheckers.h"
+#include "clang/AST/ParentMap.h"
+#include "clang/AST/StmtObjC.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+class TraversalDumper : public Checker< check::BranchCondition,
+ check::EndPath > {
+public:
+ void checkBranchCondition(const Stmt *Condition, CheckerContext &C) const;
+ void checkEndPath(CheckerContext &C) const;
+};
+}
+
+void TraversalDumper::checkBranchCondition(const Stmt *Condition,
+ CheckerContext &C) const {
+ // Special-case Objective-C's for-in loop, which uses the entire loop as its
+ // condition. We just print the collection expression.
+ const Stmt *Parent = dyn_cast<ObjCForCollectionStmt>(Condition);
+ if (!Parent) {
+ const ParentMap &Parents = C.getLocationContext()->getParentMap();
+ Parent = Parents.getParent(Condition);
+ }
+
+ // It is mildly evil to print directly to llvm::outs() rather than emitting
+ // warnings, but this ensures things do not get filtered out by the rest of
+ // the static analyzer machinery.
+ SourceLocation Loc = Parent->getLocStart();
+ llvm::outs() << C.getSourceManager().getSpellingLineNumber(Loc) << " "
+ << Parent->getStmtClassName() << "\n";
+}
+
+void TraversalDumper::checkEndPath(CheckerContext &C) const {
+ llvm::outs() << "--END PATH--\n";
+}
+
+void ento::registerTraversalDumper(CheckerManager &mgr) {
+ mgr.registerChecker<TraversalDumper>();
+}
diff --git a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
index f691d5f3d68..689f05714ff 100644
--- a/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp
@@ -76,7 +76,7 @@ public:
}
virtual void enqueue(const WorkListUnit& U) {
- Queue.push_front(U);
+ Queue.push_back(U);
}
virtual WorkListUnit dequeue() {
OpenPOWER on IntegriCloud