From 2d8a9ba47febebdc0f289217746ced0c972448df Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 16 Apr 2020 18:17:38 -0400
Subject: [PATCH 052/377] FIXME: fix region_model2 copy-ctor

---
 gcc/analyzer/region-model2.cc | 24 ++++++++++++++++++++----
 gcc/analyzer/store2.cc        | 19 ++++++++++++++++++-
 gcc/analyzer/store2.h         |  5 +++++
 3 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index e725691e8bb..edae4947ec0 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -2925,7 +2925,7 @@ region_model2_manager::get_symbolic_region (svalue2 *sval)
 /* FIXME: region_model2's default ctor.  */
 
 region_model2::region_model2 (region_model2_manager *mgr)
-: m_mgr (mgr), m_current_frame (NULL)
+: m_mgr (mgr), m_store (), m_current_frame (NULL)
 {
   //m_root_reg = add_region2 (new root_region2 ());
   //m_constraints = new impl_constraint_manager (this);
@@ -2935,9 +2935,9 @@ region_model2::region_model2 (region_model2_manager *mgr)
 /* region_model2's copy ctor.  */
 
 region_model2::region_model2 (const region_model2 &other)
-: m_mgr (other.m_mgr), m_current_frame (other.m_current_frame)
+: m_mgr (other.m_mgr), m_store (other.m_store),
+  m_current_frame (other.m_current_frame)
 {
-  // TODO: deep copy of m_cluster_map
 }
 
 /* region_model2's dtor.  */
@@ -7488,16 +7488,32 @@ test_get_representative_path_var ()
 static void
 test_model_equality_1 ()
 {
+  tree int_42 = build_int_cst (integer_type_node, 42);
+  tree int_17 = build_int_cst (integer_type_node, 17);
+
   region_model2_manager mgr;
   region_model2 model0 (&mgr);
   region_model2 model1 (&mgr);
   ASSERT_EQ (model0, model1);
 
   /* Verify that setting state in model1 makes the models non-equal.  */
-  tree int_42 = build_int_cst (integer_type_node, 42);
   tree x = build_global_decl ("x", integer_type_node);
   model0.set_value (x, int_42, NULL);
+  ASSERT_EQ (model0.get_rvalue (x, NULL)->maybe_get_constant (), int_42);
   ASSERT_NE (model0, model1);
+
+  /* Verify the copy-ctor.  */
+  region_model2 model2 (model0);
+  ASSERT_EQ (model0, model2);
+  ASSERT_EQ (model2.get_rvalue (x, NULL)->maybe_get_constant (), int_42);
+  ASSERT_NE (model1, model2);
+
+  /* Verify that models obtained from copy-ctor are independently editable
+     w/o affecting the original model.  */
+  model2.set_value (x, int_17, NULL);
+  ASSERT_NE (model0, model2);
+  ASSERT_EQ (model2.get_rvalue (x, NULL)->maybe_get_constant (), int_17);
+  ASSERT_EQ (model0.get_rvalue (x, NULL)->maybe_get_constant (), int_42);
 }
 
 /* Verify that region2 models for
diff --git a/gcc/analyzer/store2.cc b/gcc/analyzer/store2.cc
index 2d3c7f8fccc..2a342aa62b0 100644
--- a/gcc/analyzer/store2.cc
+++ b/gcc/analyzer/store2.cc
@@ -261,10 +261,27 @@ store2_manager::get_symbolic_binding (const region2 *reg,
 
 /* class store2.  */
 
+store2::store2 ()
+{
+}
+
+store2::store2 (const store2 &other)
+{
+  /* Deep copy.  TODO: replace with functional approach using immutable_map.  */
+  for (cluster_map_t::iterator iter = other.m_cluster_map.begin ();
+       iter != other.m_cluster_map.end ();
+       ++iter)
+    {
+      const region2 *reg = (*iter).first;
+      binding_cluster2 *c = (*iter).second;
+      m_cluster_map.put (reg, new binding_cluster2 (*c));
+    }
+}
+
 bool
 store2::operator== (const store2 &other) const
 {
-  if (m_cluster_map.elements () != m_cluster_map.elements ())
+  if (m_cluster_map.elements () != other.m_cluster_map.elements ())
     return false;
 
   for (cluster_map_t::iterator iter = m_cluster_map.begin ();
diff --git a/gcc/analyzer/store2.h b/gcc/analyzer/store2.h
index ef92aa70f3e..8e05e2a7293 100644
--- a/gcc/analyzer/store2.h
+++ b/gcc/analyzer/store2.h
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "analyzer/uniq-manager.h" // FIXME
 
+// TODO: convert to immutable types and a functional model
+
 /* Implementation of the region-based ternary model described in:
      "A Memory Model for Static Analysis of C Programs"
       (Zhongxing Xu, Ted Kremenek, and Jian Zhang)
@@ -180,6 +182,9 @@ private:
 class store2
 {
 public:
+  store2 ();
+  store2 (const store2 &other);
+
   bool operator== (const store2 &other) const;
   bool operator!= (const store2 &other) const
   {
-- 
2.26.2

