const CallEvent *Call) override;
/// printState - Called by ProgramStateManager to print checker-specific data.
- void printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep) override;
+ void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
+ const char *Sep,
+ const LocationContext *LCtx = nullptr) override;
ProgramStateManager& getStateManager() override { return StateMgr; }
/// printState - Called by ProgramStateManager to print checker-specific data.
virtual void printState(raw_ostream &Out, ProgramStateRef State,
- const char *NL, const char *Sep) = 0;
+ const char *NL, const char *Sep,
+ const LocationContext *LCtx = nullptr) = 0;
/// Called by CoreEngine when the analysis worklist is either empty or the
// maximum number of analysis steps have been reached.
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);
}
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 {