From 5940f49b4e0b830f2566fedc0fb83f30ec585c3e Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 6 Mar 2019 15:52:58 -0500
Subject: [PATCH 070/161] FIXME: start adding event filtering

---
 gcc/analyzer/engine.cc                         | 61 ++++++++++++++++++++++++++
 gcc/testsuite/gcc.dg/analyzer/malloc-paths-5.c | 12 +++--
 2 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 1a21e4a..a619422 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -503,6 +503,13 @@ public:
   {
     m_events.safe_push (event);
   }
+  
+  void delete_event (int idx)
+  {
+    checker_event *event = m_events[idx];
+    m_events.ordered_remove (idx);
+    delete event;
+  }
 
   auto_delete_vec<checker_event> m_events;
 };
@@ -1914,6 +1921,58 @@ engine::emit_candidate_diagnostics ()
 
 /* FIXME.  */
 
+static void
+prune_path (checker_path *path, tree var, state_machine::state_t state)
+{
+  // TODO
+  /* TODO: go backwards, skipping state change events that aren't var
+     but update the pertinent var when state-copying occurs.  */
+  int idx = path->m_events.length () - 1;
+  while (idx >= 0)
+    {
+      checker_event *base_event = path->m_events[idx];
+      switch (base_event->m_kind)
+	{
+	default:
+	  gcc_unreachable ();
+
+	case EK_STATE_CHANGE:
+	  {
+	    state_change_event *state_change = (state_change_event *)base_event;
+#if 0 
+	    inform (base_event->m_loc, "considering state_change_event %i: %s",
+		    idx, base_event->m_desc);
+#endif
+
+	    if (state_change->m_var != var)
+	      {
+		//inform (base_event->m_loc, "would filter");
+		path->delete_event (idx);
+	      }
+	  }
+	  break;
+
+	case EK_EDGE:
+	  {
+	    edge_event *event = (edge_event *)base_event;
+#if 0
+	    inform (base_event->m_loc, "considering edge_event %i: %s",
+		    idx, base_event->m_desc);
+#endif
+	    // TODO
+	  }
+	  break;
+
+	case EK_WARNING:
+	  break;
+	}
+
+      idx--;
+    }
+}
+
+/* FIXME.  */
+
 void
 engine::maybe_emit (const candidate_diagnostic &cd)
 {
@@ -1933,6 +1992,8 @@ engine::maybe_emit (const candidate_diagnostic &cd)
   checker_path path (cd.m_path);
 #endif
 
+  prune_path (&path, cd.m_var, cd.m_state);
+
   char *msg = print ("here (%qE is in state %qs)", cd.m_var,
 		     m_sm.get_state_name (cd.m_state));
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-5.c b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-5.c
index 1fcd57e..5023cca 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-5.c
@@ -16,7 +16,7 @@ int test (const char *filename, int flag)
       return -1;
     }
 
-  q = (int *)malloc (sizeof (int)); /* { dg-line malloc_of_q } */
+  q = (int *)malloc (sizeof (int));
   if (!q) /* { dg-line test_of_q } */
     {
       free (p); /* { dg-line first_free_of_p } */
@@ -32,11 +32,9 @@ int test (const char *filename, int flag)
   /* { dg-warning "double-free of 'p'" "" { target *-*-* } second_free_of_p } */
   /* { dg-message "\\(1\\) state of 'p': 'start' -> 'unchecked'" "" { target *-*-* } malloc_of_p } */
   /* { dg-message "\\(2\\) state of 'p': 'unchecked' -> 'nonnull'" "" { target *-*-* } test_of_p } */
-  /* { dg-message "\\(3\\) state of 'q': 'start' -> 'unchecked'" "" { target *-*-* } malloc_of_q } */
-  /* { dg-message "\\(4\\) state of 'q': 'unchecked' -> 'null'" "" { target *-*-* } test_of_q } */
-  /* { dg-message "\\(5\\) state of 'p': 'nonnull' -> 'free'" "" { target *-*-* } first_free_of_p } */
-  /* { dg-message "\\(6\\) here \\('p' is in state 'free'\\)" "" { target *-*-* } second_free_of_p } */
+  /* { dg-message "\\(3\\) state of 'p': 'nonnull' -> 'free'" "" { target *-*-* } first_free_of_p } */
+  /* { dg-message "\\(4\\) here \\('p' is in state 'free'\\)" "" { target *-*-* } second_free_of_p } */
 
-  /* TODO: filter the events: we don't care about the state of q, but we do care about the
-     test of it.  */
+  /* We dont' care about the state changes to q.  */
+  /* TODO: we do care about the test of q.  */
 }
-- 
1.8.5.3

