From 94b765575bd688313da03156c700c9b8188c3bdd Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 2 Jul 2020 15:06:28 -0400
Subject: [PATCH 279/377] FIXME: fix missing uninit warning when dereferencing
 uninited pointers

---
 gcc/analyzer/engine.cc                   |  3 ++-
 gcc/analyzer/region-model2-impl-calls.cc |  5 ++--
 gcc/analyzer/region-model2.cc            | 34 +++++++++++++++---------
 gcc/analyzer/region-model2.h             |  2 +-
 4 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index c765ea84d6a..26925fc5245 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -2034,7 +2034,8 @@ exploded_node::on_longjmp2 (exploded_graph &eg,
 
   region_model2 *new_region_model = new_state->m_region_model2;
   const svalue2 *buf_ptr_sval = new_region_model->get_rvalue (buf_ptr, ctxt);
-  const region2 *buf = new_region_model->deref_rvalue (buf_ptr_sval, ctxt);
+  const region2 *buf = new_region_model->deref_rvalue (buf_ptr_sval, buf_ptr,
+						       ctxt);
   if (!buf)
     return; // FIXME: can it be NULL?
 
diff --git a/gcc/analyzer/region-model2-impl-calls.cc b/gcc/analyzer/region-model2-impl-calls.cc
index 51d02823a3b..32ee3e7fd8e 100644
--- a/gcc/analyzer/region-model2-impl-calls.cc
+++ b/gcc/analyzer/region-model2-impl-calls.cc
@@ -255,7 +255,8 @@ region_model2::impl_call_memset (const call_details &cd)
   const svalue2 *fill_value_sval = cd.get_arg_svalue2 (1);
   const svalue2 *num_bytes_sval = cd.get_arg_svalue2 (2);
 
-  const region2 *dest_reg = deref_rvalue (dest_sval, cd.get_ctxt ());
+  const region2 *dest_reg = deref_rvalue (dest_sval, cd.get_arg_tree (0),
+					  cd.get_ctxt ());
 
   if (tree num_bytes = num_bytes_sval->maybe_get_constant ())
     {
@@ -297,7 +298,7 @@ region_model2::impl_call_strlen (const call_details &cd)
 {
   region_model2_context *ctxt = cd.get_ctxt ();
   const svalue2 *arg_sval = cd.get_arg_svalue2 (0);
-  const region2 *buf_reg = deref_rvalue (arg_sval, ctxt);
+  const region2 *buf_reg = deref_rvalue (arg_sval, cd.get_arg_tree (0), ctxt);
   if (const string_region2 *str_reg
       = buf_reg->dyn_cast_string_region2 ())
     {
diff --git a/gcc/analyzer/region-model2.cc b/gcc/analyzer/region-model2.cc
index 5fb071678f6..08ccd8ceea2 100644
--- a/gcc/analyzer/region-model2.cc
+++ b/gcc/analyzer/region-model2.cc
@@ -5289,7 +5289,8 @@ region_model2::on_setjmp (const gcall *call, const exploded_node *enode,
 			 region_model2_context *ctxt)
 {
   const svalue2 *buf_ptr = get_rvalue (gimple_call_arg (call, 0), ctxt);
-  const region2 *buf_reg = deref_rvalue (buf_ptr, ctxt);
+  const region2 *buf_reg = deref_rvalue (buf_ptr, gimple_call_arg (call, 0),
+					 ctxt);
 
   /* Create a setjmp_svalue2 for this call and store it in BUF_REG's
      region2.  */
@@ -5482,7 +5483,7 @@ region_model2::get_lvalue_1 (path_var pv,
 	tree offset = TREE_OPERAND (expr, 1);
 	const svalue2 *ptr_sval = get_rvalue (ptr, ctxt);
 	const svalue2 *offset_sval = get_rvalue (offset, ctxt);
-	const region2 *star_ptr = deref_rvalue (ptr_sval, ctxt);
+	const region2 *star_ptr = deref_rvalue (ptr_sval, ptr, ctxt);
 	return m_mgr->get_offset_region (star_ptr,
 					 TREE_TYPE (expr),
 					 offset_sval);
@@ -5991,10 +5992,11 @@ region_model2::get_field_region (region2 *struct_or_union_reg, tree field,
 #endif
 
 /* Get a region2 for referencing PTR_SVAL, creating a region2 if need be, and
-   potentially generating warnings via CTXT.  */
+   potentially generating warnings via CTXT.
+   PTR_TREE if non-NULL can be used when emitting diagnostics.  */
 
 const region2 *
-region_model2::deref_rvalue (const svalue2 *ptr_sval,
+region_model2::deref_rvalue (const svalue2 *ptr_sval, tree ptr_tree,
 			     region_model2_context *ctxt)
 {
   gcc_assert (ptr_sval);
@@ -6027,7 +6029,7 @@ region_model2::deref_rvalue (const svalue2 *ptr_sval,
 	      /* Perhaps instead we should capture this as an offset relative
 		 to a base region in region_offset?  */
 	      const region2 *parent_region
-		= deref_rvalue (binop_sval->get_arg0 (), ctxt);
+		= deref_rvalue (binop_sval->get_arg0 (), NULL_TREE, ctxt);
 	      const svalue2 *offset = binop_sval->get_arg1 ();
 	      tree type= TREE_TYPE (ptr_sval->get_type ());
 	      return m_mgr->get_offset_region (parent_region, type, offset);
@@ -6045,13 +6047,21 @@ region_model2::deref_rvalue (const svalue2 *ptr_sval,
     case svalue2::SK_POISONED:
       {
 	if (ctxt)
-	  if (tree ptr = get_representative_tree (ptr_sval))
-	    {
-	      const poisoned_svalue2 *poisoned_sval
-		= as_a <const poisoned_svalue2 *> (ptr_sval);
-	      enum poison_kind pkind = poisoned_sval->get_poison_kind ();
-	      ctxt->warn (new poisoned_value_diagnostic2 (ptr, pkind));
-	    }
+	  {
+	    tree ptr = get_representative_tree (ptr_sval);
+	    /* If we can't get a representative tree for PTR_SVAL
+	       (e.g. if it hasn't been bound into the store), then
+	       fall back on PTR_TREE, if non-NULL.  */
+	    if (!ptr)
+	      ptr = ptr_tree;
+	    if (ptr)
+	      {
+		const poisoned_svalue2 *poisoned_sval
+		  = as_a <const poisoned_svalue2 *> (ptr_sval);
+		enum poison_kind pkind = poisoned_sval->get_poison_kind ();
+		ctxt->warn (new poisoned_value_diagnostic2 (ptr, pkind));
+	      }
+	  }
 	goto create_symbolic_region2;
       }
 
diff --git a/gcc/analyzer/region-model2.h b/gcc/analyzer/region-model2.h
index 0aa78545d68..a57a8da5c18 100644
--- a/gcc/analyzer/region-model2.h
+++ b/gcc/analyzer/region-model2.h
@@ -2367,7 +2367,7 @@ class region_model2
 			      region_model2_context *ctxt);
 #endif
 
-  const region2 *deref_rvalue (const svalue2 *ptr_sval,
+  const region2 *deref_rvalue (const svalue2 *ptr_sval, tree ptr_tree,
 			       region_model2_context *ctxt);
 #if 0
   const region2 *deref_rvalue (tree ptr, region_model2_context *ctxt);
-- 
2.26.2

