From 7c03471de6cdf4f0e49a3ec7e46771a7331aa0bb Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 15 Apr 2020 11:39:29 -0400
Subject: [PATCH 040/315] FIXME: more on wiring up region_model2 into
 program_state

---
 gcc/analyzer/engine.cc        |   8 +-
 gcc/analyzer/region-model2.cc | 195 ++++++++++------------------------
 gcc/analyzer/region-model2.h  |  15 +--
 3 files changed, 68 insertions(+), 150 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 05b607efede..a4b37e84dd8 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -1031,14 +1031,12 @@ exploded_node::on_stmt (exploded_graph &eg,
      }
   else if (state->m_region_model2)
     {
-      // TODO:
-      gcc_unreachable ();
-#if 0
-      if (state->m_region_model2->on_stmt (eg.get_ext_state (), snode, stmt))
+      engine2 *eng2 = eg.get_ext_state ().get_engine2 ();
+      region_model2_manager *mgr = eng2->get_model_manager ();
+      if (state->m_region_model2->on_stmt (mgr, snode, stmt))
 	return on_stmt_flags (false);
       else
 	return on_stmt_flags::terminate_path ();
-#endif
     }
 
   /* Preserve the old state.  It is used here for looking
diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index f94a615508f..2e1a12b2fef 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -1221,21 +1221,22 @@ region2::get_inherited_child_sval (region2 *child,
 }
 #endif
 
+// FIXME:
 /* Copy from SRC_REG to DST_REG, using CTXT for any issues that occur.
    Copy across any value for the region2, and handle structs, unions
    and arrays recursively.  */
-#if 0
+
 void
-region_model2::copy_region2 (region2_id dst_reg, region2_id src_reg,
-			   region_model2_context *ctxt)
+region_model2::copy_region (region2 *dst_reg, region2 *src_reg,
+			    region_model2_context *ctxt)
 {
-  gcc_assert (!dst_reg.null_p ());
-  gcc_assert (!src_reg.null_p ());
+  gcc_assert (dst_reg);
+  gcc_assert (src_reg);
   if (dst_reg == src_reg)
     return;
-  region2 *dst_reg = get_region2 (dst_reg);
-  region2 *src_reg = get_region2 (src_reg);
 
+  gcc_unreachable ();
+#if 0
   /* Copy across any value for the src region2 itself.  */
   svalue2 *sval = src_reg->get_value (*this, true, ctxt);
   set_value (dst_reg, sid, ctxt);
@@ -1258,8 +1259,8 @@ region_model2::copy_region2 (region2_id dst_reg, region2_id src_reg,
     case RK_SYMBOLIC:
       return;
     }
-}
 #endif
+}
 
 /* Generate a hash value for this region2.  The work is done by the
    add_to_hash vfunc.  */
@@ -2458,7 +2459,7 @@ root_region2::compare_fields (const root_region2 &other) const
 #endif
 
 void
-root_region2::dump_to_pp (pretty_printer *pp, bool simple) const
+root_region2::dump_to_pp (pretty_printer */*pp*/, bool /*simple*/) const
 {
   gcc_unreachable ();
 }
@@ -3725,157 +3726,69 @@ region_model2::validate () const
 
 #endif
 
-/* A subclass of pending_diagnostic for complaining about uses of
-   poisoned values.  */
+/* FIXME.  */
 
-class poisoned_value_diagnostic
-: public pending_diagnostic_subclass<poisoned_value_diagnostic>
+bool
+region_model2::on_stmt (region_model2_manager *mgr,
+			const supernode *snode,
+			const gimple *stmt)
 {
-public:
-  poisoned_value_diagnostic (tree expr, enum poison_kind pkind)
-  : m_expr (expr), m_pkind (pkind)
-  {}
-
-  const char *get_kind () const FINAL OVERRIDE { return "poisoned_value_diagnostic"; }
-
-  bool operator== (const poisoned_value_diagnostic &other) const
-  {
-    return m_expr == other.m_expr;
-  }
-
-  bool emit (rich_location *rich_loc) FINAL OVERRIDE
-  {
-    switch (m_pkind)
-      {
-      default:
-	gcc_unreachable ();
-      case POISON_KIND_UNINIT:
-	{
-	  diagnostic_metadata m;
-	  m.add_cwe (457); /* "CWE-457: Use of Uninitialized Variable".  */
-	  return warning_meta (rich_loc, m,
-			       OPT_Wanalyzer_use_of_uninitialized_value,
-			       "use of uninitialized value %qE",
-			       m_expr);
-	}
-	break;
-      case POISON_KIND_FREED:
-	{
-	  diagnostic_metadata m;
-	  m.add_cwe (416); /* "CWE-416: Use After Free".  */
-	  return warning_meta (rich_loc, m,
-			       OPT_Wanalyzer_use_after_free,
-			       "use after %<free%> of %qE",
-			       m_expr);
-	}
-	break;
-      case POISON_KIND_POPPED_STACK:
-	{
-	  /* TODO: which CWE?  */
-	  return warning_at (rich_loc,
-			     OPT_Wanalyzer_use_of_pointer_in_stale_stack_frame,
-			     "use of pointer %qE within stale stack frame",
-			     m_expr);
-	}
-	break;
-      }
-  }
-
-  label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE
-  {
-    switch (m_pkind)
-      {
-      default:
-	gcc_unreachable ();
-      case POISON_KIND_UNINIT:
-	return ev.formatted_print ("use of uninitialized value %qE here",
-				   m_expr);
-      case POISON_KIND_FREED:
-	return ev.formatted_print ("use after %<free%> of %qE here",
-				   m_expr);
-      case POISON_KIND_POPPED_STACK:
-	return ev.formatted_print
-	  ("use of pointer %qE within stale stack frame here",
-	   m_expr);
-      }
-  }
-
-private:
-  tree m_expr;
-  enum poison_kind m_pkind;
-};
+#if 0
+#endif
 
-/* Determine if EXPR is poisoned, and if so, queue a diagnostic to CTXT.  */
+  switch (stmt->code)
+    {
+    case GIMPLE_COND:
+      /* This is a no-op; the condition is handled by the true/false
+	 superedges.  */
+      return true;
 
-#if 0
+    case GIMPLE_LABEL:
+      /* No-op.  */
+      return true;
 
-void
-region_model2::check_for_poison (tree expr, region_model2_context *ctxt)
-{
-  if (!ctxt)
-    return;
+    case GIMPLE_ASSIGN:
+      return on_gassign (mgr, snode, as_a <const gassign *> (stmt));
 
-  // TODO: this is disabled for now (too many false positives)
-  return;
+    case GIMPLE_RETURN:
+      return on_greturn (mgr, snode, as_a <const greturn *> (stmt));
 
-  svalue2_id expr_sval = get_rvalue (expr, ctxt);
-  gcc_assert (!expr_sval.null_p ());
-  svalue2 *expr_svalue2 = get_svalue2 (expr_sval);
-  gcc_assert (expr_svalue2);
-  if (const poisoned_svalue2 *poisoned_sval
-	= expr_svalue2->dyn_cast_poisoned_svalue2 ())
-    {
-      enum poison_kind pkind = poisoned_sval->get_poison_kind ();
-      ctxt->warn (new poisoned_value_diagnostic (expr, pkind));
+    default:
+      sorry_at (stmt->location, "unhandled stmt: %qs",
+		gimple_code_name[stmt->code]);
+      return false;
     }
 }
 
-#endif
-
+// FIXME:
 /* Update this model for the ASSIGN stmt, using CTXT to report any
    diagnostics.  */
-#if 0
-void
-region_model2::on_assignment (const gassign *assign, region_model2_context *ctxt)
+
+bool
+region_model2::on_gassign (region_model2_manager *mgr,
+			   const supernode *snode,
+			   const gassign *assign)
 {
+  region_model2_context *ctxt = NULL; // FIXME
   tree lhs = gimple_assign_lhs (assign);
   tree rhs1 = gimple_assign_rhs1 (assign);
 
-  region2 *lhs_reg = get_lvalue (lhs, ctxt);
-
-  /* Check for uses of poisoned values.  */
-  switch (get_gimple_rhs_class (gimple_expr_code (assign)))
-    {
-    case GIMPLE_INVALID_RHS:
-      gcc_unreachable ();
-      break;
-    case GIMPLE_TERNARY_RHS:
-      check_for_poison (gimple_assign_rhs3 (assign), ctxt);
-      /* Fallthru */
-    case GIMPLE_BINARY_RHS:
-      check_for_poison (gimple_assign_rhs2 (assign), ctxt);
-      /* Fallthru */
-    case GIMPLE_UNARY_RHS:
-    case GIMPLE_SINGLE_RHS:
-      check_for_poison (gimple_assign_rhs1 (assign), ctxt);
-    }
-
-  if (!lhs_reg)
-    return;
-  // TODO: issue a warning for this case
+  region2 *lhs_reg = get_lvalue (mgr, lhs, ctxt);
 
   enum tree_code op = gimple_assign_rhs_code (assign);
   switch (op)
     {
     default:
       {
-	if (0)
+	if (1)
 	  sorry_at (assign->location, "unhandled assignment op: %qs",
 		    get_tree_code_name (op));
-	set_to_new_unknown_value (lhs_reg, TREE_TYPE (lhs), ctxt);
+	gcc_unreachable ();
+	//set_to_new_unknown_value (lhs_reg, TREE_TYPE (lhs), ctxt);
       }
       break;
 
+#if 0
     case BIT_FIELD_REF:
       {
 	// TODO
@@ -4041,9 +3954,9 @@ region_model2::on_assignment (const gassign *assign, region_model2_context *ctxt
 	set_value (lhs_reg, child_sval, ctxt);
       }
       break;
+#endif
     }
 }
-#endif
 
 /* Update this model for the CALL stmt, using CTXT to report any
    diagnostics - the first half.
@@ -4413,18 +4326,22 @@ region_model2::handle_unrecognized_call (const gcall *call,
 
 /* Update this model for the RETURN_STMT, using CTXT to report any
    diagnostics.  */
-#if 0
-void
-region_model2::on_return (const greturn *return_stmt, region_model2_context *ctxt)
+
+bool
+region_model2::on_greturn (region_model2_manager *mgr,
+			   const supernode *snode,
+			   const greturn *return_stmt)
 {
+  region_model2_context *ctxt = NULL; // FIXME
   tree callee = get_current_function ()->decl;
   tree lhs = DECL_RESULT (callee);
   tree rhs = gimple_return_retval (return_stmt);
 
   if (lhs && rhs)
-    copy_region (get_lvalue (lhs, ctxt), get_lvalue (rhs, ctxt), ctxt);
+    copy_region (get_lvalue (mgr, lhs, ctxt),
+		 get_lvalue (mgr, rhs, ctxt),
+		 ctxt);
 }
-#endif
 
 /* Update this model for a call and return of setjmp/sigsetjmp at CALL within
    ENODE, using CTXT to report any diagnostics.
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index e8f105d2bb9..90c6568087e 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -1550,15 +1550,21 @@ class region_model2
 
   void validate () const;
 
-  void check_for_poison (tree expr, region_model2_context *ctxt);
-  void on_assignment (const gassign *stmt, region_model2_context *ctxt);
+  bool on_stmt (region_model2_manager *mgr,
+		const supernode *snode,
+		const gimple *stmt);
+  bool on_gassign (region_model2_manager *mgr,
+		   const supernode *snode,
+		   const gassign *stmt);
   bool on_call_pre (const gcall *stmt, region_model2_context *ctxt);
   void on_call_post (const gcall *stmt,
 		     bool unknown_side_effects,
 		     region_model2_context *ctxt);
   void handle_unrecognized_call (const gcall *call,
 				 region_model2_context *ctxt);
-  void on_return (const greturn *stmt, region_model2_context *ctxt);
+  bool on_greturn (region_model2_manager *mgr,
+		   const supernode *snode,
+		   const greturn *stmt);
   void on_setjmp (const gcall *stmt, const exploded_node *enode,
 		  region_model2_context *ctxt);
   void on_longjmp (const gcall *longjmp_call, const gcall *setjmp_call,
@@ -1573,9 +1579,6 @@ class region_model2
 		   tree lhs, tree rhs, bool is_back_edge,
 		   region_model2_context *ctxt);
 
-  bool on_stmt (const extrinsic_state &ext_state,
-		const supernode *snode,
-		const gimple *stmt);
   bool maybe_update_for_edge (region_model2_manager *mgr,
 			      const superedge &edge,
 			      const gimple *last_stmt,
-- 
2.26.2

