From cf273e8b7a4a426243a44b8107e3da1e3ab305c9 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 14 Apr 2020 18:24:10 -0400
Subject: [PATCH 036/159] FIXME: more on region_offset

---
 gcc/analyzer/region-model2.cc | 48 +++++++++++++++++++++++++++++------
 gcc/analyzer/region-model2.h  | 23 ++++++++++-------
 2 files changed, 54 insertions(+), 17 deletions(-)

diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index edd3ee418a0..ccc94cc76b3 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -879,8 +879,8 @@ region2::calc_offset () const
 	    const field_region2 *field_region
 	      = (const field_region2 *)iter_region;
 	    iter_region = iter_region->get_parent_region ();
-	    gcc_unreachable ();
-	    //offset += ;
+	    tree field_offset = DECL_FIELD_OFFSET (field_region->get_field ());
+	    byte_offset += tree_to_shwi (field_offset);
 	  }
 	  continue;
 
@@ -2889,6 +2889,15 @@ element_region2::add_to_hash (inchash::hash &hstate) const
 
 /* class binding_key.  */
 
+const binding_key *
+binding_key::make (region_model2_manager *mgr, region2 *r, enum kind kind)
+{
+  region_offset offset = r->get_offset ();
+  // FIXME: what if symbolic vs concrete?
+  return mgr->get_concrete_binding (offset.get_base_region (), kind,
+				    offset.get_byte_offset ());
+}
+
 /* FIXME.  */
 
 int
@@ -2962,18 +2971,16 @@ void
 binding_cluster::bind (region_model2_manager *mgr,
 		       region2 *reg, svalue2 *val)
 {
-  // FIXME: what if symbolic vs concrete?
   const binding_key *binding
-    = mgr->get_concrete_binding (reg, binding_key::BK_direct, 0);
+    = binding_key::make (mgr, reg, binding_key::BK_direct);
   m_map.put (binding, val);
 }
 
 svalue2 *
 binding_cluster::get_binding (region_model2_manager *mgr, region2 *reg) const
 {
-  // FIXME: what if symbolic vs concrete?
   const binding_key *binding
-    = mgr->get_concrete_binding (reg, binding_key::BK_direct, 0);
+    = binding_key::make (mgr, reg, binding_key::BK_direct);
   svalue2 **slot = const_cast<map_t &> (m_map).get (binding);
   if (slot)
     return *slot;
@@ -3077,7 +3084,7 @@ region_model2_manager::get_element_region (region2 *parent,
 }
 
 const concrete_binding *
-region_model2_manager::get_concrete_binding (region2 *region,
+region_model2_manager::get_concrete_binding (const region2 *region,
 					     enum binding_key::kind kind,
 					     concrete_binding::offset_t offset)
 {
@@ -3086,7 +3093,7 @@ region_model2_manager::get_concrete_binding (region2 *region,
 }
 
 const symbolic_binding *
-region_model2_manager::get_symbolic_binding (region2 *region,
+region_model2_manager::get_symbolic_binding (const region2 *region,
 					     enum binding_key::kind kind,
 					     region2 *concrete_offset_region)
 {
@@ -7083,6 +7090,31 @@ test_dump_2 ()
 
   // TODO: test get_value
 
+  /* Verify get_offset for "c.x".  */
+  {
+    region2 *c_x_reg = model.get_lvalue (&mgr, c_x, NULL);
+    region_offset offset = c_x_reg->get_offset ();
+    ASSERT_EQ (offset.get_base_region (), model.get_lvalue (&mgr, c, NULL));
+    ASSERT_EQ (offset.get_byte_offset (), 0);
+  }
+
+  /* Verify get_offset for "c.y".  */
+  {
+    region2 *c_y_reg = model.get_lvalue (&mgr, c_y, NULL);
+    region_offset offset = c_y_reg->get_offset ();
+    ASSERT_EQ (offset.get_base_region (), model.get_lvalue (&mgr, c, NULL));
+#if 0
+    /* FIXME: this is failing; the DECL_FIELD_OFFSET of field_y is 0
+       for some reason, even after layout_type.  */
+    ASSERT_EQ (offset.get_byte_offset (), 4);
+#endif
+    // FIXME: this assumes sizeof(int) == 4 on the target
+  }
+
+  // FIXME: test of casting to an "int *"
+
+  // FIXME: rename this test; it's doing much more that just dumps
+
   /* FIXME: fails due to lack of sorting!
      ...but time to implement a[0] = ; a[1] = ; a[i] = ;
      and a more sophisticated region binding/cluster implementation.  */
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index b55b6e4183c..fc90b423ef5 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -1214,6 +1214,8 @@ public:
 
   void dump_to_pp (pretty_printer *pp, bool simple) const FINAL OVERRIDE;
 
+  tree get_field () const { return m_field; }
+
 protected:
   void add_to_hash (inchash::hash &hstate) const OVERRIDE;
 
@@ -1264,6 +1266,9 @@ public:
     return kind == BK_direct ? "direct" : "default";
   }
 
+  static const binding_key *make (region_model2_manager *mgr, region2 *r,
+				  enum kind kind);
+
   virtual void dump_to_pp (pretty_printer *pp, bool simple) const
   {
     pp_string (pp, "region: ");
@@ -1275,10 +1280,10 @@ public:
   static int cmp (const binding_key *, const binding_key *);
 
 protected:
-  binding_key (region2 *region, enum kind kind)
+  binding_key (const region2 *region, enum kind kind)
   : m_region (region), m_kind (kind) {}
 
-  region2 *get_region () const { return m_region; }
+  const region2 *get_region () const { return m_region; }
 
   enum kind get_kind () const { return m_kind; }
 
@@ -1292,7 +1297,7 @@ protected:
   }
 
 private:
-  region2 *m_region;
+  const region2 *m_region;
   enum kind m_kind;
 };
 
@@ -1301,7 +1306,7 @@ class concrete_binding : public binding_key
 public:
   typedef unsigned offset_t;
 
-  concrete_binding (region2 *region, enum kind kind, offset_t offset)
+  concrete_binding (const region2 *region, enum kind kind, offset_t offset)
   : binding_key (region, kind), m_offset (offset)
   {}
   bool concrete_p () const FINAL OVERRIDE { return true; }
@@ -1330,8 +1335,8 @@ private:
 class symbolic_binding : public binding_key
 {
 public:
-  symbolic_binding (region2 *region, enum kind kind,
-		    region2 *concrete_offset_region)
+  symbolic_binding (const region2 *region, enum kind kind,
+		    const region2 *concrete_offset_region)
   : binding_key (region, kind),
     m_concrete_offset_region (concrete_offset_region)
   {}
@@ -1356,7 +1361,7 @@ public:
   }
 
 private:
-  region2 *m_concrete_offset_region;
+  const region2 *m_concrete_offset_region;
 };
 
 /* All of the bindings within a store for regions that share the same
@@ -1417,12 +1422,12 @@ public:
 			       region_model2_context *ctxt);
 
   const concrete_binding *
-  get_concrete_binding (region2 *region,
+  get_concrete_binding (const region2 *region,
 			enum binding_key::kind kind,
 			concrete_binding::offset_t offset);
 
   const symbolic_binding *
-  get_symbolic_binding (region2 *region,
+  get_symbolic_binding (const region2 *region,
 			enum binding_key::kind kind,
 			region2 *concrete_offset_region);
 
-- 
2.21.0

