From 6bc88df18f6f3dba1b364d166ec656a942cc4c65 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 16 Jul 2019 14:21:37 -0400
Subject: [PATCH 093/108] FIXME: always have a svalue_id_merger_mapping when
 merging region_models

---
 gcc/analyzer/constraint-manager.cc |  8 ++---
 gcc/analyzer/region-model.cc       | 67 +++++++++++++++++++-------------------
 gcc/analyzer/region-model.h        | 14 +++++---
 3 files changed, 46 insertions(+), 43 deletions(-)

diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index 73eda94..398e404 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -1492,21 +1492,19 @@ constraint_manager::merge (const constraint_manager &cm_a,
 			   constraint_manager *out,
 			   const model_merger &merger)
 {
-  /* We can only attempt to merge them if we have svalue_id mapping data.  */
-  if (!merger.m_svalue_id_mapping)
-    return;
+  gcc_assert (merger.m_sid_mapping);
 
   /* Map svalue_ids in each equiv class from both sources
      to the merged region_model, dropping ids that don't survive merger,
      and potentially creating svalues in *OUT for constants.  */
   cleaned_constraint_manager cleaned_cm_a (out);
   const one_way_svalue_id_map &map_a_to_m
-    = merger.m_svalue_id_mapping->m_map_from_a_to_m;
+    = merger.m_sid_mapping->m_map_from_a_to_m;
   clean_merger_input (cm_a, map_a_to_m, &cleaned_cm_a);
 
   cleaned_constraint_manager cleaned_cm_b (out);
   const one_way_svalue_id_map &map_b_to_m
-    = merger.m_svalue_id_mapping->m_map_from_b_to_m;
+    = merger.m_sid_mapping->m_map_from_b_to_m;
   clean_merger_input (cm_b, map_b_to_m, &cleaned_cm_b);
 
   /* At this point, the two cleaned CMs have ECs and constraints referring
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index 8deb91e..3846590 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -4326,18 +4326,20 @@ region_model::poison_any_pointers_to_bad_regions (const region_id_set &
       }
 }
 
-/* FIXME.  */
+/* Attempt to merge THIS with OTHER_MODEL, writing the result
+   to OUT_MODEL, and populating SID_MAPPING.  */
 
 bool
 region_model::can_merge_with_p (const region_model &other_model,
 				region_model *out_model,
-				svalue_id_merger_mapping *out) const
+				svalue_id_merger_mapping *sid_mapping) const
 {
   gcc_assert (m_root_rid == other_model.m_root_rid);
   gcc_assert (m_root_rid.as_int () == 0);
+  gcc_assert (sid_mapping);
 
   region_model result;
-  model_merger merger (this, &other_model, &result, out);
+  model_merger merger (this, &other_model, &result, sid_mapping);
 
   if (!root_region::can_merge_p (get_root_region (),
 				 other_model.get_root_region (),
@@ -4359,6 +4361,17 @@ region_model::can_merge_with_p (const region_model &other_model,
   return true;
 }
 
+/* As above, but supply a placeholder svalue_id_merger_mapping
+   instance to be used and receive output.  For use in selftests.  */
+
+bool
+region_model::can_merge_with_p (const region_model &other_model,
+				region_model *out_model) const
+{
+  svalue_id_merger_mapping sid_mapping (*this, other_model);
+  return can_merge_with_p (other_model, out_model, &sid_mapping);
+}
+
 ////////////////////////////////////////////////////////////////////////////
 
 /* struct model_merger.  */
@@ -4393,8 +4406,7 @@ model_merger::dump_to_pp (pretty_printer *pp) const
   m_map_regions_from_b_to_m.dump_to_pp (pp);
   pp_newline (pp);
 
-  if (m_svalue_id_mapping)
-    m_svalue_id_mapping->dump_to_pp (pp);
+  m_sid_mapping->dump_to_pp (pp);
 }
 
 /* Dump a multiline representation of this merger to FILE.  */
@@ -4444,19 +4456,16 @@ model_merger::can_merge_values_p (svalue_id sid_a,
 
   /* Have they both already been mapped to the same new svalue_id?
      If so, use it.  */
-  if (m_svalue_id_mapping)
+  svalue_id sid_a_in_m
+    = m_sid_mapping->m_map_from_a_to_m.get_dst_for_src (sid_a);
+  svalue_id sid_b_in_m
+    = m_sid_mapping->m_map_from_b_to_m.get_dst_for_src (sid_b);
+  if (!sid_a_in_m.null_p ()
+      && !sid_b_in_m.null_p ()
+      && sid_a_in_m == sid_b_in_m)
     {
-      svalue_id sid_a_in_m
-	= m_svalue_id_mapping->m_map_from_a_to_m.get_dst_for_src (sid_a);
-      svalue_id sid_b_in_m
-	= m_svalue_id_mapping->m_map_from_b_to_m.get_dst_for_src (sid_b);
-      if (!sid_a_in_m.null_p ()
-	  && !sid_b_in_m.null_p ()
-	  && sid_a_in_m == sid_b_in_m)
-	{
-	  *merged_sid = sid_a_in_m;
-	  return true;
-	}
+      *merged_sid = sid_a_in_m;
+      return true;
     }
 
 #if 0
@@ -4549,11 +4558,9 @@ model_merger::record_svalues (svalue_id a_sid,
 			      svalue_id b_sid,
 			      svalue_id merged_sid)
 {
-  if (m_svalue_id_mapping)
-    {
-      m_svalue_id_mapping->m_map_from_a_to_m.put (a_sid, merged_sid);
-      m_svalue_id_mapping->m_map_from_b_to_m.put (b_sid, merged_sid);
-    }
+  gcc_assert (m_sid_mapping);
+  m_sid_mapping->m_map_from_a_to_m.put (a_sid, merged_sid);
+  m_sid_mapping->m_map_from_b_to_m.put (b_sid, merged_sid);
 }
 
 ////////////////////////////////////////////////////////////////////////////
@@ -5168,9 +5175,7 @@ test_purging ()
 static void
 assert_region_models_merge (tree expr, tree val_a, tree val_b,
 			    region_model *out_merged_model,
-			    svalue **out_merged_svalue,
-			    svalue_id_merger_mapping *out_svalue_merger_map
-			      = NULL)
+			    svalue **out_merged_svalue)
 {
   // FIXME: break this out into a helper function:
   /* FIXME: might have to be a a class, so that the values can outlive
@@ -5186,8 +5191,7 @@ assert_region_models_merge (tree expr, tree val_a, tree val_b,
 		      model1.get_rvalue (val_b, &ctxt));
 
   /* They should be mergeable.  */
-  ASSERT_TRUE (model0.can_merge_with_p (model1, out_merged_model,
-					out_svalue_merger_map));
+  ASSERT_TRUE (model0.can_merge_with_p (model1, out_merged_model));
 
   svalue_id merged_svalue_sid = out_merged_model->get_rvalue (expr, &ctxt);
   *out_merged_svalue = out_merged_model->get_svalue (merged_svalue_sid);
@@ -5514,11 +5518,9 @@ test_state_merging ()
     model0.set_value (model0.get_lvalue (y, &ctxt), sid);
     region_model model1 (model0);
 
-    /* They should be mergeable, and the result should be the same
-       (this requires an svalue_id_merger_mapping to work).  */
+    /* They should be mergeable, and the result should be the same.  */
     region_model merged;
-    svalue_id_merger_mapping sid_mapping (model0, model1);
-    ASSERT_TRUE (model0.can_merge_with_p (model1, &merged, &sid_mapping));
+    ASSERT_TRUE (model0.can_merge_with_p (model1, &merged));
     ASSERT_EQ (model0, merged);
 
     /* In particular, we should have x == y.  */
@@ -5590,8 +5592,7 @@ test_constraint_merging ()
   /* They should be mergeable; the merged constraints should
      be: (0 <= x < n).  */
   region_model merged;
-  svalue_id_merger_mapping sid_mapping (model0, model1);
-  ASSERT_TRUE (model0.can_merge_with_p (model1, &merged, &sid_mapping));
+  ASSERT_TRUE (model0.can_merge_with_p (model1, &merged));
 
   ASSERT_EQ (merged.eval_condition (x, GE_EXPR, int_0, &ctxt),
 	     tristate (tristate::TS_TRUE));
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index bc350e5..643299a 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -1024,7 +1024,9 @@ class region_model
 
   bool can_merge_with_p (const region_model &other_model,
 			 region_model *out_model,
-			 svalue_id_merger_mapping *out = NULL) const;
+			 svalue_id_merger_mapping *out) const;
+  bool can_merge_with_p (const region_model &other_model,
+			 region_model *out_model) const;
 
  private:
   void update_for_call_superedge (const call_superedge &call_edge,
@@ -1113,13 +1115,15 @@ struct model_merger
   model_merger (const region_model *model_a,
 		const region_model *model_b,
 		region_model *merged_model,
-		svalue_id_merger_mapping *svalue_id_mapping)
+		svalue_id_merger_mapping *sid_mapping)
   : m_model_a (model_a), m_model_b (model_b),
     m_merged_model (merged_model),
     m_map_regions_from_a_to_m (model_a->get_num_regions ()),
     m_map_regions_from_b_to_m (model_b->get_num_regions ()),
-    m_svalue_id_mapping (svalue_id_mapping)
-  {}
+    m_sid_mapping (sid_mapping)
+  {
+    gcc_assert (sid_mapping);
+  }
 
   void dump_to_pp (pretty_printer *pp) const;
   void dump (FILE *fp) const;
@@ -1155,7 +1159,7 @@ struct model_merger
 
   one_way_region_id_map m_map_regions_from_a_to_m;
   one_way_region_id_map m_map_regions_from_b_to_m;
-  svalue_id_merger_mapping *m_svalue_id_mapping;
+  svalue_id_merger_mapping *m_sid_mapping;
 };
 
 /* A bundle of data that can be optionally generated during merger of two
-- 
1.8.5.3

