/* A state machine for use in DejaGnu tests, to check that
   pattern-matching works as expected.

   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/>.  */

#include "analyzer/common.h"

#include "tree-pretty-print.h"
#include "diagnostics/event-id.h"

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

#if ENABLE_ANALYZER

namespace ana {

namespace {

/* A state machine for use in DejaGnu tests, to check that
   pattern-matching works as expected.  */

class pattern_test_state_machine : public state_machine
{
public:
  pattern_test_state_machine (logger *logger);

  bool inherited_state_p () const final override { return false; }

  bool on_stmt (sm_context &sm_ctxt,
		const supernode *node,
		const gimple *stmt) const final override;

  void on_condition (sm_context &sm_ctxt,
		     const supernode *node,
		     const gimple *stmt,
		     const svalue *lhs,
		     enum tree_code op,
		     const svalue *rhs) const final override;

  bool can_purge_p (state_t s) const final override;
};

class pattern_match : public pending_diagnostic_subclass<pattern_match>
{
public:
  pattern_match (tree lhs, enum tree_code op, tree rhs)
  : m_lhs (lhs), m_op (op), m_rhs (rhs) {}

  const char *get_kind () const final override { return "pattern_match"; }

  bool operator== (const pattern_match &other) const
  {
    return (same_tree_p (m_lhs, other.m_lhs)
	    && m_op == other.m_op
	    && same_tree_p (m_rhs, other.m_rhs));
  }

  int get_controlling_option () const final override
  {
    return 0;
  }

  bool emit (diagnostic_emission_context &ctxt) final override
  {
    return ctxt.warn ("pattern match on %<%E %s %E%>",
		      m_lhs, op_symbol_code (m_op), m_rhs);
  }

private:
  tree m_lhs;
  enum tree_code m_op;
  tree m_rhs;
};

pattern_test_state_machine::pattern_test_state_machine (logger *logger)
: state_machine ("pattern-test", logger)
{
}

bool
pattern_test_state_machine::on_stmt (sm_context &sm_ctxt ATTRIBUTE_UNUSED,
				     const supernode *node ATTRIBUTE_UNUSED,
				     const gimple *stmt ATTRIBUTE_UNUSED) const
{
  return false;
}

/* Implementation of state_machine::on_condition vfunc for
   pattern_test_state_machine.

   Queue a pattern_match diagnostic for any comparison against a
   constant.  */

void
pattern_test_state_machine::on_condition (sm_context &sm_ctxt,
					  const supernode *node,
					  const gimple *stmt,
					  const svalue *lhs,
					  enum tree_code op,
					  const svalue *rhs) const
{
  if (stmt == nullptr)
    return;

  tree rhs_cst = rhs->maybe_get_constant ();
  if (!rhs_cst)
    return;

  if (tree lhs_expr = sm_ctxt.get_diagnostic_tree (lhs))
    {
      sm_ctxt.warn (node, stmt, lhs_expr,
		    std::make_unique<pattern_match> (lhs_expr, op, rhs_cst));
    }
}

bool
pattern_test_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
{
  return true;
}

} // anonymous namespace

/* Internal interface to this file. */

std::unique_ptr<state_machine>
make_pattern_test_state_machine (logger *logger)
{
  return std::make_unique<pattern_test_state_machine> (logger);
}

} // namespace ana

#endif /* #if ENABLE_ANALYZER */
