From 1c8c0ac928d9642eaba4248ec84f721c76b92f57 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Mon, 6 Apr 2026 14:36:06 -0400
Subject: [PATCH 40/98] FIXME: start trying to track data flow in more warnings

---
 gcc/analyzer/poisoned-value-diagnostic.cc |  5 +++-
 gcc/analyzer/region-model.cc              | 23 +++++++++++----
 gcc/analyzer/region-model.h               |  6 ++--
 gcc/analyzer/shift-diagnostics.cc         | 36 ++++++++++++++++++-----
 4 files changed, 53 insertions(+), 17 deletions(-)

diff --git a/gcc/analyzer/poisoned-value-diagnostic.cc b/gcc/analyzer/poisoned-value-diagnostic.cc
index d29ceeaca636..e5d5cec7a356 100644
--- a/gcc/analyzer/poisoned-value-diagnostic.cc
+++ b/gcc/analyzer/poisoned-value-diagnostic.cc
@@ -155,7 +155,10 @@ public:
   void mark_interesting_stuff (interesting_t *interest) final override
   {
     if (m_src_region)
-      interest->add_region_creation (m_src_region);
+      {
+	interest->add_region_creation (m_src_region);
+	interest->add_read_region (m_src_region, "poisoned value");
+      }
   }
 
   /* Attempt to suppress false positives.
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index f6d59f15183e..79441dc29ca3 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1110,15 +1110,26 @@ region_model::get_gassign_result (const gassign *assign,
 		  && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
 		{
 		  if (tree_int_cst_sgn (rhs2_cst) < 0)
-		    ctxt->warn
-		      (make_shift_count_negative_diagnostic (assign, rhs2_cst));
+		    {
+		      const region *rhs2_reg
+			= get_lvalue (gimple_assign_rhs2 (assign), nullptr);
+		      ctxt->warn
+			(make_shift_count_negative_diagnostic (assign,
+							       rhs2_cst,
+							       rhs2_reg));
+		    }
 		  else if (compare_tree_int (rhs2_cst,
 					     TYPE_PRECISION (TREE_TYPE (rhs1)))
 			   >= 0)
-		    ctxt->warn (make_shift_count_overflow_diagnostic
-				(assign,
-				 int (TYPE_PRECISION (TREE_TYPE (rhs1))),
-				 rhs2_cst));
+		    {
+		      const region *rhs2_reg
+			= get_lvalue (gimple_assign_rhs2 (assign), nullptr);
+		      ctxt->warn (make_shift_count_overflow_diagnostic
+				  (assign,
+				   int (TYPE_PRECISION (TREE_TYPE (rhs1))),
+				   rhs2_cst,
+				   rhs2_reg));
+		    }
 		}
 	  }
 
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index 4b0160a98b04..fd947da65e84 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -1338,12 +1338,14 @@ make_poisoned_value_diagnostic (tree expr, enum poison_kind pkind,
 
 extern std::unique_ptr<pending_diagnostic>
 make_shift_count_negative_diagnostic (const gassign *assign,
-				      tree count_cst);
+				      tree count_cst,
+				      const region *src_region);
 
 extern std::unique_ptr<pending_diagnostic>
 make_shift_count_overflow_diagnostic (const gassign *assign,
 				      int operand_precision,
-				      tree count_cst);
+				      tree count_cst,
+				      const region *src_region);
 
 extern std::unique_ptr<pending_diagnostic>
 make_write_to_const_diagnostic (const region *dest_reg, tree decl);
diff --git a/gcc/analyzer/shift-diagnostics.cc b/gcc/analyzer/shift-diagnostics.cc
index 2bc58de248dc..724c1a18d64c 100644
--- a/gcc/analyzer/shift-diagnostics.cc
+++ b/gcc/analyzer/shift-diagnostics.cc
@@ -35,8 +35,9 @@ class shift_count_negative_diagnostic
 : public pending_diagnostic_subclass<shift_count_negative_diagnostic>
 {
 public:
-  shift_count_negative_diagnostic (const gassign *assign, tree count_cst)
-  : m_assign (assign), m_count_cst (count_cst)
+  shift_count_negative_diagnostic (const gassign *assign, tree count_cst,
+				   const region *src_region)
+  : m_assign (assign), m_count_cst (count_cst), m_src_region (src_region)
   {}
 
   const char *get_kind () const final override
@@ -70,15 +71,24 @@ public:
     return true;
   }
 
+  void
+  mark_interesting_stuff (interesting_t *interest)
+  {
+    interest->add_read_region (m_src_region, "shift count value");
+  }
+
 private:
   const gassign *m_assign;
   tree m_count_cst;
+  const region *m_src_region;
 };
 
 std::unique_ptr<pending_diagnostic>
-make_shift_count_negative_diagnostic (const gassign *assign, tree count_cst)
+make_shift_count_negative_diagnostic (const gassign *assign, tree count_cst,
+				      const region *src_region)
 {
-  return std::make_unique<shift_count_negative_diagnostic> (assign, count_cst);
+  return std::make_unique<shift_count_negative_diagnostic>
+    (assign, count_cst, src_region);
 }
 
 /* A subclass of pending_diagnostic for complaining about shifts
@@ -90,9 +100,11 @@ class shift_count_overflow_diagnostic
 public:
   shift_count_overflow_diagnostic (const gassign *assign,
 				   int operand_precision,
-				   tree count_cst)
+				   tree count_cst,
+				   const region *src_region)
   : m_assign (assign), m_operand_precision (operand_precision),
-    m_count_cst (count_cst)
+    m_count_cst (count_cst),
+    m_src_region (src_region)
   {}
 
   const char *get_kind () const final override
@@ -128,19 +140,27 @@ public:
     return true;
   }
 
+  void
+  mark_interesting_stuff (interesting_t *interest)
+  {
+    interest->add_read_region (m_src_region, "shift count value");
+  }
+
 private:
   const gassign *m_assign;
   int m_operand_precision;
   tree m_count_cst;
+  const region *m_src_region;
 };
 
 std::unique_ptr<pending_diagnostic>
 make_shift_count_overflow_diagnostic (const gassign *assign,
 				      int operand_precision,
-				      tree count_cst)
+				      tree count_cst,
+				      const region *src_region)
 {
   return std::make_unique<shift_count_overflow_diagnostic>
-    (assign, operand_precision, count_cst);
+    (assign, operand_precision, count_cst, src_region);
 }
 
 } // namespace ana
-- 
2.49.0

