From 677677388c92fa0cd17ecf12ceceee2200cdcd4b Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Fri, 3 Apr 2020 15:39:59 -0400
Subject: [PATCH 005/293] FIXME: WIP on an alternate to region_model

---
 gcc/Makefile.in               |   1 +
 gcc/analyzer/engine.cc        |  24 ++-
 gcc/analyzer/program-state.cc |  51 ++++-
 gcc/analyzer/program-state.h  |   5 +
 gcc/analyzer/revamp-state.cc  | 351 ++++++++++++++++++++++++++++++++++
 gcc/analyzer/revamp-state.h   | 139 ++++++++++++++
 6 files changed, 562 insertions(+), 9 deletions(-)
 create mode 100644 gcc/analyzer/revamp-state.cc
 create mode 100644 gcc/analyzer/revamp-state.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index fa9923bb270..3f2a032b67d 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1232,6 +1232,7 @@ ANALYZER_OBJS = \
 	analyzer/program-point.o \
 	analyzer/program-state.o \
 	analyzer/region-model.o \
+	analyzer/revamp-state.o \
 	analyzer/sm.o \
 	analyzer/sm-file.o \
 	analyzer/sm-malloc.o \
diff --git a/gcc/analyzer/engine.cc b/gcc/analyzer/engine.cc
index 21641c6d0d0..8108ec9f0e9 100644
--- a/gcc/analyzer/engine.cc
+++ b/gcc/analyzer/engine.cc
@@ -723,6 +723,9 @@ point_and_state::validate (const extrinsic_state &ext_state) const
 
   m_state.validate (ext_state);
 
+  if (!m_state.m_region_model)
+    return;
+
   /* Verify that the callstring's model of the stack corresponds to that
      of the region_model.  */
   /* They should have the same depth.  */
@@ -805,7 +808,8 @@ exploded_node::exploded_node (const point_and_state &ps,
 			      int index)
 : m_ps (ps), m_status (STATUS_WORKLIST), m_index (index)
 {
-  gcc_checking_assert (ps.get_state ().m_region_model->canonicalized_p ());
+  if (ps.get_state ().m_region_model)
+    gcc_checking_assert (ps.get_state ().m_region_model->canonicalized_p ());
 }
 
 /* For use by dump_dot, get a value for the .dot "fillcolor" attribute.
@@ -1005,6 +1009,14 @@ exploded_node::on_stmt (exploded_graph &eg,
 			program_state *state,
 			state_change *change) const
 {
+  if (state->m_revamp_state)
+    {
+      if (state->m_revamp_state->on_stmt (eg.get_ext_state (), snode, stmt))
+	return on_stmt_flags (false);
+      else
+	return on_stmt_flags::terminate_path ();
+    }
+
   /* Preserve the old state.  It is used here for looking
      up old checker states, for determining state transitions, and
      also within impl_region_model_context and impl_sm_context for
@@ -1350,6 +1362,8 @@ exploded_node::detect_leaks (exploded_graph &eg) const
   gcc_assert (get_point ().get_stack_depth () == 1);
 
   const program_state &old_state = get_state ();
+  if (!old_state.m_region_model)
+    return;
 
   /* Work with a temporary copy of the state: pop the frame, and see
      what leaks (via purge_unused_svalues).  */
@@ -1857,8 +1871,7 @@ exploded_graph::add_function_entry (function *fun)
 {
   program_point point = program_point::from_function_entry (m_sg, fun);
   program_state state (m_ext_state);
-  impl_region_model_context ctxt (&state, NULL, m_ext_state, get_logger ());
-  state.m_region_model->push_frame (fun, NULL, &ctxt);
+  state.push_frame (m_ext_state, fun);
 
   if (!state.m_valid)
     return NULL;
@@ -1927,7 +1940,8 @@ exploded_graph::get_or_create_node (const program_point &point,
       pp_string (pp, "pruned_state: ");
       pruned_state.dump_to_pp (m_ext_state, true, pp);
       logger->end_log_line ();
-      pruned_state.m_region_model->dump_to_pp (logger->get_printer (), true);
+      if (pruned_state.m_region_model)
+	pruned_state.m_region_model->dump_to_pp (logger->get_printer (), true);
     }
 
   stats *per_fn_stats = get_or_create_function_stats (point.get_function ());
@@ -2460,7 +2474,7 @@ exploded_graph::process_node (exploded_node *node)
 					    NULL);
 	    const cfg_superedge *last_cfg_superedge
 	      = point.get_from_edge ()->dyn_cast_cfg_superedge ();
-	    if (last_cfg_superedge)
+	    if (last_cfg_superedge && next_state.m_region_model)
 	      next_state.m_region_model->update_for_phis
 		(node->get_supernode (),
 		 last_cfg_superedge,
diff --git a/gcc/analyzer/program-state.cc b/gcc/analyzer/program-state.cc
index 43396c65827..813cd38b422 100644
--- a/gcc/analyzer/program-state.cc
+++ b/gcc/analyzer/program-state.cc
@@ -595,10 +595,15 @@ sm_state_map::validate (const state_machine &sm,
 /* program_state's ctor.  */
 
 program_state::program_state (const extrinsic_state &ext_state)
-: m_region_model (new region_model ()),
+: m_revamp_state (NULL),
+  m_region_model (NULL),
   m_checker_states (ext_state.get_num_checkers ()),
   m_valid (true)
 {
+  if (getenv ("REVAMP"))
+    m_revamp_state = new revamp_state (ext_state);
+  else
+    m_region_model = new region_model ();
   int num_states = ext_state.get_num_checkers ();
   for (int i = 0; i < num_states; i++)
     m_checker_states.quick_push (new sm_state_map ());
@@ -607,10 +612,13 @@ program_state::program_state (const extrinsic_state &ext_state)
 /* program_state's copy ctor.  */
 
 program_state::program_state (const program_state &other)
-: m_region_model (new region_model (*other.m_region_model)),
+: m_revamp_state (other.m_revamp_state),
+  m_region_model (NULL),
   m_checker_states (other.m_checker_states.length ()),
   m_valid (true)
 {
+  if (other.m_region_model)
+    m_region_model = new region_model (*other.m_region_model);
   int i;
   sm_state_map *smap;
   FOR_EACH_VEC_ELT (other.m_checker_states, i, smap)
@@ -622,8 +630,10 @@ program_state::program_state (const program_state &other)
 program_state&
 program_state::operator= (const program_state &other)
 {
+  m_revamp_state = other.m_revamp_state;
   delete m_region_model;
-  m_region_model = new region_model (*other.m_region_model);
+  if (other.m_region_model)
+    m_region_model = new region_model (*other.m_region_model);
 
   int i;
   sm_state_map *smap;
@@ -670,7 +680,10 @@ program_state::~program_state ()
 hashval_t
 program_state::hash () const
 {
-  hashval_t result = m_region_model->hash ();
+  hashval_t result = 0;
+
+  if (m_region_model)
+    result ^= m_region_model->hash ();
 
   int i;
   sm_state_map *smap;
@@ -687,6 +700,9 @@ program_state::hash () const
 bool
 program_state::operator== (const program_state &other) const
 {
+  if (!m_region_model)
+    return true; // FIXME
+
   if (!(*m_region_model == *other.m_region_model))
     return false;
 
@@ -738,6 +754,8 @@ program_state::dump_to_pp (const extrinsic_state &ext_state,
 			   bool summarize,
 			   pretty_printer *pp) const
 {
+  if (!m_region_model)
+    return;
   pp_printf (pp, "rmodel: ");
   m_region_model->dump_to_pp (pp, summarize);
 
@@ -791,6 +809,21 @@ program_state::dump (const extrinsic_state &ext_state,
   dump_to_file (ext_state, summarize, stderr);
 }
 
+void
+program_state::push_frame (const extrinsic_state &ext_state,
+			   function *fun)
+{
+  if (m_revamp_state)
+    {
+      // TODO
+    }
+  if (m_region_model)
+    {
+      impl_region_model_context ctxt (this, NULL, ext_state, ext_state.get_logger ());
+      m_region_model->push_frame (fun, NULL, &ctxt);
+    }
+}
+
 /* Determine if following edge SUCC from ENODE is valid within the graph EG
    and update this state accordingly in-place.
 
@@ -821,6 +854,11 @@ program_state::on_edge (exploded_graph &eg,
      Adding the relevant conditions for the edge could also trigger
      sm-state transitions (e.g. transitions due to ptrs becoming known
      to be NULL or non-NULL) */
+  if (m_revamp_state)
+    {
+      return m_revamp_state->maybe_update_for_edge (*succ,
+						    last_stmt);
+    }
 
   impl_region_model_context ctxt (eg, &enode,
 				  &enode.get_state (),
@@ -862,6 +900,9 @@ program_state::prune_for_point (exploded_graph &eg,
   if (!fun)
     return *this;
 
+  if (!m_region_model)
+    return *this;
+
   program_state new_state (*this);
 
   purge_stats stats;
@@ -1079,6 +1120,8 @@ program_state::validate (const extrinsic_state &ext_state) const
   return;
 #endif
 
+  if (!m_region_model)
+    return;
   m_region_model->validate ();
   gcc_assert (m_checker_states.length () == ext_state.get_num_checkers ());
   int sm_idx;
diff --git a/gcc/analyzer/program-state.h b/gcc/analyzer/program-state.h
index 4c7fcf6bf7e..60c9e975ed1 100644
--- a/gcc/analyzer/program-state.h
+++ b/gcc/analyzer/program-state.h
@@ -61,6 +61,8 @@ private:
 
 } // namespace ana
 
+#include "revamp-state.h"
+
 template <> struct default_hash_traits<svalue_id>
 : public pod_hash_traits<svalue_id>
 {
@@ -255,6 +257,8 @@ public:
 		     FILE *outf) const;
   void dump (const extrinsic_state &ext_state, bool summarize) const;
 
+  void push_frame (const extrinsic_state &ext_state, function *fun);
+
   bool on_edge (exploded_graph &eg,
 		const exploded_node &enode,
 		const superedge *succ,
@@ -290,6 +294,7 @@ public:
 
   void validate (const extrinsic_state &ext_state) const;
 
+  revamp_state *m_revamp_state;
   /* TODO: lose the pointer here (const-correctness issues?).  */
   region_model *m_region_model;
   auto_delete_vec<sm_state_map> m_checker_states;
diff --git a/gcc/analyzer/revamp-state.cc b/gcc/analyzer/revamp-state.cc
new file mode 100644
index 00000000000..72f248a6c11
--- /dev/null
+++ b/gcc/analyzer/revamp-state.cc
@@ -0,0 +1,351 @@
+/* Classes for modeling the state of memory.
+   Copyright (C) 2019-2020 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "function.h"
+#include "basic-block.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "diagnostic-core.h"
+#include "graphviz.h"
+#include "options.h"
+#include "cgraph.h"
+#include "tree-dfa.h"
+#include "stringpool.h"
+#include "convert.h"
+#include "target.h"
+#include "fold-const.h"
+#include "tree-pretty-print.h"
+#include "diagnostic-color.h"
+#include "diagnostic-metadata.h"
+#include "tristate.h"
+#include "bitmap.h"
+#include "selftest.h"
+#include "function.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "ordered-hash-map.h"
+#include "options.h"
+#include "cgraph.h"
+#include "cfg.h"
+#include "digraph.h"
+#include "analyzer/supergraph.h"
+#include "sbitmap.h"
+#include "analyzer/region-model.h"
+#include "analyzer/constraint-manager.h"
+#include "diagnostic-event-id.h"
+#include "analyzer/sm.h"
+#include "diagnostic-event-id.h"
+#include "analyzer/sm.h"
+#include "analyzer/pending-diagnostic.h"
+#include "analyzer/analyzer-selftests.h"
+#include "stor-layout.h"
+#include "analyzer/program-state.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* class sval.  */
+
+DEBUG_FUNCTION void
+sval::dump ()
+{
+  pretty_printer pp;
+  pp_format_decoder (&pp) = default_tree_printer;
+  pp_show_color (&pp) = pp_show_color (global_dc->printer);
+  pp.buffer->stream = stderr;
+  dump_to_pp (&pp);
+  pp_flush (&pp);
+}
+
+/* dump_to_pp implementations.  */
+
+void
+cst_sval::dump_to_pp (pretty_printer *pp) const
+{
+  pp_printf (pp, "cst_sval(%qE)", m_cst);
+}
+
+void
+var_decl_region::dump_to_pp (pretty_printer *pp) const
+{
+  pp_printf (pp, "var_decl_region(%qE)", m_decl);
+}
+
+/* class environment.  */
+
+void
+environment::bind (region_val *dst, sval *val)
+{
+  m_map.put (dst, val);
+  dump ();
+}
+
+DEBUG_FUNCTION void
+environment::dump ()
+{
+  pretty_printer pp;
+  pp_format_decoder (&pp) = default_tree_printer;
+  pp_show_color (&pp) = pp_show_color (global_dc->printer);
+  pp.buffer->stream = stderr;
+  dump_to_pp (&pp);
+  pp_flush (&pp);
+}
+
+void
+environment::dump_to_pp (pretty_printer *pp) const
+{
+  pp_character (pp, '{');
+  for (map_t::iterator iter = m_map.begin ();
+       iter != m_map.end ();
+       ++iter)
+    {
+      if (iter != m_map.begin ())
+	pp_string (pp, ", ");
+      region_val *reg = (*iter).first;
+      sval *val = (*iter).second;
+      reg->dump_to_pp (pp);
+      pp_string (pp, ": ");
+      val->dump_to_pp (pp);
+    }
+  pp_character (pp, '}');
+}
+
+/* class revamp_state.  */
+
+revamp_state::revamp_state (const extrinsic_state &ext_state)
+: m_env (new environment ()) // FIXME
+{
+}
+
+bool
+revamp_state::on_stmt (const extrinsic_state &ext_state,
+		       const supernode *snode,
+		       const gimple *stmt)
+{
+  switch (stmt->code)
+    {
+    case GIMPLE_COND:
+      /* This is a no-op; the condition is handled by the true/false
+	 superedges.  */
+      return true;
+
+    case GIMPLE_LABEL:
+      /* No-op.  */
+      return true;
+
+    case GIMPLE_ASSIGN:
+      return on_gassign (ext_state, snode, as_a <const gassign *> (stmt));
+
+    case GIMPLE_RETURN:
+      return on_greturn (ext_state, snode, as_a <const greturn *> (stmt));
+
+    default:
+      sorry_at (stmt->location, "unhandled stmt: %qs",
+		gimple_code_name[stmt->code]);
+      return false;
+    }
+}
+
+bool
+revamp_state::on_gassign (const extrinsic_state &ext_state,
+			  const supernode *snode,
+			  const gassign *stmt)
+{
+  tree lhs = gimple_assign_lhs (stmt);
+  tree rhs1 = gimple_assign_rhs1 (stmt);
+
+  enum tree_code op = gimple_assign_rhs_code (stmt);
+  switch (op)
+    {
+    case INTEGER_CST:
+      bind (ext_state, lhs, rhs1);
+      break;
+
+    default:
+      sorry_at (stmt->location, "unhandled assignment op: %qs",
+		get_tree_code_name (op));
+      break;
+    }
+
+  return true;
+}
+
+bool
+revamp_state::on_greturn (const extrinsic_state &ext_state,
+			  const supernode *snode,
+			  const greturn *stmt)
+{
+  return true;
+}
+
+bool
+revamp_state::maybe_update_for_edge (const superedge &edge,
+				     const gimple *last_stmt)
+{
+  /* Handle frame updates for interprocedural edges.  */
+  switch (edge.m_kind)
+    {
+    default:
+      break;
+
+    case SUPEREDGE_CALL:
+      {
+	const call_superedge *call_edge = as_a <const call_superedge *> (&edge);
+	update_for_call_superedge (*call_edge);
+      }
+      break;
+
+    case SUPEREDGE_RETURN:
+      {
+	const return_superedge *return_edge
+	  = as_a <const return_superedge *> (&edge);
+	update_for_return_superedge (*return_edge);
+      }
+      break;
+
+    case SUPEREDGE_INTRAPROCEDURAL_CALL:
+      {
+	const callgraph_superedge *cg_sedge
+	  = as_a <const callgraph_superedge *> (&edge);
+	update_for_call_summary (*cg_sedge);
+      }
+      break;
+    }
+
+  if (last_stmt == NULL)
+    return true;
+
+  /* Apply any constraints for conditionals/switch statements.  */
+
+  if (const gcond *cond_stmt = dyn_cast <const gcond *> (last_stmt))
+    {
+      const cfg_superedge *cfg_sedge = as_a <const cfg_superedge *> (&edge);
+      return apply_constraints_for_gcond (*cfg_sedge, cond_stmt);
+    }
+
+  if (const gswitch *switch_stmt = dyn_cast <const gswitch *> (last_stmt))
+    {
+      const switch_cfg_superedge *switch_sedge
+	= as_a <const switch_cfg_superedge *> (&edge);
+      return apply_constraints_for_gswitch (*switch_sedge, switch_stmt);
+    }
+
+  return true;
+}
+
+void
+revamp_state::update_for_call_superedge (const call_superedge &call_edge)
+{
+  // TODO
+}
+
+void
+revamp_state::update_for_return_superedge (const return_superedge &return_edge)
+{
+  // TODO
+}
+
+void
+revamp_state::update_for_call_summary (const callgraph_superedge &cg_sedge)
+{
+  // TODO
+}
+
+bool
+revamp_state::apply_constraints_for_gcond (const cfg_superedge &sedge,
+					   const gcond *cond_stmt)
+{
+  ::edge cfg_edge = sedge.get_cfg_edge ();
+  gcc_assert (cfg_edge != NULL);
+  gcc_assert (cfg_edge->flags & (EDGE_TRUE_VALUE | EDGE_FALSE_VALUE));
+
+  enum tree_code op = gimple_cond_code (cond_stmt);
+  tree lhs = gimple_cond_lhs (cond_stmt);
+  tree rhs = gimple_cond_rhs (cond_stmt);
+  if (cfg_edge->flags & EDGE_FALSE_VALUE)
+    op = invert_tree_comparison (op, false /* honor_nans */);
+  return add_constraint (lhs, op, rhs);
+}
+
+bool
+revamp_state::apply_constraints_for_gswitch (const switch_cfg_superedge &edge,
+					     const gswitch *switch_stmt)
+{
+  return true; // TODO
+}
+
+bool
+revamp_state::add_constraint (tree lhs, enum tree_code op, tree rhs)
+{
+  // TODO:
+#if 0
+  sval *get_sval (lhs);
+  sval *get_sval (rhs);
+#endif
+  return true;
+}
+
+void
+revamp_state::bind (const extrinsic_state &ext_state,
+		    tree lhs, tree rhs)
+{
+  loc_val *dst = get_lvalue (ext_state, lhs);
+  sval *src = get_rvalue (ext_state, rhs);
+  if (region_val *rval = dst->dyn_cast_region_val ())
+    m_env->bind (rval, src);
+  else
+    gcc_unreachable (); // unknown loc_val; what could be clobbered?
+}
+
+loc_val *
+revamp_state::get_lvalue (const extrinsic_state &ext_state, tree expr)
+{
+  switch (TREE_CODE (expr))
+    {
+    case VAR_DECL:
+      return new var_decl_region (expr); // TODO: uniquify
+    default:
+      gcc_unreachable ();
+      //return ext_state::new_unknown_sval (expr);
+    }
+}
+
+sval *
+revamp_state::get_rvalue (const extrinsic_state &ext_state, tree expr)
+{
+  switch (TREE_CODE (expr))
+    {
+    case INTEGER_CST:
+      return new cst_sval (expr); //ext_state.get_or_add_cst_sval (expr);
+    default:
+      gcc_unreachable ();
+      //return ext_state::new_unknown_sval (expr);
+    }
+}
+
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/revamp-state.h b/gcc/analyzer/revamp-state.h
new file mode 100644
index 00000000000..295d084df7d
--- /dev/null
+++ b/gcc/analyzer/revamp-state.h
@@ -0,0 +1,139 @@
+/* Classes for representing the state of interest at a given path of analysis.
+   Copyright (C) 2019-2020 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ANALYZER_REVAMP_STATE_H
+#define GCC_ANALYZER_REVAMP_STATE_H
+
+namespace ana {
+
+class region_val;
+
+// TODO:
+class sval
+{
+public:
+  void dump ();
+  virtual void dump_to_pp (pretty_printer *pp) const = 0;
+  virtual region_val *dyn_cast_region_val () { return NULL; }
+};
+
+class nonloc_val : public sval
+{
+};
+
+class cst_sval : public nonloc_val
+{
+public:
+  cst_sval (tree cst) : m_cst (cst)
+  {
+    gcc_assert (CONSTANT_CLASS_P (cst));
+  }
+
+  void dump_to_pp (pretty_printer *pp) const FINAL OVERRIDE;
+
+private:
+  tree m_cst;
+};
+
+class loc_val : public sval
+{
+};
+
+class unknown_loc_val : public loc_val
+{
+};
+
+class region_val : public loc_val
+{
+ public:
+  region_val *dyn_cast_region_val () FINAL OVERRIDE { return this; }
+};
+
+class var_decl_region : public region_val
+{
+public:
+  var_decl_region (tree decl) : m_decl (decl)
+  {
+    gcc_assert (TREE_CODE (decl) == VAR_DECL);
+  }
+
+  void dump_to_pp (pretty_printer *pp) const FINAL OVERRIDE;
+
+private:
+  tree m_decl;
+};
+
+class environment
+{
+ public:
+  typedef hash_map <region_val *, sval *> map_t; // or region * ?
+  typedef map_t::iterator iterator_t;
+
+  void bind (region_val *dst, sval *val);
+
+  void dump ();
+  void dump_to_pp (pretty_printer *pp) const;
+
+ private:
+  map_t m_map;
+};
+
+// TODO:
+class revamp_state
+{
+public:
+  revamp_state (const extrinsic_state &ext_state);
+
+  bool on_stmt (const extrinsic_state &ext_state,
+		const supernode *snode,
+		const gimple *stmt);
+  bool maybe_update_for_edge (const superedge &succ, const gimple *last_stmt);
+
+  bool add_constraint (tree lhs, enum tree_code op, tree rhs);
+
+  void bind (const extrinsic_state &ext_state,
+	     tree lhs, tree rhs);
+
+  loc_val *get_lvalue (const extrinsic_state &ext_state, tree expr);
+  sval *get_rvalue (const extrinsic_state &ext_state, tree expr);
+
+private:
+  bool on_gassign (const extrinsic_state &ext_state,
+		   const supernode *snode,
+		   const gassign *stmt);
+  bool on_greturn (const extrinsic_state &ext_state,
+		   const supernode *snode,
+		   const greturn *stmt);
+
+  void update_for_call_superedge (const call_superedge &call_edge);
+  void update_for_return_superedge (const return_superedge &return_edge);
+  void update_for_call_summary (const callgraph_superedge &cg_sedge);
+  bool apply_constraints_for_gcond (const cfg_superedge &edge,
+				    const gcond *cond_stmt);
+  bool apply_constraints_for_gswitch (const switch_cfg_superedge &edge,
+				      const gswitch *switch_stmt);
+
+  // TODO
+  environment *m_env;
+};
+
+} // namespace ana
+
+#endif /* GCC_ANALYZER_REVAMP_STATE_H */
-- 
2.26.2

