r324660 - [analyzer] Self-debug: Dump environment frame-by-frame.
Artem Dergachev via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 8 14:24:38 PST 2018
Author: dergachev
Date: Thu Feb 8 14:24:38 2018
New Revision: 324660
URL: http://llvm.org/viewvc/llvm-project?rev=324660&view=rev
Log:
[analyzer] Self-debug: Dump environment frame-by-frame.
It makes it easier to discriminate between values of similar expressions
in different stack frames.
It also makes the separate backtrace section in ExplodedGraph dumps redundant.
Differential Revision: https://reviews.llvm.org/D42552
Modified:
cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
cfe/trunk/test/Analysis/crash-trace.c
cfe/trunk/test/Analysis/expr-inspection.c
Modified: cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h Thu Feb 8 14:24:38 2018
@@ -265,7 +265,11 @@ public:
virtual void Profile(llvm::FoldingSetNodeID &ID) = 0;
- void dumpStack(raw_ostream &OS, StringRef Indent = "") const;
+ void dumpStack(
+ raw_ostream &OS, StringRef Indent = "", const char *NL = "\n",
+ const char *Sep = "",
+ std::function<void(const LocationContext *)> printMoreInfoPerContext =
+ [](const LocationContext *) {}) const;
void dumpStack() const;
public:
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h Thu Feb 8 14:24:38 2018
@@ -92,12 +92,9 @@ public:
bool operator==(const Environment& RHS) const {
return ExprBindings == RHS.ExprBindings;
}
-
- void print(raw_ostream &Out, const char *NL, const char *Sep) const;
-
-private:
- void printAux(raw_ostream &Out, bool printLocations,
- const char *NL, const char *Sep) const;
+
+ void print(raw_ostream &Out, const char *NL, const char *Sep,
+ const LocationContext *WithLC = nullptr) const;
};
class EnvironmentManager {
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h Thu Feb 8 14:24:38 2018
@@ -435,9 +435,10 @@ public:
}
// Pretty-printing.
- void print(raw_ostream &Out, const char *nl = "\n",
- const char *sep = "") const;
- void printDOT(raw_ostream &Out) const;
+ void print(raw_ostream &Out, const char *nl = "\n", const char *sep = "",
+ const LocationContext *CurrentLC = nullptr) const;
+ void printDOT(raw_ostream &Out,
+ const LocationContext *CurrentLC = nullptr) const;
void printTaint(raw_ostream &Out, const char *nl = "\n",
const char *sep = "") const;
Modified: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp (original)
+++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp Thu Feb 8 14:24:38 2018
@@ -463,28 +463,54 @@ bool LocationContext::isParentOf(const L
return false;
}
-void LocationContext::dumpStack(raw_ostream &OS, StringRef Indent) const {
+static void printLocation(raw_ostream &OS, const SourceManager &SM,
+ SourceLocation SLoc) {
+ if (SLoc.isFileID() && SM.isInMainFile(SLoc))
+ OS << "line " << SM.getExpansionLineNumber(SLoc);
+ else
+ SLoc.print(OS, SM);
+}
+
+void LocationContext::dumpStack(
+ raw_ostream &OS, StringRef Indent, const char *NL, const char *Sep,
+ std::function<void(const LocationContext *)> printMoreInfoPerContext) const {
ASTContext &Ctx = getAnalysisDeclContext()->getASTContext();
PrintingPolicy PP(Ctx.getLangOpts());
PP.TerseOutput = 1;
+ const SourceManager &SM =
+ getAnalysisDeclContext()->getASTContext().getSourceManager();
+
unsigned Frame = 0;
for (const LocationContext *LCtx = this; LCtx; LCtx = LCtx->getParent()) {
+
switch (LCtx->getKind()) {
case StackFrame:
- OS << Indent << '#' << Frame++ << ' ';
- cast<StackFrameContext>(LCtx)->getDecl()->print(OS, PP);
- OS << '\n';
+ OS << Indent << '#' << Frame << ' ';
+ ++Frame;
+ if (const NamedDecl *D = dyn_cast<NamedDecl>(LCtx->getDecl()))
+ OS << "Calling " << D->getQualifiedNameAsString();
+ else
+ OS << "Calling anonymous code";
+ if (const Stmt *S = cast<StackFrameContext>(LCtx)->getCallSite()) {
+ OS << " at ";
+ printLocation(OS, SM, S->getLocStart());
+ }
break;
case Scope:
- OS << Indent << " (scope)\n";
+ OS << "Entering scope";
break;
case Block:
- OS << Indent << " (block context: "
- << cast<BlockInvocationContext>(LCtx)->getContextData()
- << ")\n";
+ OS << "Invoking block";
+ if (const Decl *D = cast<BlockInvocationContext>(LCtx)->getDecl()) {
+ OS << " defined at ";
+ printLocation(OS, SM, D->getLocStart());
+ }
break;
}
+ OS << NL;
+
+ printMoreInfoPerContext(LCtx);
}
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp Thu Feb 8 14:24:38 2018
@@ -186,28 +186,41 @@ EnvironmentManager::removeDeadBindings(E
}
void Environment::print(raw_ostream &Out, const char *NL,
- const char *Sep) const {
- bool isFirst = true;
+ const char *Sep, const LocationContext *WithLC) const {
+ if (ExprBindings.isEmpty())
+ return;
- for (Environment::iterator I = begin(), E = end(); I != E; ++I) {
- const EnvironmentEntry &En = I.getKey();
-
- if (isFirst) {
- Out << NL << NL
- << "Expressions:"
- << NL;
- isFirst = false;
- } else {
- Out << NL;
+ if (!WithLC) {
+ // Find the freshest location context.
+ llvm::SmallPtrSet<const LocationContext *, 16> FoundContexts;
+ for (auto I : *this) {
+ const LocationContext *LC = I.first.getLocationContext();
+ if (FoundContexts.count(LC) == 0) {
+ // This context is fresher than all other contexts so far.
+ WithLC = LC;
+ for (const LocationContext *LCI = LC; LCI; LCI = LCI->getParent())
+ FoundContexts.insert(LCI);
+ }
}
+ }
- const Stmt *S = En.getStmt();
- assert(S != nullptr && "Expected non-null Stmt");
+ assert(WithLC);
- Out << " (" << (const void*) En.getLocationContext() << ','
- << (const void*) S << ") ";
- LangOptions LO; // FIXME.
- S->printPretty(Out, nullptr, PrintingPolicy(LO));
- Out << " : " << I.getData();
- }
+ LangOptions LO; // FIXME.
+ PrintingPolicy PP(LO);
+
+ Out << NL << NL << "Expressions by stack frame:" << NL;
+ WithLC->dumpStack(Out, "", NL, Sep, [&](const LocationContext *LC) {
+ for (auto I : ExprBindings) {
+ if (I.first.getLocationContext() != LC)
+ continue;
+
+ const Stmt *S = I.first.getStmt();
+ assert(S != nullptr && "Expected non-null Stmt");
+
+ Out << "(" << (const void *)LC << ',' << (const void *)S << ") ";
+ S->printPretty(Out, nullptr, PP);
+ Out << " : " << I.second << NL;
+ }
+ });
}
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Thu Feb 8 14:24:38 2018
@@ -2768,12 +2768,6 @@ struct DOTGraphTraits<ExplodedNode*> :
<< "\\l";
}
}
- static void printLocation2(raw_ostream &Out, SourceLocation SLoc) {
- if (SLoc.isFileID() && GraphPrintSourceManager->isInMainFile(SLoc))
- Out << "line " << GraphPrintSourceManager->getExpansionLineNumber(SLoc);
- else
- SLoc.print(Out, *GraphPrintSourceManager);
- }
static std::string getNodeLabel(const ExplodedNode *N, void*){
@@ -2948,40 +2942,7 @@ struct DOTGraphTraits<ExplodedNode*> :
Out << "\\|StateID: " << (const void*) state.get()
<< " NodeID: " << (const void*) N << "\\|";
- // Analysis stack backtrace.
- Out << "Location context stack (from current to outer):\\l";
- const LocationContext *LC = Loc.getLocationContext();
- unsigned Idx = 0;
- for (; LC; LC = LC->getParent(), ++Idx) {
- Out << Idx << ". (" << (const void *)LC << ") ";
- switch (LC->getKind()) {
- case LocationContext::StackFrame:
- if (const NamedDecl *D = dyn_cast<NamedDecl>(LC->getDecl()))
- Out << "Calling " << D->getQualifiedNameAsString();
- else
- Out << "Calling anonymous code";
- if (const Stmt *S = cast<StackFrameContext>(LC)->getCallSite()) {
- Out << " at ";
- printLocation2(Out, S->getLocStart());
- }
- break;
- case LocationContext::Block:
- Out << "Invoking block";
- if (const Decl *D = cast<BlockInvocationContext>(LC)->getBlockDecl()) {
- Out << " defined at ";
- printLocation2(Out, D->getLocStart());
- }
- break;
- case LocationContext::Scope:
- Out << "Entering scope";
- // FIXME: Add more info once ScopeContext is activated.
- break;
- }
- Out << "\\l";
- }
- Out << "\\l";
-
- state->printDOT(Out);
+ state->printDOT(Out, N->getLocationContext());
Out << "\\l";
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Thu Feb 8 14:24:38 2018
@@ -437,14 +437,14 @@ void ProgramState::setStore(const StoreR
// State pretty-printing.
//===----------------------------------------------------------------------===//
-void ProgramState::print(raw_ostream &Out,
- const char *NL, const char *Sep) const {
+void ProgramState::print(raw_ostream &Out, const char *NL, const char *Sep,
+ const LocationContext *LC) const {
// Print the store.
ProgramStateManager &Mgr = getStateManager();
Mgr.getStoreManager().print(getStore(), Out, NL, Sep);
// Print out the environment.
- Env.print(Out, NL, Sep);
+ Env.print(Out, NL, Sep, LC);
// Print out the constraints.
Mgr.getConstraintManager().print(this, Out, NL, Sep);
@@ -453,8 +453,8 @@ void ProgramState::print(raw_ostream &Ou
Mgr.getOwningEngine()->printState(Out, this, NL, Sep);
}
-void ProgramState::printDOT(raw_ostream &Out) const {
- print(Out, "\\l", "\\|");
+void ProgramState::printDOT(raw_ostream &Out, const LocationContext *LC) const {
+ print(Out, "\\l", "\\|", LC);
}
LLVM_DUMP_METHOD void ProgramState::dump() const {
Modified: cfe/trunk/test/Analysis/crash-trace.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/crash-trace.c?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/crash-trace.c (original)
+++ cfe/trunk/test/Analysis/crash-trace.c Thu Feb 8 14:24:38 2018
@@ -18,6 +18,6 @@ void test() {
// CHECK: 0. Program arguments: {{.*}}clang
// CHECK-NEXT: 1. <eof> parser at end of file
// CHECK-NEXT: 2. While analyzing stack:
-// CHECK-NEXT: #0 void inlined()
-// CHECK-NEXT: #1 void test()
+// CHECK-NEXT: #0 Calling inlined at line 15
+// CHECK-NEXT: #1 Calling test
// CHECK-NEXT: 3. {{.*}}crash-trace.c:{{[0-9]+}}:3: Error evaluating statement
Modified: cfe/trunk/test/Analysis/expr-inspection.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/expr-inspection.c?rev=324660&r1=324659&r2=324660&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/expr-inspection.c (original)
+++ cfe/trunk/test/Analysis/expr-inspection.c Thu Feb 8 14:24:38 2018
@@ -18,6 +18,8 @@ void foo(int x) {
// CHECK: Store (direct and default bindings)
// CHECK-NEXT: (y,0,direct) : 1 S32b
-// CHECK: Expressions:
+// CHECK: Expressions by stack frame:
+// CHECK-NEXT: #0 Calling foo
// CHECK-NEXT: clang_analyzer_printState : &code{clang_analyzer_printState}
-// CHECK-NEXT: {{(Ranges are empty.)|(Constraints:[[:space:]]*$)}}
+
+// CHECK: {{(Ranges are empty.)|(Constraints:[[:space:]]*$)}}
More information about the cfe-commits
mailing list