From b86163dce6f08666d159265d199143c09497fd40 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 12 Mar 2019 14:36:58 -0400
Subject: [PATCH 096/217] FIXME: add -fdump-analyzer-summaries

---
 gcc/analyzer/engine.cc                       | 65 ++++++++++++++++++++++++++++
 gcc/common.opt                               |  3 ++
 gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8.c |  6 ++-
 3 files changed, 72 insertions(+), 2 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index e2b1837..4e1df7c 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -884,6 +884,9 @@ public:
   void prune_path (checker_path *path, tree var, state_machine::state_t state);
   void maybe_emit (const candidate_diagnostic &cd);
 
+  void dump_analyzer_summary (const supernode *node) const;
+  void dump_analyzer_summary (const supernode *node, tree var) const;
+
   const supergraph &m_sg;
 
   // FIXME: this implies one traversal per state machine; should we instead
@@ -2626,6 +2629,58 @@ engine::maybe_emit (const candidate_diagnostic &cd)
   delete expanded_path;
 }
 
+/* FIXME.  return-value, args.  */
+
+void
+engine::dump_analyzer_summary (const supernode *node) const
+{
+
+  tree fndecl = node->m_fun->decl;
+  tree result = DECL_RESULT (fndecl);
+  if (result)
+    dump_analyzer_summary (node, result);
+
+  int i = 0;
+  for (tree parm = DECL_ARGUMENTS (fndecl); parm;
+       parm = DECL_CHAIN (parm), ++i)
+    {
+      tree parm_default_ssa = ssa_default_def (node->m_fun, parm);
+      dump_analyzer_summary (node, parm_default_ssa);
+    }
+}
+
+/* FIXME.  */
+
+void
+engine::dump_analyzer_summary (const supernode *node, tree var) const
+{
+  per_node_t &data = const_cast <engine &> (*this).get_data_for_node (node);
+  const set_of_summary_edges &sfx_add = data.m_sfx_add;
+  const set_of_summary_edges &sfx_transition = data.m_sfx_transition;
+  for (set_of_summary_edges::iterator iter = sfx_add.begin ();
+       iter != sfx_add.end ();
+       ++iter)
+    {
+      if ((*iter).m_start.m_varstate.m_var == var)
+	inform (node->get_start_location (),
+		"summary: add: %qE: %qs -> %qs",
+		var,
+		m_sm.get_state_name ((*iter).m_start.m_varstate.m_state),
+		m_sm.get_state_name ((*iter).m_end.m_varstate.m_state));
+    }
+  for (set_of_summary_edges::iterator iter = sfx_transition.begin ();
+       iter != sfx_transition.end ();
+       ++iter)
+    {
+      if ((*iter).m_start.m_varstate.m_var == var)
+	inform (node->get_start_location (),
+		"summary: transition: %qE: %qs -> %qs",
+		var,
+		m_sm.get_state_name ((*iter).m_start.m_varstate.m_state),
+		m_sm.get_state_name ((*iter).m_end.m_varstate.m_state));
+    }
+}
+
 /* FIXME.  */
 
 class engine_annotator : public dot_annotator
@@ -2823,6 +2878,16 @@ run_one_checker (const supergraph &sg, const state_machine &sm, logger *logger)
       e.emit_candidate_diagnostics ();
     }
 
+  if (flag_dump_analyzer_summaries)
+    {
+      int i;
+      FOR_EACH_VEC_ELT (root_functions, i, node)
+	{
+	  function *fun = node->get_fun ();
+	  e.dump_analyzer_summary (sg.get_node_for_function_entry (fun));
+	}
+    }
+
   if (1)
     {
       engine_annotator a (e);
diff --git a/gcc/common.opt b/gcc/common.opt
index 2335ab1..67529af 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -1344,6 +1344,9 @@ Common Joined RejectNegative Var(common_deferred_options) Defer
 fdump-analyzer
 Common RejectNegative Var(flag_dump_analyzer)
 
+fdump-analyzer-summaries
+Common RejectNegative Var(flag_dump_analyzer_summaries)
+
 fanalyzer-verbosity=
 Common Joined UInteger Var(analyzer_verbosity) Init(1)
 FIXME
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8.c b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8.c
index 574d73e..d630138 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8.c
@@ -1,11 +1,13 @@
+/* { dg-options "--analyzer -fdump-analyzer-summaries -fanalyzer-checker=malloc" } */
+
 #include <stdlib.h>
 
-void *wrapped_malloc (size_t size)
+void *wrapped_malloc (size_t size) /* { dg-message "summary: add: '<return-value>': 'start' -> 'unchecked'" } */
 {
   return malloc (size);
 }
 
-void wrapped_free (void *ptr)
+void wrapped_free (void *ptr) /* { dg-message "summary: add: 'ptr': 'start' -> 'free'" } */
 {
   free (ptr);
 }
-- 
1.8.5.3

