From c72697ffdea66df32203b01ea469fcfdd7f669c3 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 14 Aug 2019 11:44:09 -0400
Subject: [PATCH 077/124] FIXME: pass origin to describe_state_change

---
 gcc/analyzer/impl-2.cc                  |  3 +-
 gcc/analyzer/impl-3.cc                  |  4 +-
 gcc/analyzer/impl-4.cc                  | 97 ++++++++++++++++++---------------
 gcc/analyzer/pending-diagnostic.h       |  7 ++-
 gcc/analyzer/sm-taint.cc                | 11 +++-
 gcc/testsuite/gcc.dg/analyzer/taint-1.c |  2 +-
 6 files changed, 72 insertions(+), 52 deletions(-)

diff --git a/gcc/analyzer/impl-2.cc b/gcc/analyzer/impl-2.cc
index f405694..6de81d7 100644
--- a/gcc/analyzer/impl-2.cc
+++ b/gcc/analyzer/impl-2.cc
@@ -700,7 +700,8 @@ public:
 	  {
 	    label_text custom_desc
 	      = m_pending_diagnostic->describe_state_change
-	      (evdesc::state_change (colorize, m_var, m_from, m_to, m_emission_id));
+	      (evdesc::state_change (colorize, m_var, m_origin,
+				     m_from, m_to, m_emission_id));
 	    if (custom_desc.m_buffer)
 	      {
 		if (flag_analyzer_verbose_state_changes)
diff --git a/gcc/analyzer/impl-3.cc b/gcc/analyzer/impl-3.cc
index 8ec9ea0..151b8e5 100644
--- a/gcc/analyzer/impl-3.cc
+++ b/gcc/analyzer/impl-3.cc
@@ -347,8 +347,8 @@ public:
 	  {
 	    label_text custom_desc
 	      = m_pending_diagnostic->describe_state_change
-		 (evdesc::state_change (colorize, m_var, m_from, m_to,
-					m_emission_id));
+	      (evdesc::state_change (colorize, m_var, m_origin,
+				     m_from, m_to, m_emission_id));
 	    if (custom_desc.m_buffer)
 	      {
 		if (flag_analyzer_verbose_state_changes)
diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index 8ddbdf1..daed361 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -1741,8 +1741,55 @@ public:
   {
   }
 
+  /* Attempt to generate a nicer human-readable description.
+     For greatest precision-of-wording, give the pending diagnostic
+     a chance to describe this state change (in terms of the
+     diagnostic).
+     Note that we only have a pending_diagnostic set on the event once
+     the diagnostic is about to being emitted, so the description for
+     an event can change.  */
+
   label_text get_desc (bool can_colorize) const FINAL OVERRIDE
   {
+    if (m_pending_diagnostic)
+      {
+	/* FIXME: pass m_origin to it.  */
+	label_text custom_desc
+	  = m_pending_diagnostic->describe_state_change
+	  (evdesc::state_change (can_colorize, m_var, m_origin,
+				 m_from, m_to, m_emission_id));
+	if (custom_desc.m_buffer)
+	  {
+	    if (flag_analyzer_verbose_state_changes)
+	      {
+		/* Append debug version.  */
+		label_text result;
+		if (m_origin)
+		  result = label_text::take
+		    (print (can_colorize,
+			    "%s (state of %qE: %qs -> %qs, origin: %qE)",
+			    custom_desc.m_buffer,
+			    m_var,
+			    m_sm.get_state_name (m_from),
+			    m_sm.get_state_name (m_to),
+			    m_origin));
+		else
+		  result = label_text::take
+		    (print (can_colorize,
+			    "%s (state of %qE: %qs -> %qs, origin: NULL)",
+			    custom_desc.m_buffer,
+			    m_var,
+			    m_sm.get_state_name (m_from),
+			    m_sm.get_state_name (m_to)));
+		custom_desc.maybe_free ();
+		return result;
+	      }
+	    else
+	      return custom_desc;
+	  }
+      }
+
+    /* Fallback description.  */
     if (m_origin)
       return label_text::take
 	(print (can_colorize,
@@ -1752,50 +1799,12 @@ public:
 		m_sm.get_state_name (m_to),
 		m_origin));
     else
-      {
-	/* If there is no origin, then presumably this
-	   state change came directly from a pattern match.
-	   Attempt to generate a nicer human-readable description.
-	   For greatest precision-of-wording, give the pending diagnostic
-	   a chance to describe this state change (in terms of the
-	   diagnostic).
-	   Note that we only have a pending_diagnostic set on the event once
-	   the diagnostic is about to being emitted, so the description for
-	   an event can change.  */
-	if (m_pending_diagnostic)
-	  {
-	    label_text custom_desc
-	      = m_pending_diagnostic->describe_state_change
-	      (evdesc::state_change (can_colorize, m_var, m_from, m_to,
-				     m_emission_id));
-	    if (custom_desc.m_buffer)
-	      {
-		if (flag_analyzer_verbose_state_changes)
-		  {
-		    /* Append debug version.  */
-		    label_text result = label_text::take
-		      (print (can_colorize,
-			      "%s (state of %qE: %qs -> %qs, origin: NULL)",
-			      custom_desc.m_buffer,
-			      m_var,
-			      m_sm.get_state_name (m_from),
-			      m_sm.get_state_name (m_to)));
-		    custom_desc.maybe_free ();
-		    return result;
-		  }
-		else
-		  return custom_desc;
-	      }
-	  }
-
-	/* Fallback description.  */
-	return label_text::take
-	  (print (can_colorize,
-		  "state of %qE: %qs -> %qs (origin: NULL)",
-		  m_var,
-		  m_sm.get_state_name (m_from),
-		  m_sm.get_state_name (m_to)));
-      }
+      return label_text::take
+	(print (can_colorize,
+		"state of %qE: %qs -> %qs (origin: NULL)",
+		m_var,
+		m_sm.get_state_name (m_from),
+		m_sm.get_state_name (m_to)));
   }
 
   checker4_event *clone () const FINAL OVERRIDE
diff --git a/gcc/analyzer/pending-diagnostic.h b/gcc/analyzer/pending-diagnostic.h
index e963576..2e434e7 100644
--- a/gcc/analyzer/pending-diagnostic.h
+++ b/gcc/analyzer/pending-diagnostic.h
@@ -84,15 +84,18 @@ struct state_change : public event_desc
 {
   state_change (bool colorize,
 		tree expr,
+		tree origin,
 		state_machine::state_t old_state,
 		state_machine::state_t new_state,
 		event_id_t event_id)
   : event_desc (colorize),
-    m_expr (expr), m_old_state (old_state),
-    m_new_state (new_state), m_event_id (event_id)
+    m_expr (expr), m_origin (origin),
+    m_old_state (old_state), m_new_state (new_state),
+    m_event_id (event_id)
   {}
 
   tree m_expr;
+  tree m_origin;
   state_machine::state_t m_old_state;
   state_machine::state_t m_new_state;
   event_id_t m_event_id;
diff --git a/gcc/analyzer/sm-taint.cc b/gcc/analyzer/sm-taint.cc
index ee0038e..2c8a7bf 100644
--- a/gcc/analyzer/sm-taint.cc
+++ b/gcc/analyzer/sm-taint.cc
@@ -125,8 +125,15 @@ public:
     FINAL OVERRIDE
   {
     if (change.m_new_state == m_sm.m_tainted)
-      return change.formatted_print ("%qE gets an unchecked value here",
-				     change.m_expr);
+      {
+	if (change.m_origin)
+	  return change.formatted_print ("%qE has an unchecked value here"
+					 " (from %qE)",
+					 change.m_expr, change.m_origin);
+	else
+	  return change.formatted_print ("%qE gets an unchecked value here",
+					 change.m_expr);
+      }
     return label_text ();
   }
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-1.c b/gcc/testsuite/gcc.dg/analyzer/taint-1.c
index 8ae38fe..128f094 100644
--- a/gcc/testsuite/gcc.dg/analyzer/taint-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-1.c
@@ -18,7 +18,7 @@ char test_1(FILE *f)
        in the range 0 <= i < 256; otherwise it's accessing the stack */
     return tmp.buf[tmp.i]; // { dg-warning "use of tainted value 'tmp.i' in array lookup without bounds checking" } */
     /* { dg-message "23: \\(3\\) \\.\\.\\.to here" "" { target *-*-* } .-1 } */
-    /* { dg-message "23: \\(4\\) state of 'tmp.i': 'start' -> 'tainted'" "" { target *-*-* } .-2 } */
+    /* { dg-message "23: \\(4\\) 'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "" { target *-*-* } .-2 } */
     /* { dg-message "\\(5\\) use of tainted value 'tmp.i' in array lookup without bounds checking" "" { target *-*-* } .-3 } */
     
     // TOOD: better messages for state changes
-- 
1.8.5.3

