summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorArtem Dergachev <artem.dergachev@gmail.com>2018-02-08 22:32:38 +0000
committerArtem Dergachev <artem.dergachev@gmail.com>2018-02-08 22:32:38 +0000
commitaf84ce162c0486039c6ef6ef5e0275a3d48e65ae (patch)
treec954238dd3c442175983240e867e050f3028b425 /clang/lib/StaticAnalyzer
parent9e030c9e0010b423e877d7a7c8ef3742b16a079f (diff)
downloadbcm5719-llvm-af84ce162c0486039c6ef6ef5e0275a3d48e65ae.tar.gz
bcm5719-llvm-af84ce162c0486039c6ef6ef5e0275a3d48e65ae.zip
[analyzer] Self-debug: Dump the core's internal state traits to the egraph.
It is useful for debugging problems with C++ operator new() or temporaries. Differential Revision: https://reviews.llvm.org/D42560 llvm-svn: 324663
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngine.cpp56
-rw-r--r--clang/lib/StaticAnalyzer/Core/ProgramState.cpp2
2 files changed, 56 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 39f36477bde..3df69e891b7 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -383,8 +383,62 @@ ExprEngine::processRegionChanges(ProgramStateRef state,
LCtx, Call);
}
+static void printInitializedTemporariesForContext(raw_ostream &Out,
+ ProgramStateRef State,
+ const char *NL,
+ const char *Sep,
+ const LocationContext *LC) {
+ PrintingPolicy PP =
+ LC->getAnalysisDeclContext()->getASTContext().getPrintingPolicy();
+ for (auto I : State->get<InitializedTemporariesSet>()) {
+ if (I.second != LC)
+ continue;
+ Out << '(' << I.second << ',' << I.first << ") ";
+ I.first->printPretty(Out, nullptr, PP);
+ Out << NL;
+ }
+}
+
+static void printCXXNewAllocatorValuesForContext(raw_ostream &Out,
+ ProgramStateRef State,
+ const char *NL,
+ const char *Sep,
+ const LocationContext *LC) {
+ PrintingPolicy PP =
+ LC->getAnalysisDeclContext()->getASTContext().getPrintingPolicy();
+
+ for (auto I : State->get<CXXNewAllocatorValues>()) {
+ std::pair<const CXXNewExpr *, const LocationContext *> Key = I.first;
+ SVal Value = I.second;
+ if (Key.second != LC)
+ continue;
+ Out << '(' << Key.second << ',' << Key.first << ") ";
+ Key.first->printPretty(Out, nullptr, PP);
+ Out << " : " << Value << NL;
+ }
+}
+
void ExprEngine::printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep) {
+ const char *NL, const char *Sep,
+ const LocationContext *LCtx) {
+ if (LCtx) {
+ if (!State->get<InitializedTemporariesSet>().isEmpty()) {
+ Out << Sep << "Initialized temporaries:" << NL;
+
+ LCtx->dumpStack(Out, "", NL, Sep, [&](const LocationContext *LC) {
+ printInitializedTemporariesForContext(Out, State, NL, Sep, LC);
+ });
+ }
+
+ if (!State->get<CXXNewAllocatorValues>().isEmpty()) {
+ Out << Sep << "operator new() allocator return values:" << NL;
+
+ LCtx->dumpStack(Out, "", NL, Sep, [&](const LocationContext *LC) {
+ printCXXNewAllocatorValuesForContext(Out, State, NL, Sep, LC);
+ });
+ }
+ }
+
getCheckerManager().runCheckersForPrintState(Out, State, NL, Sep);
}
diff --git a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
index 53646e295ef..eccbc30bbe5 100644
--- a/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -450,7 +450,7 @@ void ProgramState::print(raw_ostream &Out, const char *NL, const char *Sep,
Mgr.getConstraintManager().print(this, Out, NL, Sep);
// Print checker-specific data.
- Mgr.getOwningEngine()->printState(Out, this, NL, Sep);
+ Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC);
}
void ProgramState::printDOT(raw_ostream &Out, const LocationContext *LC) const {
OpenPOWER on IntegriCloud