/* Classes for representing locations within the program.
   Copyright (C) 2019-2023 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"
#define INCLUDE_MEMORY
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "gimple-pretty-print.h"
#include "gcc-rich-location.h"
#include "ordered-hash-map.h"
#include "options.h"
#include "cgraph.h"
#include "function.h"
#include "cfg.h"
#include "basic-block.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "digraph.h"
#include "analyzer/analyzer.h"
#include "analyzer/analyzer-logging.h"
#include "analyzer/call-string.h"
#include "analyzer/supergraph.h"
#include "analyzer/program-point.h"
#include "sbitmap.h"
#include "bitmap.h"
#include "selftest.h"
#include "analyzer/store.h"
#include "analyzer/region-model.h"
#include "analyzer/sm.h"
#include "analyzer/program-state.h"
#include "diagnostic-event-id.h"
#include "analyzer/pending-diagnostic.h"
#include "analyzer/diagnostic-manager.h"
#include "shortest-paths.h"
#include "analyzer/exploded-graph.h"
#include "analyzer/analysis-plan.h"
#include "analyzer/inlining-iterator.h"

#if ENABLE_ANALYZER

namespace ana {

/* Get a string for PK.  */

const char *
point_kind_to_string (enum point_kind pk)
{
  switch (pk)
    {
    default:
      gcc_unreachable ();
    case PK_ORIGIN:
      return "PK_ORIGIN";
    case PK_BEFORE_SUPERNODE:
      return "PK_BEFORE_SUPERNODE";
    case PK_BEFORE_STMT:
      return "PK_BEFORE_STMT";
    case PK_AFTER_SUPERNODE:
      return "PK_AFTER_SUPERNODE";
    case PK_EMPTY:
      return "PK_EMPTY";
    case PK_DELETED:
      return "PK_DELETED";
    }
}

/* class function_point.  */

function_point::function_point (const supernode *supernode,
				const superedge *from_edge,
				unsigned stmt_idx,
				enum point_kind kind)
: m_supernode (supernode), m_from_edge (from_edge),
  m_stmt_idx (stmt_idx), m_kind (kind)
{
  if (from_edge)
    {
      gcc_checking_assert (m_kind == PK_BEFORE_SUPERNODE);
      gcc_checking_assert (from_edge->get_kind () == SUPEREDGE_CFG_EDGE);
    }
  if (stmt_idx)
    gcc_checking_assert (m_kind == PK_BEFORE_STMT);
}

/* Print this function_point to PP.  */

void
function_point::print (pretty_printer *pp, const format &f) const
{
  switch (get_kind ())
    {
    default:
      gcc_unreachable ();

    case PK_ORIGIN:
      pp_printf (pp, "origin");
      if (f.m_newlines)
	pp_newline (pp);
      break;

    case PK_BEFORE_SUPERNODE:
      {
	if (m_from_edge)
	  {
	    if (basic_block bb = m_from_edge->m_src->m_bb)
	      pp_printf (pp, "before SN: %i (from SN: %i (bb: %i))",
			 m_supernode->m_index, m_from_edge->m_src->m_index,
			 bb->index);
	    else
	      pp_printf (pp, "before SN: %i (from SN: %i)",
			 m_supernode->m_index, m_from_edge->m_src->m_index);
	  }
	else
	  pp_printf (pp, "before SN: %i (NULL from-edge)",
		     m_supernode->m_index);
	f.spacer (pp);
	for (gphi_iterator gpi
	       = const_cast<supernode *>(get_supernode ())->start_phis ();
	     !gsi_end_p (gpi); gsi_next (&gpi))
	  {
	    const gphi *phi = gpi.phi ();
	    pp_gimple_stmt_1 (pp, phi, 0, (dump_flags_t)0);
	  }
      }
      break;

    case PK_BEFORE_STMT:
      pp_printf (pp, "before (SN: %i stmt: %i): ", m_supernode->m_index,
		 m_stmt_idx);
      f.spacer (pp);
      pp_gimple_stmt_1 (pp, get_stmt (), 0, (dump_flags_t)0);
      if (f.m_newlines)
	{
	  pp_newline (pp);
	  print_source_line (pp);
	}
      break;

    case PK_AFTER_SUPERNODE:
      pp_printf (pp, "after SN: %i", m_supernode->m_index);
      if (f.m_newlines)
	pp_newline (pp);
      break;
    }
}

/* Generate a hash value for this function_point.  */

hashval_t
function_point::hash () const
{
  inchash::hash hstate;
  if (m_supernode)
    hstate.add_int (m_supernode->m_index);
  hstate.add_ptr (m_from_edge);
  hstate.add_int (m_stmt_idx);
  hstate.add_int (m_kind);
  return hstate.end ();
}

/* Get the function at this point, if any.  */

function *
function_point::get_function () const
{
  if (m_supernode)
    return m_supernode->m_fun;
  else
    return NULL;
}

/* Get the gimple stmt for this function_point, if any.  */

const gimple *
function_point::get_stmt () const
{
  if (m_kind == PK_BEFORE_STMT)
    return m_supernode->m_stmts[m_stmt_idx];
  else if (m_kind == PK_AFTER_SUPERNODE)
    return m_supernode->get_last_stmt ();
  else
    return NULL;
}

/* Get a location for this function_point, if any.  */

location_t
function_point::get_location () const
{
  const gimple *stmt = get_stmt ();
  if (stmt)
    return stmt->location;
  if (m_kind == PK_BEFORE_SUPERNODE)
    return m_supernode->get_start_location ();
  else if (m_kind == PK_AFTER_SUPERNODE)
    return m_supernode->get_end_location ();
  else
    return UNKNOWN_LOCATION;
}

/* Return true if this function_point is a before_stmt for
   the final stmt in its supernode.  */

bool
function_point::final_stmt_p () const
{
  if (m_kind != PK_BEFORE_STMT)
    return false;
  return m_stmt_idx == get_supernode ()->m_stmts.length () - 1;
}

/* Create a function_point representing the entrypoint of function FUN.  */

function_point
function_point::from_function_entry (const supergraph &sg, function *fun)
{
  return before_supernode (sg.get_node_for_function_entry (fun), NULL);
}

/* Create a function_point representing entering supernode SUPERNODE,
   having reached it via FROM_EDGE (which could be NULL).  */

function_point
function_point::before_supernode (const supernode *supernode,
				  const superedge *from_edge)
{
  if (from_edge && from_edge->get_kind () != SUPEREDGE_CFG_EDGE)
    from_edge = NULL;
  return function_point (supernode, from_edge, 0, PK_BEFORE_SUPERNODE);
}

/* A subclass of diagnostic_context for use by
   program_point::print_source_line.  */

class debug_diagnostic_context : public diagnostic_context
{
public:
  debug_diagnostic_context ()
  {
    diagnostic_initialize (this, 0);
    show_line_numbers_p = true;
    show_caret = true;
  }
  ~debug_diagnostic_context ()
  {
    diagnostic_finish (this);
  }
};

/* Print the source line (if any) for this function_point to PP.  */

void
function_point::print_source_line (pretty_printer *pp) const
{
  const gimple *stmt = get_stmt ();
  if (!stmt)
    return;
  // TODO: monospace font
  debug_diagnostic_context tmp_dc;
  gcc_rich_location richloc (stmt->location);
  diagnostic_show_locus (&tmp_dc, &richloc, DK_ERROR);
  pp_string (pp, pp_formatted_text (tmp_dc.printer));
}

/* class program_point.  */

/* Print this program_point to PP.  */

void
program_point::print (pretty_printer *pp, const format &f) const
{
  pp_string (pp, "callstring: ");
  m_call_string->print (pp);
  f.spacer (pp);

  m_function_point.print (pp, f);
}

/* Dump this point to stderr.  */

DEBUG_FUNCTION void
program_point::dump () const
{
  pretty_printer pp;
  pp_show_color (&pp) = pp_show_color (global_dc->printer);
  pp.buffer->stream = stderr;
  print (&pp, format (true));
  pp_flush (&pp);
}

/* Return a new json::object of the form
   {"kind"  : str,
    "snode_idx" : int (optional), the index of the supernode,
    "from_edge_snode_idx" : int (only for kind=='PK_BEFORE_SUPERNODE'),
    "stmt_idx": int (only for kind=='PK_BEFORE_STMT',
    "call_string": object for the call_string}.  */

json::object *
program_point::to_json () const
{
  json::object *point_obj = new json::object ();

  point_obj->set ("kind",
		  new json::string (point_kind_to_string (get_kind ())));

  if (get_supernode ())
    point_obj->set ("snode_idx",
		    new json::integer_number (get_supernode ()->m_index));

  switch (get_kind ())
    {
    default: break;
    case PK_BEFORE_SUPERNODE:
      if (const superedge *sedge = get_from_edge ())
	point_obj->set ("from_edge_snode_idx",
			new json::integer_number (sedge->m_src->m_index));
      break;
    case PK_BEFORE_STMT:
      point_obj->set ("stmt_idx", new json::integer_number (get_stmt_idx ()));
      break;
    }

  point_obj->set ("call_string", m_call_string->to_json ());

  return point_obj;
}

/* Update the callstack to represent a call from caller to callee.

   Generally used to push a custom call to a perticular program point 
   where we don't have a superedge representing the call.  */
void
program_point::push_to_call_stack (const supernode *caller,
				   const supernode *callee)
{
  m_call_string = m_call_string->push_call (callee, caller);
}

/* Pop the topmost call from the current callstack.  */
void
program_point::pop_from_call_stack ()
{
  m_call_string = m_call_string->get_parent ();
  gcc_assert (m_call_string);
}

/* Generate a hash value for this program_point.  */

hashval_t
program_point::hash () const
{
  inchash::hash hstate;
  hstate.merge_hash (m_function_point.hash ());
  hstate.add_ptr (m_call_string);
  return hstate.end ();
}

/* Get the function * at DEPTH within the call stack.  */

function *
program_point::get_function_at_depth (unsigned depth) const
{
  gcc_assert (depth <= m_call_string->length ());
  if (depth == m_call_string->length ())
    return m_function_point.get_function ();
  else
    return get_call_string ()[depth].get_caller_function ();
}

/* Assert that this object is sane.  */

void
program_point::validate () const
{
  /* Skip this in a release build.  */
#if !CHECKING_P
  return;
#endif

  m_call_string->validate ();
  /* The "callee" of the final entry in the callstring should be the
     function of the m_function_point.  */
  if (m_call_string->length () > 0)
    gcc_assert
      ((*m_call_string)[m_call_string->length () - 1].get_callee_function ()
       == get_function ());
}

/* Check to see if SUCC is a valid edge to take (ensuring that we have
   interprocedurally valid paths in the exploded graph, and enforcing
   recursion limits).

   Update the call string if SUCC is a call or a return.

   Return true if SUCC can be taken, or false otherwise.

   This is the "point" half of exploded_node::on_edge.  */

bool
program_point::on_edge (exploded_graph &eg,
			const superedge *succ)
{
  logger * const logger = eg.get_logger ();
  LOG_FUNC (logger);
  switch (succ->m_kind)
    {
    case SUPEREDGE_CFG_EDGE:
      {
	const cfg_superedge *cfg_sedge = as_a <const cfg_superedge *> (succ);

	/* Reject abnormal edges; we special-case setjmp/longjmp.  */
	if (cfg_sedge->get_flags () & EDGE_ABNORMAL)
	  return false;
      }
      break;

    case SUPEREDGE_CALL:
      {
	const call_superedge *call_sedge = as_a <const call_superedge *> (succ);

	if (eg.get_analysis_plan ().use_summary_p (call_sedge->m_cedge))
	  {
	    if (logger)
	      logger->log ("rejecting call edge: using summary instead");
	    return false;
	  }

	/* Add the callsite to the call string.  */
	m_call_string = m_call_string->push_call (eg.get_supergraph (),
						  call_sedge);

	/* Impose a maximum recursion depth and don't analyze paths
	   that exceed it further.
	   This is something of a blunt workaround, but it only
	   applies to recursion (and mutual recursion), not to
	   general call stacks.  */
	if (m_call_string->calc_recursion_depth ()
	    > param_analyzer_max_recursion_depth)
	  {
	    if (logger)
	      logger->log ("rejecting call edge: recursion limit exceeded");
	    // TODO: issue a sorry for this?
	    return false;
	  }
      }
      break;

    case SUPEREDGE_RETURN:
      {
	/* Require that we return to the call site in the call string.  */
	if (m_call_string->empty_p ())
	  {
	    if (logger)
	      logger->log ("rejecting return edge: empty call string");
	    return false;
	  }
	const call_string::element_t &top_of_stack
	  = m_call_string->get_top_of_stack ();
	m_call_string = m_call_string->get_parent ();
	call_string::element_t current_call_string_element (succ->m_dest,
							    succ->m_src);
	if (top_of_stack != current_call_string_element)
	  {
	    if (logger)
	      logger->log ("rejecting return edge: return to wrong callsite");
	    return false;
	  }
      }
      break;

    case SUPEREDGE_INTRAPROCEDURAL_CALL:
      {
	const callgraph_superedge *cg_sedge
	  = as_a <const callgraph_superedge *> (succ);
	/* Consider turning this edge into a use of an
	   interprocedural summary.  */
	if (eg.get_analysis_plan ().use_summary_p (cg_sedge->m_cedge))
	  {
	    if (logger)
	      logger->log ("using function summary for %qE in %qE",
			   cg_sedge->get_callee_decl (),
			   cg_sedge->get_caller_decl ());
	    return true;
	  }
	else
	  {
	    /* Otherwise, we ignore these edges  */
	    if (logger)
	      logger->log ("rejecting interprocedural edge");
	    return false;
	  }
      }
    }

  return true;
}

/* Comparator for program points within the same supernode,
   for implementing worklist::key_t comparison operators.
   Return negative if POINT_A is before POINT_B
   Return positive if POINT_A is after POINT_B
   Return 0 if they are equal.  */

int
function_point::cmp_within_supernode_1 (const function_point &point_a,
					const function_point &point_b)
{
  gcc_assert (point_a.get_supernode () == point_b.get_supernode ());

  switch (point_a.m_kind)
    {
    default:
      gcc_unreachable ();
    case PK_BEFORE_SUPERNODE:
      switch (point_b.m_kind)
	{
	default:
	  gcc_unreachable ();
	case PK_BEFORE_SUPERNODE:
	  {
	    int a_src_idx = -1;
	    int b_src_idx = -1;
	    if (point_a.m_from_edge)
	      a_src_idx = point_a.m_from_edge->m_src->m_index;
	    if (point_b.m_from_edge)
	      b_src_idx = point_b.m_from_edge->m_src->m_index;
	    return a_src_idx - b_src_idx;
	  }
	  break;

	case PK_BEFORE_STMT:
	case PK_AFTER_SUPERNODE:
	  return -1;
	}
      break;
    case PK_BEFORE_STMT:
      switch (point_b.m_kind)
	{
	default:
	  gcc_unreachable ();
	case PK_BEFORE_SUPERNODE:
	  return 1;

	case PK_BEFORE_STMT:
	  return point_a.m_stmt_idx - point_b.m_stmt_idx;

	case PK_AFTER_SUPERNODE:
	  return -1;
	}
      break;
    case PK_AFTER_SUPERNODE:
      switch (point_b.m_kind)
	{
	default:
	  gcc_unreachable ();
	case PK_BEFORE_SUPERNODE:
	case PK_BEFORE_STMT:
	  return 1;

	case PK_AFTER_SUPERNODE:
	  return 0;
	}
      break;
    }
}

/* Comparator for program points within the same supernode,
   for implementing worklist::key_t comparison operators.
   Return negative if POINT_A is before POINT_B
   Return positive if POINT_A is after POINT_B
   Return 0 if they are equal.  */

int
function_point::cmp_within_supernode (const function_point &point_a,
				      const function_point &point_b)
{
  int result = cmp_within_supernode_1 (point_a, point_b);

  /* Check that the ordering is symmetric  */
#if CHECKING_P
  int reversed = cmp_within_supernode_1 (point_b, point_a);
  gcc_assert (reversed == -result);
#endif

  return result;
}

/* Comparator for imposing an order on function_points.  */

int
function_point::cmp (const function_point &point_a,
		     const function_point &point_b)
{
  int idx_a = point_a.m_supernode ? point_a.m_supernode->m_index : -1;
  int idx_b = point_b.m_supernode ? point_b.m_supernode->m_index : -1;
  if (int cmp_idx = idx_a - idx_b)
    return cmp_idx;
  gcc_assert (point_a.m_supernode == point_b.m_supernode);
  if (point_a.m_supernode)
    return cmp_within_supernode (point_a, point_b);
  else
    return 0;
}

/* Comparator for use by vec<function_point>::qsort.  */

int
function_point::cmp_ptr (const void *p1, const void *p2)
{
  const function_point *fp1 = (const function_point *)p1;
  const function_point *fp2 = (const function_point *)p2;
  return cmp (*fp1, *fp2);
}

/* For PK_BEFORE_STMT, go to next stmt (or to PK_AFTER_SUPERNODE).  */

void
function_point::next_stmt ()
{
  gcc_assert (m_kind == PK_BEFORE_STMT);
  if (++m_stmt_idx == m_supernode->m_stmts.length ())
    {
      m_kind = PK_AFTER_SUPERNODE;
      m_stmt_idx = 0;
    }
}

/* For those function points for which there is a uniquely-defined
   successor, return it.  */

function_point
function_point::get_next () const
{
  switch (get_kind ())
    {
    default:
      gcc_unreachable ();
    case PK_ORIGIN:
    case PK_AFTER_SUPERNODE:
      gcc_unreachable (); /* Not uniquely defined.  */
    case PK_BEFORE_SUPERNODE:
      if (get_supernode ()->m_stmts.length () > 0)
	return before_stmt (get_supernode (), 0);
      else
	return after_supernode (get_supernode ());
    case PK_BEFORE_STMT:
      {
	unsigned next_idx = get_stmt_idx () + 1;
	if (next_idx < get_supernode ()->m_stmts.length ())
	  return before_stmt (get_supernode (), next_idx);
	else
	  return after_supernode (get_supernode ());
      }
    }
}

/* class program_point.  */

program_point
program_point::origin (const region_model_manager &mgr)
{
  return program_point (function_point (NULL, NULL,
					0, PK_ORIGIN),
			mgr.get_empty_call_string ());
}

program_point
program_point::from_function_entry (const region_model_manager &mgr,
				    const supergraph &sg,
				    function *fun)
{
  return program_point (function_point::from_function_entry (sg, fun),
			mgr.get_empty_call_string ());
}

/* For those program points for which there is a uniquely-defined
   successor, return it.  */

program_point
program_point::get_next () const
{
  switch (m_function_point.get_kind ())
    {
    default:
      gcc_unreachable ();
    case PK_ORIGIN:
    case PK_AFTER_SUPERNODE:
      gcc_unreachable (); /* Not uniquely defined.  */
    case PK_BEFORE_SUPERNODE:
      if (get_supernode ()->m_stmts.length () > 0)
	return before_stmt (get_supernode (), 0, get_call_string ());
      else
	return after_supernode (get_supernode (), get_call_string ());
    case PK_BEFORE_STMT:
      {
	unsigned next_idx = get_stmt_idx () + 1;
	if (next_idx < get_supernode ()->m_stmts.length ())
	  return before_stmt (get_supernode (), next_idx, get_call_string ());
	else
	  return after_supernode (get_supernode (), get_call_string ());
      }
    }
}

/* Return true iff POINT_A and POINT_B share the same function and
   call_string, both directly, and when attempting to undo inlining
   information.  */

bool
program_point::effectively_intraprocedural_p (const program_point &point_a,
					      const program_point &point_b)
{
  /* First, compare without considering inlining info.  */
  if (point_a.get_function ()
      != point_b.get_function ())
    return false;
  if (&point_a.get_call_string ()
      != &point_b.get_call_string ())
    return false;

  /* Consider inlining info; they must have originally come from
     the same function and have been inlined in the same way.  */
  location_t loc_a = point_a.get_location ();
  location_t loc_b = point_b.get_location ();
  inlining_iterator iter_a (loc_a);
  inlining_iterator iter_b (loc_b);
  while (!(iter_a.done_p () || iter_b.done_p ()))
    {
      if (iter_a.done_p () || iter_b.done_p ())
	return false;

      if (iter_a.get_fndecl () != iter_b.get_fndecl ())
	return false;
      if (iter_a.get_callsite () != iter_b.get_callsite ())
	return false;
      if (iter_a.get_block () != iter_b.get_block ())
	return false;

      iter_a.next ();
      iter_b.next ();
    }

  return true;
}

#if CHECKING_P

namespace selftest {

/* Verify that function_point::operator== works as expected.  */

static void
test_function_point_equality ()
{
  const supernode *snode = NULL;

  function_point a = function_point (snode, NULL, 0,
				     PK_BEFORE_SUPERNODE);
  function_point b = function_point::before_supernode (snode, NULL);
  ASSERT_EQ (a, b);
}

/* Verify that function_point::cmp_within_supernode works as expected.  */

static void
test_function_point_ordering ()
{
  const supernode *snode = NULL;

  /* Populate an array with various points within the same
     snode, in order.  */
  auto_vec<function_point> points;
  points.safe_push (function_point::before_supernode (snode, NULL));
  points.safe_push (function_point::before_stmt (snode, 0));
  points.safe_push (function_point::before_stmt (snode, 1));
  points.safe_push (function_point::after_supernode (snode));

  /* Check all pairs.  */
  unsigned i;
  function_point *point_a;
  FOR_EACH_VEC_ELT (points, i, point_a)
    {
      unsigned j;
      function_point *point_b;
      FOR_EACH_VEC_ELT (points, j, point_b)
	{
	  int cmp = function_point::cmp_within_supernode (*point_a, *point_b);
	  if (i == j)
	    ASSERT_EQ (cmp, 0);
	  if (i < j)
	    ASSERT_TRUE (cmp < 0);
	  if (i > j)
	    ASSERT_TRUE (cmp > 0);
	}
    }
}

/* Verify that program_point::operator== works as expected.  */

static void
test_program_point_equality ()
{
  region_model_manager mgr;

  const supernode *snode = NULL;

  const call_string &cs = mgr.get_empty_call_string ();

  program_point a = program_point::before_supernode (snode, NULL,
						     cs);

  program_point b = program_point::before_supernode (snode, NULL,
						     cs);

  ASSERT_EQ (a, b);
  // TODO: verify with non-empty callstrings, with different edges
}

/* Run all of the selftests within this file.  */

void
analyzer_program_point_cc_tests ()
{
  test_function_point_equality ();
  test_function_point_ordering ();
  test_program_point_equality ();
}

} // namespace selftest

#endif /* CHECKING_P */

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
