/* -Wnonnull-compare warning support.
   Copyright (C) 2016 Free Software Foundation, Inc.
   Contributed by Jakub Jelinek <jakub@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 "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "diagnostic-core.h"
#include "tree-dfa.h"

/* Warn about comparison of nonnull_arg_p argument initial values
   with NULL.  */

static void
do_warn_nonnull_compare (function *fun, tree arg)
{
  if (!POINTER_TYPE_P (TREE_TYPE (arg))
      && TREE_CODE (TREE_TYPE (arg)) != OFFSET_TYPE)
    return;

  if (!nonnull_arg_p (arg))
    return;

  tree d = ssa_default_def (fun, arg);
  if (d == NULL_TREE)
    return;

  use_operand_p use_p;
  imm_use_iterator iter;

  FOR_EACH_IMM_USE_FAST (use_p, iter, d)
    {
      gimple *stmt = USE_STMT (use_p);
      tree op = NULL_TREE;
      location_t loc = gimple_location (stmt);
      if (gimple_code (stmt) == GIMPLE_COND)
	switch (gimple_cond_code (stmt))
	  {
	  case EQ_EXPR:
	  case NE_EXPR:
	    if (gimple_cond_lhs (stmt) == d)
	      op = gimple_cond_rhs (stmt);
	    break;
	  default:
	    break;
	  }
      else if (is_gimple_assign (stmt))
	switch (gimple_assign_rhs_code (stmt))
	  {
	  case EQ_EXPR:
	  case NE_EXPR:
	    if (gimple_assign_rhs1 (stmt) == d)
	      op = gimple_assign_rhs2 (stmt);
	    break;
	  case COND_EXPR:
	    switch (TREE_CODE (gimple_assign_rhs1 (stmt)))
	      {
	      case EQ_EXPR:
	      case NE_EXPR:
		op = gimple_assign_rhs1 (stmt);
		if (TREE_OPERAND (op, 0) != d)
		  {
		    op = NULL_TREE;
		    break;
		  }
		loc = EXPR_LOC_OR_LOC (op, loc);
		op = TREE_OPERAND (op, 1);
		break;
	      default:
		break;
	      }
	    break;
	  default:
	    break;
	  }
      if (op
	  && (POINTER_TYPE_P (TREE_TYPE (arg))
	      ? integer_zerop (op) : integer_minus_onep (op))
	  && !gimple_no_warning_p (stmt))
	warning_at (loc, OPT_Wnonnull_compare,
		    "nonnull argument %qD compared to NULL", arg);
    }
}

namespace {

const pass_data pass_data_warn_nonnull_compare =
{
  GIMPLE_PASS, /* type */
  "*nonnullcmp", /* 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_nonnull_compare : public gimple_opt_pass
{
public:
  pass_warn_nonnull_compare (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_warn_nonnull_compare, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *) { return warn_nonnull_compare; }

  virtual unsigned int execute (function *);

}; // class pass_warn_nonnull_compare

unsigned int
pass_warn_nonnull_compare::execute (function *fun)
{
  if (fun->static_chain_decl)
    do_warn_nonnull_compare (fun, fun->static_chain_decl);

  for (tree arg = DECL_ARGUMENTS (cfun->decl); arg; arg = DECL_CHAIN (arg))
    do_warn_nonnull_compare (fun, arg);
  return 0;
}

} // anon namespace

gimple_opt_pass *
make_pass_warn_nonnull_compare (gcc::context *ctxt)
{
  return new pass_warn_nonnull_compare (ctxt);
}
