summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
diff options
context:
space:
mode:
authorAdam Balogh <adam.balogh@ericsson.com>2019-12-02 19:37:37 +0100
committerAdam Balogh <adam.balogh@ericsson.com>2019-12-11 14:20:17 +0100
commit6e9c58946eeeebfe8eed7308a3b57611e225ad67 (patch)
tree13bb881afabdbcf3794b6a9d59532724ea491d51 /clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
parent3bf8558fbb2f3e9348bf1f5aafb64d8095ad6420 (diff)
downloadbcm5719-llvm-6e9c58946eeeebfe8eed7308a3b57611e225ad67.tar.gz
bcm5719-llvm-6e9c58946eeeebfe8eed7308a3b57611e225ad67.zip
[Analyzer] Iterator Modeling: Print Container Data and Iterator Positions when printing the Program State
Debugging the Iterator Modeling checker or any of the iterator checkers is difficult without being able to see the relations between the iterator variables and their abstract positions, as well as the abstract symbols denoting the begin and the end of the container. This patch adds the checker-specific part of the Program State printing to the Iterator Modeling checker.
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp55
1 files changed, 55 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
index 9730de0e4cd..0a7015e85e9 100644
--- a/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp
@@ -121,6 +121,9 @@ class IteratorModeling
void handleEraseAfter(CheckerContext &C, const SVal &Iter) const;
void handleEraseAfter(CheckerContext &C, const SVal &Iter1,
const SVal &Iter2) const;
+ void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
+ const char *Sep) const override;
+
public:
IteratorModeling() {}
@@ -1080,6 +1083,58 @@ void IteratorModeling::handleEraseAfter(CheckerContext &C, const SVal &Iter1,
C.addTransition(State);
}
+void IteratorModeling::printState(raw_ostream &Out, ProgramStateRef State,
+ const char *NL, const char *Sep) const {
+
+ auto ContMap = State->get<ContainerMap>();
+
+ if (!ContMap.isEmpty()) {
+ Out << Sep << "Container Data :" << NL;
+ for (const auto Cont : ContMap) {
+ Cont.first->dumpToStream(Out);
+ Out << " : [ ";
+ const auto CData = Cont.second;
+ if (CData.getBegin())
+ CData.getBegin()->dumpToStream(Out);
+ else
+ Out << "<Unknown>";
+ Out << " .. ";
+ if (CData.getEnd())
+ CData.getEnd()->dumpToStream(Out);
+ else
+ Out << "<Unknown>";
+ Out << " ]" << NL;
+ }
+ }
+
+ auto SymbolMap = State->get<IteratorSymbolMap>();
+ auto RegionMap = State->get<IteratorRegionMap>();
+
+ if (!SymbolMap.isEmpty() || !RegionMap.isEmpty()) {
+ Out << Sep << "Iterator Positions :" << NL;
+ for (const auto Sym : SymbolMap) {
+ Sym.first->dumpToStream(Out);
+ Out << " : ";
+ const auto Pos = Sym.second;
+ Out << (Pos.isValid() ? "Valid" : "Invalid") << " ; Container == ";
+ Pos.getContainer()->dumpToStream(Out);
+ Out<<" ; Offset == ";
+ Pos.getOffset()->dumpToStream(Out);
+ }
+
+ for (const auto Reg : RegionMap) {
+ Reg.first->dumpToStream(Out);
+ Out << " : ";
+ const auto Pos = Reg.second;
+ Out << (Pos.isValid() ? "Valid" : "Invalid") << " ; Container == ";
+ Pos.getContainer()->dumpToStream(Out);
+ Out<<" ; Offset == ";
+ Pos.getOffset()->dumpToStream(Out);
+ }
+ }
+}
+
+
namespace {
const CXXRecordDecl *getCXXRecordDecl(ProgramStateRef State,
OpenPOWER on IntegriCloud