diff options
author | Adam Balogh <adam.balogh@ericsson.com> | 2019-12-02 19:37:37 +0100 |
---|---|---|
committer | Adam Balogh <adam.balogh@ericsson.com> | 2019-12-11 14:20:17 +0100 |
commit | 6e9c58946eeeebfe8eed7308a3b57611e225ad67 (patch) | |
tree | 13bb881afabdbcf3794b6a9d59532724ea491d51 /clang/lib/StaticAnalyzer/Checkers/IteratorModeling.cpp | |
parent | 3bf8558fbb2f3e9348bf1f5aafb64d8095ad6420 (diff) | |
download | bcm5719-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.cpp | 55 |
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, |