From 707682bc0ecb694466753f22622f0e1e30c99575 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Sat, 11 Apr 2020 12:33:00 -0400
Subject: [PATCH 21/96] FIXME: start adding conjured_savl

---
 gcc/analyzer/revamp-state.cc | 59 +++++++++++++++++++++++++++--------
 gcc/analyzer/revamp-state.h  | 60 ++++++++++++++++++++++++++++++++++++
 2 files changed, 106 insertions(+), 13 deletions(-)

diff --git a/gcc/analyzer/revamp-state.cc b/gcc/analyzer/revamp-state.cc
index 35657a62a29..b24dccf1fbf 100644
--- a/gcc/analyzer/revamp-state.cc
+++ b/gcc/analyzer/revamp-state.cc
@@ -199,6 +199,18 @@ mem_region_val::add_to_hash (inchash::hash &hstate) const
   hstate.add_ptr (m_region);
 }
 
+void
+symbolic_sval::add_to_hash (inchash::hash &hstate) const
+{
+  // no-op: don't hash the ID, to get reuse
+}
+
+void
+conjured_sval::add_to_hash (inchash::hash &hstate) const
+{
+  hstate.add_ptr (m_stmt);
+}
+
 /* mem_region hash implementations.  */
 
 void
@@ -270,6 +282,23 @@ mem_region_val::cmp_fields (const sval &base_other) const
   return m_region == sub_other.m_region;
 }
 
+bool
+symbolic_sval::cmp_fields (const sval &base_other) const
+{
+  const symbolic_sval &sub_other = (const symbolic_sval &)base_other;
+  // FIXME: we deliberately don't compare the ID, to merge them
+  return true;
+}
+
+bool
+conjured_sval::cmp_fields (const sval &base_other) const
+{
+  const conjured_sval &sub_other = (const conjured_sval &)base_other;
+  if (!symbolic_sval::cmp_fields (sub_other))
+    return false;
+  return m_stmt == sub_other.m_stmt;
+}
+
 /* mem_region cmp_fields implementations.  */
 
 bool
@@ -351,6 +380,12 @@ mem_region_val::dump_to_pp (pretty_printer *pp) const
   pp_printf (pp, ")");
 }
 
+void
+conjured_sval::dump_to_pp (pretty_printer *pp) const
+{
+  pp_printf (pp, "conjured_sval($%i)", get_id ());
+}
+
 /* mem_region dump_to_pp implementations.  */
 
 void
@@ -449,20 +484,17 @@ store::get_val_for_loc (const extrinsic_state &ext_state, const loc_val *val)
 	{
 	  gcc_unreachable ();
 	}
-      else
-	{
-	  gcc_unreachable ();
-	}
-    }
-  else
-    {
-      // TODO:
-      /* No value recorded for this region; try parent.  */
-      // ...and try inheritance, default values, etc
-      // FIXME: for now, an unknown value
-      engine *eng = ext_state.get_engine ();
-      return eng->consolidate_sval (new unknown_sval ());
     }
+
+  // TODO:
+  /* No value recorded for this region; try parent.  */
+  // ...and try inheritance, default values, etc
+  // FIXME: for now, an unknown value
+  engine *eng = ext_state.get_engine ();
+  return eng->consolidate_sval (new conjured_sval (eng->alloc_sym_id (),
+						   NULL)); // FIXME
+  /* FIXME: we only want to allocate a sym ID if it's going to be a
+     new conjured_sval.  */
 }
 
 json::value *
@@ -889,6 +921,7 @@ revamp_state::get_super_region_for_decl (const extrinsic_state &ext_state,
 /* class engine.  */
 
 engine::engine ()
+: m_next_sym_id (0)
 {
   m_sval_mgr = new uniq_manager<sval> ();
   m_mem_region_mgr = new uniq_manager<mem_region> ();
diff --git a/gcc/analyzer/revamp-state.h b/gcc/analyzer/revamp-state.h
index 357b10d5485..a06634445f3 100644
--- a/gcc/analyzer/revamp-state.h
+++ b/gcc/analyzer/revamp-state.h
@@ -39,11 +39,14 @@ public:
    SK_cst_sval,
    SK_unknown_sval,
    SK_mem_region_val,
+   SK_conjured_sval
   };
   virtual ~sval () {}
 
   virtual kind get_kind () const = 0;
 
+  virtual bool loc_val_p () const { return false; }
+
   /* For use with uniq_manager.  */
   hashval_t hash () const;
   bool operator== (const sval &other) const;
@@ -106,14 +109,66 @@ private:
   // FIXME: is there a single unknown_sval, or multiple ones?
   // FIXME: perhaps there's just one, and equality
   // is recorded in constraint manager?  (but how?)
+  // There's a single unknown_sval, but multiple conjured_sval
 };
 
 class loc_val : public sval
 {
  public:
+  bool loc_val_p () const FINAL OVERRIDE { return true; }
+
   virtual const mem_region *get_mem_region () const = 0;
 };
 
+/* A symbolic val, with a unique ID.  */
+
+class symbolic_sval : public sval
+{
+public:
+  typedef unsigned id_t;
+
+  id_t get_id () const { return m_id; }
+
+protected:
+  symbolic_sval (id_t id) : m_id (id) {}
+
+  void add_to_hash (inchash::hash &hstate) const OVERRIDE;
+  bool cmp_fields (const sval &other) const OVERRIDE;
+
+private:
+  id_t m_id;
+};
+
+class conjured_sval : public symbolic_sval
+{
+public:
+  conjured_sval (id_t id, const gimple *stmt)
+  : symbolic_sval (id), m_stmt (stmt) {}
+
+  kind get_kind () const FINAL OVERRIDE { return SK_conjured_sval; }
+
+  void dump_to_pp (pretty_printer *pp) const FINAL OVERRIDE;
+
+ protected:
+  void add_to_hash (inchash::hash &hstate) const FINAL OVERRIDE;
+  bool cmp_fields (const sval &other) const FINAL OVERRIDE;
+
+private:
+  const gimple *m_stmt;
+};
+
+} // namespace ana
+
+template <>
+template <>
+inline bool
+is_a_helper <const loc_val *>::test (const sval *val)
+{
+  return val->loc_val_p ();
+}
+
+namespace ana {
+
 class unknown_loc_val : public loc_val
 {
  public:
@@ -519,6 +574,9 @@ class engine
     return &m_store_map_mgr;
   }
 
+  /* Symbolic value IDs.  */
+  symbolic_sval::id_t alloc_sym_id () { return m_next_sym_id++; }
+
  private:
   uniq_manager<sval> *m_sval_mgr;
   uniq_manager<mem_region> *m_mem_region_mgr;
@@ -526,6 +584,8 @@ class engine
   uniq_manager<revamp_state> *m_state_mgr;
   uniq_manager<binding_cluster> m_binding_cluster_mgr;
   uniq_manager<store::cluster_map_t> m_store_map_mgr;
+
+  symbolic_sval::id_t m_next_sym_id;
 };
 
 } // namespace ana
-- 
2.21.0

