/* This plugin contains an analysis pass that detects and warns about
   self-assignment statements.  */
/* { dg-options "-O" } */

#include "gcc-plugin.h"
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "stringpool.h"
#include "toplev.h"
#include "basic-block.h"
#include "hash-table.h"
#include "vec.h"
#include "ggc.h"
#include "basic-block.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimple-expr.h"
#include "is-a.h"
#include "gimple.h"
#include "gimple-iterator.h"
#include "tree.h"
#include "tree-pass.h"
#include "intl.h"
#include "plugin-version.h"
#include "diagnostic.h"
#include "context.h"

int plugin_is_GPL_compatible;

/* Indicate whether to check overloaded operator '=', which is performed by
   default. To disable it, use -fplugin-arg-NAME-no-check-operator-eq.  */
bool check_operator_eq = true;

/* Given a rhs EXPR of a gimple assign statement, if it is
   - SSA_NAME : returns its var decl, or, if it is a temp variable,
                returns the rhs of its SSA def statement.
   - VAR_DECL, PARM_DECL, FIELD_DECL, or a reference expression :
                returns EXPR itself.
   - any other expression : returns NULL_TREE.  */

static tree
get_real_ref_rhs (tree expr)
{
  switch (TREE_CODE (expr))
    {
      case SSA_NAME:
        {
          /* Given a self-assign statement, say foo.x = foo.x,
             the IR (after SSA) looks like:

             D.1797_14 = foo.x;
             foo.x ={v} D.1797_14;

             So if the rhs EXPR is an SSA_NAME of a temp variable,
             e.g. D.1797_14, we need to grab the rhs of its SSA def
             statement (i.e. foo.x).  */
          tree vdecl = SSA_NAME_VAR (expr);
          if ((!vdecl || DECL_ARTIFICIAL (vdecl))
              && !gimple_nop_p (SSA_NAME_DEF_STMT (expr)))
            {
	      gimple *def_stmt = SSA_NAME_DEF_STMT (expr);
              /* We are only interested in an assignment with a single
                 rhs operand because if it is not, the original assignment
                 will not possibly be a self-assignment.  */
              if (gimple_assign_single_p (def_stmt))
                return get_real_ref_rhs (gimple_assign_rhs1 (def_stmt));
              else
                return NULL_TREE;
            }
          else
            return vdecl;
        }
      case VAR_DECL:
      case PARM_DECL:
      case FIELD_DECL:
      case COMPONENT_REF:
      case MEM_REF:
      case ARRAY_REF:
        return expr;
      default:
        return NULL_TREE;
    }
}

/* Given an expression tree, EXPR, that may contains SSA names, returns an
   equivalent tree with the SSA names converted to var/parm/field decls
   so that it can be used with '%E' format modifier when emitting warning
   messages.

   This function currently only supports VAR/PARM/FIELD_DECL, reference
   expressions (COMPONENT_REF, INDIRECT_REF, ARRAY_REF), integer constant,
   and SSA_NAME. If EXPR contains any other tree nodes (e.g. an arithmetic
   expression appears in array index), NULL_TREE is returned.  */

static tree
get_non_ssa_expr (tree expr)
{
  if (!expr)
    return NULL_TREE;
  switch (TREE_CODE (expr))
    {
      case VAR_DECL:
      case PARM_DECL:
      case FIELD_DECL:
        {
          if (DECL_NAME (expr))
            return expr;
          else
            return NULL_TREE;
        }
      case COMPONENT_REF:
        {
          tree base, orig_base = TREE_OPERAND (expr, 0);
          tree component, orig_component = TREE_OPERAND (expr, 1);
          base = get_non_ssa_expr (orig_base);
          if (!base)
            return NULL_TREE;
          component = get_non_ssa_expr (orig_component);
          if (!component)
            return NULL_TREE;
          /* If either BASE or COMPONENT is converted, build a new
             component reference tree.  */
          if (base != orig_base || component != orig_component)
            return build3 (COMPONENT_REF, TREE_TYPE (component),
                           base, component, NULL_TREE);
          else
            return expr;
        }
      case MEM_REF:
        {
          tree orig_base = TREE_OPERAND (expr, 0);
	  if (TREE_CODE (orig_base) == SSA_NAME)
	    {
	      tree base = get_non_ssa_expr (orig_base);
	      if (!base)
		return NULL_TREE;
	      return fold_build2 (MEM_REF, TREE_TYPE (expr),
				  base, TREE_OPERAND (expr, 1));
	    }
	  return expr;
        }
      case ARRAY_REF:
        {
          tree array, orig_array = TREE_OPERAND (expr, 0);
          tree index, orig_index = TREE_OPERAND (expr, 1);
          array = get_non_ssa_expr (orig_array);
          if (!array)
            return NULL_TREE;
          index = get_non_ssa_expr (orig_index);
          if (!index)
            return NULL_TREE;
          /* If either ARRAY or INDEX is converted, build a new array
             reference tree.  */
          if (array != orig_array || index != orig_index)
            return build4 (ARRAY_REF, TREE_TYPE (expr), array, index,
                           TREE_OPERAND (expr, 2), TREE_OPERAND (expr, 3));
          else
            return expr;
        }
      case SSA_NAME:
        {
          tree vdecl = SSA_NAME_VAR (expr);
          if ((!vdecl || DECL_ARTIFICIAL (vdecl))
              && !gimple_nop_p (SSA_NAME_DEF_STMT (expr)))
            {
	      gimple *def_stmt = SSA_NAME_DEF_STMT (expr);
              if (gimple_assign_single_p (def_stmt))
                vdecl = gimple_assign_rhs1 (def_stmt);
            }
          return get_non_ssa_expr (vdecl);
        }
      case INTEGER_CST:
        return expr;
      default:
        /* Return NULL_TREE for any other kind of tree nodes.  */
        return NULL_TREE;
    }
}

/* Given the LHS and (real) RHS of a gimple assign statement, STMT, check if
   they are the same. If so, print a warning message about self-assignment.  */

static void
compare_and_warn (gimple *stmt, tree lhs, tree rhs)
{
  if (operand_equal_p (lhs, rhs, OEP_PURE_SAME))
    {
      location_t location;
      location = (gimple_has_location (stmt)
                  ? gimple_location (stmt)
                  : (DECL_P (lhs)
                     ? DECL_SOURCE_LOCATION (lhs)
                     : input_location));
      /* If LHS contains any tree node not currently supported by
         get_non_ssa_expr, simply emit a generic warning without
         specifying LHS in the message.  */
      lhs = get_non_ssa_expr (lhs);
      if (lhs)
        warning_at (location, 0, G_("%qE is assigned to itself"), lhs);
      else
        warning_at (location, 0, G_("self-assignment detected"));
    }
}

/* Check and warn if STMT is a self-assign statement.  */

static void
warn_self_assign (gimple *stmt)
{
  tree rhs, lhs;

  /* Check assigment statement.  */
  if (gimple_assign_single_p (stmt))
    {
      rhs = get_real_ref_rhs (gimple_assign_rhs1 (stmt));
      if (!rhs)
        return;

      lhs = gimple_assign_lhs (stmt);
      if (TREE_CODE (lhs) == SSA_NAME)
        {
          lhs = SSA_NAME_VAR (lhs);
          if (!lhs || DECL_ARTIFICIAL (lhs))
            return;
        }

      compare_and_warn (stmt, lhs, rhs);
    }
  /* Check overloaded operator '=' (if enabled).  */
  else if (check_operator_eq && is_gimple_call (stmt))
    {
      tree fdecl = gimple_call_fndecl (stmt);
      if (fdecl && (DECL_NAME (fdecl) == maybe_get_identifier ("operator=")))
        {
          /* If 'operator=' takes reference operands, the arguments will be 
             ADDR_EXPR trees. In this case, just remove the address-taken
             operator before we compare the lhs and rhs.  */
          lhs = gimple_call_arg (stmt, 0);
          if (TREE_CODE (lhs) == ADDR_EXPR)
            lhs = TREE_OPERAND (lhs, 0);
          rhs = gimple_call_arg (stmt, 1);
          if (TREE_CODE (rhs) == ADDR_EXPR)
            rhs = TREE_OPERAND (rhs, 0);

          compare_and_warn (stmt, lhs, rhs);
        }
    }
}

namespace {

const pass_data pass_data_warn_self_assign =
{
  GIMPLE_PASS, /* type */
  "warn_self_assign", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  PROP_ssa, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_warn_self_assign : public gimple_opt_pass
{
public:
  pass_warn_self_assign(gcc::context *ctxt)
    : gimple_opt_pass(pass_data_warn_self_assign, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *) { return true; }
  virtual unsigned int execute (function *);

}; // class pass_warn_self_assign

unsigned int
pass_warn_self_assign::execute (function *fun)
{
  gimple_stmt_iterator gsi;
  basic_block bb;

  FOR_EACH_BB_FN (bb, fun)
    {
      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        warn_self_assign (gsi_stmt (gsi));
    }

  return 0;
}

} // anon namespace

static gimple_opt_pass *
make_pass_warn_self_assign (gcc::context *ctxt)
{
  return new pass_warn_self_assign (ctxt);
}

/* The initialization routine exposed to and called by GCC. The spec of this
   function is defined in gcc/gcc-plugin.h.

   PLUGIN_NAME - name of the plugin (useful for error reporting)
   ARGC        - the size of the ARGV array
   ARGV        - an array of key-value argument pair

   Returns 0 if initialization finishes successfully.

   Note that this function needs to be named exactly "plugin_init".  */

int
plugin_init (struct plugin_name_args *plugin_info,
             struct plugin_gcc_version *version)
{
  struct register_pass_info pass_info;
  const char *plugin_name = plugin_info->base_name;
  int argc = plugin_info->argc;
  struct plugin_argument *argv = plugin_info->argv;
  bool enabled = true;
  int i;

  if (!plugin_default_version_check (version, &gcc_version))
    return 1;

  /* Self-assign detection should happen after SSA is constructed.  */
  pass_info.pass = make_pass_warn_self_assign (g);
  pass_info.reference_pass_name = "ssa";
  pass_info.ref_pass_instance_number = 1;
  pass_info.pos_op = PASS_POS_INSERT_AFTER;

  /* Process the plugin arguments. This plugin takes the following arguments:
     check-operator-eq, no-check-operator-eq, enable, and disable.
     By default, the analysis is enabled with 'operator=' checked.  */
  for (i = 0; i < argc; ++i)
    {
      if (!strcmp (argv[i].key, "check-operator-eq"))
        {
          if (argv[i].value)
            warning (0, G_("option '-fplugin-arg-%s-check-operator-eq=%s'"
                           " ignored (superfluous '=%s')"),
                     plugin_name, argv[i].value, argv[i].value);
          else
            check_operator_eq = true;
        }
      else if (!strcmp (argv[i].key, "no-check-operator-eq"))
        {
          if (argv[i].value)
            warning (0, G_("option '-fplugin-arg-%s-no-check-operator-eq=%s'"
                           " ignored (superfluous '=%s')"),
                     plugin_name, argv[i].value, argv[i].value);
          else
            check_operator_eq = false;
        }
      else if (!strcmp (argv[i].key, "enable"))
        {
          if (argv[i].value)
            warning (0, G_("option '-fplugin-arg-%s-enable=%s' ignored"
                           " (superfluous '=%s')"),
                     plugin_name, argv[i].value, argv[i].value);
          else
            enabled = true;
        }
      else if (!strcmp (argv[i].key, "disable"))
        {
          if (argv[i].value)
            warning (0, G_("option '-fplugin-arg-%s-disable=%s' ignored"
                           " (superfluous '=%s')"),
                     plugin_name, argv[i].value, argv[i].value);
          else
            enabled = false;
        }
      else
        warning (0, G_("plugin %qs: unrecognized argument %qs ignored"),
                 plugin_name, argv[i].key);
    }

  /* Register this new pass with GCC if the analysis is enabled.  */
  if (enabled)
    register_callback (plugin_name, PLUGIN_PASS_MANAGER_SETUP, NULL,
                       &pass_info);

  return 0;
}
