From fa5f51e90bff18c419ab9f726ef5c201514b4498 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 16 Apr 2020 12:17:58 -0400
Subject: [PATCH 047/193] FIXME: get simple dereferencing working

---
 gcc/analyzer/region-model2.cc | 95 ++++++++++++++++++++++++++---------
 gcc/analyzer/region-model2.h  |  8 +--
 2 files changed, 75 insertions(+), 28 deletions(-)

diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index e46d71011a1..d128cf4b460 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -4380,18 +4380,26 @@ region_model2::get_lvalue_1 (path_var pv,
 				   ctxt);
       };
       break;
-
+#endif
     case MEM_REF:
       {
 	tree ptr = TREE_OPERAND (expr, 0);
 	tree offset = TREE_OPERAND (expr, 1);
 	svalue2 *ptr_sval = get_rvalue (ptr, ctxt);
 	svalue2 *offset_sval = get_rvalue (offset, ctxt);
+	region2 *star_ptr = deref_rvalue (ptr_sval, ctxt);
+	return m_mgr->get_element_region (star_ptr,
+					  TREE_TYPE (TREE_TYPE (ptr)),
+					  offset_sval, ctxt); // FIXME: offset_sval is in bytes; should this be in elements?
+#if 0
 	return get_or_create_mem_ref (TREE_TYPE (expr), ptr_sval,
 				      offset_sval, ctxt);
+#endif
+	/* TODO: a selftest of casting a buffer to both an (int *)
+	   and a (coord *), and doing array accesses with both arrays.  */
       }
       break;
-#endif
+
     case VAR_DECL:
       /* Handle globals.  */
       if (is_global_var (expr))
@@ -4544,22 +4552,22 @@ region_model2::get_rvalue_1 (path_var pv,
       }
       break;
 
-#if 0
     case ADDR_EXPR:
       {
 	/* "&EXPR".  */
 	tree expr = pv.m_tree;
 	tree op0 = TREE_OPERAND (expr, 0);
+#if 0
 	if (TREE_CODE (op0) == FUNCTION_DECL)
-	  return get_svalue2_for_fndecl (TREE_TYPE (expr), op0, ctxt);
+	  return m_mgr->get_svalue2_for_fndecl (TREE_TYPE (expr), op0, ctxt);
 	else if (TREE_CODE (op0) == LABEL_DECL)
-	  return get_svalue2_for_label (TREE_TYPE (expr), op0, ctxt);
+	  return m_mgr->get_svalue2_for_label (TREE_TYPE (expr), op0, ctxt);
+#endif
 	region2 *expr_reg = get_lvalue (op0, ctxt);
-	return get_or_create_ptr_svalue2 (TREE_TYPE (expr), expr_reg);
+	return m_mgr->get_ptr_svalue2 (TREE_TYPE (expr), expr_reg);
       }
       break;
 
-#endif
     case SSA_NAME:
     case VAR_DECL:
     case PARM_DECL:
@@ -4574,14 +4582,13 @@ region_model2::get_rvalue_1 (path_var pv,
     case REAL_CST:
     case STRING_CST:
       return m_mgr->get_or_create_constant_svalue2 (pv.m_tree);
-#if 0
+
     case COMPONENT_REF:
     case MEM_REF:
       {
-	region2 *var_reg = get_lvalue (pv, ctxt);
-	return get_region2 (var_reg)->get_value (*this, true, ctxt);
+	region2 *ref_reg = get_lvalue (pv, ctxt);
+	return get_store_value (ref_reg);
       }
-#endif
     }
 }
 
@@ -4898,39 +4905,41 @@ region_model2::get_field_region (region2 *struct_or_union_reg, tree field,
 
 /* Get a region2 *for referencing PTR_SVAL, creating a region2 if need be, and
    potentially generating warnings via CTXT.  */
-#if 0
-region2_id
+
+region2 *
 region_model2::deref_rvalue (svalue2 *ptr_sval, region_model2_context *ctxt)
 {
-  gcc_assert (!ptr_sval.null_p ());
-  svalue2 *ptr_svalue2 = get_svalue2 (ptr_sval);
-  gcc_assert (ptr_svalue2);
+  gcc_assert (ptr_sval);
 
-  switch (ptr_svalue2->get_kind ())
+  switch (ptr_sval->get_kind ())
     {
-    case SK_REGION2:
+    default:
+      gcc_unreachable ();
+
+    case svalue2::SK_REGION:
       {
-	region_svalue2 *region2_sval = as_a <region_svalue2 *> (ptr_svalue2);
+	region_svalue2 *region2_sval = as_a <region_svalue2 *> (ptr_sval);
 	return region2_sval->get_pointee ();
       }
 
-    case SK_CONSTANT:
+#if 0
+    case svalue2::SK_CONSTANT:
       goto create_symbolic_region2;
 
-    case SK_POISONED:
+    case svalue2::SK_POISONED:
       {
 	if (ctxt)
 	  if (tree ptr = get_representative_tree (ptr_sval))
 	    {
 	      poisoned_svalue2 *poisoned_sval
-		= as_a <poisoned_svalue2 *> (ptr_svalue2);
+		= as_a <poisoned_svalue2 *> (ptr_sval);
 	      enum poison_kind pkind = poisoned_sval->get_poison_kind ();
 	      ctxt->warn (new poisoned_value_diagnostic (ptr, pkind));
 	    }
 	goto create_symbolic_region2;
       }
 
-    case SK_UNKNOWN:
+    case svalue2::SK_UNKNOWN:
       {
       create_symbolic_region2:
 	/* We need a symbolic_region2 to represent this unknown region2.
@@ -4947,19 +4956,22 @@ region_model2::deref_rvalue (svalue2 *ptr_sval, region_model2_context *ctxt)
 	   to PTR's lvalue since there could be several places sharing
 	   the same unknown ptr value.  */
 	svalue2 *ptr_val
-	  = new region_svalue2 (ptr_svalue2->get_type (), new_reg);
+	  = new region_svalue2 (ptr_sval->get_type (), new_reg);
 	replace_svalue2 (ptr_sval, ptr_val);
 
 	return new_reg;
       }
 
-    case SK_SETJMP:
+    case svalue2::SK_SETJMP:
       goto create_symbolic_region2;
+#endif
     }
 
   gcc_unreachable ();
 }
 
+#if 0
+
 /* Get a region2 *for referencing PTR, creating a region2 if need be, and
    potentially generating warnings via CTXT.  */
 
@@ -8375,6 +8387,38 @@ test_array ()
 
 }
 
+/* FIXME.  */
+
+static void
+test_mem_ref ()
+{
+  /*
+    x = 17;
+    p = &x;
+    *p;
+   */
+  tree x = build_global_decl ("x", integer_type_node);
+  tree int_star = build_pointer_type (integer_type_node);
+  tree p = build_global_decl ("p", int_star);
+
+  tree int_17 = build_int_cst (integer_type_node, 17);
+  tree addr_of_x = build1 (ADDR_EXPR, int_star, x);
+  tree offset_0 = build_int_cst (integer_type_node, 0);
+  tree star_p = build2 (MEM_REF, integer_type_node, p, offset_0);
+
+  region_model2_manager mgr;
+  region_model2 model (&mgr);
+
+  /* "x = 17;".  */
+  model.set_value (x, int_17, NULL);
+
+  /* "p = &x;".  */
+  model.set_value (p, addr_of_x, NULL);
+
+  svalue2 *sval = model.get_rvalue (star_p, NULL);
+  ASSERT_EQ (sval->maybe_get_constant (), int_17);
+}
+
 /* Run all of the selftests within this file.  */
 
 void
@@ -8413,6 +8457,7 @@ analyzer_region_model2_cc_tests ()
 #endif
   test_var ();
   test_array ();
+  test_mem_ref ();
 }
 
 } // namespace selftest
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index e2104c51176..15ee9ef6bc4 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -1635,11 +1635,13 @@ class region_model2
 
   region2_id get_field_region2 (region2_id rid, tree field,
 			      region_model2_context *ctxt);
+#endif
 
-  region2_id deref_rvalue (svalue2_id ptr_sid, region_model2_context *ctxt);
-  region2_id deref_rvalue (tree ptr, region_model2_context *ctxt);
-
+  region2 *deref_rvalue (svalue2 *ptr_sval, region_model2_context *ctxt);
+#if 0
+  region2 *deref_rvalue (tree ptr, region_model2_context *ctxt);
 #endif
+
   void set_value (region2 *lhs_reg, svalue2 *rhs_sval,
 		  region_model2_context *ctxt);
   void set_value (tree lhs, tree rhs, region_model2_context *ctxt);
-- 
2.21.0

