/* Modeling API uses and misuses via state machines.
   Copyright (C) 2019-2025 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/>.  */

#define INCLUDE_LIST
#include "analyzer/common.h"

#include "tree-diagnostic.h"

#include "analyzer/analyzer-logging.h"
#include "analyzer/sm.h"
#include "analyzer/call-string.h"
#include "analyzer/program-point.h"
#include "analyzer/store.h"
#include "analyzer/svalue.h"
#include "analyzer/program-state.h"
#include "analyzer/pending-diagnostic.h"

#if ENABLE_ANALYZER

namespace ana {

/* Return true if VAR has pointer or reference type.  */

bool
any_pointer_p (tree var)
{
  return POINTER_TYPE_P (TREE_TYPE (var));
}

/* Return true if SVAL has pointer or reference type.  */

bool
any_pointer_p (const svalue *sval)
{
  if (!sval->get_type ())
    return false;
  return POINTER_TYPE_P (sval->get_type ());
}

/* class state_machine::state.  */

/* Base implementation of dump_to_pp vfunc.  */

void
state_machine::state::dump_to_pp (pretty_printer *pp) const
{
  pp_string (pp, m_name);
}

/* Return a new json::string describing the state.  */

std::unique_ptr<json::value>
state_machine::state::to_json () const
{
  pretty_printer pp;
  pp_format_decoder (&pp) = default_tree_printer;
  dump_to_pp (&pp);
  return std::make_unique<json::string> (pp_formatted_text (&pp));
}

/* class state_machine.  */

/* state_machine's ctor.  */

state_machine::state_machine (const char *name, logger *logger)
: log_user (logger), m_name (name), m_next_state_id (0),
  m_start (add_state ("start"))
{
}

/* Add a state with name NAME to this state_machine.
   The string is required to outlive the state_machine.

   Return the state_t for the new state.  */

state_machine::state_t
state_machine::add_state (const char *name)
{
  state *s = new state (name, alloc_state_id ());
  m_states.safe_push (s);
  return s;
}

/* Get the state with name NAME, which must exist.
   This is purely intended for use in selftests.  */

state_machine::state_t
state_machine::get_state_by_name (const char *name) const
{
  unsigned i;
  state *s;
  FOR_EACH_VEC_ELT (m_states, i, s)
    if (!strcmp (name, s->get_name ()))
      return s;
  /* Name not found.  */
  gcc_unreachable ();
}

/* Base implementation of state_machine::on_leak.  */

std::unique_ptr<pending_diagnostic>
state_machine::on_leak (tree var ATTRIBUTE_UNUSED,
			const program_state *old_state ATTRIBUTE_UNUSED,
			const program_state *new_state ATTRIBUTE_UNUSED) const
{
  return nullptr;
}

/* Dump a multiline representation of this state machine to PP.  */

void
state_machine::dump_to_pp (pretty_printer *pp) const
{
  unsigned i;
  state *s;
  FOR_EACH_VEC_ELT (m_states, i, s)
    {
      pp_printf (pp, "  state %i: ", i);
      s->dump_to_pp (pp);
      pp_newline (pp);
    }
}

/* Return a new json::object of the form
   {"name" : str,
    "states" : [str]}.  */

std::unique_ptr<json::object>
state_machine::to_json () const
{
  auto sm_obj = std::make_unique<json::object> ();

  sm_obj->set_string ("name", m_name);
  {
    auto states_arr = std::make_unique<json::array> ();
    unsigned i;
    state *s;
    FOR_EACH_VEC_ELT (m_states, i, s)
      states_arr->append (s->to_json ());
    sm_obj->set ("states", std::move (states_arr));
  }

  return sm_obj;
}

void
state_machine::add_state_to_state_graph (analyzer_state_graph &out_state_graph,
					 const svalue &sval,
					 state_machine::state_t state) const
{
  // no-op
}

void
state_machine::add_global_state_to_state_graph (analyzer_state_graph &out_state_graph,
						state_machine::state_t state) const
{
  // no-op
}

/* class sm_context.  */

const region_model *
sm_context::get_old_region_model () const
{
  if (const program_state *old_state = get_old_program_state ())
    return old_state->m_region_model;
  else
    return nullptr;
}

/* Create instances of the various state machines, each using LOGGER,
   returning a vector of them.  */

std::vector<std::unique_ptr<state_machine>>
make_checkers (logger *logger)
{
  /* Start with a list so that we can filter it.  */
  std::list<std::unique_ptr<state_machine>> out;
  out.push_back (make_malloc_state_machine (logger));
  out.push_back (make_fileptr_state_machine (logger));
  out.push_back (make_fd_state_machine (logger));
  out.push_back (make_taint_state_machine (logger));
  out.push_back (make_sensitive_state_machine (logger));
  out.push_back (make_signal_state_machine (logger));
  out.push_back (make_va_list_state_machine (logger));

  /* We only attempt to run the pattern tests if it might have been manually
     enabled (for DejaGnu purposes).  */
  if (flag_analyzer_checker)
    out.push_back (make_pattern_test_state_machine (logger));

  if (flag_analyzer_checker)
    {
      out.remove_if ([] (auto &sm)
		     {
		       return 0 != strcmp (flag_analyzer_checker,
					   sm->get_name ());
		     });
    }

  std::vector<std::unique_ptr<state_machine>> out_vec;
  for (auto &iter: out)
    out_vec.push_back (std::move (iter));

  return out_vec;
}

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
