From c2f3242353c281f149a5e2cbe69c983d7f4b5800 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 23 Jun 2020 16:38:47 -0400
Subject: [PATCH 246/251] FIXME: implement region2::descendent_of_p

---
 gcc/analyzer/region-model2.cc | 52 +++++++++++++++++++++++++++++------
 gcc/analyzer/region-model2.h  |  8 ++++++
 2 files changed, 51 insertions(+), 9 deletions(-)

diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index 534eaa53b05..7665e0029db 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -1192,6 +1192,22 @@ region2::get_base_region () const
   return iter;
 }
 
+/* Return true if this region is ELDER or one of its descendents.  */
+// FIXME: unit test
+
+bool
+region2::descendent_of_p (const region2 *elder) const
+{
+  const region2 *iter = this;
+  while (iter)
+    {
+      if (iter == elder)
+	return true;
+      iter = iter->get_parent_region ();
+    }
+  return false;
+}
+
 /* FIXME.  */
 
 tree
@@ -9004,6 +9020,28 @@ test_sub_svalue2_folding ()
   ASSERT_EQ (sub->get_type (), TREE_TYPE (ct.m_x_field));
 }
 
+/* Test that region2::descendent_of_p works as expected.  */
+
+static void
+test_descendent_of_p ()
+{
+  region_model2_manager mgr;
+  const region2 *stack = mgr.get_stack_region ();
+  const region2 *heap = mgr.get_heap_region ();
+  const region2 *code = mgr.get_code_region ();
+  const region2 *globals = mgr.get_globals_region ();
+
+  /* descendent_of_p should return true when used on the region itself.  */
+  ASSERT_TRUE (stack->descendent_of_p (stack));
+  ASSERT_FALSE (stack->descendent_of_p (heap));
+  ASSERT_FALSE (stack->descendent_of_p (code));
+  ASSERT_FALSE (stack->descendent_of_p (globals));
+
+  tree x = build_global_decl ("x", integer_type_node);
+  const region2 *x_reg = mgr.get_region_for_global (x);
+  ASSERT_TRUE (x_reg->descendent_of_p (globals));
+}
+
 #if 0
 /* A subclass of purge_criteria for selftests: purge all const svalue2 *instances.  */
 
@@ -9336,15 +9374,10 @@ test_stack_frames ()
 		   mgr.get_ptr_svalue2 (ptr_type_node, p_in_globals_reg),
 		   &ctxt);
 
-  /* Test get_descendents.  */
-#if 0
-  region2_id_set descendents (&model);
-  model.get_descendents (child_frame_reg, &descendents, region2_id::null ());
-  ASSERT_TRUE (descendents.region2_p (child_frame_reg));
-  ASSERT_TRUE (descendents.region2_p (x_in_child_reg));
-  ASSERT_FALSE (descendents.region2_p (a_in_parent_reg));
-  ASSERT_EQ (descendents.num_region2s (), 3);
-#endif
+  /* Test region2::descendent_of_p.  */
+  ASSERT_TRUE (child_frame_reg->descendent_of_p (child_frame_reg));
+  ASSERT_TRUE (x_in_child_reg->descendent_of_p (child_frame_reg));
+  ASSERT_FALSE (a_in_parent_reg->descendent_of_p (child_frame_reg));
 #if 0
   auto_vec<region2_id> test_vec;
   for (region2_id_set::iterator_t iter = descendents.begin ();
@@ -10610,6 +10643,7 @@ analyzer_region_model2_cc_tests ()
   test_unaryop_svalue2_folding ();
   test_binop_svalue2_folding ();
   test_sub_svalue2_folding ();
+  test_descendent_of_p ();
 #if 0
   test_purging_by_criteria ();
   test_purge_unused_svalue2s ();
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index f949c445ac1..97ac2bced52 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -1155,6 +1155,7 @@ public:
 
   const region2 *get_parent_region () const { return m_parent; }
   const region2 *get_base_region () const;
+  bool descendent_of_p (const region2 *elder) const;
 
   tree maybe_get_decl () const;
 
@@ -1963,6 +1964,13 @@ public:
 						 const svalue2 *iter_svalue);
 
   /* region2 consolidation.  */
+  const stack_region2 * get_stack_region () const { return &m_stack_region; }
+  const heap_region2 *get_heap_region () const { return &m_heap_region; }
+  const code_region2 *get_code_region () const { return &m_code_region; }
+  const globals_region2 *get_globals_region () const
+  {
+    return &m_globals_region;
+  }
   const function_region2 *get_region_for_fndecl (tree fndecl);
   const label_region2 *get_region_for_label (tree label);
   const decl_region2 *get_region_for_global (tree expr);
-- 
2.26.2

