From 891c34436905682f0d33105173fc65b8b9f75251 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 13 May 2020 16:21:34 -0400
Subject: [PATCH 130/377] FIXME: add cast in region_model2::get_store_value;
 fold away unnecessary casts

---
 gcc/analyzer/region-model2.cc | 58 +++++++++++++++++++++++++++++++----
 gcc/analyzer/region-model2.h  |  1 +
 2 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index 9357822bd89..3e8b73c3896 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -2689,6 +2689,10 @@ const svalue2 *
 region_model2_manager::maybe_fold_unaryop (tree type, enum tree_code op,
 					   const svalue2 *arg)
 {
+  /* Handle redundant casts.  */
+  if (op == NOP_EXPR && useless_type_conversion_p (arg->get_type (), type))
+    return arg;
+
   /* Constants.  */
   if (tree cst = arg->maybe_get_constant ())
     if (tree result = fold_unary (op, type, cst))
@@ -2710,6 +2714,12 @@ region_model2_manager::get_or_create_unaryop (tree type, enum tree_code op,
   return unaryop_sval;
 }
 
+const svalue2 *
+region_model2_manager::get_or_create_cast (tree type, const svalue2 *arg)
+{
+  return get_or_create_unaryop (type, NOP_EXPR, arg);
+}
+
 const svalue2 *
 region_model2_manager::maybe_fold_binop (tree type, enum tree_code op,
 					 const svalue2 *arg0, const svalue2 *arg1)
@@ -5068,7 +5078,7 @@ region_model2::get_store_value (const region2 *reg)
   const svalue2 *sval
     = m_store.get_any_binding (m_mgr->get_store2_manager (), reg);
   if (sval)
-    return sval;
+    return m_mgr->get_or_create_cast (reg->get_type (), sval);
 
   /* Special-case: read at a constant index within a STRING_CST.  */
   if (const offset_region2 *offset_reg = reg->dyn_cast_offset_region2 ())
@@ -7831,10 +7841,47 @@ test_region2_equality ()
 }
 #endif
 
+/* Verify that unary ops are folded as expected.  */
+
+static void
+test_initial_svalue2_folding ()
+{
+  region_model2_manager mgr;
+  tree x = build_global_decl ("x", integer_type_node);
+
+  test_region_model2_context ctxt;
+  region_model2 model (&mgr);
+  const svalue2 *x_init = model.get_rvalue (x, &ctxt);
+  const region2 *x_reg = model.get_lvalue (x, &ctxt);
+  ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg));
+
+}
+
+/* Verify unary ops are folded as expected.  */
+
+static void
+test_unaryop_svalue2_folding ()
+{
+  region_model2_manager mgr;
+  tree x = build_global_decl ("x", integer_type_node);
+
+  test_region_model2_context ctxt;
+  region_model2 model (&mgr);
+  const svalue2 *x_init = model.get_rvalue (x, &ctxt);
+  const region2 *x_reg = model.get_lvalue (x, &ctxt);
+  ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg));
+
+  /* "(int)x" -> "x".  */
+  ASSERT_EQ (x_init, mgr.get_or_create_cast (integer_type_node, x_init));
+
+  /* "(void *nt)x" -> something other than "x".  */
+  ASSERT_NE (x_init, mgr.get_or_create_cast (ptr_type_node, x_init));
+}
+
 /* Verify that binops on constant svalues are folded.  */
 
 static void
-test_svalue2_folding ()
+test_binop_svalue2_folding ()
 {
 #define NUM_CSTS 10
   tree cst_int[NUM_CSTS];
@@ -7884,13 +7931,10 @@ test_svalue2_folding ()
       }
 
   tree x = build_global_decl ("x", integer_type_node);
-  tree y = build_global_decl ("y", integer_type_node);
 
   test_region_model2_context ctxt;
   region_model2 model (&mgr);
   const svalue2 *x_init = model.get_rvalue (x, &ctxt);
-  const region2 *x_reg = model.get_lvalue (x, &ctxt);
-  ASSERT_EQ (x_init, mgr.get_or_create_initial_value (x_reg));
 
   /* PLUS_EXPR folding.  */
   const svalue2 *x_init_plus_zero
@@ -9292,7 +9336,9 @@ analyzer_region_model2_cc_tests ()
   test_svalue2_equality ();
   test_region2_equality ();
 #endif
-  test_svalue2_folding ();
+  test_initial_svalue2_folding ();
+  test_unaryop_svalue2_folding ();
+  test_binop_svalue2_folding ();
 #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 e9eadaa3830..aceb7e9240a 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -1574,6 +1574,7 @@ public:
   const svalue2 *get_ptr_svalue2 (tree ptr_type, const region2 *pointee);
   const svalue2 *get_or_create_unaryop (tree type, enum tree_code op,
 					const svalue2 *arg);
+  const svalue2 *get_or_create_cast (tree type, const svalue2 *arg);
   const svalue2 *get_or_create_binop (tree type,
 				      enum tree_code op,
 				      const svalue2 *arg0, const svalue2 *arg1);
-- 
2.26.2

