commit 65d44272bd988f695a9b5fa7e1b88c266c3089cb
Author: Aldy Hernandez <aldyh@redhat.com>
Date:   Tue May 5 18:40:44 2020 +0200

    Move array bounds checking out of vrp_prop and into its own class.

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4f48d443235..64681dd97fe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2020-05-17  Aldy Hernandez  <aldyh@redhat.com>
+
+	* tree-vrp.c (class vrp_prop): Move check_all_array_refs,
+	check_array_ref, check_mem_ref, and search_for_addr_array
+	into new class...
+	(class array_bounds_checker): ...here.
+	(class check_array_bounds_dom_walker): Adjust to use
+	array_bounds_checker.
+	(check_all_array_refs): Move into array_bounds_checker and rename
+	to check.
+	(class vrp_folder): Make fold_predicate_in private.
+
 2020-05-15 Jeff Law  <law@redhat.com>
 
 	* config/h8300/h8300.md (SFI iterator): New iterator for
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 1001c7f41d8..6e3510856a5 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3521,7 +3521,7 @@ vrp_insert::insert_range_assertions (void)
 
 class vrp_prop : public ssa_propagation_engine
 {
- public:
+public:
   enum ssa_prop_result visit_stmt (gimple *, edge *, tree *) FINAL OVERRIDE;
   enum ssa_prop_result visit_phi (gphi *) FINAL OVERRIDE;
 
@@ -3529,12 +3529,10 @@ class vrp_prop : public ssa_propagation_engine
 
   void vrp_initialize (struct function *);
   void vrp_finalize (bool);
-  void check_all_array_refs (void);
-  bool check_array_ref (location_t, tree, bool);
-  bool check_mem_ref (location_t, tree, bool);
-  void search_for_addr_array (tree, location_t);
 
   class vr_values vr_values;
+
+private:
   /* Temporary delegator to minimize code churn.  */
   const value_range_equiv *get_value_range (const_tree op)
     { return vr_values.get_value_range (op); }
@@ -3552,6 +3550,29 @@ class vrp_prop : public ssa_propagation_engine
   void extract_range_from_phi_node (gphi *phi, value_range_equiv *vr)
     { vr_values.extract_range_from_phi_node (phi, vr); }
 };
+
+/* Array bounds checking pass.  */
+
+class array_bounds_checker
+{
+  friend class check_array_bounds_dom_walker;
+
+public:
+  array_bounds_checker (struct function *fun, class vr_values *v)
+    : fun (fun), ranges (v) { }
+  void check ();
+
+private:
+  static tree check_array_bounds (tree *tp, int *walk_subtree, void *data);
+  bool check_array_ref (location_t, tree, bool ignore_off_by_one);
+  bool check_mem_ref (location_t, tree, bool ignore_off_by_one);
+  void check_addr_expr (location_t, tree);
+  const value_range_equiv *get_value_range (const_tree op)
+    { return ranges->get_value_range (op); }
+  struct function *fun;
+  class vr_values *ranges;
+};
+
 /* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible arrays
    and "struct" hacks. If VRP can determine that the
    array subscript is a constant, check if it is outside valid
@@ -3561,8 +3582,8 @@ class vrp_prop : public ssa_propagation_engine
    Returns true if a warning has been issued.  */
 
 bool
-vrp_prop::check_array_ref (location_t location, tree ref,
-			   bool ignore_off_by_one)
+array_bounds_checker::check_array_ref (location_t location, tree ref,
+				       bool ignore_off_by_one)
 {
   if (TREE_NO_WARNING (ref))
     return false;
@@ -3760,8 +3781,8 @@ vrp_prop::check_array_ref (location_t location, tree ref,
    Returns true if a warning has been issued.  */
 
 bool
-vrp_prop::check_mem_ref (location_t location, tree ref,
-			 bool ignore_off_by_one)
+array_bounds_checker::check_mem_ref (location_t location, tree ref,
+				     bool ignore_off_by_one)
 {
   if (TREE_NO_WARNING (ref))
     return false;
@@ -4038,7 +4059,7 @@ vrp_prop::check_mem_ref (location_t location, tree ref,
    address of an ARRAY_REF, and call check_array_ref on it.  */
 
 void
-vrp_prop::search_for_addr_array (tree t, location_t location)
+array_bounds_checker::check_addr_expr (location_t location, tree t)
 {
   /* Check each ARRAY_REF and MEM_REF in the reference chain. */
   do
@@ -4122,14 +4143,12 @@ vrp_prop::search_for_addr_array (tree t, location_t location)
     }
 }
 
-/* walk_tree() callback that checks if *TP is
-   an ARRAY_REF inside an ADDR_EXPR (in which an array
-   subscript one outside the valid range is allowed). Call
-   check_array_ref for each ARRAY_REF found. The location is
-   passed in DATA.  */
+/* Callback for walk_tree to check a tree for out of bounds array
+   accesses.  The array_bounds_checker class is passed in DATA.  */
 
-static tree
-check_array_bounds (tree *tp, int *walk_subtree, void *data)
+tree
+array_bounds_checker::check_array_bounds (tree *tp, int *walk_subtree,
+					  void *data)
 {
   tree t = *tp;
   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
@@ -4143,14 +4162,16 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
   *walk_subtree = TRUE;
 
   bool warned = false;
-  vrp_prop *vrp_prop = (class vrp_prop *)wi->info;
+  array_bounds_checker *checker = (array_bounds_checker *) wi->info;
   if (TREE_CODE (t) == ARRAY_REF)
-    warned = vrp_prop->check_array_ref (location, t, false/*ignore_off_by_one*/);
+    warned = checker->check_array_ref (location, t,
+				       false/*ignore_off_by_one*/);
   else if (TREE_CODE (t) == MEM_REF)
-    warned = vrp_prop->check_mem_ref (location, t, false /*ignore_off_by_one*/);
+    warned = checker->check_mem_ref (location, t,
+				     false /*ignore_off_by_one*/);
   else if (TREE_CODE (t) == ADDR_EXPR)
     {
-      vrp_prop->search_for_addr_array (t, location);
+      checker->check_addr_expr (location, t);
       *walk_subtree = FALSE;
     }
   /* Propagate the no-warning bit to the outer expression.  */
@@ -4160,26 +4181,26 @@ check_array_bounds (tree *tp, int *walk_subtree, void *data)
   return NULL_TREE;
 }
 
-/* A dom_walker subclass for use by vrp_prop::check_all_array_refs,
-   to walk over all statements of all reachable BBs and call
-   check_array_bounds on them.  */
+/* A dom_walker subclass for use by check_all_array_refs, to walk over
+   all statements of all reachable BBs and call check_array_bounds on
+   them.  */
 
 class check_array_bounds_dom_walker : public dom_walker
 {
- public:
-  check_array_bounds_dom_walker (vrp_prop *prop)
+public:
+  check_array_bounds_dom_walker (array_bounds_checker *checker)
     : dom_walker (CDI_DOMINATORS,
 		  /* Discover non-executable edges, preserving EDGE_EXECUTABLE
 		     flags, so that we can merge in information on
 		     non-executable edges from vrp_folder .  */
 		  REACHABLE_BLOCKS_PRESERVING_FLAGS),
-      m_prop (prop) {}
+    checker (checker) { }
   ~check_array_bounds_dom_walker () {}
 
   edge before_dom_children (basic_block) FINAL OVERRIDE;
 
- private:
-  vrp_prop *m_prop;
+private:
+  array_bounds_checker *checker;
 };
 
 /* Implementation of dom_walker::before_dom_children.
@@ -4201,9 +4222,9 @@ check_array_bounds_dom_walker::before_dom_children (basic_block bb)
 
       memset (&wi, 0, sizeof (wi));
 
-      wi.info = m_prop;
+      wi.info = checker;
 
-      walk_gimple_op (stmt, check_array_bounds, &wi);
+      walk_gimple_op (stmt, array_bounds_checker::check_array_bounds, &wi);
     }
 
   /* Determine if there's a unique successor edge, and if so, return
@@ -4213,11 +4234,10 @@ check_array_bounds_dom_walker::before_dom_children (basic_block bb)
   return find_taken_edge (bb, NULL_TREE);
 }
 
-/* Walk over all statements of all reachable BBs and call check_array_bounds
-   on them.  */
+/* Entry point into array bounds checking pass.  */
 
 void
-vrp_prop::check_all_array_refs ()
+array_bounds_checker::check ()
 {
   check_array_bounds_dom_walker w (this);
   w.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));
@@ -4851,14 +4871,15 @@ vrp_prop::visit_phi (gphi *phi)
 
 class vrp_folder : public substitute_and_fold_engine
 {
- public:
+public:
   vrp_folder () : substitute_and_fold_engine (/* Fold all stmts.  */ true) {  }
   tree get_value (tree) FINAL OVERRIDE;
   bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
-  bool fold_predicate_in (gimple_stmt_iterator *);
 
   class vr_values *vr_values;
 
+private:
+  bool fold_predicate_in (gimple_stmt_iterator *);
   /* Delegators.  */
   tree vrp_evaluate_conditional (tree_code code, tree op0,
 				 tree op1, gimple *stmt)
@@ -5293,7 +5314,10 @@ vrp_prop::vrp_finalize (bool warn_array_bounds_p)
   vrp_folder.substitute_and_fold ();
 
   if (warn_array_bounds && warn_array_bounds_p)
-    check_all_array_refs ();
+    {
+      array_bounds_checker array_checker (fun, &vr_values);
+      array_checker.check ();
+    }
 }
 
 /* Main entry point to VRP (Value Range Propagation).  This pass is
