From efbb4aaacedf0ded734d0b40c42d4419d03a59ff Mon Sep 17 00:00:00 2001 From: Martin Braenne Date: Thu, 22 Jun 2023 14:02:54 +0000 Subject: [PATCH] [clang][dataflow] Dump useful debugging information when we crash. - 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 --- .../TypeErasedDataflowAnalysis.cpp | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp index 38853c4d754294..de22d63812574e 100644 --- a/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp +++ b/clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp @@ -18,6 +18,7 @@ #include #include +#include "clang/AST/ASTDumper.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/OperationKinds.h" #include "clang/AST/StmtVisitor.h" @@ -179,6 +180,47 @@ struct AnalysisContext { llvm::ArrayRef> 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()) { + OS << "Stmt:\n"; + ASTDumper Dumper(OS, false); + Dumper.Visit(Stmt->getStmt()); + } + } + +private: + const CFGElement ∈ + int BlockIdx; + int ElementIdx; + const char *Message; +}; + } // namespace /// Computes the input state for a given basic block by joining the output @@ -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()) { @@ -395,6 +441,8 @@ runTypeErasedDataflowAnalysis( std::function PostVisitCFG) { + PrettyStackTraceAnalysis CrashInfo(CFCtx, "runTypeErasedDataflowAnalysis"); + PostOrderCFGView POV(&CFCtx.getCFG()); ForwardDataflowWorklist Worklist(CFCtx.getCFG(), &POV);