From 31b7e507f61a0bea18898bf782754b27b62ef15b Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 19 May 2020 12:09:36 -0400
Subject: [PATCH 150/179] FIXME: eliminate base class
 region2::get_representative_path_var

---
 gcc/analyzer/analyzer.h            |   1 +
 gcc/analyzer/diagnostic-manager.cc |   6 +-
 gcc/analyzer/engine.cc             |   4 +-
 gcc/analyzer/region-model2.cc      | 106 +++++++++++++++++++++++++----
 gcc/analyzer/region-model2.h       |  39 ++++++++++-
 gcc/analyzer/store2.cc             |   4 +-
 6 files changed, 140 insertions(+), 20 deletions(-)

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index bec06713210..95bae455778 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -107,6 +107,7 @@ class engine2;
 /* Forward decls of functions.  */
 
 extern void dump_quoted_tree (pretty_printer *pp, tree t);
+extern int readability_comparator (const void *p1, const void *p2);
 
 /* A tree, extended with stack frame information for locals, so that
    we can distinguish between different values of locals within a potentially
diff --git a/gcc/analyzer/diagnostic-manager.cc b/gcc/analyzer/diagnostic-manager.cc
index d2f97b0fdb8..85234d4f133 100644
--- a/gcc/analyzer/diagnostic-manager.cc
+++ b/gcc/analyzer/diagnostic-manager.cc
@@ -1448,13 +1448,15 @@ diagnostic_manager::prune_for_sm_diagnostic (checker_path *path,
 	      }
 	    else if (m_verbosity < 4)
 	      {
-		if (var)
+		if (var && state_change->m_var)
 		  log ("filtering event %i:"
 		       " state change to %qE unrelated to %qE",
 		       idx, state_change->m_var, var);
-		else
+		else if (state_change->m_var)
 		  log ("filtering event %i: state change to %qE",
 		       idx, state_change->m_var);
+		else
+		  log ("filtering event %i: global state change", idx);
 		if (ctxt_had_errors)
 		  log ("context had errors");
 		path->delete_event (idx);
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 53d08f7be3d..b43e1643719 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -68,8 +68,6 @@ along with GCC; see the file COPYING3.  If not see
 
 namespace ana {
 
-static int readability_comparator (const void *p1, const void *p2);
-
 /* class impl_region_model_context : public region_model_context.  */
 
 impl_region_model_context::
@@ -765,7 +763,7 @@ readability (const_tree expr)
 /* A qsort comparator for trees to sort them into most user-readable to
    least user-readable.  */
 
-static int
+int
 readability_comparator (const void *p1, const void *p2)
 {
   path_var pv1 = *(path_var const *)p1;
diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index 5533860e767..4926f1cbcb3 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -1104,13 +1104,6 @@ region2::calc_offset () const
   return region_offset::make_concrete (iter_region, accum_bit_offset);
 }
 
-path_var
-region2::get_representative_path_var () const
-{
-  // TODO: convert to pure virtual
-  gcc_unreachable ();
-}
-
 /* Set this region2's value to RHS_SVAL (or potentially a variant of it,
    for some kinds of casts).  */
 #if 0
@@ -1911,6 +1904,13 @@ label_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     }
 }
 
+bool
+label_region2::get_representative_path_var (path_var *) const
+{
+  // TODO
+  return false;
+}
+
 /* class stack_region2 : public region2.  */
 
 void
@@ -2383,6 +2383,13 @@ symbolic_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     }
 }
 
+bool
+symbolic_region2::get_representative_path_var (path_var *) const
+{
+  // TODO
+  return false;
+}
+
 /* class decl_region2 : public region2.  */
 
 void
@@ -2415,11 +2422,13 @@ decl_region2::dump_to_pp (pretty_printer *pp, bool simple) const
 
 /* FIXME.  */
 
-path_var
-decl_region2::get_representative_path_var () const
+bool
+decl_region2::get_representative_path_var (path_var *out) const
 {
   // FIXME: use correct stack depth
-  return path_var (m_decl, 0);
+  // FIXME: should we store a path_var, rather that a tree?
+  *out = path_var (m_decl, 0);
+  return true;
 }
 
 /* class field_region2 : public region2.  */
@@ -2456,6 +2465,13 @@ field_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     }
 }
 
+bool
+field_region2::get_representative_path_var (path_var *) const
+{
+  // TODO
+  return false;
+}
+
 /* class element_region2 : public region2.  */
 
 bool
@@ -2488,6 +2504,29 @@ element_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     }
 }
 
+bool
+element_region2::get_representative_path_var (path_var *) const
+{
+  // TODO:
+#if 0
+  path_var parent_pv (NULL_TREE, 0);
+  if (get_parent_region ()->get_representative_path_var (&parent_pv))
+    {
+      path_var index_pv  (NULL_TREE, 0);
+      if (m_index->get_representative_path_var (&index_pv))
+	{
+	  *out = path_var (build4 (ARRAY_REF,
+				   get_type (),
+				   parent_pv.m_tree, index_pv.m_tree,
+				   NULL_TREE, NULL_TREE),
+			   parent_pv.m_stack_depth);
+	  return true;
+	}
+    }
+#endif
+  return false;
+}
+
 void
 element_region2::add_to_hash (inchash::hash &hstate) const
 {
@@ -2526,6 +2565,13 @@ offset_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     }
 }
 
+bool
+offset_region2::get_representative_path_var (path_var *) const
+{
+  // TODO
+  return false;
+}
+
 void
 offset_region2::add_to_hash (inchash::hash &hstate) const
 {
@@ -2562,6 +2608,13 @@ cast_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     }
 }
 
+bool
+cast_region2::get_representative_path_var (path_var *) const
+{
+  // TODO
+  return false;
+}
+
 void
 cast_region2::add_to_hash (inchash::hash &hstate) const
 {
@@ -2581,6 +2634,12 @@ heap_allocated_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     pp_string (pp, "heap_allocated_region2()");
 }
 
+bool
+heap_allocated_region2::get_representative_path_var (path_var *) const
+{
+  return false;
+}
+
 /* class alloca_region2 : public region2.  */
 
 void
@@ -2593,6 +2652,12 @@ alloca_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     pp_string (pp, "alloca_region2()");
 }
 
+bool
+alloca_region2::get_representative_path_var (path_var *) const
+{
+  return false;
+}
+
 /* class string_region2 : public region2.  */
 
 void
@@ -2611,6 +2676,12 @@ string_region2::dump_to_pp (pretty_printer *pp, bool simple) const
     }
 }
 
+bool
+string_region2::get_representative_path_var (path_var *) const
+{
+  return false;
+}
+
 /* class unknown_region2 : public region2.  */
 
 void
@@ -2619,6 +2690,12 @@ unknown_region2::dump_to_pp (pretty_printer *pp, bool /*simple*/) const
   pp_string (pp, "UNKNOWN_REGION");
 }
 
+bool
+unknown_region2::get_representative_path_var (path_var *) const
+{
+  return false;
+}
+
 /* class region_model2_manager.  */
 
 region_model2_manager::region_model2_manager ()
@@ -5983,12 +6060,17 @@ region_model2::get_representative_tree (const svalue2 *sval) const
   if (const initial_svalue2 *init_sval = sval->dyn_cast_initial_svalue2 ())
     {
       const region2 *reg = init_sval->get_region ();
-      pvs.safe_push (reg->get_representative_path_var ());
+      path_var pv (NULL_TREE, 0);
+      if (reg->get_representative_path_var (&pv))
+	pvs.safe_push (pv);
     }
   if (tree cst = sval->maybe_get_constant ())
     pvs.safe_push (path_var (cst, 0));
 
-  // TODO: sort; pick the best; handle the empty case
+  if (pvs.length () < 1)
+    return NULL_TREE;
+
+  pvs.qsort (readability_comparator);
   return pvs[0].m_tree;
 
 #if 0
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index 06daaa6179e..39a43252113 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -915,7 +915,7 @@ public:
   bool get_byte_size (byte_size_t *out) const;
   bool get_bit_size (bit_size_t *out) const;
 
-  virtual path_var get_representative_path_var () const;
+  virtual bool get_representative_path_var (path_var *out) const = 0;
 
  protected:
   region2 (unsigned id, const region2 *parent, tree type);
@@ -954,6 +954,13 @@ namespace ana {
 
 class space_region2 : public region2
 {
+public:
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE
+  {
+    /* space_region2s are not expressible as trees.  */
+    return false;
+  }
+
 protected:
   space_region2 (unsigned id, const region2 *parent)
   : region2 (id, parent, NULL_TREE)
@@ -1102,6 +1109,10 @@ public:
   enum kind get_kind () const FINAL OVERRIDE { return RK_FUNCTION; }
   const function_region2 *
   dyn_cast_function_region2 () const FINAL OVERRIDE{ return this; }
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE
+  {
+    return false;
+  }
 
   tree get_fndecl () const { return m_fndecl; }
 
@@ -1143,6 +1154,7 @@ public:
   /* region2 vfuncs.  */
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
   enum kind get_kind () const FINAL OVERRIDE { return RK_LABEL; }
+  bool get_representative_path_var (path_var *out) const FINAL OVERRIDE;
 
   //bool compare_fields (const function_region2 &other) const;
 
@@ -1179,6 +1191,11 @@ public:
 
   enum kind get_kind () const FINAL OVERRIDE { return RK_STACK; }
 
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE
+  {
+    return false;
+  }
+
 #if 0
   static bool can_merge_p (const stack_region2 *stack_region2_a,
 			   const stack_region2 *stack_region2_b,
@@ -1234,6 +1251,10 @@ public:
 			   heap_region2 *merged_heap, region2_id merged_heap_rid,
 			   model_merger *merger);
 #endif
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE
+  {
+    return false;
+  }
 };
 
 } // namespace ana
@@ -1262,6 +1283,11 @@ public:
   enum kind get_kind () const FINAL OVERRIDE { return RK_ROOT; }
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
 
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE
+  {
+    return false;
+  }
+
 #if 0
   region2_id push_frame (region_model2 *model, function *fun,
 			vec<svalue2_id> *arg_sids,
@@ -1333,6 +1359,7 @@ public:
   enum kind get_kind () const FINAL OVERRIDE { return region2::RK_SYMBOLIC; }
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE;
 
   const svalue2 *get_pointer () const { return m_sval_ptr; }
 
@@ -1356,7 +1383,7 @@ public:
   dyn_cast_decl_region2 () const FINAL OVERRIDE { return this; }
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
-  path_var get_representative_path_var () const FINAL OVERRIDE;
+  bool get_representative_path_var (path_var *out) const FINAL OVERRIDE;
 
   tree get_decl () const { return m_decl; }
 
@@ -1383,6 +1410,7 @@ public:
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
   const field_region2 *
   dyn_cast_field_region2 () const FINAL OVERRIDE { return this; }
+  bool get_representative_path_var (path_var *out) const FINAL OVERRIDE;
 
   tree get_field () const { return m_field; }
 
@@ -1408,6 +1436,7 @@ public:
   enum region2::kind get_kind () const FINAL OVERRIDE { return RK_ELEMENT; }
   const element_region2 *
   dyn_cast_element_region2 () const FINAL OVERRIDE { return this; }
+  bool get_representative_path_var (path_var *out) const FINAL OVERRIDE;
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
 
@@ -1436,6 +1465,7 @@ public:
   enum region2::kind get_kind () const FINAL OVERRIDE { return RK_OFFSET; }
   const offset_region2 *
   dyn_cast_offset_region2 () const FINAL OVERRIDE { return this; }
+  bool get_representative_path_var (path_var *out) const FINAL OVERRIDE;
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
 
@@ -1463,6 +1493,7 @@ public:
   enum region2::kind get_kind () const FINAL OVERRIDE { return RK_CAST; }
   const cast_region2 *
   dyn_cast_cast_region2 () const FINAL OVERRIDE { return this; }
+  bool get_representative_path_var (path_var *out) const FINAL OVERRIDE;
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
 
@@ -1493,6 +1524,7 @@ public:
   enum region2::kind get_kind () const FINAL OVERRIDE { return RK_HEAP_ALLOCATED; }
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE;
 
 protected:
 #if 0
@@ -1515,6 +1547,7 @@ public:
   enum region2::kind get_kind () const FINAL OVERRIDE { return RK_ALLOCA; }
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE;
 
 protected:
 #if 0
@@ -1540,6 +1573,7 @@ public:
   enum region2::kind get_kind () const FINAL OVERRIDE { return RK_STRING; }
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE;
 
   tree get_string_cst () const { return m_string_cst; }
 
@@ -1564,6 +1598,7 @@ public:
   bool compare_fields (const element_region2 &other) const;
 #endif
   enum region2::kind get_kind () const FINAL OVERRIDE { return RK_UNKNOWN; }
+  bool get_representative_path_var (path_var *) const FINAL OVERRIDE;
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
 
diff --git a/gcc/analyzer/store2.cc b/gcc/analyzer/store2.cc
index 0689c1d0768..be2668ebad2 100644
--- a/gcc/analyzer/store2.cc
+++ b/gcc/analyzer/store2.cc
@@ -644,7 +644,9 @@ binding_cluster2::get_representative_path_vars (const region2 *base_reg,
 	      // TODO: check size as well
 	      if (ckey->get_start_bit_offset () == 0)
 		{
-		  out_pvs->safe_push (base_reg->get_representative_path_var ());
+		  path_var pv (NULL_TREE, 0);
+		  if (base_reg->get_representative_path_var (&pv))
+		    out_pvs->safe_push (pv);
 		}
 	      else
 		gcc_unreachable ();
-- 
2.21.0

