Skip to content

Commit

Permalink
[clang][dataflow] Dump useful debugging information when we crash.
Browse files Browse the repository at this point in the history
- The AST of the function we're currently analyzing
- The CFG
- The CFG element we're currently processing

Reviewed By: ymandel

Differential Revision: https://reviews.llvm.org/D153549
  • Loading branch information
martinboehme committed Jun 23, 2023
1 parent 2ef2c64 commit efbb4aa
Showing 1 changed file with 48 additions and 0 deletions.
48 changes: 48 additions & 0 deletions clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <utility>
#include <vector>

#include "clang/AST/ASTDumper.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/StmtVisitor.h"
Expand Down Expand Up @@ -179,6 +180,47 @@ struct AnalysisContext {
llvm::ArrayRef<std::optional<TypeErasedDataflowAnalysisState>> BlockStates;
};

class PrettyStackTraceAnalysis : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceAnalysis(const ControlFlowContext &CFCtx, const char *Message)
: CFCtx(CFCtx), Message(Message) {}

void print(raw_ostream &OS) const override {
OS << Message << "\n";
OS << "Decl:\n";
CFCtx.getDecl()->dump(OS);
OS << "CFG:\n";
CFCtx.getCFG().print(OS, LangOptions(), false);
}

private:
const ControlFlowContext &CFCtx;
const char *Message;
};

class PrettyStackTraceCFGElement : public llvm::PrettyStackTraceEntry {
public:
PrettyStackTraceCFGElement(const CFGElement &Element, int BlockIdx,
int ElementIdx, const char *Message)
: Element(Element), BlockIdx(BlockIdx), ElementIdx(ElementIdx),
Message(Message) {}

void print(raw_ostream &OS) const override {
OS << Message << ": Element [B" << BlockIdx << "." << ElementIdx << "]\n";
if (auto Stmt = Element.getAs<CFGStmt>()) {
OS << "Stmt:\n";
ASTDumper Dumper(OS, false);
Dumper.Visit(Stmt->getStmt());
}
}

private:
const CFGElement &Element;
int BlockIdx;
int ElementIdx;
const char *Message;
};

} // namespace

/// Computes the input state for a given basic block by joining the output
Expand Down Expand Up @@ -357,7 +399,11 @@ transferCFGBlock(const CFGBlock &Block, AnalysisContext &AC,
AC.Log.enterBlock(Block);
auto State = computeBlockInputState(Block, AC);
AC.Log.recordState(State);
int ElementIdx = 1;
for (const auto &Element : Block) {
PrettyStackTraceCFGElement CrashInfo(Element, Block.getBlockID(),
ElementIdx++, "transferCFGBlock");

AC.Log.enterElement(Element);
// Built-in analysis
if (AC.Analysis.builtinOptions()) {
Expand Down Expand Up @@ -395,6 +441,8 @@ runTypeErasedDataflowAnalysis(
std::function<void(const CFGElement &,
const TypeErasedDataflowAnalysisState &)>
PostVisitCFG) {
PrettyStackTraceAnalysis CrashInfo(CFCtx, "runTypeErasedDataflowAnalysis");

PostOrderCFGView POV(&CFCtx.getCFG());
ForwardDataflowWorklist Worklist(CFCtx.getCFG(), &POV);

Expand Down

0 comments on commit efbb4aa

Please sign in to comment.