r343352 - [analyzer] Provide an option to dump generated exploded graphs to a given file.
George Karpenkov via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 28 11:49:21 PDT 2018
Author: george.karpenkov
Date: Fri Sep 28 11:49:21 2018
New Revision: 343352
URL: http://llvm.org/viewvc/llvm-project?rev=343352&view=rev
Log:
[analyzer] Provide an option to dump generated exploded graphs to a given file.
Dumping graphs instead of opening them is often very useful,
e.g. for transfer or converting to SVG.
Basic sanity check for generated exploded graphs.
Differential Revision: https://reviews.llvm.org/D52637
Added:
cfe/trunk/test/Analysis/dump_egraph.c
Modified:
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=343352&r1=343351&r2=343352&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Fri Sep 28 11:49:21 2018
@@ -80,6 +80,9 @@ def trim_egraph : Flag<["-"], "trim-egra
HelpText<"Only show error-related paths in the analysis graph">;
def analyzer_viz_egraph_graphviz : Flag<["-"], "analyzer-viz-egraph-graphviz">,
HelpText<"Display exploded graph using GraphViz">;
+def analyzer_dump_egraph : Separate<["-"], "analyzer-dump-egraph">,
+ HelpText<"Dump exploded graph to the specified file">;
+def analyzer_dump_egraph_EQ : Joined<["-"], "analyzer-dump-egraph=">, Alias<analyzer_dump_egraph>;
def analyzer_inline_max_stack_depth : Separate<["-"], "analyzer-inline-max-stack-depth">,
HelpText<"Bound on stack depth while inlining (4 by default)">;
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=343352&r1=343351&r2=343352&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Sep 28 11:49:21 2018
@@ -140,6 +140,9 @@ public:
std::string AnalyzeSpecificFunction;
+ /// File path to which the exploded graph should be dumped.
+ std::string DumpExplodedGraphTo;
+
/// Store full compiler invocation for reproducible instructions in the
/// generated report.
std::string FullCompilerInvocation;
Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=343352&r1=343351&r2=343352&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Fri Sep 28 11:49:21 2018
@@ -204,6 +204,18 @@ public:
void enqueueEndOfPath(ExplodedNodeSet &S);
void GenerateCallExitNode(ExplodedNode *N);
+
+ /// Dump graph to the specified filename.
+ /// If filename is empty, generate a temporary one.
+ /// \return The filename the graph is written into.
+ std::string DumpGraph(bool trim = false, StringRef Filename="");
+
+ /// Dump the graph consisting of the given nodes to a specified filename.
+ /// Generate a temporary filename if it's not provided.
+ /// \return The filename the graph is written into.
+ std::string DumpGraph(ArrayRef<const ExplodedNode *> Nodes,
+ StringRef Filename = "");
+
/// Visualize the ExplodedGraph created by executing the simulation.
void ViewGraph(bool trim = false);
Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=343352&r1=343351&r2=343352&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Fri Sep 28 11:49:21 2018
@@ -284,6 +284,7 @@ static bool ParseAnalyzerArgs(AnalyzerOp
Opts.visualizeExplodedGraphWithGraphViz =
Args.hasArg(OPT_analyzer_viz_egraph_graphviz);
+ Opts.DumpExplodedGraphTo = Args.getLastArgValue(OPT_analyzer_dump_egraph);
Opts.NoRetryExhausted = Args.hasArg(OPT_analyzer_disable_retry_exhausted);
Opts.AnalyzeAll = Args.hasArg(OPT_analyzer_opt_analyze_headers);
Opts.AnalyzerDisplayProgress = Args.hasArg(OPT_analyzer_display_progress);
Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=343352&r1=343351&r2=343352&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Fri Sep 28 11:49:21 2018
@@ -3058,6 +3058,23 @@ struct DOTGraphTraits<ExplodedGraph*> :
void ExprEngine::ViewGraph(bool trim) {
#ifndef NDEBUG
+ std::string Filename = DumpGraph(trim);
+ llvm::DisplayGraph(Filename, false, llvm::GraphProgram::DOT);
+#endif
+ llvm::errs() << "Warning: viewing graph requires assertions" << "\n";
+}
+
+
+void ExprEngine::ViewGraph(ArrayRef<const ExplodedNode*> Nodes) {
+#ifndef NDEBUG
+ std::string Filename = DumpGraph(Nodes);
+ llvm::DisplayGraph(Filename, false, llvm::GraphProgram::DOT);
+#endif
+ llvm::errs() << "Warning: viewing graph requires assertions" << "\n";
+}
+
+std::string ExprEngine::DumpGraph(bool trim, StringRef Filename) {
+#ifndef NDEBUG
if (trim) {
std::vector<const ExplodedNode *> Src;
@@ -3067,22 +3084,30 @@ void ExprEngine::ViewGraph(bool trim) {
const auto *N = const_cast<ExplodedNode *>(EI->begin()->getErrorNode());
if (N) Src.push_back(N);
}
-
- ViewGraph(Src);
+ return DumpGraph(Src, Filename);
} else {
- llvm::ViewGraph(&G, "ExprEngine");
+ return llvm::WriteGraph(&G, "ExprEngine", /*ShortNames=*/false,
+ /*Title=*/"Exploded Graph", /*Filename=*/Filename);
}
#endif
+ llvm::errs() << "Warning: dumping graph requires assertions" << "\n";
+ return "";
}
-void ExprEngine::ViewGraph(ArrayRef<const ExplodedNode*> Nodes) {
+std::string ExprEngine::DumpGraph(ArrayRef<const ExplodedNode*> Nodes,
+ StringRef Filename) {
#ifndef NDEBUG
std::unique_ptr<ExplodedGraph> TrimmedG(G.trim(Nodes));
if (!TrimmedG.get()) {
llvm::errs() << "warning: Trimmed ExplodedGraph is empty.\n";
} else {
- llvm::ViewGraph(TrimmedG.get(), "TrimmedExprEngine");
+ return llvm::WriteGraph(TrimmedG.get(), "TrimmedExprEngine",
+ /*ShortNames=*/false,
+ /*Title=*/"Trimmed Exploded Graph",
+ /*Filename=*/Filename);
}
#endif
+ llvm::errs() << "Warning: dumping graph requires assertions" << "\n";
+ return "";
}
Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=343352&r1=343351&r2=343352&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Fri Sep 28 11:49:21 2018
@@ -745,6 +745,9 @@ void AnalysisConsumer::ActionExprEngine(
Eng.ExecuteWorkList(Mgr->getAnalysisDeclContextManager().getStackFrame(D),
Mgr->options.getMaxNodesPerTopLevelFunction());
+ if (!Mgr->options.DumpExplodedGraphTo.empty())
+ Eng.DumpGraph(Mgr->options.TrimGraph, Mgr->options.DumpExplodedGraphTo);
+
// Visualize the exploded graph.
if (Mgr->options.visualizeExplodedGraphWithGraphViz)
Eng.ViewGraph(Mgr->options.TrimGraph);
Added: cfe/trunk/test/Analysis/dump_egraph.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/dump_egraph.c?rev=343352&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/dump_egraph.c (added)
+++ cfe/trunk/test/Analysis/dump_egraph.c Fri Sep 28 11:49:21 2018
@@ -0,0 +1,15 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-dump-egraph=%t.dot %s
+// RUN: cat %t.dot | FileCheck %s
+// REQUIRES: asserts
+
+int getJ();
+
+int foo() {
+ int *x = 0;
+ return *x;
+}
+
+// CHECK: digraph "Exploded Graph" {
+// CHECK: Edge: (B2, B1)
+// CHECK: Block Entrance: B1
+// CHECK: Bug report attached
More information about the cfe-commits
mailing list