From d7607690b34452645b711b03c4b8278ebffccb07 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 24 Apr 2019 11:38:30 -0400
Subject: [PATCH 194/217] FIXME: impl-4: run all checkers at once

---
 gcc/analyzer/hardcoded-state-machine.cc |  21 +++++-
 gcc/analyzer/hardcoded-state-machine.h  |   2 +
 gcc/analyzer/impl-4.cc                  | 130 ++++++++++++--------------------
 3 files changed, 72 insertions(+), 81 deletions(-)

diff --git a/gcc/analyzer/hardcoded-state-machine.cc b/gcc/analyzer/hardcoded-state-machine.cc
index fa69b6c..91fb081 100644
--- a/gcc/analyzer/hardcoded-state-machine.cc
+++ b/gcc/analyzer/hardcoded-state-machine.cc
@@ -142,5 +142,24 @@ make_checkers (auto_delete_vec <state_machine> &out, logger *logger)
   out.safe_push (new fileptr_state_machine (logger));
   out.safe_push (new taint_state_machine (logger));
   out.safe_push (new sensitive_state_machine (logger));
-  // we don't add pattern_test_state_machine by default
+
+  /* We only attempt to run the pattern tests if it might have been manually
+     enabled (for DejaGnu purposes).  */
+  if (flag_analyzer_checker)
+    out.safe_push (new pattern_test_state_machine (logger));
+
+  if (flag_analyzer_checker)
+    {
+#if 0
+      if (0 != strcmp (flag_analyzer_checker, sm.get_name ()))
+	{
+	  // TODO
+	  if (logger)
+	    logger->log ("skipping checker %s (does not match %s)",
+			 sm.get_name (), flag_analyzer_checker);
+	  return;
+	}
+#endif
+    }
+
 }
diff --git a/gcc/analyzer/hardcoded-state-machine.h b/gcc/analyzer/hardcoded-state-machine.h
index bdc79e0..274c968 100644
--- a/gcc/analyzer/hardcoded-state-machine.h
+++ b/gcc/analyzer/hardcoded-state-machine.h
@@ -48,6 +48,8 @@ public:
   state_machine (const char *name, logger *logger)
   : log_user (logger), m_name (name) {}
 
+  virtual ~state_machine () {}
+
   const char *get_name () const { return m_name; }
 
   const char *get_state_name (state_t s) const;
diff --git a/gcc/analyzer/impl-4.cc b/gcc/analyzer/impl-4.cc
index fe9650f..c1ede9e 100644
--- a/gcc/analyzer/impl-4.cc
+++ b/gcc/analyzer/impl-4.cc
@@ -180,6 +180,18 @@ public:
   }
 };
 
+#if 0
+/* Map from var to state machine state.  */
+
+class sm_state_map
+{
+  typedef hash_map <path_var, state_machine::state_t> map_t;
+  map_t m_var_to_state;
+};
+#endif
+
+/* FIXME.  */
+
 class program_state
 {
 public:
@@ -190,6 +202,11 @@ public:
   path_state m_path_state;
 #endif
 
+#if 0
+  // TODO: maybe have multiple of these; do all state machines at once
+  sm_state_map m_sm_map;
+#endif
+
   // TODO: add "backtrace" of calls
 };
 
@@ -293,7 +310,8 @@ private:
 class exploded_graph : public digraph, public log_user
 {
 public:
-  exploded_graph (const supergraph &sg, logger *logger);
+  exploded_graph (const supergraph &sg, logger *logger,
+		  auto_delete_vec <state_machine> &checkers);
 
   void add_function_entry (function *fun);
   void process_worklist ();
@@ -315,6 +333,9 @@ public:
 
   auto_vec<exploded_node *> m_worklist;
   auto_vec<exploded_node *> m_entrypoints;
+
+  /* The state machines.  */
+  auto_delete_vec <state_machine> &m_checkers;
 };
 
 /* FIXME.  */
@@ -654,8 +675,9 @@ exploded_edge::dump_dot (pretty_printer *pp) const
 
 /* FIXME.  */
 
-exploded_graph::exploded_graph (const supergraph &sg, logger *logger)
-: log_user (logger), m_sg (sg)
+exploded_graph::exploded_graph (const supergraph &sg, logger *logger,
+				auto_delete_vec <state_machine> &checkers)
+: log_user (logger), m_sg (sg), m_checkers (checkers)
 {
 }
 
@@ -854,36 +876,41 @@ function_comparator (const void *pn1, const void *pn2)
 }
 #endif
 
-/* FIXME.  */
-/* TODO: should we run them all at once, or serially?
-   For now, this does them serially.  */
-
 void
-run_one_checker (const supergraph &sg, const state_machine &sm, logger *logger)
+impl_run_checkers (logger *logger)
 {
-  JIT_LOG_FUNC_1 (logger, "sm: %s", sm.get_name ());
+  JIT_LOG_SCOPE (logger);
+
+  /* Create the supergraph.  */
+  supergraph sg (logger);
 
-  if (flag_analyzer_checker)
+  if (1)
     {
-      if (0 != strcmp (flag_analyzer_checker, sm.get_name ()))
-	{
-	  if (logger)
-	    logger->log ("skipping checker %s (does not match %s)",
-			 sm.get_name (), flag_analyzer_checker);
-	  return;
-	}
+      char *filename = concat (dump_base_name, ".supergraph.dot", NULL);
+      sg.dump_dot (filename, (enum supergraph_dot_flags)0);
+      free (filename);
     }
 
-  engine e (sg, sm, logger, analyzer_verbosity);
+  // TODO: selftest for auto_delete_vec
+  auto_delete_vec <state_machine> checkers;
+  make_checkers (checkers, logger);
+
+  if (logger)
+    {
+      int i;
+      state_machine *sm;
+      FOR_EACH_VEC_ELT (checkers, i, sm)
+	logger->log ("checkers[%i]: %s", i, sm->get_name ());
+    }
+  //engine e (sg, sm, logger, analyzer_verbosity);
 
   // TODO: add initial nodes
-  exploded_graph eg (sg, logger);
+  impl_4::exploded_graph eg (sg, logger, checkers);
 
   cgraph_node *node;
   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
   {
     function *fun = node->get_fun ();
-
     if (!TREE_PUBLIC (fun->decl))
       {
 	if (logger)
@@ -898,12 +925,12 @@ run_one_checker (const supergraph &sg, const state_machine &sm, logger *logger)
   if (1)
     {
       char *filename
-	= concat (dump_base_name, ".", sm.get_name (), ".eg.dot", NULL);
+	= concat (dump_base_name, ".eg.dot", NULL);
       eg.dump_dot (filename);
       free (filename);
     }
 
-  e.log_stats ();
+  //e.log_stats ();
 }
 
 } // namespace impl_4
@@ -925,64 +952,7 @@ run_checkers_impl_4 ()
       }
     JIT_LOG_SCOPE (the_logger.get_logger ());
 
-    /* Create the supergraph.  */
-    supergraph sg (the_logger.get_logger ());
-
-    if (1)
-      {
-	char *filename = concat (dump_base_name, ".supergraph.dot", NULL);
-	sg.dump_dot (filename, (enum supergraph_dot_flags)0);
-	free (filename);
-      }
-
-#if 0
-    // TODO: selftest for auto_delete_vec
-    auto_delete_vec <state_machine> checkers;
-    make_checkers (checkers, the_logger.get_logger ());
-
-    int i;
-    state_machine *checker;
-    FOR_EACH_VEC_ELT (checkers, i, checker)
-      // FIXME: this requires better timevar ID management
-#endif
-
-    // TODO
-    // For now, just count paths through the supergraph
-
-#if 1
-    {
-      auto_client_timevar tv ("malloc_state_machine");
-      malloc_state_machine sm (the_logger.get_logger ());
-      impl_4::run_one_checker (sg, sm, the_logger.get_logger ());
-    }
-
-    {
-      auto_client_timevar tv ("fileptr_state_machine");
-      fileptr_state_machine sm (the_logger.get_logger ());
-      impl_4::run_one_checker (sg, sm, the_logger.get_logger ());
-    }
-
-    {
-      auto_client_timevar tv ("taint_state_machine");
-      taint_state_machine sm (the_logger.get_logger ());
-      impl_4::run_one_checker (sg, sm, the_logger.get_logger ());
-    }
-
-    {
-      auto_client_timevar tv ("sensitive_state_machine");
-      sensitive_state_machine sm (the_logger.get_logger ());
-      impl_4::run_one_checker (sg, sm, the_logger.get_logger ());
-    }
-
-    /* We only attempt to run the pattern tests if it might have been manually
-       enabled (for DejaGnu purposes).  */
-    if (flag_analyzer_checker)
-      {
-	auto_client_timevar tv ("pattern_test_state_machine");
-	pattern_test_state_machine sm (the_logger.get_logger ());
-	impl_4::run_one_checker (sg, sm, the_logger.get_logger ());
-      }
-#endif
+    impl_4::impl_run_checkers (the_logger.get_logger ());
 
     /* end of lifetime of the_logger (so that dump file is closed after the
        various dtors run).  */
-- 
1.8.5.3

