/* -Wnonnull-compare warning support.
   Copyright (C) 2016-2019 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);
}
