From ed07f8275bb7fa643716c67cad8428ad19ce3175 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 27 May 2020 18:08:19 -0400
Subject: [PATCH 187/237] FIXME: implement __analyzer_describe

---
 gcc/analyzer/engine.cc                        |  4 ++-
 gcc/analyzer/region-model2.cc                 | 25 +++++++++++++++++++
 gcc/analyzer/region-model2.h                  |  3 +++
 gcc/doc/analyzer.texi                         |  2 ++
 .../gcc.dg/analyzer/analyzer-decls.h          |  4 +++
 5 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 1ca2a5ab0a1..6370b56e729 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1663,7 +1663,9 @@ exploded_node::on_stmt2 (exploded_graph &eg,
   if (const gcall *call = dyn_cast <const gcall *> (stmt))
     {
       /* Debugging/test support.  */
-      if (is_special_named_call_p (call, "__analyzer_dump", 0))
+      if (is_special_named_call_p (call, "__analyzer_describe", 2))
+	state->m_region_model2->impl_call_analyzer_describe (call, &ctxt);
+      else if (is_special_named_call_p (call, "__analyzer_dump", 0))
 	{
 	  /* Handle the builtin "__analyzer_dump" by dumping state
 	     to stderr.  */
diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index f69b1bdbf72..fff49c3dc06 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -1531,6 +1531,17 @@ region2::dump (bool simple) const
   pp_flush (&pp);
 }
 
+/* FIXME.  */
+
+DEBUG_FUNCTION label_text
+region2::get_desc (bool simple) const
+{
+  pretty_printer pp;
+  pp_format_decoder (&pp) = default_tree_printer;
+  dump_to_pp (&pp, simple);
+  return label_text::take (xstrdup (pp_formatted_text (&pp)));
+}
+
 /* Base implementation of region2::validate vfunc.
    Assert that the fields of "region2" are valid; subclasses should
    chain up their implementation to this one.  */
@@ -4516,6 +4527,20 @@ region_model2::impl_call_alloca (const call_details &cd)
   return true;
 }
 
+/* FIXME.  */
+
+void
+region_model2::impl_call_analyzer_describe (const gcall *call,
+					    region_model2_context *ctxt)
+{
+  tree t_kind = gimple_call_arg (call, 0);
+  tree t_arg = gimple_call_arg (call, 1);
+  const svalue2 *sval = get_rvalue (t_arg, ctxt);
+  bool simple = zerop (t_kind);
+  label_text desc = sval->get_desc (simple);
+  warning_at (call->location, 0, "%s", desc.m_buffer);
+}
+
 /* Handle the "__analyzer_eval" by evaluating the input
    and dumping as a dummy warning, so that test cases can use
    dg-warning to validate the result (and so unexpected warnings will
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index fbc4578161c..2e3953174f7 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -890,6 +890,7 @@ public:
 
   void print (const region_model2 &model,
 	      pretty_printer *pp) const;
+  label_text get_desc (bool simple=true) const;
 
 #if 0
   virtual void dump_dot_to_pp (const region_model2 &model,
@@ -1800,6 +1801,8 @@ class region_model2
 
   /* Specific handling for on_call_pre.  */
   bool impl_call_alloca (const call_details &cd);
+  void impl_call_analyzer_describe (const gcall *call,
+				    region_model2_context *ctxt);
   void impl_call_analyzer_eval (const gcall *call,
 				region_model2_context *ctxt);
   bool impl_call_builtin_expect (const call_details &cd);
diff --git a/gcc/doc/analyzer.texi b/gcc/doc/analyzer.texi
index 7040f775d82..5899fbf0bf3 100644
--- a/gcc/doc/analyzer.texi
+++ b/gcc/doc/analyzer.texi
@@ -450,6 +450,8 @@ to the source being analyzed to trigger a breakpoint in the analyzer when
 that source is reached.  By putting a series of these in the source, it's
 much easier to effectively step through the program state as it's analyzed.
 
+TODO: document __analyzer_describe.
+
 @smallexample
 __analyzer_dump ();
 @end smallexample
diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
index 180e873b67c..bd09de57acb 100644
--- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
+++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
@@ -7,6 +7,10 @@
 /* Trigger a breakpoint in the analyzer when reached.  */
 extern void __analyzer_break (void);
 
+/* Describe the 2nd argument (which can be of any type), at the given
+   verbosity level.  */
+extern void __analyzer_describe (int verbosity, ...);
+
 /* Dump copious information about the analyzer’s state when reached.  */
 extern void __analyzer_dump (void);
 
-- 
2.26.2

