/* Pass to detect and issue warnings for invalid accesses, including
   invalid or mismatched allocation/deallocation calls.

   Copyright (C) 2020-2022 Free Software Foundation, Inc.
   Contributed by Martin Sebor <msebor@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/>.  */

#define INCLUDE_STRING
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "builtins.h"
#include "diagnostic.h"
#include "ssa.h"
#include "gimple-pretty-print.h"
#include "gimple-ssa-warn-access.h"
#include "gimple-ssa-warn-restrict.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "gimple-fold.h"
#include "gimple-iterator.h"
#include "langhooks.h"
#include "memmodel.h"
#include "target.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-cfg.h"
#include "tree-object-size.h"
#include "tree-ssa-strlen.h"
#include "calls.h"
#include "cfgloop.h"
#include "intl.h"
#include "gimple-range.h"
#include "stringpool.h"
#include "attribs.h"
#include "demangle.h"
#include "attr-fnspec.h"
#include "pointer-query.h"

/* Return true if tree node X has an associated location.  */

static inline location_t
has_location (const_tree x)
{
  if (DECL_P (x))
    return DECL_SOURCE_LOCATION (x) != UNKNOWN_LOCATION;

  if (EXPR_P (x))
    return EXPR_HAS_LOCATION (x);

  return false;
}

/* Return the associated location of STMT.  */

static inline location_t
get_location (const gimple *stmt)
{
  return gimple_location (stmt);
}

/* Return the associated location of tree node X.  */

static inline location_t
get_location (tree x)
{
  if (DECL_P (x))
    return DECL_SOURCE_LOCATION (x);

  if (EXPR_P (x))
    return EXPR_LOCATION (x);

  return UNKNOWN_LOCATION;
}

/* Overload of the nascent tree function for GIMPLE STMT.  */

static inline tree
get_callee_fndecl (const gimple *stmt)
{
  return gimple_call_fndecl (stmt);
}

static inline unsigned
call_nargs (const gimple *stmt)
{
  return gimple_call_num_args (stmt);
}

static inline unsigned
call_nargs (const_tree expr)
{
  return call_expr_nargs (expr);
}


static inline tree
call_arg (const gimple *stmt, unsigned argno)
{
  return gimple_call_arg (stmt, argno);
}

static inline tree
call_arg (tree expr, unsigned argno)
{
  return CALL_EXPR_ARG (expr, argno);
}

/* For a call EXPR at LOC to a function FNAME that expects a string
   in the argument ARG, issue a diagnostic due to it being a called
   with an argument that is a character array with no terminating
   NUL.  SIZE is the EXACT size of the array, and BNDRNG the number
   of characters in which the NUL is expected.  Either EXPR or FNAME
   may be null but noth both.  SIZE may be null when BNDRNG is null.  */

template <class GimpleOrTree>
static void
warn_string_no_nul (location_t loc, GimpleOrTree expr, const char *fname,
		    tree arg, tree decl, tree size, bool exact,
		    const wide_int bndrng[2] /* = NULL */)
{
  const opt_code opt = OPT_Wstringop_overread;
  if ((expr && warning_suppressed_p (expr, opt))
      || warning_suppressed_p (arg, opt))
    return;

  loc = expansion_point_location_if_in_system_header (loc);
  bool warned;

  /* Format the bound range as a string to keep the nuber of messages
     from exploding.  */
  char bndstr[80];
  *bndstr = 0;
  if (bndrng)
    {
      if (bndrng[0] == bndrng[1])
	sprintf (bndstr, "%llu", (unsigned long long) bndrng[0].to_uhwi ());
      else
	sprintf (bndstr, "[%llu, %llu]",
		 (unsigned long long) bndrng[0].to_uhwi (),
		 (unsigned long long) bndrng[1].to_uhwi ());
    }

  const tree maxobjsize = max_object_size ();
  const wide_int maxsiz = wi::to_wide (maxobjsize);
  if (expr)
    {
      tree func = get_callee_fndecl (expr);
      if (bndrng)
	{
	  if (wi::ltu_p (maxsiz, bndrng[0]))
	    warned = warning_at (loc, opt,
				 "%qD specified bound %s exceeds "
				 "maximum object size %E",
				 func, bndstr, maxobjsize);
	  else
	    {
	      bool maybe = wi::to_wide (size) == bndrng[0];
	      warned = warning_at (loc, opt,
				   exact
				   ? G_("%qD specified bound %s exceeds "
					"the size %E of unterminated array")
				   : (maybe
				      ? G_("%qD specified bound %s may "
					   "exceed the size of at most %E "
					   "of unterminated array")
				      : G_("%qD specified bound %s exceeds "
					   "the size of at most %E "
					   "of unterminated array")),
				   func, bndstr, size);
	    }
	}
      else
	warned = warning_at (loc, opt,
			     "%qD argument missing terminating nul",
			     func);
    }
  else
    {
      if (bndrng)
	{
	  if (wi::ltu_p (maxsiz, bndrng[0]))
	    warned = warning_at (loc, opt,
				 "%qs specified bound %s exceeds "
				 "maximum object size %E",
				 fname, bndstr, maxobjsize);
	  else
	    {
	      bool maybe = wi::to_wide (size) == bndrng[0];
	      warned = warning_at (loc, opt,
				   exact
				   ? G_("%qs specified bound %s exceeds "
					"the size %E of unterminated array")
				   : (maybe
				      ? G_("%qs specified bound %s may "
					   "exceed the size of at most %E "
					   "of unterminated array")
				      : G_("%qs specified bound %s exceeds "
					   "the size of at most %E "
					   "of unterminated array")),
				   fname, bndstr, size);
	    }
	}
      else
	warned = warning_at (loc, opt,
			     "%qs argument missing terminating nul",
			     fname);
    }

  if (warned)
    {
      inform (get_location (decl),
	      "referenced argument declared here");
      suppress_warning (arg, opt);
      if (expr)
	suppress_warning (expr, opt);
    }
}

void
warn_string_no_nul (location_t loc, gimple *stmt, const char *fname,
		    tree arg, tree decl, tree size /* = NULL_TREE */,
		    bool exact /* = false */,
		    const wide_int bndrng[2] /* = NULL */)
{
  return warn_string_no_nul<gimple *> (loc, stmt, fname,
				       arg, decl, size, exact, bndrng);
}

void
warn_string_no_nul (location_t loc, tree expr, const char *fname,
		    tree arg, tree decl, tree size /* = NULL_TREE */,
		    bool exact /* = false */,
		    const wide_int bndrng[2] /* = NULL */)
{
  return warn_string_no_nul<tree> (loc, expr, fname,
				   arg, decl, size, exact, bndrng);
}

/* If EXP refers to an unterminated constant character array return
   the declaration of the object of which the array is a member or
   element and if SIZE is not null, set *SIZE to the size of
   the unterminated array and set *EXACT if the size is exact or
   clear it otherwise.  Otherwise return null.  */

tree
unterminated_array (tree exp, tree *size /* = NULL */, bool *exact /* = NULL */)
{
  /* C_STRLEN will return NULL and set DECL in the info
     structure if EXP references a unterminated array.  */
  c_strlen_data lendata = { };
  tree len = c_strlen (exp, 1, &lendata);
  if (len || !lendata.minlen || !lendata.decl)
    return NULL_TREE;

  if (!size)
    return lendata.decl;

  len = lendata.minlen;
  if (lendata.off)
    {
      /* Constant offsets are already accounted for in LENDATA.MINLEN,
	 but not in a SSA_NAME + CST expression.  */
      if (TREE_CODE (lendata.off) == INTEGER_CST)
	*exact = true;
      else if (TREE_CODE (lendata.off) == PLUS_EXPR
	       && TREE_CODE (TREE_OPERAND (lendata.off, 1)) == INTEGER_CST)
	{
	  /* Subtract the offset from the size of the array.  */
	  *exact = false;
	  tree temp = TREE_OPERAND (lendata.off, 1);
	  temp = fold_convert (ssizetype, temp);
	  len = fold_build2 (MINUS_EXPR, ssizetype, len, temp);
	}
      else
	*exact = false;
    }
  else
    *exact = true;

  *size = len;
  return lendata.decl;
}

/* For a call EXPR (which may be null) that expects a string argument
   SRC as an argument, returns false if SRC is a character array with
   no terminating NUL.  When nonnull, BOUND is the number of characters
   in which to expect the terminating NUL.  When EXPR is nonnull also
   issues a warning.  */

template <class GimpleOrTree>
static bool
check_nul_terminated_array (GimpleOrTree expr, tree src, tree bound)
{
  /* The constant size of the array SRC points to.  The actual size
     may be less of EXACT is true, but not more.  */
  tree size;
  /* True if SRC involves a non-constant offset into the array.  */
  bool exact;
  /* The unterminated constant array SRC points to.  */
  tree nonstr = unterminated_array (src, &size, &exact);
  if (!nonstr)
    return true;

  /* NONSTR refers to the non-nul terminated constant array and SIZE
     is the constant size of the array in bytes.  EXACT is true when
     SIZE is exact.  */

  wide_int bndrng[2];
  if (bound)
    {
      value_range r;

      get_global_range_query ()->range_of_expr (r, bound);

      if (r.kind () != VR_RANGE)
	return true;

      bndrng[0] = r.lower_bound ();
      bndrng[1] = r.upper_bound ();

      if (exact)
	{
	  if (wi::leu_p (bndrng[0], wi::to_wide (size)))
	    return true;
	}
      else if (wi::lt_p (bndrng[0], wi::to_wide (size), UNSIGNED))
	return true;
    }

  if (expr)
    warn_string_no_nul (get_location (expr), expr, NULL, src, nonstr,
			size, exact, bound ? bndrng : NULL);

  return false;
}

bool
check_nul_terminated_array (gimple *stmt, tree src, tree bound /* = NULL_TREE */)
{
  return check_nul_terminated_array<gimple *>(stmt, src, bound);
}

bool
check_nul_terminated_array (tree expr, tree src, tree bound /* = NULL_TREE */)
{
  return check_nul_terminated_array<tree>(expr, src, bound);
}

/* Warn about passing a non-string array/pointer to a built-in function
   that expects a nul-terminated string argument.  Returns true if
   a warning has been issued.*/

template <class GimpleOrTree>
static bool
maybe_warn_nonstring_arg (tree fndecl, GimpleOrTree exp)
{
  if (!fndecl || !fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    return false;

  if (!warn_stringop_overread
      || warning_suppressed_p (exp, OPT_Wstringop_overread))
    return false;

  /* Avoid clearly invalid calls (more checking done below).  */
  unsigned nargs = call_nargs (exp);
  if (!nargs)
    return false;

  /* The bound argument to a bounded string function like strncpy.  */
  tree bound = NULL_TREE;

  /* The longest known or possible string argument to one of the comparison
     functions.  If the length is less than the bound it is used instead.
     Since the length is only used for warning and not for code generation
     disable strict mode in the calls to get_range_strlen below.  */
  tree maxlen = NULL_TREE;

  /* It's safe to call "bounded" string functions with a non-string
     argument since the functions provide an explicit bound for this
     purpose.  The exception is strncat where the bound may refer to
     either the destination or the source.  */
  int fncode = DECL_FUNCTION_CODE (fndecl);
  switch (fncode)
    {
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRNCMP:
    case BUILT_IN_STRNCASECMP:
      {
	/* For these, if one argument refers to one or more of a set
	   of string constants or arrays of known size, determine
	   the range of their known or possible lengths and use it
	   conservatively as the bound for the unbounded function,
	   and to adjust the range of the bound of the bounded ones.  */
	for (unsigned argno = 0;
	     argno < MIN (nargs, 2)
	       && !(maxlen && TREE_CODE (maxlen) == INTEGER_CST); argno++)
	  {
	    tree arg = call_arg (exp, argno);
	    if (!get_attr_nonstring_decl (arg))
	      {
		c_strlen_data lendata = { };
		/* Set MAXBOUND to an arbitrary non-null non-integer
		   node as a request to have it set to the length of
		   the longest string in a PHI.  */
		lendata.maxbound = arg;
		get_range_strlen (arg, &lendata, /* eltsize = */ 1);
		maxlen = lendata.maxbound;
	      }
	  }
      }
      /* Fall through.  */

    case BUILT_IN_STRNCAT:
    case BUILT_IN_STPNCPY:
    case BUILT_IN_STRNCPY:
      if (nargs > 2)
	bound = call_arg (exp, 2);
      break;

    case BUILT_IN_STRNDUP:
      if (nargs < 2)
	return false;
      bound = call_arg (exp, 1);
      break;

    case BUILT_IN_STRNLEN:
      {
	tree arg = call_arg (exp, 0);
	if (!get_attr_nonstring_decl (arg))
	  {
	    c_strlen_data lendata = { };
	    /* Set MAXBOUND to an arbitrary non-null non-integer
	       node as a request to have it set to the length of
	       the longest string in a PHI.  */
	    lendata.maxbound = arg;
	    get_range_strlen (arg, &lendata, /* eltsize = */ 1);
	    maxlen = lendata.maxbound;
	  }
	if (nargs > 1)
	  bound = call_arg (exp, 1);
	break;
      }

    default:
      break;
    }

  /* Determine the range of the bound argument (if specified).  */
  tree bndrng[2] = { NULL_TREE, NULL_TREE };
  if (bound)
    {
      STRIP_NOPS (bound);
      get_size_range (bound, bndrng);
    }

  location_t loc = get_location (exp);

  if (bndrng[0])
    {
      /* Diagnose excessive bound prior to the adjustment below and
	 regardless of attribute nonstring.  */
      tree maxobjsize = max_object_size ();
      if (tree_int_cst_lt (maxobjsize, bndrng[0]))
	{
	  bool warned = false;
	  if (tree_int_cst_equal (bndrng[0], bndrng[1]))
	    warned = warning_at (loc, OPT_Wstringop_overread,
				 "%qD specified bound %E "
				 "exceeds maximum object size %E",
				 fndecl, bndrng[0], maxobjsize);
	  else
	    warned = warning_at (loc, OPT_Wstringop_overread,
				 "%qD specified bound [%E, %E] "
				 "exceeds maximum object size %E",
				 fndecl, bndrng[0], bndrng[1],
				 maxobjsize);
	  if (warned)
	    suppress_warning (exp, OPT_Wstringop_overread);

	  return warned;
	}
    }

  if (maxlen && !integer_all_onesp (maxlen))
    {
      /* Add one for the nul.  */
      maxlen = const_binop (PLUS_EXPR, TREE_TYPE (maxlen), maxlen,
			    size_one_node);

      if (!bndrng[0])
	{
	  /* Conservatively use the upper bound of the lengths for
	     both the lower and the upper bound of the operation.  */
	  bndrng[0] = maxlen;
	  bndrng[1] = maxlen;
	  bound = void_type_node;
	}
      else if (maxlen)
	{
	  /* Replace the bound on the operation with the upper bound
	     of the length of the string if the latter is smaller.  */
	  if (tree_int_cst_lt (maxlen, bndrng[0]))
	    bndrng[0] = maxlen;
	  else if (tree_int_cst_lt (maxlen, bndrng[1]))
	    bndrng[1] = maxlen;
	}
    }

  bool any_arg_warned = false;
  /* Iterate over the built-in function's formal arguments and check
     each const char* against the actual argument.  If the actual
     argument is declared attribute non-string issue a warning unless
     the argument's maximum length is bounded.  */
  function_args_iterator it;
  function_args_iter_init (&it, TREE_TYPE (fndecl));

  for (unsigned argno = 0; ; ++argno, function_args_iter_next (&it))
    {
      /* Avoid iterating past the declared argument in a call
	 to function declared without a prototype.  */
      if (argno >= nargs)
	break;

      tree argtype = function_args_iter_cond (&it);
      if (!argtype)
	break;

      if (TREE_CODE (argtype) != POINTER_TYPE)
	continue;

      argtype = TREE_TYPE (argtype);

      if (TREE_CODE (argtype) != INTEGER_TYPE
	  || !TYPE_READONLY (argtype))
	continue;

      argtype = TYPE_MAIN_VARIANT (argtype);
      if (argtype != char_type_node)
	continue;

      tree callarg = call_arg (exp, argno);
      if (TREE_CODE (callarg) == ADDR_EXPR)
	callarg = TREE_OPERAND (callarg, 0);

      /* See if the destination is declared with attribute "nonstring".  */
      tree decl = get_attr_nonstring_decl (callarg);
      if (!decl)
	continue;

      /* The maximum number of array elements accessed.  */
      offset_int wibnd = 0;

      if (argno && fncode == BUILT_IN_STRNCAT)
	{
	  /* See if the bound in strncat is derived from the length
	     of the strlen of the destination (as it's expected to be).
	     If so, reset BOUND and FNCODE to trigger a warning.  */
	  tree dstarg = call_arg (exp, 0);
	  if (is_strlen_related_p (dstarg, bound))
	    {
	      /* The bound applies to the destination, not to the source,
		 so reset these to trigger a warning without mentioning
		 the bound.  */
	      bound = NULL;
	      fncode = 0;
	    }
	  else if (bndrng[1])
	    /* Use the upper bound of the range for strncat.  */
	    wibnd = wi::to_offset (bndrng[1]);
	}
      else if (bndrng[0])
	/* Use the lower bound of the range for functions other than
	   strncat.  */
	wibnd = wi::to_offset (bndrng[0]);

      /* Determine the size of the argument array if it is one.  */
      offset_int asize = wibnd;
      bool known_size = false;
      tree type = TREE_TYPE (decl);

      /* Determine the array size.  For arrays of unknown bound and
	 pointers reset BOUND to trigger the appropriate warning.  */
      if (TREE_CODE (type) == ARRAY_TYPE)
	{
	  if (tree arrbnd = TYPE_DOMAIN (type))
	    {
	      if ((arrbnd = TYPE_MAX_VALUE (arrbnd)))
		{
		  asize = wi::to_offset (arrbnd) + 1;
		  known_size = true;
		}
	    }
	  else if (bound == void_type_node)
	    bound = NULL_TREE;
	}
      else if (bound == void_type_node)
	bound = NULL_TREE;

      /* In a call to strncat with a bound in a range whose lower but
	 not upper bound is less than the array size, reset ASIZE to
	 be the same as the bound and the other variable to trigger
	 the apprpriate warning below.  */
      if (fncode == BUILT_IN_STRNCAT
	  && bndrng[0] != bndrng[1]
	  && wi::ltu_p (wi::to_offset (bndrng[0]), asize)
	  && (!known_size
	      || wi::ltu_p (asize, wibnd)))
	{
	  asize = wibnd;
	  bound = NULL_TREE;
	  fncode = 0;
	}

      bool warned = false;

      auto_diagnostic_group d;
      if (wi::ltu_p (asize, wibnd))
	{
	  if (bndrng[0] == bndrng[1])
	    warned = warning_at (loc, OPT_Wstringop_overread,
				 "%qD argument %i declared attribute "
				 "%<nonstring%> is smaller than the specified "
				 "bound %wu",
				 fndecl, argno + 1, wibnd.to_uhwi ());
	  else if (wi::ltu_p (asize, wi::to_offset (bndrng[0])))
	    warned = warning_at (loc, OPT_Wstringop_overread,
				 "%qD argument %i declared attribute "
				 "%<nonstring%> is smaller than "
				 "the specified bound [%E, %E]",
				 fndecl, argno + 1, bndrng[0], bndrng[1]);
	  else
	    warned = warning_at (loc, OPT_Wstringop_overread,
				 "%qD argument %i declared attribute "
				 "%<nonstring%> may be smaller than "
				 "the specified bound [%E, %E]",
				 fndecl, argno + 1, bndrng[0], bndrng[1]);
	}
      else if (fncode == BUILT_IN_STRNCAT)
	; /* Avoid warning for calls to strncat() when the bound
	     is equal to the size of the non-string argument.  */
      else if (!bound)
	warned = warning_at (loc, OPT_Wstringop_overread,
			     "%qD argument %i declared attribute %<nonstring%>",
			     fndecl, argno + 1);

      if (warned)
	{
	  inform (DECL_SOURCE_LOCATION (decl),
		  "argument %qD declared here", decl);
	  any_arg_warned = true;
	}
    }

  if (any_arg_warned)
    suppress_warning (exp, OPT_Wstringop_overread);

  return any_arg_warned;
}

bool
maybe_warn_nonstring_arg (tree fndecl, gimple *stmt)
{
  return maybe_warn_nonstring_arg<gimple *>(fndecl, stmt);
}


bool
maybe_warn_nonstring_arg (tree fndecl, tree expr)
{
  return maybe_warn_nonstring_arg<tree>(fndecl, expr);
}

/* Issue a warning OPT for a bounded call EXP with a bound in RANGE
   accessing an object with SIZE.  */

template <class GimpleOrTree>
static bool
maybe_warn_for_bound (opt_code opt, location_t loc, GimpleOrTree exp, tree func,
		      tree bndrng[2], tree size, const access_data *pad)
{
  if (!bndrng[0] || warning_suppressed_p (exp, opt))
    return false;

  tree maxobjsize = max_object_size ();

  bool warned = false;

  if (opt == OPT_Wstringop_overread)
    {
      bool maybe = pad && pad->src.phi ();
      if (maybe)
	{
	  /* Issue a "maybe" warning only if the PHI refers to objects
	     at least one of which has more space remaining than the bound.
	     Otherwise, if the bound is greater, use the definitive form.  */
	  offset_int remmax = pad->src.size_remaining ();
	  if (remmax < wi::to_offset (bndrng[0]))
	    maybe = false;
	}

      if (tree_int_cst_lt (maxobjsize, bndrng[0]))
	{
	  if (bndrng[0] == bndrng[1])
	    warned = (func
		      ? warning_at (loc, opt,
				    (maybe
				     ? G_("%qD specified bound %E may "
					  "exceed maximum object size %E")
				     : G_("%qD specified bound %E "
					  "exceeds maximum object size %E")),
				    func, bndrng[0], maxobjsize)
		      : warning_at (loc, opt,
				    (maybe
				     ? G_("specified bound %E may "
					  "exceed maximum object size %E")
				     : G_("specified bound %E "
					  "exceeds maximum object size %E")),
				    bndrng[0], maxobjsize));
	  else
	    warned = (func
		      ? warning_at (loc, opt,
				    (maybe
				     ? G_("%qD specified bound [%E, %E] may "
					  "exceed maximum object size %E")
				     : G_("%qD specified bound [%E, %E] "
					  "exceeds maximum object size %E")),
				    func,
				    bndrng[0], bndrng[1], maxobjsize)
		      : warning_at (loc, opt,
				    (maybe
				     ? G_("specified bound [%E, %E] may "
					  "exceed maximum object size %E")
				     : G_("specified bound [%E, %E] "
					  "exceeds maximum object size %E")),
				    bndrng[0], bndrng[1], maxobjsize));
	}
      else if (!size || tree_int_cst_le (bndrng[0], size))
	return false;
      else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
	warned = (func
		  ? warning_at (loc, opt,
				(maybe
				 ? G_("%qD specified bound %E may exceed "
				      "source size %E")
				 : G_("%qD specified bound %E exceeds "
				      "source size %E")),
				func, bndrng[0], size)
		  : warning_at (loc, opt,
				(maybe
				 ? G_("specified bound %E may exceed "
				      "source size %E")
				 : G_("specified bound %E exceeds "
				      "source size %E")),
				bndrng[0], size));
      else
	warned = (func
		  ? warning_at (loc, opt,
				(maybe
				 ? G_("%qD specified bound [%E, %E] may "
				      "exceed source size %E")
				 : G_("%qD specified bound [%E, %E] exceeds "
				      "source size %E")),
				func, bndrng[0], bndrng[1], size)
		  : warning_at (loc, opt,
				(maybe
				 ? G_("specified bound [%E, %E] may exceed "
				      "source size %E")
				 : G_("specified bound [%E, %E] exceeds "
				      "source size %E")),
				bndrng[0], bndrng[1], size));
      if (warned)
	{
	  if (pad && pad->src.ref
	      && has_location (pad->src.ref))
	    inform (get_location (pad->src.ref),
		    "source object allocated here");
	  suppress_warning (exp, opt);
	}

      return warned;
    }

  bool maybe = pad && pad->dst.phi ();
  if (maybe)
    {
      /* Issue a "maybe" warning only if the PHI refers to objects
	 at least one of which has more space remaining than the bound.
	 Otherwise, if the bound is greater, use the definitive form.  */
      offset_int remmax = pad->dst.size_remaining ();
      if (remmax < wi::to_offset (bndrng[0]))
	maybe = false;
    }
  if (tree_int_cst_lt (maxobjsize, bndrng[0]))
    {
      if (bndrng[0] == bndrng[1])
	warned = (func
		  ? warning_at (loc, opt,
				(maybe
				 ? G_("%qD specified size %E may "
				      "exceed maximum object size %E")
				 : G_("%qD specified size %E "
				      "exceeds maximum object size %E")),
				func, bndrng[0], maxobjsize)
		  : warning_at (loc, opt,
				(maybe
				 ? G_("specified size %E may exceed "
				      "maximum object size %E")
				 : G_("specified size %E exceeds "
				      "maximum object size %E")),
				bndrng[0], maxobjsize));
      else
	warned = (func
		  ? warning_at (loc, opt,
				(maybe
				 ? G_("%qD specified size between %E and %E "
				      "may exceed maximum object size %E")
				 : G_("%qD specified size between %E and %E "
				      "exceeds maximum object size %E")),
				func, bndrng[0], bndrng[1], maxobjsize)
		  : warning_at (loc, opt,
				(maybe
				 ? G_("specified size between %E and %E "
				      "may exceed maximum object size %E")
				 : G_("specified size between %E and %E "
				      "exceeds maximum object size %E")),
				bndrng[0], bndrng[1], maxobjsize));
    }
  else if (!size || tree_int_cst_le (bndrng[0], size))
    return false;
  else if (tree_int_cst_equal (bndrng[0], bndrng[1]))
    warned = (func
	      ? warning_at (loc, opt,
			    (maybe
			     ? G_("%qD specified bound %E may exceed "
				  "destination size %E")
			     : G_("%qD specified bound %E exceeds "
				  "destination size %E")),
			    func, bndrng[0], size)
	      : warning_at (loc, opt,
			    (maybe
			     ? G_("specified bound %E may exceed "
				  "destination size %E")
			     : G_("specified bound %E exceeds "
				  "destination size %E")),
			    bndrng[0], size));
  else
    warned = (func
	      ? warning_at (loc, opt,
			    (maybe
			     ? G_("%qD specified bound [%E, %E] may exceed "
				  "destination size %E")
			     : G_("%qD specified bound [%E, %E] exceeds "
				  "destination size %E")),
			    func, bndrng[0], bndrng[1], size)
	      : warning_at (loc, opt,
			    (maybe
			     ? G_("specified bound [%E, %E] exceeds "
				  "destination size %E")
			     : G_("specified bound [%E, %E] exceeds "
				  "destination size %E")),
			    bndrng[0], bndrng[1], size));

  if (warned)
    {
      if (pad && pad->dst.ref
	  && has_location (pad->dst.ref))
	inform (get_location (pad->dst.ref),
		"destination object allocated here");
      suppress_warning (exp, opt);
    }

  return warned;
}

bool
maybe_warn_for_bound (opt_code opt, location_t loc, gimple *stmt, tree func,
		      tree bndrng[2], tree size,
		      const access_data *pad /* = NULL */)
{
  return maybe_warn_for_bound<gimple *> (opt, loc, stmt, func, bndrng, size,
					 pad);
}

bool
maybe_warn_for_bound (opt_code opt, location_t loc, tree expr, tree func,
		      tree bndrng[2], tree size,
		      const access_data *pad /* = NULL */)
{
  return maybe_warn_for_bound<tree> (opt, loc, expr, func, bndrng, size, pad);
}

/* For an expression EXP issue an access warning controlled by option OPT
   with access to a region SIZE bytes in size in the RANGE of sizes.
   WRITE is true for a write access, READ for a read access, neither for
   call that may or may not perform an access but for which the range
   is expected to valid.
   Returns true when a warning has been issued.  */

template <class GimpleOrTree>
static bool
warn_for_access (location_t loc, tree func, GimpleOrTree exp, int opt,
		 tree range[2], tree size, bool write, bool read, bool maybe)
{
  bool warned = false;

  if (write && read)
    {
      if (tree_int_cst_equal (range[0], range[1]))
	warned = (func
		  ? warning_n (loc, opt, tree_to_uhwi (range[0]),
			       (maybe
				? G_("%qD may access %E byte in a region "
				     "of size %E")
				: G_("%qD accessing %E byte in a region "
				     "of size %E")),
				(maybe
				 ? G_ ("%qD may access %E bytes in a region "
				       "of size %E")
				 : G_ ("%qD accessing %E bytes in a region "
				       "of size %E")),
			       func, range[0], size)
		  : warning_n (loc, opt, tree_to_uhwi (range[0]),
			       (maybe
				? G_("may access %E byte in a region "
				     "of size %E")
				: G_("accessing %E byte in a region "
				     "of size %E")),
			       (maybe
				? G_("may access %E bytes in a region "
				     "of size %E")
				: G_("accessing %E bytes in a region "
				     "of size %E")),
			       range[0], size));
      else if (tree_int_cst_sign_bit (range[1]))
	{
	  /* Avoid printing the upper bound if it's invalid.  */
	  warned = (func
		    ? warning_at (loc, opt,
				  (maybe
				   ? G_("%qD may access %E or more bytes "
					"in a region of size %E")
				   : G_("%qD accessing %E or more bytes "
					"in a region of size %E")),
				  func, range[0], size)
		    : warning_at (loc, opt,
				  (maybe
				   ? G_("may access %E or more bytes "
					"in a region of size %E")
				   : G_("accessing %E or more bytes "
					"in a region of size %E")),
				  range[0], size));
	}
      else
	warned = (func
		  ? warning_at (loc, opt,
				(maybe
				 ? G_("%qD may access between %E and %E "
				      "bytes in a region of size %E")
				 : G_("%qD accessing between %E and %E "
				      "bytes in a region of size %E")),
				func, range[0], range[1], size)
		  : warning_at (loc, opt,
				(maybe
				 ? G_("may access between %E and %E bytes "
				      "in a region of size %E")
				 : G_("accessing between %E and %E bytes "
				      "in a region of size %E")),
				range[0], range[1], size));
      return warned;
    }

  if (write)
    {
      if (tree_int_cst_equal (range[0], range[1]))
	warned = (func
		  ? warning_n (loc, opt, tree_to_uhwi (range[0]),
			       (maybe
				? G_("%qD may write %E byte into a region "
				     "of size %E")
				: G_("%qD writing %E byte into a region "
				     "of size %E overflows the destination")),
			       (maybe
				? G_("%qD may write %E bytes into a region "
				     "of size %E")
				: G_("%qD writing %E bytes into a region "
				     "of size %E overflows the destination")),
			       func, range[0], size)
		  : warning_n (loc, opt, tree_to_uhwi (range[0]),
			       (maybe
				? G_("may write %E byte into a region "
				     "of size %E")
				: G_("writing %E byte into a region "
				     "of size %E overflows the destination")),
			       (maybe
				? G_("may write %E bytes into a region "
				     "of size %E")
				: G_("writing %E bytes into a region "
				     "of size %E overflows the destination")),
			       range[0], size));
      else if (tree_int_cst_sign_bit (range[1]))
	{
	  /* Avoid printing the upper bound if it's invalid.  */
	  warned = (func
		    ? warning_at (loc, opt,
				  (maybe
				   ? G_("%qD may write %E or more bytes "
					"into a region of size %E")
				   : G_("%qD writing %E or more bytes "
					"into a region of size %E overflows "
					"the destination")),
				  func, range[0], size)
		    : warning_at (loc, opt,
				  (maybe
				   ? G_("may write %E or more bytes into "
					"a region of size %E")
				   : G_("writing %E or more bytes into "
					"a region of size %E overflows "
					"the destination")),
				  range[0], size));
	}
      else
	warned = (func
		  ? warning_at (loc, opt,
				(maybe
				 ? G_("%qD may write between %E and %E bytes "
				      "into a region of size %E")
				 : G_("%qD writing between %E and %E bytes "
				      "into a region of size %E overflows "
				      "the destination")),
				func, range[0], range[1], size)
		  : warning_at (loc, opt,
				(maybe
				 ? G_("may write between %E and %E bytes "
				      "into a region of size %E")
				 : G_("writing between %E and %E bytes "
				      "into a region of size %E overflows "
				      "the destination")),
				range[0], range[1], size));
      return warned;
    }

  if (read)
    {
      if (tree_int_cst_equal (range[0], range[1]))
	warned = (func
		  ? warning_n (loc, OPT_Wstringop_overread,
			       tree_to_uhwi (range[0]),
			       (maybe
				? G_("%qD may read %E byte from a region "
				     "of size %E")
				: G_("%qD reading %E byte from a region "
				     "of size %E")),
			       (maybe
				? G_("%qD may read %E bytes from a region "
				     "of size %E")
				: G_("%qD reading %E bytes from a region "
				     "of size %E")),
			       func, range[0], size)
		  : warning_n (loc, OPT_Wstringop_overread,
			       tree_to_uhwi (range[0]),
			       (maybe
				? G_("may read %E byte from a region "
				     "of size %E")
				: G_("reading %E byte from a region "
				     "of size %E")),
			       (maybe
				? G_("may read %E bytes from a region "
				     "of size %E")
				: G_("reading %E bytes from a region "
				     "of size %E")),
			       range[0], size));
      else if (tree_int_cst_sign_bit (range[1]))
	{
	  /* Avoid printing the upper bound if it's invalid.  */
	  warned = (func
		    ? warning_at (loc, OPT_Wstringop_overread,
				  (maybe
				   ? G_("%qD may read %E or more bytes "
					"from a region of size %E")
				   : G_("%qD reading %E or more bytes "
					"from a region of size %E")),
				  func, range[0], size)
		    : warning_at (loc, OPT_Wstringop_overread,
				  (maybe
				   ? G_("may read %E or more bytes "
					"from a region of size %E")
				   : G_("reading %E or more bytes "
					"from a region of size %E")),
				  range[0], size));
	}
      else
	warned = (func
		  ? warning_at (loc, OPT_Wstringop_overread,
				(maybe
				 ? G_("%qD may read between %E and %E bytes "
				      "from a region of size %E")
				 : G_("%qD reading between %E and %E bytes "
				      "from a region of size %E")),
				func, range[0], range[1], size)
		  : warning_at (loc, opt,
				(maybe
				 ? G_("may read between %E and %E bytes "
				      "from a region of size %E")
				 : G_("reading between %E and %E bytes "
				      "from a region of size %E")),
				range[0], range[1], size));

      if (warned)
	suppress_warning (exp, OPT_Wstringop_overread);

      return warned;
    }

  if (tree_int_cst_equal (range[0], range[1])
      || tree_int_cst_sign_bit (range[1]))
    warned = (func
	      ? warning_n (loc, OPT_Wstringop_overread,
			   tree_to_uhwi (range[0]),
			   "%qD expecting %E byte in a region of size %E",
			   "%qD expecting %E bytes in a region of size %E",
			   func, range[0], size)
	      : warning_n (loc, OPT_Wstringop_overread,
			   tree_to_uhwi (range[0]),
			   "expecting %E byte in a region of size %E",
			   "expecting %E bytes in a region of size %E",
			   range[0], size));
  else if (tree_int_cst_sign_bit (range[1]))
    {
      /* Avoid printing the upper bound if it's invalid.  */
      warned = (func
		? warning_at (loc, OPT_Wstringop_overread,
			      "%qD expecting %E or more bytes in a region "
			      "of size %E",
			      func, range[0], size)
		: warning_at (loc, OPT_Wstringop_overread,
			      "expecting %E or more bytes in a region "
			      "of size %E",
			      range[0], size));
    }
  else
    warned = (func
	      ? warning_at (loc, OPT_Wstringop_overread,
			    "%qD expecting between %E and %E bytes in "
			    "a region of size %E",
			    func, range[0], range[1], size)
	      : warning_at (loc, OPT_Wstringop_overread,
			    "expecting between %E and %E bytes in "
			    "a region of size %E",
			    range[0], range[1], size));

  if (warned)
    suppress_warning (exp, OPT_Wstringop_overread);

  return warned;
}

static bool
warn_for_access (location_t loc, tree func, gimple *stmt, int opt,
		 tree range[2], tree size, bool write, bool read, bool maybe)
{
  return warn_for_access<gimple *>(loc, func, stmt, opt, range, size,
				   write, read, maybe);
}

static bool
warn_for_access (location_t loc, tree func, tree expr, int opt,
		 tree range[2], tree size, bool write, bool read, bool maybe)
{
  return warn_for_access<tree>(loc, func, expr, opt, range, size,
			       write, read, maybe);
}

/* Helper to set RANGE to the range of BOUND if it's nonnull, bounded
   by BNDRNG if nonnull and valid.  */

static void
get_size_range (range_query *query, tree bound, gimple *stmt, tree range[2],
		const offset_int bndrng[2])
{
  if (bound)
    get_size_range (query, bound, stmt, range);

  if (!bndrng || (bndrng[0] == 0 && bndrng[1] == HOST_WIDE_INT_M1U))
    return;

  if (range[0] && TREE_CODE (range[0]) == INTEGER_CST)
    {
      offset_int r[] =
	{ wi::to_offset (range[0]), wi::to_offset (range[1]) };
      if (r[0] < bndrng[0])
	range[0] = wide_int_to_tree (sizetype, bndrng[0]);
      if (bndrng[1] < r[1])
	range[1] = wide_int_to_tree (sizetype, bndrng[1]);
    }
  else
    {
      range[0] = wide_int_to_tree (sizetype, bndrng[0]);
      range[1] = wide_int_to_tree (sizetype, bndrng[1]);
    }
}

/* Try to verify that the sizes and lengths of the arguments to a string
   manipulation function given by EXP are within valid bounds and that
   the operation does not lead to buffer overflow or read past the end.
   Arguments other than EXP may be null.  When non-null, the arguments
   have the following meaning:
   DST is the destination of a copy call or NULL otherwise.
   SRC is the source of a copy call or NULL otherwise.
   DSTWRITE is the number of bytes written into the destination obtained
   from the user-supplied size argument to the function (such as in
   memcpy(DST, SRCs, DSTWRITE) or strncpy(DST, DRC, DSTWRITE).
   MAXREAD is the user-supplied bound on the length of the source sequence
   (such as in strncat(d, s, N).  It specifies the upper limit on the number
   of bytes to write.  If NULL, it's taken to be the same as DSTWRITE.
   SRCSTR is the source string (such as in strcpy(DST, SRC)) when the
   expression EXP is a string function call (as opposed to a memory call
   like memcpy).  As an exception, SRCSTR can also be an integer denoting
   the precomputed size of the source string or object (for functions like
   memcpy).
   DSTSIZE is the size of the destination object.

   When DSTWRITE is null LEN is checked to verify that it doesn't exceed
   SIZE_MAX.

   WRITE is true for write accesses, READ is true for reads.  Both are
   false for simple size checks in calls to functions that neither read
   from nor write to the region.

   When nonnull, PAD points to a more detailed description of the access.

   If the call is successfully verified as safe return true, otherwise
   return false.  */

template <class GimpleOrTree>
static bool
check_access (GimpleOrTree exp, tree dstwrite,
	      tree maxread, tree srcstr, tree dstsize,
	      access_mode mode, const access_data *pad,
	      range_query *rvals)
{
  /* The size of the largest object is half the address space, or
     PTRDIFF_MAX.  (This is way too permissive.)  */
  tree maxobjsize = max_object_size ();

  /* Either an approximate/minimum the length of the source string for
     string functions or the size of the source object for raw memory
     functions.  */
  tree slen = NULL_TREE;

  /* The range of the access in bytes; first set to the write access
     for functions that write and then read for those that also (or
     just) read.  */
  tree range[2] = { NULL_TREE, NULL_TREE };

  /* Set to true when the exact number of bytes written by a string
     function like strcpy is not known and the only thing that is
     known is that it must be at least one (for the terminating nul).  */
  bool at_least_one = false;
  if (srcstr)
    {
      /* SRCSTR is normally a pointer to string but as a special case
	 it can be an integer denoting the length of a string.  */
      if (POINTER_TYPE_P (TREE_TYPE (srcstr)))
	{
	  if (!check_nul_terminated_array (exp, srcstr, maxread))
	    /* Return if the array is not nul-terminated and a warning
	       has been issued.  */
	    return false;

	  /* Try to determine the range of lengths the source string
	     refers to.  If it can be determined and is less than
	     the upper bound given by MAXREAD add one to it for
	     the terminating nul.  Otherwise, set it to one for
	     the same reason, or to MAXREAD as appropriate.  */
	  c_strlen_data lendata = { };
	  get_range_strlen (srcstr, &lendata, /* eltsize = */ 1);
	  range[0] = lendata.minlen;
	  range[1] = lendata.maxbound ? lendata.maxbound : lendata.maxlen;
	  if (range[0]
	      && TREE_CODE (range[0]) == INTEGER_CST
	      && TREE_CODE (range[1]) == INTEGER_CST
	      && (!maxread || TREE_CODE (maxread) == INTEGER_CST))
	    {
	      if (maxread && tree_int_cst_le (maxread, range[0]))
		range[0] = range[1] = maxread;
	      else
		range[0] = fold_build2 (PLUS_EXPR, size_type_node,
					range[0], size_one_node);

	      if (maxread && tree_int_cst_le (maxread, range[1]))
		range[1] = maxread;
	      else if (!integer_all_onesp (range[1]))
		range[1] = fold_build2 (PLUS_EXPR, size_type_node,
					range[1], size_one_node);

	      slen = range[0];
	    }
	  else
	    {
	      at_least_one = true;
	      slen = size_one_node;
	    }
	}
      else
	slen = srcstr;
    }

  if (!dstwrite && !maxread)
    {
      /* When the only available piece of data is the object size
	 there is nothing to do.  */
      if (!slen)
	return true;

      /* Otherwise, when the length of the source sequence is known
	 (as with strlen), set DSTWRITE to it.  */
      if (!range[0])
	dstwrite = slen;
    }

  if (!dstsize)
    dstsize = maxobjsize;

  /* Set RANGE to that of DSTWRITE if non-null, bounded by PAD->DST_BNDRNG
     if valid.  */
  gimple *stmt = pad ? pad->stmt : nullptr;
  get_size_range (rvals, dstwrite, stmt, range, pad ? pad->dst_bndrng : NULL);

  tree func = get_callee_fndecl (exp);
  /* Read vs write access by built-ins can be determined from the const
     qualifiers on the pointer argument.  In the absence of attribute
     access, non-const qualified pointer arguments to user-defined
     functions are assumed to both read and write the objects.  */
  const bool builtin = func ? fndecl_built_in_p (func) : false;

  /* First check the number of bytes to be written against the maximum
     object size.  */
  if (range[0]
      && TREE_CODE (range[0]) == INTEGER_CST
      && tree_int_cst_lt (maxobjsize, range[0]))
    {
      location_t loc = get_location (exp);
      maybe_warn_for_bound (OPT_Wstringop_overflow_, loc, exp, func, range,
			    NULL_TREE, pad);
      return false;
    }

  /* The number of bytes to write is "exact" if DSTWRITE is non-null,
     constant, and in range of unsigned HOST_WIDE_INT.  */
  bool exactwrite = dstwrite && tree_fits_uhwi_p (dstwrite);

  /* Next check the number of bytes to be written against the destination
     object size.  */
  if (range[0] || !exactwrite || integer_all_onesp (dstwrite))
    {
      if (range[0]
	  && TREE_CODE (range[0]) == INTEGER_CST
	  && ((tree_fits_uhwi_p (dstsize)
	       && tree_int_cst_lt (dstsize, range[0]))
	      || (dstwrite
		  && tree_fits_uhwi_p (dstwrite)
		  && tree_int_cst_lt (dstwrite, range[0]))))
	{
	  const opt_code opt = OPT_Wstringop_overflow_;
	  if (warning_suppressed_p (exp, opt)
	      || (pad && pad->dst.ref
		  && warning_suppressed_p (pad->dst.ref, opt)))
	    return false;

	  location_t loc = get_location (exp);
	  bool warned = false;
	  if (dstwrite == slen && at_least_one)
	    {
	      /* This is a call to strcpy with a destination of 0 size
		 and a source of unknown length.  The call will write
		 at least one byte past the end of the destination.  */
	      warned = (func
			? warning_at (loc, opt,
				      "%qD writing %E or more bytes into "
				      "a region of size %E overflows "
				      "the destination",
				      func, range[0], dstsize)
			: warning_at (loc, opt,
				      "writing %E or more bytes into "
				      "a region of size %E overflows "
				      "the destination",
				      range[0], dstsize));
	    }
	  else
	    {
	      const bool read
		= mode == access_read_only || mode == access_read_write;
	      const bool write
		= mode == access_write_only || mode == access_read_write;
	      const bool maybe = pad && pad->dst.parmarray;
	      warned = warn_for_access (loc, func, exp,
					OPT_Wstringop_overflow_,
					range, dstsize,
					write, read && !builtin, maybe);
	    }

	  if (warned)
	    {
	      suppress_warning (exp, OPT_Wstringop_overflow_);
	      if (pad)
		pad->dst.inform_access (pad->mode);
	    }

	  /* Return error when an overflow has been detected.  */
	  return false;
	}
    }

  /* Check the maximum length of the source sequence against the size
     of the destination object if known, or against the maximum size
     of an object.  */
  if (maxread)
    {
      /* Set RANGE to that of MAXREAD, bounded by PAD->SRC_BNDRNG if
	 PAD is nonnull and BNDRNG is valid.  */
      get_size_range (rvals, maxread, stmt, range, pad ? pad->src_bndrng : NULL);

      location_t loc = get_location (exp);
      tree size = dstsize;
      if (pad && pad->mode == access_read_only)
	size = wide_int_to_tree (sizetype, pad->src.size_remaining ());

      if (range[0] && maxread && tree_fits_uhwi_p (size))
	{
	  if (tree_int_cst_lt (maxobjsize, range[0]))
	    {
	      maybe_warn_for_bound (OPT_Wstringop_overread, loc, exp, func,
				    range, size, pad);
	      return false;
	    }

	  if (size != maxobjsize && tree_int_cst_lt (size, range[0]))
	    {
	      opt_code opt = (dstwrite || mode != access_read_only
			      ? OPT_Wstringop_overflow_
			      : OPT_Wstringop_overread);
	      maybe_warn_for_bound (opt, loc, exp, func, range, size, pad);
	      return false;
	    }
	}

      maybe_warn_nonstring_arg (func, exp);
    }

  /* Check for reading past the end of SRC.  */
  bool overread = (slen
		   && slen == srcstr
		   && dstwrite
		   && range[0]
		   && TREE_CODE (slen) == INTEGER_CST
		   && tree_int_cst_lt (slen, range[0]));
  /* If none is determined try to get a better answer based on the details
     in PAD.  */
  if (!overread
      && pad
      && pad->src.sizrng[1] >= 0
      && pad->src.offrng[0] >= 0
      && (pad->src.offrng[1] < 0
	  || pad->src.offrng[0] <= pad->src.offrng[1]))
    {
      /* Set RANGE to that of MAXREAD, bounded by PAD->SRC_BNDRNG if
	 PAD is nonnull and BNDRNG is valid.  */
      get_size_range (rvals, maxread, stmt, range, pad ? pad->src_bndrng : NULL);
      /* Set OVERREAD for reads starting just past the end of an object.  */
      overread = pad->src.sizrng[1] - pad->src.offrng[0] < pad->src_bndrng[0];
      range[0] = wide_int_to_tree (sizetype, pad->src_bndrng[0]);
      slen = size_zero_node;
    }

  if (overread)
    {
      const opt_code opt = OPT_Wstringop_overread;
      if (warning_suppressed_p (exp, opt)
	  || (srcstr && warning_suppressed_p (srcstr, opt))
	  || (pad && pad->src.ref
	      && warning_suppressed_p (pad->src.ref, opt)))
	return false;

      location_t loc = get_location (exp);
      const bool read
	= mode == access_read_only || mode == access_read_write;
      const bool maybe = pad && pad->dst.parmarray;
      if (warn_for_access (loc, func, exp, opt, range, slen, false, read,
			   maybe))
	{
	  suppress_warning (exp, opt);
	  if (pad)
	    pad->src.inform_access (access_read_only);
	}
      return false;
    }

  return true;
}

static bool
check_access (gimple *stmt, tree dstwrite,
	      tree maxread, tree srcstr, tree dstsize,
	      access_mode mode, const access_data *pad,
	      range_query *rvals)
{
  return check_access<gimple *> (stmt, dstwrite, maxread, srcstr, dstsize,
				 mode, pad, rvals);
}

bool
check_access (tree expr, tree dstwrite,
	      tree maxread, tree srcstr, tree dstsize,
	      access_mode mode, const access_data *pad /* = NULL */)
{
  return check_access<tree> (expr, dstwrite, maxread, srcstr, dstsize,
			     mode, pad, nullptr);
}

/* Return true if STMT is a call to an allocation function.  Unless
   ALL_ALLOC is set, consider only functions that return dynmamically
   allocated objects.  Otherwise return true even for all forms of
   alloca (including VLA).  */

static bool
fndecl_alloc_p (tree fndecl, bool all_alloc)
{
  if (!fndecl)
    return false;

  /* A call to operator new isn't recognized as one to a built-in.  */
  if (DECL_IS_OPERATOR_NEW_P (fndecl))
    return true;

  if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL))
    {
      switch (DECL_FUNCTION_CODE (fndecl))
	{
	case BUILT_IN_ALLOCA:
	case BUILT_IN_ALLOCA_WITH_ALIGN:
	  return all_alloc;
	case BUILT_IN_ALIGNED_ALLOC:
	case BUILT_IN_CALLOC:
	case BUILT_IN_GOMP_ALLOC:
	case BUILT_IN_MALLOC:
	case BUILT_IN_REALLOC:
	case BUILT_IN_STRDUP:
	case BUILT_IN_STRNDUP:
	  return true;
	default:
	  break;
	}
    }

  /* A function is considered an allocation function if it's declared
     with attribute malloc with an argument naming its associated
     deallocation function.  */
  tree attrs = DECL_ATTRIBUTES (fndecl);
  if (!attrs)
    return false;

  for (tree allocs = attrs;
       (allocs = lookup_attribute ("malloc", allocs));
       allocs = TREE_CHAIN (allocs))
    {
      tree args = TREE_VALUE (allocs);
      if (!args)
	continue;

      if (TREE_VALUE (args))
	return true;
    }

  return false;
}

/* Return true if STMT is a call to an allocation function.  A wrapper
   around fndecl_alloc_p.  */

static bool
gimple_call_alloc_p (gimple *stmt, bool all_alloc = false)
{
  return fndecl_alloc_p (gimple_call_fndecl (stmt), all_alloc);
}

/* Return true if DELC doesn't refer to an operator delete that's
   suitable to call with a pointer returned from the operator new
   described by NEWC.  */

static bool
new_delete_mismatch_p (const demangle_component &newc,
		       const demangle_component &delc)
{
  if (newc.type != delc.type)
    return true;

  switch (newc.type)
    {
    case DEMANGLE_COMPONENT_NAME:
      {
	int len = newc.u.s_name.len;
	const char *news = newc.u.s_name.s;
	const char *dels = delc.u.s_name.s;
	if (len != delc.u.s_name.len || memcmp (news, dels, len))
	  return true;

	if (news[len] == 'n')
	  {
	    if (news[len + 1] == 'a')
	      return dels[len] != 'd' || dels[len + 1] != 'a';
	    if (news[len + 1] == 'w')
	      return dels[len] != 'd' || dels[len + 1] != 'l';
	  }
	return false;
      }

    case DEMANGLE_COMPONENT_OPERATOR:
      /* Operator mismatches are handled above.  */
      return false;

    case DEMANGLE_COMPONENT_EXTENDED_OPERATOR:
      if (newc.u.s_extended_operator.args != delc.u.s_extended_operator.args)
	return true;
      return new_delete_mismatch_p (*newc.u.s_extended_operator.name,
				    *delc.u.s_extended_operator.name);

    case DEMANGLE_COMPONENT_FIXED_TYPE:
      if (newc.u.s_fixed.accum != delc.u.s_fixed.accum
	  || newc.u.s_fixed.sat != delc.u.s_fixed.sat)
	return true;
      return new_delete_mismatch_p (*newc.u.s_fixed.length,
				    *delc.u.s_fixed.length);

    case DEMANGLE_COMPONENT_CTOR:
      if (newc.u.s_ctor.kind != delc.u.s_ctor.kind)
	return true;
      return new_delete_mismatch_p (*newc.u.s_ctor.name,
				    *delc.u.s_ctor.name);

    case DEMANGLE_COMPONENT_DTOR:
      if (newc.u.s_dtor.kind != delc.u.s_dtor.kind)
	return true;
      return new_delete_mismatch_p (*newc.u.s_dtor.name,
				    *delc.u.s_dtor.name);

    case DEMANGLE_COMPONENT_BUILTIN_TYPE:
      {
	/* The demangler API provides no better way to compare built-in
	   types except to by comparing their demangled names. */
	size_t nsz, dsz;
	demangle_component *pnc = const_cast<demangle_component *>(&newc);
	demangle_component *pdc = const_cast<demangle_component *>(&delc);
	char *nts = cplus_demangle_print (0, pnc, 16, &nsz);
	char *dts = cplus_demangle_print (0, pdc, 16, &dsz);
	if (!nts != !dts)
	  return true;
	bool mismatch = strcmp (nts, dts);
	free (nts);
	free (dts);
	return mismatch;
      }

    case DEMANGLE_COMPONENT_SUB_STD:
      if (newc.u.s_string.len != delc.u.s_string.len)
	return true;
      return memcmp (newc.u.s_string.string, delc.u.s_string.string,
		     newc.u.s_string.len);

    case DEMANGLE_COMPONENT_FUNCTION_PARAM:
    case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
      return newc.u.s_number.number != delc.u.s_number.number;

    case DEMANGLE_COMPONENT_CHARACTER:
      return newc.u.s_character.character != delc.u.s_character.character;

    case DEMANGLE_COMPONENT_DEFAULT_ARG:
    case DEMANGLE_COMPONENT_LAMBDA:
      if (newc.u.s_unary_num.num != delc.u.s_unary_num.num)
	return true;
      return new_delete_mismatch_p (*newc.u.s_unary_num.sub,
				    *delc.u.s_unary_num.sub);
    default:
      break;
    }

  if (!newc.u.s_binary.left != !delc.u.s_binary.left)
    return true;

  if (!newc.u.s_binary.left)
    return false;

  if (new_delete_mismatch_p (*newc.u.s_binary.left, *delc.u.s_binary.left)
      || !newc.u.s_binary.right != !delc.u.s_binary.right)
    return true;

  if (newc.u.s_binary.right)
    return new_delete_mismatch_p (*newc.u.s_binary.right,
				  *delc.u.s_binary.right);
  return false;
}

/* Return true if DELETE_DECL is an operator delete that's not suitable
   to call with a pointer returned fron NEW_DECL.  */

static bool
new_delete_mismatch_p (tree new_decl, tree delete_decl)
{
  tree new_name = DECL_ASSEMBLER_NAME (new_decl);
  tree delete_name = DECL_ASSEMBLER_NAME (delete_decl);

  /* valid_new_delete_pair_p() returns a conservative result (currently
     it only handles global operators).  A true result is reliable but
     a false result doesn't necessarily mean the operators don't match
     unless CERTAIN is set.  */
  bool certain;
  if (valid_new_delete_pair_p (new_name, delete_name, &certain))
    return false;
  /* CERTAIN is set when the negative result is certain.  */
  if (certain)
    return true;

  /* For anything not handled by valid_new_delete_pair_p() such as member
     operators compare the individual demangled components of the mangled
     name.  */
  const char *new_str = IDENTIFIER_POINTER (new_name);
  const char *del_str = IDENTIFIER_POINTER (delete_name);

  void *np = NULL, *dp = NULL;
  demangle_component *ndc = cplus_demangle_v3_components (new_str, 0, &np);
  demangle_component *ddc = cplus_demangle_v3_components (del_str, 0, &dp);
  bool mismatch = new_delete_mismatch_p (*ndc, *ddc);
  free (np);
  free (dp);
  return mismatch;
}

/* ALLOC_DECL and DEALLOC_DECL are pair of allocation and deallocation
   functions.  Return true if the latter is suitable to deallocate objects
   allocated by calls to the former.  */

static bool
matching_alloc_calls_p (tree alloc_decl, tree dealloc_decl)
{
  /* Set to alloc_kind_t::builtin if ALLOC_DECL is associated with
     a built-in deallocator.  */
  enum class alloc_kind_t { none, builtin, user }
  alloc_dealloc_kind = alloc_kind_t::none;

  if (DECL_IS_OPERATOR_NEW_P (alloc_decl))
    {
      if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl))
	/* Return true iff both functions are of the same array or
	   singleton form and false otherwise.  */
	return !new_delete_mismatch_p (alloc_decl, dealloc_decl);

      /* Return false for deallocation functions that are known not
	 to match.  */
      if (fndecl_built_in_p (dealloc_decl, BUILT_IN_FREE)
	  || fndecl_built_in_p (dealloc_decl, BUILT_IN_REALLOC))
	return false;
      /* Otherwise proceed below to check the deallocation function's
	 "*dealloc" attributes to look for one that mentions this operator
	 new.  */
    }
  else if (fndecl_built_in_p (alloc_decl, BUILT_IN_NORMAL))
    {
      switch (DECL_FUNCTION_CODE (alloc_decl))
	{
	case BUILT_IN_ALLOCA:
	case BUILT_IN_ALLOCA_WITH_ALIGN:
	  return false;

	case BUILT_IN_ALIGNED_ALLOC:
	case BUILT_IN_CALLOC:
	case BUILT_IN_GOMP_ALLOC:
	case BUILT_IN_MALLOC:
	case BUILT_IN_REALLOC:
	case BUILT_IN_STRDUP:
	case BUILT_IN_STRNDUP:
	  if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl))
	    return false;

	  if (fndecl_built_in_p (dealloc_decl, BUILT_IN_FREE)
	      || fndecl_built_in_p (dealloc_decl, BUILT_IN_REALLOC))
	    return true;

	  alloc_dealloc_kind = alloc_kind_t::builtin;
	  break;

	default:
	  break;
	}
    }

  /* Set if DEALLOC_DECL both allocates and deallocates.  */
  alloc_kind_t realloc_kind = alloc_kind_t::none;

  if (fndecl_built_in_p (dealloc_decl, BUILT_IN_NORMAL))
    {
      built_in_function dealloc_code = DECL_FUNCTION_CODE (dealloc_decl);
      if (dealloc_code == BUILT_IN_REALLOC)
	realloc_kind = alloc_kind_t::builtin;

      for (tree amats = DECL_ATTRIBUTES (alloc_decl);
	   (amats = lookup_attribute ("malloc", amats));
	   amats = TREE_CHAIN (amats))
	{
	  tree args = TREE_VALUE (amats);
	  if (!args)
	    continue;

	  tree fndecl = TREE_VALUE (args);
	  if (!fndecl || !DECL_P (fndecl))
	    continue;

	  if (fndecl_built_in_p (fndecl, BUILT_IN_NORMAL)
	      && dealloc_code == DECL_FUNCTION_CODE (fndecl))
	    return true;
	}
    }

  const bool alloc_builtin = fndecl_built_in_p (alloc_decl, BUILT_IN_NORMAL);
  alloc_kind_t realloc_dealloc_kind = alloc_kind_t::none;

  /* If DEALLOC_DECL has an internal "*dealloc" attribute scan the list
     of its associated allocation functions for ALLOC_DECL.
     If the corresponding ALLOC_DECL is found they're a matching pair,
     otherwise they're not.
     With DDATS set to the Deallocator's *Dealloc ATtributes...  */
  for (tree ddats = DECL_ATTRIBUTES (dealloc_decl);
       (ddats = lookup_attribute ("*dealloc", ddats));
       ddats = TREE_CHAIN (ddats))
    {
      tree args = TREE_VALUE (ddats);
      if (!args)
	continue;

      tree alloc = TREE_VALUE (args);
      if (!alloc)
	continue;

      if (alloc == DECL_NAME (dealloc_decl))
	realloc_kind = alloc_kind_t::user;

      if (DECL_P (alloc))
	{
	  gcc_checking_assert (fndecl_built_in_p (alloc, BUILT_IN_NORMAL));

	  switch (DECL_FUNCTION_CODE (alloc))
	    {
	    case BUILT_IN_ALIGNED_ALLOC:
	    case BUILT_IN_CALLOC:
	    case BUILT_IN_GOMP_ALLOC:
	    case BUILT_IN_MALLOC:
	    case BUILT_IN_REALLOC:
	    case BUILT_IN_STRDUP:
	    case BUILT_IN_STRNDUP:
	      realloc_dealloc_kind = alloc_kind_t::builtin;
	      break;
	    default:
	      break;
	    }

	  if (!alloc_builtin)
	    continue;

	  if (DECL_FUNCTION_CODE (alloc) != DECL_FUNCTION_CODE (alloc_decl))
	    continue;

	  return true;
	}

      if (alloc == DECL_NAME (alloc_decl))
	return true;
    }

  if (realloc_kind == alloc_kind_t::none)
    return false;

  hash_set<tree> common_deallocs;
  /* Special handling for deallocators.  Iterate over both the allocator's
     and the reallocator's associated deallocator functions looking for
     the first one in common.  If one is found, the de/reallocator is
     a match for the allocator even though the latter isn't directly
     associated with the former.  This simplifies declarations in system
     headers.
     With AMATS set to the Allocator's Malloc ATtributes,
     and  RMATS set to Reallocator's Malloc ATtributes...  */
  for (tree amats = DECL_ATTRIBUTES (alloc_decl),
	 rmats = DECL_ATTRIBUTES (dealloc_decl);
       (amats = lookup_attribute ("malloc", amats))
	 || (rmats = lookup_attribute ("malloc", rmats));
       amats = amats ? TREE_CHAIN (amats) : NULL_TREE,
	 rmats = rmats ? TREE_CHAIN (rmats) : NULL_TREE)
    {
      if (tree args = amats ? TREE_VALUE (amats) : NULL_TREE)
	if (tree adealloc = TREE_VALUE (args))
	  {
	    if (DECL_P (adealloc)
		&& fndecl_built_in_p (adealloc, BUILT_IN_NORMAL))
	      {
		built_in_function fncode = DECL_FUNCTION_CODE (adealloc);
		if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC)
		  {
		    if (realloc_kind == alloc_kind_t::builtin)
		      return true;
		    alloc_dealloc_kind = alloc_kind_t::builtin;
		  }
		continue;
	      }

	    common_deallocs.add (adealloc);
	  }

      if (tree args = rmats ? TREE_VALUE (rmats) : NULL_TREE)
	if (tree ddealloc = TREE_VALUE (args))
	  {
	    if (DECL_P (ddealloc)
		&& fndecl_built_in_p (ddealloc, BUILT_IN_NORMAL))
	      {
		built_in_function fncode = DECL_FUNCTION_CODE (ddealloc);
		if (fncode == BUILT_IN_FREE || fncode == BUILT_IN_REALLOC)
		  {
		    if (alloc_dealloc_kind == alloc_kind_t::builtin)
		      return true;
		    realloc_dealloc_kind = alloc_kind_t::builtin;
		  }
		continue;
	      }

	    if (common_deallocs.add (ddealloc))
	      return true;
	  }
    }

  /* Succeed only if ALLOC_DECL and the reallocator DEALLOC_DECL share
     a built-in deallocator.  */
  return  (alloc_dealloc_kind == alloc_kind_t::builtin
	   && realloc_dealloc_kind == alloc_kind_t::builtin);
}

/* Return true if DEALLOC_DECL is a function suitable to deallocate
   objectes allocated by the ALLOC call.  */

static bool
matching_alloc_calls_p (gimple *alloc, tree dealloc_decl)
{
  tree alloc_decl = gimple_call_fndecl (alloc);
  if (!alloc_decl)
    return true;

  return matching_alloc_calls_p (alloc_decl, dealloc_decl);
}

/* Diagnose a call EXP to deallocate a pointer referenced by AREF if it
   includes a nonzero offset.  Such a pointer cannot refer to the beginning
   of an allocated object.  A negative offset may refer to it only if
   the target pointer is unknown.  */

static bool
warn_dealloc_offset (location_t loc, gimple *call, const access_ref &aref)
{
  if (aref.deref || aref.offrng[0] <= 0 || aref.offrng[1] <= 0)
    return false;

  tree dealloc_decl = gimple_call_fndecl (call);
  if (!dealloc_decl)
    return false;

  if (DECL_IS_OPERATOR_DELETE_P (dealloc_decl)
      && !DECL_IS_REPLACEABLE_OPERATOR (dealloc_decl))
    {
      /* A call to a user-defined operator delete with a pointer plus offset
	 may be valid if it's returned from an unknown function (i.e., one
	 that's not operator new).  */
      if (TREE_CODE (aref.ref) == SSA_NAME)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (aref.ref);
	  if (is_gimple_call (def_stmt))
	    {
	      tree alloc_decl = gimple_call_fndecl (def_stmt);
	      if (!alloc_decl || !DECL_IS_OPERATOR_NEW_P (alloc_decl))
		return false;
	    }
	}
    }

  char offstr[80];
  offstr[0] = '\0';
  if (wi::fits_shwi_p (aref.offrng[0]))
    {
      if (aref.offrng[0] == aref.offrng[1]
	  || !wi::fits_shwi_p (aref.offrng[1]))
	sprintf (offstr, " %lli",
		 (long long)aref.offrng[0].to_shwi ());
      else
	sprintf (offstr, " [%lli, %lli]",
		 (long long)aref.offrng[0].to_shwi (),
		 (long long)aref.offrng[1].to_shwi ());
    }

  if (!warning_at (loc, OPT_Wfree_nonheap_object,
		   "%qD called on pointer %qE with nonzero offset%s",
		   dealloc_decl, aref.ref, offstr))
    return false;

  if (DECL_P (aref.ref))
    inform (get_location (aref.ref), "declared here");
  else if (TREE_CODE (aref.ref) == SSA_NAME)
    {
      gimple *def_stmt = SSA_NAME_DEF_STMT (aref.ref);
      if (is_gimple_call (def_stmt))
	{
	  location_t def_loc = get_location (def_stmt);
	  tree alloc_decl = gimple_call_fndecl (def_stmt);
	  if (alloc_decl)
	    inform (def_loc,
		    "returned from %qD", alloc_decl);
	  else if (tree alloc_fntype = gimple_call_fntype (def_stmt))
	    inform (def_loc,
		    "returned from %qT", alloc_fntype);
	  else
	    inform (def_loc,  "obtained here");
	}
    }

  return true;
}

namespace {

const pass_data pass_data_waccess = {
  GIMPLE_PASS,
  "waccess",
  OPTGROUP_NONE,
  TV_NONE,
  PROP_cfg, /* properties_required  */
  0,	    /* properties_provided  */
  0,	    /* properties_destroyed  */
  0,	    /* properties_start */
  0,	    /* properties_finish */
};

/* Pass to detect invalid accesses.  */
class pass_waccess : public gimple_opt_pass
{
 public:
  pass_waccess (gcc::context *);

  ~pass_waccess ();

  opt_pass *clone ();

  virtual bool gate (function *);

  void set_pass_param (unsigned, bool);

  virtual unsigned int execute (function *);

private:
  /* Not copyable or assignable.  */
  pass_waccess (pass_waccess &) = delete;
  void operator= (pass_waccess &) = delete;

  /* Check a call to an atomic built-in function.  */
  bool check_atomic_builtin (gcall *);

  /* Check a call to a built-in function.  */
  bool check_builtin (gcall *);

  /* Check a call to an ordinary function for invalid accesses.  */
  bool check_call_access (gcall *);

  /* Check a non-call statement.  */
  void check_stmt (gimple *);

  /* Check statements in a basic block.  */
  void check_block (basic_block);

  /* Check a call to a function.  */
  void check_call (gcall *);

  /* Check a call to the named built-in function.  */
  void check_alloca (gcall *);
  void check_alloc_size_call (gcall *);
  void check_strcat (gcall *);
  void check_strncat (gcall *);
  void check_stxcpy (gcall *);
  void check_stxncpy (gcall *);
  void check_strncmp (gcall *);
  void check_memop_access (gimple *, tree, tree, tree);
  void check_read_access (gimple *, tree, tree = NULL_TREE, int = 1);

  void maybe_check_dealloc_call (gcall *);
  void maybe_check_access_sizes (rdwr_map *, tree, tree, gimple *);
  bool maybe_warn_memmodel (gimple *, tree, tree, const unsigned char *);
  void check_atomic_memmodel (gimple *, tree, tree, const unsigned char *);

  /* Check for uses of indeterminate pointers.  */
  void check_pointer_uses (gimple *, tree, tree = NULL_TREE, bool = false);

  /* Return the argument that a call returns.  */
  tree gimple_call_return_arg (gcall *);
  tree gimple_call_return_arg_ref (gcall *);

  /* Check a call for uses of a dangling pointer arguments.  */
  void check_call_dangling (gcall *);

  /* Check uses of a dangling pointer or those derived from it.  */
  void check_dangling_uses (tree, tree, bool = false, bool = false);
  void check_dangling_uses ();
  void check_dangling_stores ();
  void check_dangling_stores (basic_block, hash_set<tree> &, auto_bitmap &);

  void warn_invalid_pointer (tree, gimple *, gimple *, tree, bool, bool = false);

  /* Return true if use follows an invalidating statement.  */
  bool use_after_inval_p (gimple *, gimple *, bool = false);

  /* A pointer_query object and its cache to store information about
     pointers and their targets in.  */
  pointer_query m_ptr_qry;
  pointer_query::cache_type m_var_cache;
  /* Mapping from DECLs and their clobber statements in the function.  */
  hash_map<tree, gimple *> m_clobbers;
  /* A bit is set for each basic block whose statements have been assigned
     valid UIDs.  */
  bitmap m_bb_uids_set;
  /* The current function.  */
  function *m_func;
  /* True to run checks for uses of dangling pointers.  */
  bool m_check_dangling_p;
  /* True to run checks early on in the optimization pipeline.  */
  bool m_early_checks_p;
};

/* Construct the pass.  */

pass_waccess::pass_waccess (gcc::context *ctxt)
  : gimple_opt_pass (pass_data_waccess, ctxt),
    m_ptr_qry (NULL, &m_var_cache),
    m_var_cache (),
    m_clobbers (),
    m_bb_uids_set (),
    m_func (),
    m_check_dangling_p (),
    m_early_checks_p ()
{
}

/* Return a copy of the pass with RUN_NUMBER one greater than THIS.  */

opt_pass*
pass_waccess::clone ()
{
  return new pass_waccess (m_ctxt);
}

/* Release pointer_query cache.  */

pass_waccess::~pass_waccess ()
{
  m_ptr_qry.flush_cache ();
}

void
pass_waccess::set_pass_param (unsigned int n, bool early)
{
  gcc_assert (n == 0);

  m_early_checks_p = early;
}

/* Return true when any checks performed by the pass are enabled.  */

bool
pass_waccess::gate (function *)
{
  return (warn_free_nonheap_object
	  || warn_mismatched_alloc
	  || warn_mismatched_new_delete);
}

/* Initialize ALLOC_OBJECT_SIZE_LIMIT based on the -Walloc-size-larger-than=
   setting if the option is specified, or to the maximum object size if it
   is not.  Return the initialized value.  */

static tree
alloc_max_size (void)
{
  HOST_WIDE_INT limit = warn_alloc_size_limit;
  if (limit == HOST_WIDE_INT_MAX)
    limit = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));

  return build_int_cst (size_type_node, limit);
}

/* Diagnose a call EXP to function FN decorated with attribute alloc_size
   whose argument numbers given by IDX with values given by ARGS exceed
   the maximum object size or cause an unsigned oveflow (wrapping) when
   multiplied.  FN is null when EXP is a call via a function pointer.
   When ARGS[0] is null the function does nothing.  ARGS[1] may be null
   for functions like malloc, and non-null for those like calloc that
   are decorated with a two-argument attribute alloc_size.  */

void
maybe_warn_alloc_args_overflow (gimple *stmt, const tree args[2],
				const int idx[2])
{
  /* The range each of the (up to) two arguments is known to be in.  */
  tree argrange[2][2] = { { NULL_TREE, NULL_TREE }, { NULL_TREE, NULL_TREE } };

  /* Maximum object size set by -Walloc-size-larger-than= or SIZE_MAX / 2.  */
  tree maxobjsize = alloc_max_size ();

  location_t loc = get_location (stmt);

  tree fn = gimple_call_fndecl (stmt);
  tree fntype = fn ? TREE_TYPE (fn) : gimple_call_fntype (stmt);
  bool warned = false;

  /* Validate each argument individually.  */
  for (unsigned i = 0; i != 2 && args[i]; ++i)
    {
      if (TREE_CODE (args[i]) == INTEGER_CST)
	{
	  argrange[i][0] = args[i];
	  argrange[i][1] = args[i];

	  if (tree_int_cst_lt (args[i], integer_zero_node))
	    {
	      warned = warning_at (loc, OPT_Walloc_size_larger_than_,
				   "argument %i value %qE is negative",
				   idx[i] + 1, args[i]);
	    }
	  else if (integer_zerop (args[i]))
	    {
	      /* Avoid issuing -Walloc-zero for allocation functions other
		 than __builtin_alloca that are declared with attribute
		 returns_nonnull because there's no portability risk.  This
		 avoids warning for such calls to libiberty's xmalloc and
		 friends.
		 Also avoid issuing the warning for calls to function named
		 "alloca".  */
	      if (fn && fndecl_built_in_p (fn, BUILT_IN_ALLOCA)
		  ? IDENTIFIER_LENGTH (DECL_NAME (fn)) != 6
		  : !lookup_attribute ("returns_nonnull",
				       TYPE_ATTRIBUTES (fntype)))
		warned = warning_at (loc, OPT_Walloc_zero,
				     "argument %i value is zero",
				     idx[i] + 1);
	    }
	  else if (tree_int_cst_lt (maxobjsize, args[i]))
	    {
	      /* G++ emits calls to ::operator new[](SIZE_MAX) in C++98
		 mode and with -fno-exceptions as a way to indicate array
		 size overflow.  There's no good way to detect C++98 here
		 so avoid diagnosing these calls for all C++ modes.  */
	      if (i == 0
		  && fn
		  && !args[1]
		  && lang_GNU_CXX ()
		  && DECL_IS_OPERATOR_NEW_P (fn)
		  && integer_all_onesp (args[i]))
		continue;

	      warned = warning_at (loc, OPT_Walloc_size_larger_than_,
				   "argument %i value %qE exceeds "
				   "maximum object size %E",
				   idx[i] + 1, args[i], maxobjsize);
	    }
	}
      else if (TREE_CODE (args[i]) == SSA_NAME
	       && get_size_range (args[i], argrange[i]))
	{
	  /* Verify that the argument's range is not negative (including
	     upper bound of zero).  */
	  if (tree_int_cst_lt (argrange[i][0], integer_zero_node)
	      && tree_int_cst_le (argrange[i][1], integer_zero_node))
	    {
	      warned = warning_at (loc, OPT_Walloc_size_larger_than_,
				   "argument %i range [%E, %E] is negative",
				   idx[i] + 1,
				   argrange[i][0], argrange[i][1]);
	    }
	  else if (tree_int_cst_lt (maxobjsize, argrange[i][0]))
	    {
	      warned = warning_at (loc, OPT_Walloc_size_larger_than_,
				   "argument %i range [%E, %E] exceeds "
				   "maximum object size %E",
				   idx[i] + 1,
				   argrange[i][0], argrange[i][1],
				   maxobjsize);
	    }
	}
    }

  if (!argrange[0][0])
    return;

  /* For a two-argument alloc_size, validate the product of the two
     arguments if both of their values or ranges are known.  */
  if (!warned && tree_fits_uhwi_p (argrange[0][0])
      && argrange[1][0] && tree_fits_uhwi_p (argrange[1][0])
      && !integer_onep (argrange[0][0])
      && !integer_onep (argrange[1][0]))
    {
      /* Check for overflow in the product of a function decorated with
	 attribute alloc_size (X, Y).  */
      unsigned szprec = TYPE_PRECISION (size_type_node);
      wide_int x = wi::to_wide (argrange[0][0], szprec);
      wide_int y = wi::to_wide (argrange[1][0], szprec);

      wi::overflow_type vflow;
      wide_int prod = wi::umul (x, y, &vflow);

      if (vflow)
	warned = warning_at (loc, OPT_Walloc_size_larger_than_,
			     "product %<%E * %E%> of arguments %i and %i "
			     "exceeds %<SIZE_MAX%>",
			     argrange[0][0], argrange[1][0],
			     idx[0] + 1, idx[1] + 1);
      else if (wi::ltu_p (wi::to_wide (maxobjsize, szprec), prod))
	warned = warning_at (loc, OPT_Walloc_size_larger_than_,
			     "product %<%E * %E%> of arguments %i and %i "
			     "exceeds maximum object size %E",
			     argrange[0][0], argrange[1][0],
			     idx[0] + 1, idx[1] + 1,
			     maxobjsize);

      if (warned)
	{
	  /* Print the full range of each of the two arguments to make
	     it clear when it is, in fact, in a range and not constant.  */
	  if (argrange[0][0] != argrange [0][1])
	    inform (loc, "argument %i in the range [%E, %E]",
		    idx[0] + 1, argrange[0][0], argrange[0][1]);
	  if (argrange[1][0] != argrange [1][1])
	    inform (loc, "argument %i in the range [%E, %E]",
		    idx[1] + 1, argrange[1][0], argrange[1][1]);
	}
    }

  if (warned && fn)
    {
      location_t fnloc = DECL_SOURCE_LOCATION (fn);

      if (DECL_IS_UNDECLARED_BUILTIN (fn))
	inform (loc,
		"in a call to built-in allocation function %qD", fn);
      else
	inform (fnloc,
		"in a call to allocation function %qD declared here", fn);
    }
}

/* Check a call to an alloca function for an excessive size.  */

void
pass_waccess::check_alloca (gcall *stmt)
{
  if (m_early_checks_p)
    return;

  if ((warn_vla_limit >= HOST_WIDE_INT_MAX
       && warn_alloc_size_limit < warn_vla_limit)
      || (warn_alloca_limit >= HOST_WIDE_INT_MAX
	  && warn_alloc_size_limit < warn_alloca_limit))
    {
      /* -Walloca-larger-than and -Wvla-larger-than settings of less
	 than  HWI_MAX override the more general -Walloc-size-larger-than
	 so unless either of the former options is smaller than the last
	 one (wchich would imply that the call was already checked), check
	 the alloca arguments for overflow.  */
      const tree alloc_args[] = { call_arg (stmt, 0), NULL_TREE };
      const int idx[] = { 0, -1 };
      maybe_warn_alloc_args_overflow (stmt, alloc_args, idx);
    }
}

/* Check a call to an allocation function for an excessive size.  */

void
pass_waccess::check_alloc_size_call (gcall *stmt)
{
  if (m_early_checks_p)
    return;

  if (gimple_call_num_args (stmt) < 1)
    /* Avoid invalid calls to functions without a prototype.  */
    return;

  tree fndecl = gimple_call_fndecl (stmt);
  if (fndecl && gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    {
      /* Alloca is handled separately.  */
      switch (DECL_FUNCTION_CODE (fndecl))
	{
	case BUILT_IN_ALLOCA:
	case BUILT_IN_ALLOCA_WITH_ALIGN:
	case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
	  return;
	default:
	  break;
	}
    }

  tree fntype = gimple_call_fntype (stmt);
  tree fntypeattrs = TYPE_ATTRIBUTES (fntype);

  tree alloc_size = lookup_attribute ("alloc_size", fntypeattrs);
  if (!alloc_size)
    return;

  /* Extract attribute alloc_size from the type of the called expression
     (which could be a function or a function pointer) and if set, store
     the indices of the corresponding arguments in ALLOC_IDX, and then
     the actual argument(s) at those indices in ALLOC_ARGS.  */
  int idx[2] = { -1, -1 };
  tree alloc_args[] = { NULL_TREE, NULL_TREE };
  unsigned nargs = gimple_call_num_args (stmt);

  tree args = TREE_VALUE (alloc_size);
  idx[0] = TREE_INT_CST_LOW (TREE_VALUE (args)) - 1;
  /* Avoid invalid calls to functions without a prototype.  */
  if ((unsigned) idx[0] >= nargs)
    return;
  alloc_args[0] = call_arg (stmt, idx[0]);
  if (TREE_CHAIN (args))
    {
      idx[1] = TREE_INT_CST_LOW (TREE_VALUE (TREE_CHAIN (args))) - 1;
      if ((unsigned) idx[1] >= nargs)
	return;
      alloc_args[1] = call_arg (stmt, idx[1]);
    }

  maybe_warn_alloc_args_overflow (stmt, alloc_args, idx);
}

/* Check a call STMT to strcat() for overflow and warn if it does.  */

void
pass_waccess::check_strcat (gcall *stmt)
{
  if (m_early_checks_p)
    return;

  if (!warn_stringop_overflow && !warn_stringop_overread)
    return;

  tree dest = call_arg (stmt, 0);
  tree src = call_arg (stmt, 1);

  /* There is no way here to determine the length of the string in
     the destination to which the SRC string is being appended so
     just diagnose cases when the souce string is longer than
     the destination object.  */
  access_data data (m_ptr_qry.rvals, stmt, access_read_write, NULL_TREE,
		    true, NULL_TREE, true);
  const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
  compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
  tree destsize = compute_objsize (dest, stmt, ost, &data.dst, &m_ptr_qry);

  check_access (stmt, /*dstwrite=*/NULL_TREE, /*maxread=*/NULL_TREE,
		src, destsize, data.mode, &data, m_ptr_qry.rvals);
}

/* Check a call STMT to strcat() for overflow and warn if it does.  */

void
pass_waccess::check_strncat (gcall *stmt)
{
  if (m_early_checks_p)
    return;

  if (!warn_stringop_overflow && !warn_stringop_overread)
    return;

  tree dest = call_arg (stmt, 0);
  tree src = call_arg (stmt, 1);
  /* The upper bound on the number of bytes to write.  */
  tree maxread = call_arg (stmt, 2);

  /* Detect unterminated source (only).  */
  if (!check_nul_terminated_array (stmt, src, maxread))
    return;

  /* The length of the source sequence.  */
  tree slen = c_strlen (src, 1);

  /* Try to determine the range of lengths that the source expression
     refers to.  Since the lengths are only used for warning and not
     for code generation disable strict mode below.  */
  tree maxlen = slen;
  if (!maxlen)
    {
      c_strlen_data lendata = { };
      get_range_strlen (src, &lendata, /* eltsize = */ 1);
      maxlen = lendata.maxbound;
    }

  access_data data (m_ptr_qry.rvals, stmt, access_read_write);
  /* Try to verify that the destination is big enough for the shortest
     string.  First try to determine the size of the destination object
     into which the source is being copied.  */
  const int ost = warn_stringop_overflow - 1;
  tree destsize = compute_objsize (dest, stmt, ost, &data.dst, &m_ptr_qry);

  /* Add one for the terminating nul.  */
  tree srclen = (maxlen
		 ? fold_build2 (PLUS_EXPR, size_type_node, maxlen,
				size_one_node)
		 : NULL_TREE);

  /* The strncat function copies at most MAXREAD bytes and always appends
     the terminating nul so the specified upper bound should never be equal
     to (or greater than) the size of the destination.  */
  if (tree_fits_uhwi_p (maxread) && tree_fits_uhwi_p (destsize)
      && tree_int_cst_equal (destsize, maxread))
    {
      location_t loc = get_location (stmt);
      warning_at (loc, OPT_Wstringop_overflow_,
		  "%qD specified bound %E equals destination size",
		  get_callee_fndecl (stmt), maxread);

      return;
    }

  if (!srclen
      || (maxread && tree_fits_uhwi_p (maxread)
	  && tree_fits_uhwi_p (srclen)
	  && tree_int_cst_lt (maxread, srclen)))
    srclen = maxread;

  check_access (stmt, /*dstwrite=*/NULL_TREE, maxread, srclen,
		destsize, data.mode, &data, m_ptr_qry.rvals);
}

/* Check a call STMT to stpcpy() or strcpy() for overflow and warn
   if it does.  */

void
pass_waccess::check_stxcpy (gcall *stmt)
{
  if (m_early_checks_p)
    return;

  tree dst = call_arg (stmt, 0);
  tree src = call_arg (stmt, 1);

  tree size;
  bool exact;
  if (tree nonstr = unterminated_array (src, &size, &exact))
    {
      /* NONSTR refers to the non-nul terminated constant array.  */
      warn_string_no_nul (get_location (stmt), stmt, NULL, src, nonstr,
			  size, exact);
      return;
    }

  if (warn_stringop_overflow)
    {
      access_data data (m_ptr_qry.rvals, stmt, access_read_write, NULL_TREE,
			true, NULL_TREE, true);
      const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
      compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
      tree dstsize = compute_objsize (dst, stmt, ost, &data.dst, &m_ptr_qry);
      check_access (stmt, /*dstwrite=*/ NULL_TREE,
		    /*maxread=*/ NULL_TREE, /*srcstr=*/ src,
		    dstsize, data.mode, &data, m_ptr_qry.rvals);
    }

  /* Check to see if the argument was declared attribute nonstring
     and if so, issue a warning since at this point it's not known
     to be nul-terminated.  */
  tree fndecl = get_callee_fndecl (stmt);
  maybe_warn_nonstring_arg (fndecl, stmt);
}

/* Check a call STMT to stpncpy() or strncpy() for overflow and warn
   if it does.  */

void
pass_waccess::check_stxncpy (gcall *stmt)
{
  if (m_early_checks_p || !warn_stringop_overflow)
    return;

  tree dst = call_arg (stmt, 0);
  tree src = call_arg (stmt, 1);
  /* The number of bytes to write (not the maximum).  */
  tree len = call_arg (stmt, 2);

  access_data data (m_ptr_qry.rvals, stmt, access_read_write, len, true, len,
		    true);
  const int ost = warn_stringop_overflow ? warn_stringop_overflow - 1 : 1;
  compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
  tree dstsize = compute_objsize (dst, stmt, ost, &data.dst, &m_ptr_qry);

  check_access (stmt, /*dstwrite=*/len, /*maxread=*/len, src, dstsize,
		data.mode, &data, m_ptr_qry.rvals);
}

/* Check a call STMT to stpncpy() or strncpy() for overflow and warn
   if it does.  */

void
pass_waccess::check_strncmp (gcall *stmt)
{
  if (m_early_checks_p || !warn_stringop_overread)
    return;

  tree arg1 = call_arg (stmt, 0);
  tree arg2 = call_arg (stmt, 1);
  tree bound = call_arg (stmt, 2);

  /* First check each argument separately, considering the bound.  */
  if (!check_nul_terminated_array (stmt, arg1, bound)
      || !check_nul_terminated_array (stmt, arg2, bound))
    return;

  /* A strncmp read from each argument is constrained not just by
     the bound but also by the length of the shorter string.  Specifying
     a bound that's larger than the size of either array makes no sense
     and is likely a bug.  When the length of neither of the two strings
     is known but the sizes of both of the arrays they are stored in is,
     issue a warning if the bound is larger than than the size of
     the larger of the two arrays.  */

  c_strlen_data lendata1{ }, lendata2{ };
  tree len1 = c_strlen (arg1, 1, &lendata1);
  tree len2 = c_strlen (arg2, 1, &lendata2);

  if (len1 && TREE_CODE (len1) != INTEGER_CST)
    len1 = NULL_TREE;
  if (len2 && TREE_CODE (len2) != INTEGER_CST)
    len2 = NULL_TREE;

  if (len1 && len2)
    /* If the length of both arguments was computed they must both be
       nul-terminated and no further checking is necessary regardless
       of the bound.  */
    return;

  /* Check to see if the argument was declared with attribute nonstring
     and if so, issue a warning since at this point it's not known to be
     nul-terminated.  */
  if (maybe_warn_nonstring_arg (get_callee_fndecl (stmt), stmt))
    return;

  access_data adata1 (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE, false,
		      bound, true);
  access_data adata2 (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE, false,
		      bound, true);

  /* Determine the range of the bound first and bail if it fails; it's
     cheaper than computing the size of the objects.  */
  tree bndrng[2] = { NULL_TREE, NULL_TREE };
  get_size_range (m_ptr_qry.rvals, bound, stmt, bndrng, adata1.src_bndrng);
  if (!bndrng[0] || integer_zerop (bndrng[0]))
    return;

  if (len1 && tree_int_cst_lt (len1, bndrng[0]))
    bndrng[0] = len1;
  if (len2 && tree_int_cst_lt (len2, bndrng[0]))
    bndrng[0] = len2;

  /* compute_objsize almost never fails (and ultimately should never
     fail).  Don't bother to handle the rare case when it does.  */
  if (!compute_objsize (arg1, stmt, 1, &adata1.src, &m_ptr_qry)
      || !compute_objsize (arg2, stmt, 1, &adata2.src, &m_ptr_qry))
    return;

  /* Compute the size of the remaining space in each array after
     subtracting any offset into it.  */
  offset_int rem1 = adata1.src.size_remaining ();
  offset_int rem2 = adata2.src.size_remaining ();

  /* Cap REM1 and REM2 at the other if the other's argument is known
     to be an unterminated array, either because there's no space
     left in it after adding its offset or because it's constant and
     has no nul.  */
  if (rem1 == 0 || (rem1 < rem2 && lendata1.decl))
    rem2 = rem1;
  else if (rem2 == 0 || (rem2 < rem1 && lendata2.decl))
    rem1 = rem2;

  /* Point PAD at the array to reference in the note if a warning
     is issued.  */
  access_data *pad = len1 ? &adata2 : &adata1;
  offset_int maxrem = wi::max (rem1, rem2, UNSIGNED);
  if (lendata1.decl || lendata2.decl
      || maxrem < wi::to_offset (bndrng[0]))
    {
      /* Warn when either argument isn't nul-terminated or the maximum
	 remaining space in the two arrays is less than the bound.  */
      tree func = get_callee_fndecl (stmt);
      location_t loc = gimple_location (stmt);
      maybe_warn_for_bound (OPT_Wstringop_overread, loc, stmt, func,
			    bndrng, wide_int_to_tree (sizetype, maxrem),
			    pad);
    }
}

/* Determine and check the sizes of the source and the destination
   of calls to __builtin_{bzero,memcpy,mempcpy,memset} calls.  STMT is
   the call statement, DEST is the destination argument, SRC is the source
   argument or null, and SIZE is the number of bytes being accessed.  Use
   Object Size type-0 regardless of the OPT_Wstringop_overflow_ setting.
   Return true on success (no overflow or invalid sizes), false otherwise.  */

void
pass_waccess::check_memop_access (gimple *stmt, tree dest, tree src, tree size)
{
  if (m_early_checks_p)
    return;

  /* For functions like memset and memcpy that operate on raw memory
     try to determine the size of the largest source and destination
     object using type-0 Object Size regardless of the object size
     type specified by the option.  */
  access_data data (m_ptr_qry.rvals, stmt, access_read_write);
  tree srcsize
    = src ? compute_objsize (src, stmt, 0, &data.src, &m_ptr_qry) : NULL_TREE;
  tree dstsize = compute_objsize (dest, stmt, 0, &data.dst, &m_ptr_qry);

  check_access (stmt, size, /*maxread=*/NULL_TREE, srcsize, dstsize,
		data.mode, &data, m_ptr_qry.rvals);
}

/* A convenience wrapper for check_access to check access by a read-only
   function like puts or strcmp.  */

void
pass_waccess::check_read_access (gimple *stmt, tree src,
				 tree bound /* = NULL_TREE */,
				 int ost /* = 1 */)
{
  if (m_early_checks_p || !warn_stringop_overread)
    return;

  if (bound && !useless_type_conversion_p (size_type_node, TREE_TYPE (bound)))
    bound = fold_convert (size_type_node, bound);

  tree fndecl = get_callee_fndecl (stmt);
  maybe_warn_nonstring_arg (fndecl, stmt);

  access_data data (m_ptr_qry.rvals, stmt, access_read_only, NULL_TREE,
		   false, bound, true);
  compute_objsize (src, stmt, ost, &data.src, &m_ptr_qry);
  check_access (stmt, /*dstwrite=*/ NULL_TREE, /*maxread=*/ bound,
		/*srcstr=*/ src, /*dstsize=*/ NULL_TREE, data.mode,
		&data, m_ptr_qry.rvals);
}

/* Return true if memory model ORD is constant in the context of STMT and
   set *CSTVAL to the constant value.  Otherwise return false.  Warn for
   invalid ORD.  */

bool
memmodel_to_uhwi (tree ord, gimple *stmt, unsigned HOST_WIDE_INT *cstval)
{
  unsigned HOST_WIDE_INT val;

  if (TREE_CODE (ord) == INTEGER_CST)
    {
      if (!tree_fits_uhwi_p (ord))
	return false;
      val = tree_to_uhwi (ord);
    }
  else
    {
      /* Use the range query to determine constant values in the absence
	 of constant proppagation (such as at -O0).  */
      value_range rng;
      if (!get_range_query (cfun)->range_of_expr (rng, ord, stmt)
	  || !rng.constant_p ()
	  || !rng.singleton_p (&ord))
	return false;

      wide_int lob = rng.lower_bound ();
      if (!wi::fits_uhwi_p (lob))
	return false;

      val = lob.to_shwi ();
    }

  if (targetm.memmodel_check)
    /* This might warn for an invalid VAL but return a conservatively
       valid result.  */
    val = targetm.memmodel_check (val);
  else if (val & ~MEMMODEL_MASK)
    {
      tree fndecl = gimple_call_fndecl (stmt);
      location_t loc = gimple_location (stmt);
      loc = expansion_point_location_if_in_system_header (loc);

      warning_at (loc, OPT_Winvalid_memory_model,
		  "unknown architecture specifier in memory model "
		  "%wi for %qD", val, fndecl);
      return false;
    }

  *cstval = val;

  return true;
}

/* Valid memory model for each set of atomic built-in functions.  */

struct memmodel_pair
{
  memmodel modval;
  const char* modname;

#define MEMMODEL_PAIR(val, str)			\
  { MEMMODEL_ ## val, "memory_order_" str }
};

/* Valid memory models in the order of increasing strength.  */

static const memmodel_pair memory_models[] =
  { MEMMODEL_PAIR (RELAXED, "relaxed"),
    MEMMODEL_PAIR (SEQ_CST, "seq_cst"),
    MEMMODEL_PAIR (ACQUIRE, "acquire"),
    MEMMODEL_PAIR (CONSUME, "consume"),
    MEMMODEL_PAIR (RELEASE, "release"),
    MEMMODEL_PAIR (ACQ_REL, "acq_rel")
  };

/* Return the name of the memory model VAL.  */

static const char*
memmodel_name (unsigned HOST_WIDE_INT val)
{
  val = memmodel_base (val);

  for (unsigned i = 0; i != sizeof memory_models / sizeof *memory_models; ++i)
    {
      if (val == memory_models[i].modval)
	return memory_models[i].modname;
    }
  return NULL;
}

/* Indices of valid MEMORY_MODELS above for corresponding atomic operations.  */
static const unsigned char load_models[] = { 0, 1, 2, 3, UCHAR_MAX };
static const unsigned char store_models[] = { 0, 1, 4, UCHAR_MAX };
static const unsigned char xchg_models[] = { 0, 1, 3, 4, 5, UCHAR_MAX };
static const unsigned char flag_clr_models[] = { 0, 1, 4, UCHAR_MAX };
static const unsigned char all_models[] = { 0, 1, 2, 3, 4, 5, UCHAR_MAX };

/* Check the success memory model argument ORD_SUCS to the call STMT to
   an atomic function and warn if it's invalid.  If nonnull, also check
   the failure memory model ORD_FAIL and warn if it's invalid.  Return
   true if a warning has been issued.  */

bool
pass_waccess::maybe_warn_memmodel (gimple *stmt, tree ord_sucs,
				   tree ord_fail, const unsigned char *valid)
{
  unsigned HOST_WIDE_INT sucs, fail = 0;
  if (!memmodel_to_uhwi (ord_sucs, stmt, &sucs)
      || (ord_fail && !memmodel_to_uhwi (ord_fail, stmt, &fail)))
    return false;

  bool is_valid = false;
  if (valid)
    for (unsigned i = 0; valid[i] != UCHAR_MAX; ++i)
      {
	memmodel model = memory_models[valid[i]].modval;
	if (memmodel_base (sucs) == model)
	  {
	    is_valid = true;
	    break;
	  }
      }
  else
    is_valid = true;

  tree fndecl = gimple_call_fndecl (stmt);
  location_t loc = gimple_location (stmt);
  loc = expansion_point_location_if_in_system_header (loc);

  if (!is_valid)
    {
      bool warned = false;
      if (const char *modname = memmodel_name (sucs))
	warned = warning_at (loc, OPT_Winvalid_memory_model,
			     "invalid memory model %qs for %qD",
			     modname, fndecl);
      else
	warned = warning_at (loc, OPT_Winvalid_memory_model,
			     "invalid memory model %wi for %qD",
			     sucs, fndecl);

      if (!warned)
	return false;

      /* Print a note with the valid memory models.  */
      pretty_printer pp;
      pp_show_color (&pp) = pp_show_color (global_dc->printer);
      for (unsigned i = 0; valid[i] != UCHAR_MAX; ++i)
	{
	  const char *modname = memory_models[valid[i]].modname;
	  pp_printf (&pp, "%s%qs", i ? ", " : "", modname);
	}

      inform (loc, "valid models are %s", pp_formatted_text (&pp));
      return true;
    }

  if (!ord_fail)
    return false;

  if (fail == MEMMODEL_RELEASE || fail == MEMMODEL_ACQ_REL)
    if (const char *failname = memmodel_name (fail))
      {
	/* If both memory model arguments are valid but their combination
	   is not, use their names in the warning.  */
	if (!warning_at (loc, OPT_Winvalid_memory_model,
			 "invalid failure memory model %qs for %qD",
			 failname, fndecl))
	  return false;

	inform (loc,
		"valid failure models are %qs, %qs, %qs, %qs",
		"memory_order_relaxed", "memory_order_seq_cst",
		"memory_order_acquire", "memory_order_consume");
	return true;
      }

  if (memmodel_base (fail) <= memmodel_base (sucs))
    return false;

  if (const char *sucsname = memmodel_name (sucs))
    if (const char *failname = memmodel_name (fail))
      {
	/* If both memory model arguments are valid but their combination
	   is not, use their names in the warning.  */
	if (!warning_at (loc, OPT_Winvalid_memory_model,
			 "failure memory model %qs cannot be stronger "
			 "than success memory model %qs for %qD",
			 failname, sucsname, fndecl))
	  return false;

	/* Print a note with the valid failure memory models which are
	   those with a value less than or equal to the success mode.  */
	char buf[120];
	*buf = '\0';
	for (unsigned i = 0;
	     memory_models[i].modval <= memmodel_base (sucs); ++i)
	  {
	    if (*buf)
	      strcat (buf, ", ");

	    const char *modname = memory_models[valid[i]].modname;
	    sprintf (buf + strlen (buf), "'%s'", modname);
	  }

	inform (loc, "valid models are %s", buf);
	return true;
      }

  /* If either memory model argument value is invalid use the numerical
     value of both in the message.  */
  return warning_at (loc, OPT_Winvalid_memory_model,
		     "failure memory model %wi cannot be stronger "
		     "than success memory model %wi for %qD",
		     fail, sucs, fndecl);
}

/* Wrapper for the above.  */

void
pass_waccess::check_atomic_memmodel (gimple *stmt, tree ord_sucs,
				     tree ord_fail, const unsigned char *valid)
{
  if (warning_suppressed_p (stmt, OPT_Winvalid_memory_model))
    return;

  if (!maybe_warn_memmodel (stmt, ord_sucs, ord_fail, valid))
    return;

  suppress_warning (stmt, OPT_Winvalid_memory_model);
}

/* Check a call STMT to an atomic or sync built-in.  */

bool
pass_waccess::check_atomic_builtin (gcall *stmt)
{
  tree callee = gimple_call_fndecl (stmt);
  if (!callee)
    return false;

  /* The size in bytes of the access by the function, and the number
     of the second argument to check (if any).  */
  unsigned bytes = 0, arg2 = UINT_MAX;
  unsigned sucs_arg = UINT_MAX, fail_arg = UINT_MAX;
  /* Points to the array of indices of valid memory models.  */
  const unsigned char *pvalid_models = NULL;

  switch (DECL_FUNCTION_CODE (callee))
    {
#define BUILTIN_ACCESS_SIZE_FNSPEC(N)			\
      BUILT_IN_SYNC_FETCH_AND_ADD_ ## N:		\
    case BUILT_IN_SYNC_FETCH_AND_SUB_ ## N:		\
    case BUILT_IN_SYNC_FETCH_AND_OR_ ## N:		\
    case BUILT_IN_SYNC_FETCH_AND_AND_ ## N:		\
    case BUILT_IN_SYNC_FETCH_AND_XOR_ ## N:		\
    case BUILT_IN_SYNC_FETCH_AND_NAND_ ## N:		\
    case BUILT_IN_SYNC_ADD_AND_FETCH_ ## N:		\
    case BUILT_IN_SYNC_SUB_AND_FETCH_ ## N:		\
    case BUILT_IN_SYNC_OR_AND_FETCH_ ## N:		\
    case BUILT_IN_SYNC_AND_AND_FETCH_ ## N:		\
    case BUILT_IN_SYNC_XOR_AND_FETCH_ ## N:		\
    case BUILT_IN_SYNC_NAND_AND_FETCH_ ## N:		\
    case BUILT_IN_SYNC_LOCK_TEST_AND_SET_ ## N:		\
    case BUILT_IN_SYNC_BOOL_COMPARE_AND_SWAP_ ## N:	\
    case BUILT_IN_SYNC_VAL_COMPARE_AND_SWAP_ ## N:	\
    case BUILT_IN_SYNC_LOCK_RELEASE_ ## N:		\
      bytes = N;					\
      break;						\
    case BUILT_IN_ATOMIC_LOAD_ ## N:			\
      pvalid_models = load_models;			\
      sucs_arg = 1;					\
      /* FALLTHROUGH */					\
    case BUILT_IN_ATOMIC_STORE_ ## N:			\
      if (!pvalid_models)				\
	pvalid_models = store_models;			\
      /* FALLTHROUGH */					\
    case BUILT_IN_ATOMIC_ADD_FETCH_ ## N:		\
    case BUILT_IN_ATOMIC_SUB_FETCH_ ## N:		\
    case BUILT_IN_ATOMIC_AND_FETCH_ ## N:		\
    case BUILT_IN_ATOMIC_NAND_FETCH_ ## N:		\
    case BUILT_IN_ATOMIC_XOR_FETCH_ ## N:		\
    case BUILT_IN_ATOMIC_OR_FETCH_ ## N:		\
    case BUILT_IN_ATOMIC_FETCH_ADD_ ## N:		\
    case BUILT_IN_ATOMIC_FETCH_SUB_ ## N:		\
    case BUILT_IN_ATOMIC_FETCH_AND_ ## N:		\
    case BUILT_IN_ATOMIC_FETCH_NAND_ ## N:		\
    case BUILT_IN_ATOMIC_FETCH_OR_ ## N:		\
    case BUILT_IN_ATOMIC_FETCH_XOR_ ## N:		\
	bytes = N;					\
	if (sucs_arg == UINT_MAX)			\
	  sucs_arg = 2;					\
	if (!pvalid_models)				\
	  pvalid_models = all_models;			\
	break;						\
    case BUILT_IN_ATOMIC_EXCHANGE_ ## N:		\
	bytes = N;					\
	sucs_arg = 3;					\
	pvalid_models = xchg_models;			\
	break;						\
    case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_ ## N:	\
	bytes = N;					\
	sucs_arg = 4;					\
	fail_arg = 5;					\
	pvalid_models = all_models;			\
	arg2 = 1

    case BUILTIN_ACCESS_SIZE_FNSPEC (1);
      break;
    case BUILTIN_ACCESS_SIZE_FNSPEC (2);
      break;
    case BUILTIN_ACCESS_SIZE_FNSPEC (4);
      break;
    case BUILTIN_ACCESS_SIZE_FNSPEC (8);
      break;
    case BUILTIN_ACCESS_SIZE_FNSPEC (16);
      break;

    case BUILT_IN_ATOMIC_CLEAR:
      sucs_arg = 1;
      pvalid_models = flag_clr_models;
      break;

    default:
      return false;
    }

  unsigned nargs = gimple_call_num_args (stmt);
  if (sucs_arg < nargs)
    {
      tree ord_sucs = gimple_call_arg (stmt, sucs_arg);
      tree ord_fail = NULL_TREE;
      if (fail_arg < nargs)
	ord_fail = gimple_call_arg (stmt, fail_arg);
      check_atomic_memmodel (stmt, ord_sucs, ord_fail, pvalid_models);
    }

  if (!bytes)
    return true;

  tree size = build_int_cstu (sizetype, bytes);
  tree dst = gimple_call_arg (stmt, 0);
  check_memop_access (stmt, dst, NULL_TREE, size);

  if (arg2 != UINT_MAX)
    {
      tree dst = gimple_call_arg (stmt, arg2);
      check_memop_access (stmt, dst, NULL_TREE, size);
    }

  return true;
}

/* Check call STMT to a built-in function for invalid accesses.  Return
   true if a call has been handled.  */

bool
pass_waccess::check_builtin (gcall *stmt)
{
  tree callee = gimple_call_fndecl (stmt);
  if (!callee)
    return false;

  switch (DECL_FUNCTION_CODE (callee))
    {
    case BUILT_IN_ALLOCA:
    case BUILT_IN_ALLOCA_WITH_ALIGN:
    case BUILT_IN_ALLOCA_WITH_ALIGN_AND_MAX:
      check_alloca (stmt);
      return true;

    case BUILT_IN_EXECL:
    case BUILT_IN_EXECLE:
    case BUILT_IN_EXECLP:
    case BUILT_IN_EXECV:
    case BUILT_IN_EXECVE:
    case BUILT_IN_EXECVP:
      check_read_access (stmt, call_arg (stmt, 0));
      return true;

    case BUILT_IN_FREE:
    case BUILT_IN_REALLOC:
      if (!m_early_checks_p)
	{
	  tree arg = call_arg (stmt, 0);
	  if (TREE_CODE (arg) == SSA_NAME)
	    check_pointer_uses (stmt, arg);
	}
      return true;

    case BUILT_IN_GETTEXT:
    case BUILT_IN_PUTS:
    case BUILT_IN_PUTS_UNLOCKED:
    case BUILT_IN_STRDUP:
      check_read_access (stmt, call_arg (stmt, 0));
      return true;

    case BUILT_IN_INDEX:
    case BUILT_IN_RINDEX:
    case BUILT_IN_STRCHR:
    case BUILT_IN_STRRCHR:
    case BUILT_IN_STRLEN:
      check_read_access (stmt, call_arg (stmt, 0));
      return true;

    case BUILT_IN_FPUTS:
    case BUILT_IN_FPUTS_UNLOCKED:
      check_read_access (stmt, call_arg (stmt, 0));
      return true;

    case BUILT_IN_STRNDUP:
    case BUILT_IN_STRNLEN:
      {
	tree str = call_arg (stmt, 0);
	tree len = call_arg (stmt, 1);
	check_read_access (stmt, str, len);
	return true;
      }

    case BUILT_IN_STRCAT:
      check_strcat (stmt);
      return true;

    case BUILT_IN_STRNCAT:
      check_strncat (stmt);
      return true;

    case BUILT_IN_STPCPY:
    case BUILT_IN_STRCPY:
      check_stxcpy (stmt);
      return true;

    case BUILT_IN_STPNCPY:
    case BUILT_IN_STRNCPY:
      check_stxncpy (stmt);
      return true;

    case BUILT_IN_STRCASECMP:
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRPBRK:
    case BUILT_IN_STRSPN:
    case BUILT_IN_STRCSPN:
    case BUILT_IN_STRSTR:
      check_read_access (stmt, call_arg (stmt, 0));
      check_read_access (stmt, call_arg (stmt, 1));
      return true;

    case BUILT_IN_STRNCASECMP:
    case BUILT_IN_STRNCMP:
      check_strncmp (stmt);
      return true;

    case BUILT_IN_MEMCMP:
      {
	tree a1 = call_arg (stmt, 0);
	tree a2 = call_arg (stmt, 1);
	tree len = call_arg (stmt, 2);
	check_read_access (stmt, a1, len, 0);
	check_read_access (stmt, a2, len, 0);
	return true;
      }

    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMMOVE:
      {
	tree dst = call_arg (stmt, 0);
	tree src = call_arg (stmt, 1);
	tree len = call_arg (stmt, 2);
	check_memop_access (stmt, dst, src, len);
	return true;
      }

    case BUILT_IN_MEMCHR:
      {
	tree src = call_arg (stmt, 0);
	tree len = call_arg (stmt, 2);
	check_read_access (stmt, src, len, 0);
	return true;
      }

    case BUILT_IN_MEMSET:
      {
	tree dst = call_arg (stmt, 0);
	tree len = call_arg (stmt, 2);
	check_memop_access (stmt, dst, NULL_TREE, len);
	return true;
      }
	
    default:
      if (check_atomic_builtin (stmt))
	return true;
      break;
    }

  return false;
}

/* Returns the type of the argument ARGNO to function with type FNTYPE
   or null when the typoe cannot be determined or no such argument exists.  */

static tree
fntype_argno_type (tree fntype, unsigned argno)
{
  if (!prototype_p (fntype))
    return NULL_TREE;

  tree argtype;
  function_args_iterator it;
  FOREACH_FUNCTION_ARGS (fntype, argtype, it)
    if (argno-- == 0)
      return argtype;

  return NULL_TREE;
}

/* Helper to append the "human readable" attribute access specification
   described by ACCESS to the array ATTRSTR with size STRSIZE.  Used in
   diagnostics.  */

static inline void
append_attrname (const std::pair<int, attr_access> &access,
		 char *attrstr, size_t strsize)
{
  if (access.second.internal_p)
    return;

  tree str = access.second.to_external_string ();
  gcc_assert (strsize >= (size_t) TREE_STRING_LENGTH (str));
  strcpy (attrstr, TREE_STRING_POINTER (str));
}

/* Iterate over attribute access read-only, read-write, and write-only
   arguments and diagnose past-the-end accesses and related problems
   in the function call EXP.  */

void
pass_waccess::maybe_check_access_sizes (rdwr_map *rwm, tree fndecl, tree fntype,
					gimple *stmt)
{
  auto_diagnostic_group adg;

  /* Set if a warning has been issued for any argument (used to decide
     whether to emit an informational note at the end).  */
  opt_code opt_warned = no_warning;

  /* A string describing the attributes that the warnings issued by this
     function apply to.  Used to print one informational note per function
     call, rather than one per warning.  That reduces clutter.  */
  char attrstr[80];
  attrstr[0] = 0;

  for (rdwr_map::iterator it = rwm->begin (); it != rwm->end (); ++it)
    {
      std::pair<int, attr_access> access = *it;

      /* Get the function call arguments corresponding to the attribute's
	 positional arguments.  When both arguments have been specified
	 there will be two entries in *RWM, one for each.  They are
	 cross-referenced by their respective argument numbers in
	 ACCESS.PTRARG and ACCESS.SIZARG.  */
      const int ptridx = access.second.ptrarg;
      const int sizidx = access.second.sizarg;

      gcc_assert (ptridx != -1);
      gcc_assert (access.first == ptridx || access.first == sizidx);

      /* The pointer is set to null for the entry corresponding to
	 the size argument.  Skip it.  It's handled when the entry
	 corresponding to the pointer argument comes up.  */
      if (!access.second.ptr)
	continue;

      tree ptrtype = fntype_argno_type (fntype, ptridx);
      if (!ptrtype)
	/* A function with a prototype was redeclared without one and
	   the protype has been lost.  See pr102759.  Avoid dealing
	   with this pathological case.  */
	return;

      tree argtype = TREE_TYPE (ptrtype);

      /* The size of the access by the call in elements.  */
      tree access_nelts;
      if (sizidx == -1)
	{
	  /* If only the pointer attribute operand was specified and
	     not size, set SIZE to the greater of MINSIZE or size of
	     one element of the pointed to type to detect smaller
	     objects (null pointers are diagnosed in this case only
	     if the pointer is also declared with attribute nonnull.  */
	  if (access.second.minsize
	      && access.second.minsize != HOST_WIDE_INT_M1U)
	    access_nelts = build_int_cstu (sizetype, access.second.minsize);
	  else if (VOID_TYPE_P (argtype) && access.second.mode == access_none)
	    /* Treat access mode none on a void* argument as expecting
	       as little as zero bytes.  */
	    access_nelts = size_zero_node;
	  else
	    access_nelts = size_one_node;
	}
      else
	access_nelts = rwm->get (sizidx)->size;

      /* Format the value or range to avoid an explosion of messages.  */
      char sizstr[80];
      tree sizrng[2] = { size_zero_node, build_all_ones_cst (sizetype) };
      if (get_size_range (m_ptr_qry.rvals, access_nelts, stmt, sizrng, 1))
	{
	  char *s0 = print_generic_expr_to_str (sizrng[0]);
	  if (tree_int_cst_equal (sizrng[0], sizrng[1]))
	    {
	      gcc_checking_assert (strlen (s0) < sizeof sizstr);
	      strcpy (sizstr, s0);
	    }
	  else
	    {
	      char *s1 = print_generic_expr_to_str (sizrng[1]);
	      gcc_checking_assert (strlen (s0) + strlen (s1)
				   < sizeof sizstr - 4);
	      sprintf (sizstr, "[%.37s, %.37s]", s0, s1);
	      free (s1);
	    }
	  free (s0);
	}
      else
	*sizstr = '\0';

      /* Set if a warning has been issued for the current argument.  */
      opt_code arg_warned = no_warning;
      location_t loc = get_location (stmt);
      tree ptr = access.second.ptr;
      if (*sizstr
	  && tree_int_cst_sgn (sizrng[0]) < 0
	  && tree_int_cst_sgn (sizrng[1]) < 0)
	{
	  /* Warn about negative sizes.  */
	  if (access.second.internal_p)
	    {
	      const std::string argtypestr
		= access.second.array_as_string (ptrtype);

	      if (warning_at (loc, OPT_Wstringop_overflow_,
			      "bound argument %i value %s is "
			      "negative for a variable length array "
			      "argument %i of type %s",
			      sizidx + 1, sizstr,
			      ptridx + 1, argtypestr.c_str ()))
		arg_warned = OPT_Wstringop_overflow_;
	    }
	  else if (warning_at (loc, OPT_Wstringop_overflow_,
			       "argument %i value %s is negative",
			       sizidx + 1, sizstr))
	    arg_warned = OPT_Wstringop_overflow_;

	  if (arg_warned != no_warning)
	    {
	      append_attrname (access, attrstr, sizeof attrstr);
	      /* Remember a warning has been issued and avoid warning
		 again below for the same attribute.  */
	      opt_warned = arg_warned;
	      continue;
	    }
	}

      /* The size of the access by the call in bytes.  */
      tree access_size = NULL_TREE;
      if (tree_int_cst_sgn (sizrng[0]) >= 0)
	{
	  if (COMPLETE_TYPE_P (argtype))
	    {
	      /* Multiply ACCESS_SIZE by the size of the type the pointer
		 argument points to.  If it's incomplete the size is used
		 as is.  */
	      if (tree argsize = TYPE_SIZE_UNIT (argtype))
		if (TREE_CODE (argsize) == INTEGER_CST)
		  {
		    const int prec = TYPE_PRECISION (sizetype);
		    wide_int minsize = wi::to_wide (sizrng[0], prec);
		    minsize *= wi::to_wide (argsize, prec);
		    access_size = wide_int_to_tree (sizetype, minsize);
		  }
	    }
	  else
	    access_size = access_nelts;
	}

      if (integer_zerop (ptr))
	{
	  if (sizidx >= 0 && tree_int_cst_sgn (sizrng[0]) > 0)
	    {
	      /* Warn about null pointers with positive sizes.  This is
		 different from also declaring the pointer argument with
		 attribute nonnull when the function accepts null pointers
		 only when the corresponding size is zero.  */
	      if (access.second.internal_p)
		{
		  const std::string argtypestr
		    = access.second.array_as_string (ptrtype);

		  if (warning_at (loc, OPT_Wnonnull,
				  "argument %i of variable length "
				  "array %s is null but "
				  "the corresponding bound argument "
				  "%i value is %s",
				  ptridx + 1, argtypestr.c_str (),
				  sizidx + 1, sizstr))
		    arg_warned = OPT_Wnonnull;
		}
	      else if (warning_at (loc, OPT_Wnonnull,
				   "argument %i is null but "
				   "the corresponding size argument "
				   "%i value is %s",
				   ptridx + 1, sizidx + 1, sizstr))
		arg_warned = OPT_Wnonnull;
	    }
	  else if (access_size && access.second.static_p)
	    {
	      /* Warn about null pointers for [static N] array arguments
		 but do not warn for ordinary (i.e., nonstatic) arrays.  */
	      if (warning_at (loc, OPT_Wnonnull,
			      "argument %i to %<%T[static %E]%> "
			      "is null where non-null expected",
			      ptridx + 1, argtype, access_size))
		arg_warned = OPT_Wnonnull;
	    }

	  if (arg_warned != no_warning)
	    {
	      append_attrname (access, attrstr, sizeof attrstr);
	      /* Remember a warning has been issued and avoid warning
		 again below for the same attribute.  */
	      opt_warned = OPT_Wnonnull;
	      continue;
	    }
	}

      access_data data (m_ptr_qry.rvals, stmt, access.second.mode,
			NULL_TREE, false, NULL_TREE, false);
      access_ref* const pobj = (access.second.mode == access_write_only
				? &data.dst : &data.src);
      tree objsize = compute_objsize (ptr, stmt, 1, pobj, &m_ptr_qry);

      /* The size of the destination or source object.  */
      tree dstsize = NULL_TREE, srcsize = NULL_TREE;
      if (access.second.mode == access_read_only
	  || access.second.mode == access_none)
	{
	  /* For a read-only argument there is no destination.  For
	     no access, set the source as well and differentiate via
	     the access flag below.  */
	  srcsize = objsize;
	  if (access.second.mode == access_read_only
	      || access.second.mode == access_none)
	    {
	      /* For a read-only attribute there is no destination so
		 clear OBJSIZE.  This emits "reading N bytes" kind of
		 diagnostics instead of the "writing N bytes" kind,
		 unless MODE is none.  */
	      objsize = NULL_TREE;
	    }
	}
      else
	dstsize = objsize;

      /* Clear the no-warning bit in case it was set by check_access
	 in a prior iteration so that accesses via different arguments
	 are diagnosed.  */
      suppress_warning (stmt, OPT_Wstringop_overflow_, false);
      access_mode mode = data.mode;
      if (mode == access_deferred)
	mode = TYPE_READONLY (argtype) ? access_read_only : access_read_write;
      check_access (stmt, access_size, /*maxread=*/ NULL_TREE, srcsize,
		    dstsize, mode, &data, m_ptr_qry.rvals);

      if (warning_suppressed_p (stmt, OPT_Wstringop_overflow_))
	opt_warned = OPT_Wstringop_overflow_;
      if (opt_warned != no_warning)
	{
	  if (access.second.internal_p)
	    {
	      unsigned HOST_WIDE_INT nelts =
		access_nelts ? access.second.minsize : HOST_WIDE_INT_M1U;
	      tree arrtype = build_printable_array_type (argtype, nelts);
	      inform (loc, "referencing argument %u of type %qT",
		      ptridx + 1, arrtype);
	    }
	  else
	    /* If check_access issued a warning above, append the relevant
	       attribute to the string.  */
	    append_attrname (access, attrstr, sizeof attrstr);
	}
    }

  if (*attrstr)
    {
      if (fndecl)
	inform (get_location (fndecl),
		"in a call to function %qD declared with attribute %qs",
		fndecl, attrstr);
      else
	inform (get_location (stmt),
		"in a call with type %qT and attribute %qs",
		fntype, attrstr);
    }
  else if (opt_warned != no_warning)
    {
      if (fndecl)
	inform (get_location (fndecl),
		"in a call to function %qD", fndecl);
      else
	inform (get_location (stmt),
		"in a call with type %qT", fntype);
    }

  /* Set the bit in case if was cleared and not set above.  */
  if (opt_warned != no_warning)
    suppress_warning (stmt, opt_warned);
}

/* Check call STMT to an ordinary (non-built-in) function for invalid
   accesses.  Return true if a call has been handled.  */

bool
pass_waccess::check_call_access (gcall *stmt)
{
  tree fntype = gimple_call_fntype (stmt);
  if (!fntype)
    return false;

  tree fntypeattrs = TYPE_ATTRIBUTES (fntype);
  if (!fntypeattrs)
    return false;

  /* Map of attribute accewss specifications for function arguments.  */
  rdwr_map rdwr_idx;
  init_attr_rdwr_indices (&rdwr_idx, fntypeattrs);

  unsigned nargs = call_nargs (stmt);
  for (unsigned i = 0; i != nargs; ++i)
    {
      tree arg = call_arg (stmt, i);

      /* Save the actual argument that corresponds to the access attribute
	 operand for later processing.  */
      if (attr_access *access = rdwr_idx.get (i))
	{
	  if (POINTER_TYPE_P (TREE_TYPE (arg)))
	    {
	      access->ptr = arg;
	      // A nonnull ACCESS->SIZE contains VLA bounds.  */
	    }
	  else
	    {
	      access->size = arg;
	      gcc_assert (access->ptr == NULL_TREE);
	    }
	}
    }

  /* Check attribute access arguments.  */
  tree fndecl = gimple_call_fndecl (stmt);
  maybe_check_access_sizes (&rdwr_idx, fndecl, fntype, stmt);

  check_alloc_size_call (stmt);
  return true;
}

/* Check arguments in a call STMT for attribute nonstring.  */

static void
check_nonstring_args (gcall *stmt)
{
  tree fndecl = gimple_call_fndecl (stmt);

  /* Detect passing non-string arguments to functions expecting
     nul-terminated strings.  */
  maybe_warn_nonstring_arg (fndecl, stmt);
}

/* Issue a warning if a deallocation function such as free, realloc,
   or C++ operator delete is called with an argument not returned by
   a matching allocation function such as malloc or the corresponding
   form of C++ operatorn new.  */

void
pass_waccess::maybe_check_dealloc_call (gcall *call)
{
  tree fndecl = gimple_call_fndecl (call);
  if (!fndecl)
    return;

  unsigned argno = fndecl_dealloc_argno (fndecl);
  if ((unsigned) call_nargs (call) <= argno)
    return;

  tree ptr = gimple_call_arg (call, argno);
  if (integer_zerop (ptr))
    return;

  access_ref aref;
  if (!compute_objsize (ptr, call, 0, &aref, &m_ptr_qry))
    return;

  tree ref = aref.ref;
  if (integer_zerop (ref))
    return;

  tree dealloc_decl = fndecl;
  location_t loc = gimple_location (call);

  if (DECL_P (ref) || EXPR_P (ref))
    {
      /* Diagnose freeing a declared object.  */
      if (aref.ref_declared ()
	  && warning_at (loc, OPT_Wfree_nonheap_object,
			 "%qD called on unallocated object %qD",
			 dealloc_decl, ref))
	{
	  inform (get_location (ref), "declared here");
	  return;
	}

      /* Diagnose freeing a pointer that includes a positive offset.
	 Such a pointer cannot refer to the beginning of an allocated
	 object.  A negative offset may refer to it.  */
      if (aref.sizrng[0] != aref.sizrng[1]
	  && warn_dealloc_offset (loc, call, aref))
	return;
    }
  else if (CONSTANT_CLASS_P (ref))
    {
      if (warning_at (loc, OPT_Wfree_nonheap_object,
		      "%qD called on a pointer to an unallocated "
		      "object %qE", dealloc_decl, ref))
	{
	  if (TREE_CODE (ptr) == SSA_NAME)
	    {
	      gimple *def_stmt = SSA_NAME_DEF_STMT (ptr);
	      if (is_gimple_assign (def_stmt))
		{
		  location_t loc = gimple_location (def_stmt);
		  inform (loc, "assigned here");
		}
	    }
	  return;
	}
    }
  else if (TREE_CODE (ref) == SSA_NAME)
    {
      /* Also warn if the pointer argument refers to the result
	 of an allocation call like alloca or VLA.  */
      gimple *def_stmt = SSA_NAME_DEF_STMT (ref);
      if (!def_stmt)
	return;

      if (is_gimple_call (def_stmt))
	{
	  bool warned = false;
	  if (gimple_call_alloc_p (def_stmt))
	    {
	      if (matching_alloc_calls_p (def_stmt, dealloc_decl))
		{
		  if (warn_dealloc_offset (loc, call, aref))
		    return;
		}
	      else
		{
		  tree alloc_decl = gimple_call_fndecl (def_stmt);
		  const opt_code opt =
		    (DECL_IS_OPERATOR_NEW_P (alloc_decl)
		     || DECL_IS_OPERATOR_DELETE_P (dealloc_decl)
		     ? OPT_Wmismatched_new_delete
		     : OPT_Wmismatched_dealloc);
		  warned = warning_at (loc, opt,
				       "%qD called on pointer returned "
				       "from a mismatched allocation "
				       "function", dealloc_decl);
		}
	    }
	  else if (gimple_call_builtin_p (def_stmt, BUILT_IN_ALLOCA)
		   || gimple_call_builtin_p (def_stmt,
					     BUILT_IN_ALLOCA_WITH_ALIGN))
	    warned = warning_at (loc, OPT_Wfree_nonheap_object,
				 "%qD called on pointer to "
				 "an unallocated object",
				 dealloc_decl);
	  else if (warn_dealloc_offset (loc, call, aref))
	    return;

	  if (warned)
	    {
	      tree fndecl = gimple_call_fndecl (def_stmt);
	      inform (gimple_location (def_stmt),
		      "returned from %qD", fndecl);
	      return;
	    }
	}
      else if (gimple_nop_p (def_stmt))
	{
	  ref = SSA_NAME_VAR (ref);
	  /* Diagnose freeing a pointer that includes a positive offset.  */
	  if (TREE_CODE (ref) == PARM_DECL
	      && !aref.deref
	      && aref.sizrng[0] != aref.sizrng[1]
	      && aref.offrng[0] > 0 && aref.offrng[1] > 0
	      && warn_dealloc_offset (loc, call, aref))
	    return;
	}
    }
}

/* Return true if either USE_STMT's basic block (that of a pointer's use)
   is dominated by INVAL_STMT's (that of a pointer's invalidating statement,
   which is either a clobber or a deallocation call), or if they're in
   the same block, USE_STMT follows INVAL_STMT.  */

bool
pass_waccess::use_after_inval_p (gimple *inval_stmt, gimple *use_stmt,
				 bool last_block /* = false */)
{
  tree clobvar =
    gimple_clobber_p (inval_stmt) ? gimple_assign_lhs (inval_stmt) : NULL_TREE;

  basic_block inval_bb = gimple_bb (inval_stmt);
  basic_block use_bb = gimple_bb (use_stmt);

  if (!inval_bb || !use_bb)
    return false;

  if (inval_bb != use_bb)
    {
      if (dominated_by_p (CDI_DOMINATORS, use_bb, inval_bb))
	return true;

      if (!clobvar || !last_block)
	return false;

      /* Proceed only when looking for uses of dangling pointers.  */
      auto gsi = gsi_for_stmt (use_stmt);

      auto_bitmap visited;

      /* A use statement in the last basic block in a function or one that
	 falls through to it is after any other prior clobber of the used
	 variable unless it's followed by a clobber of the same variable. */
      basic_block bb = use_bb;
      while (bb != inval_bb
	     && single_succ_p (bb)
	     && !(single_succ_edge (bb)->flags & (EDGE_EH|EDGE_DFS_BACK)))
	{
	  if (!bitmap_set_bit (visited, bb->index))
	    /* Avoid cycles. */
	    return true;

	  for (; !gsi_end_p (gsi); gsi_next_nondebug (&gsi))
	    {
	      gimple *stmt = gsi_stmt (gsi);
	      if (gimple_clobber_p (stmt))
		{
		  if (clobvar == gimple_assign_lhs (stmt))
		    /* The use is followed by a clobber.  */
		    return false;
		}
	    }

	  bb = single_succ (bb);
	  gsi = gsi_start_bb (bb);
	}

      /* The use is one of a dangling pointer if a clobber of the variable
	 [the pointer points to] has not been found before the function exit
	 point.  */
      return bb == EXIT_BLOCK_PTR_FOR_FN (cfun);
    }

  if (bitmap_set_bit (m_bb_uids_set, inval_bb->index))
    /* The first time this basic block is visited assign increasing ids
       to consecutive statements in it.  Use the ids to determine which
       precedes which.  This avoids the linear traversal on subsequent
       visits to the same block.  */
    for (auto si = gsi_start_bb (inval_bb); !gsi_end_p (si);
	 gsi_next_nondebug (&si))
      {
	gimple *stmt = gsi_stmt (si);
	unsigned uid = inc_gimple_stmt_max_uid (m_func);
	gimple_set_uid (stmt, uid);
      }

  return gimple_uid (inval_stmt) < gimple_uid (use_stmt);
}

/* Issue a warning for the USE_STMT of pointer or reference REF rendered
   invalid by INVAL_STMT.  REF may be null when it's been optimized away.
   When nonnull, INVAL_STMT is the deallocation function that rendered
   the pointer or reference dangling.  Otherwise, VAR is the auto variable
   (including an unnamed temporary such as a compound literal) whose
   lifetime's rended it dangling.  MAYBE is true to issue the "maybe"
   kind of warning.  EQUALITY is true when the pointer is used in
   an equality expression.  */

void
pass_waccess::warn_invalid_pointer (tree ref, gimple *use_stmt,
				    gimple *inval_stmt, tree var,
				    bool maybe, bool equality /* = false */)
{
  /* Avoid printing the unhelpful "<unknown>" in the diagnostics.  */
  if (ref && TREE_CODE (ref) == SSA_NAME
      && (!SSA_NAME_VAR (ref) || DECL_ARTIFICIAL (SSA_NAME_VAR (ref))))
    ref = NULL_TREE;

  location_t use_loc = gimple_location (use_stmt);
  if (use_loc == UNKNOWN_LOCATION)
    {
      use_loc = m_func->function_end_locus;
      if (!ref)
	/* Avoid issuing a warning with no context other than
	   the function.  That would make it difficult to debug
	   in any but very simple cases.  */
	return;
    }

  if (is_gimple_call (inval_stmt))
    {
      if ((equality && warn_use_after_free < 3)
	  || (maybe && warn_use_after_free < 2)
	  || warning_suppressed_p (use_stmt, OPT_Wuse_after_free))
	return;

      const tree inval_decl = gimple_call_fndecl (inval_stmt);

      if ((ref && warning_at (use_loc, OPT_Wuse_after_free,
			      (maybe
			       ? G_("pointer %qE may be used after %qD")
			       : G_("pointer %qE used after %qD")),
			      ref, inval_decl))
	  || (!ref && warning_at (use_loc, OPT_Wuse_after_free,
			      (maybe
			       ? G_("pointer may be used after %qD")
			       : G_("pointer used after %qD")),
				  inval_decl)))
	{
	  location_t loc = gimple_location (inval_stmt);
	  inform (loc, "call to %qD here", inval_decl);
	  suppress_warning (use_stmt, OPT_Wuse_after_free);
	}
      return;
    }

  if ((maybe && warn_dangling_pointer < 2)
      || warning_suppressed_p (use_stmt, OPT_Wdangling_pointer_))
    return;

  if (DECL_NAME (var))
    {
      if ((ref
	   && warning_at (use_loc, OPT_Wdangling_pointer_,
			  (maybe
			   ? G_("dangling pointer %qE to %qD may be used")
			   : G_("using dangling pointer %qE to %qD")),
			  ref, var))
	  || (!ref
	      && warning_at (use_loc, OPT_Wdangling_pointer_,
			     (maybe
			      ? G_("dangling pointer to %qD may be used")
			      : G_("using a dangling pointer to %qD")),
			     var)))
	inform (DECL_SOURCE_LOCATION (var),
		"%qD declared here", var);
      suppress_warning (use_stmt, OPT_Wdangling_pointer_);
      return;
    }

  if ((ref
       && warning_at (use_loc, OPT_Wdangling_pointer_,
		      (maybe
		       ? G_("dangling pointer %qE to an unnamed temporary "
			    "may be used")
		       : G_("using dangling pointer %qE to an unnamed "
			    "temporary")),
		      ref))
      || (!ref
	  && warning_at (use_loc, OPT_Wdangling_pointer_,
			 (maybe
			  ? G_("dangling pointer to an unnamed temporary "
			       "may be used")
			  : G_("using a dangling pointer to an unnamed "
			       "temporary")))))
    {
      inform (DECL_SOURCE_LOCATION (var),
	      "unnamed temporary defined here");
      suppress_warning (use_stmt, OPT_Wdangling_pointer_);
    }
}

/* If STMT is a call to either the standard realloc or to a user-defined
   reallocation function returns its LHS and set *PTR to the reallocated
   pointer.  Otherwise return null.  */

static tree
get_realloc_lhs (gimple *stmt, tree *ptr)
{
  if (gimple_call_builtin_p (stmt, BUILT_IN_REALLOC))
    {
      *ptr = gimple_call_arg (stmt, 0);
      return gimple_call_lhs (stmt);
    }

  gcall *call = dyn_cast<gcall *>(stmt);
  if (!call)
    return NULL_TREE;

  tree fnattr = NULL_TREE;
  tree fndecl = gimple_call_fndecl (call);
  if (fndecl)
    fnattr = DECL_ATTRIBUTES (fndecl);
  else
    {
      tree fntype = gimple_call_fntype (stmt);
      if (!fntype)
	return NULL_TREE;
      fnattr = TYPE_ATTRIBUTES (fntype);
    }

  if (!fnattr)
    return NULL_TREE;

  for (tree ats = fnattr;  (ats = lookup_attribute ("*dealloc", ats));
       ats = TREE_CHAIN (ats))
    {
      tree args = TREE_VALUE (ats);
      if (!args)
	continue;

      tree alloc = TREE_VALUE (args);
      if (!alloc)
	continue;

      if (alloc == DECL_NAME (fndecl))
	{
	  unsigned argno = 0;
	  if (tree index = TREE_CHAIN (args))
	    argno = TREE_INT_CST_LOW (TREE_VALUE (index)) - 1;
	  *ptr = gimple_call_arg (stmt, argno);
	  return gimple_call_lhs (stmt);
	}
    }

  return NULL_TREE;
}

/* Warn if STMT is a call to a deallocation function that's not a match
   for the REALLOC_STMT call.  Return true if warned.  */

static bool
maybe_warn_mismatched_realloc (tree ptr, gimple *realloc_stmt, gimple *stmt)
{
  if (!is_gimple_call (stmt))
    return false;

  tree fndecl = gimple_call_fndecl (stmt);
  if (!fndecl)
    return false;

  unsigned argno = fndecl_dealloc_argno (fndecl);
  if (call_nargs (stmt) <= argno)
    return false;

  if (matching_alloc_calls_p (realloc_stmt, fndecl))
    return false;

  /* Avoid printing the unhelpful "<unknown>" in the diagnostics.  */
  if (ptr && TREE_CODE (ptr) == SSA_NAME
      && (!SSA_NAME_VAR (ptr) || DECL_ARTIFICIAL (SSA_NAME_VAR (ptr))))
    ptr = NULL_TREE;

  location_t loc = gimple_location (stmt);
  tree realloc_decl = gimple_call_fndecl (realloc_stmt);
  tree dealloc_decl = gimple_call_fndecl (stmt);
  if (ptr && !warning_at (loc, OPT_Wmismatched_dealloc,
			  "%qD called on pointer %qE passed to mismatched "
			  "allocation function %qD",
			  dealloc_decl, ptr, realloc_decl))
    return false;
  if (!ptr && !warning_at (loc, OPT_Wmismatched_dealloc,
			   "%qD called on a pointer passed to mismatched "
			   "reallocation function %qD",
			   dealloc_decl, realloc_decl))
    return false;

  inform (gimple_location (realloc_stmt),
	  "call to %qD", realloc_decl);
  return true;
}

/* Return true if P and Q point to the same object, and false if they
   either don't or their relationship cannot be determined.  */

static bool
pointers_related_p (gimple *stmt, tree p, tree q, pointer_query &qry)
{
  if (!ptr_derefs_may_alias_p (p, q))
    return false;

  /* TODO: Work harder to rule out relatedness.  */
  access_ref pref, qref;
  if (!qry.get_ref (p, stmt, &pref, 0)
      || !qry.get_ref (q, stmt, &qref, 0))
    /* GET_REF() only rarely fails.  When it does, it's likely because
       it involves a self-referential PHI.  Return a conservative result.  */
    return false;

  return pref.ref == qref.ref;
}

/* For a STMT either a call to a deallocation function or a clobber, warn
   for uses of the pointer PTR it was called with (including its copies
   or others derived from it by pointer arithmetic).  If STMT is a clobber,
   VAR is the decl of the clobbered variable.  When MAYBE is true use
   a "maybe" form of diagnostic.  */

void
pass_waccess::check_pointer_uses (gimple *stmt, tree ptr,
				  tree var /* = NULL_TREE */,
				  bool maybe /* = false */)
{
  gcc_assert (TREE_CODE (ptr) == SSA_NAME);

  const bool check_dangling = !is_gimple_call (stmt);
  basic_block stmt_bb = gimple_bb (stmt);

  /* If STMT is a reallocation function set to the reallocated pointer
     and the LHS of the call, respectively.  */
  tree realloc_ptr = NULL_TREE;
  tree realloc_lhs = get_realloc_lhs (stmt, &realloc_ptr);

  auto_bitmap visited;

  auto_vec<tree> pointers;
  pointers.safe_push (ptr);

  /* Starting with PTR, iterate over POINTERS added by the loop, and
     either warn for their uses in basic blocks dominated by the STMT
     or in statements that follow it in the same basic block, or add
     them to POINTERS if they point into the same object as PTR (i.e.,
     are obtained by pointer arithmetic on PTR).  */
  for (unsigned i = 0; i != pointers.length (); ++i)
    {
      tree ptr = pointers[i];
      if (TREE_CODE (ptr) == SSA_NAME
	  && !bitmap_set_bit (visited, SSA_NAME_VERSION (ptr)))
	/* Avoid revisiting the same pointer.  */
	continue;

      use_operand_p use_p;
      imm_use_iterator iter;
      FOR_EACH_IMM_USE_FAST (use_p, iter, ptr)
	{
	  gimple *use_stmt = USE_STMT (use_p);
	  if (use_stmt == stmt || is_gimple_debug (use_stmt))
	    continue;

	  if (realloc_lhs)
	    {
	      /* Check to see if USE_STMT is a mismatched deallocation
		 call for the pointer passed to realloc.  That's a bug
		 regardless of the pointer's value and so warn.  */
	      if (maybe_warn_mismatched_realloc (*use_p->use, stmt, use_stmt))
		continue;

	      /* Pointers passed to realloc that are used in basic blocks
		 where the realloc call is known to have failed are valid.
		 Ignore pointers that nothing is known about.  Those could
		 have escaped along with their nullness.  */
	      value_range vr;
	      if (m_ptr_qry.rvals->range_of_expr (vr, realloc_lhs, use_stmt))
		{
		  if (vr.zero_p ())
		    continue;

		  if (!pointers_related_p (stmt, ptr, realloc_ptr, m_ptr_qry))
		    continue;
		}
	    }

	  if (check_dangling
	      && gimple_code (use_stmt) == GIMPLE_RETURN)
	    /* Avoid interfering with -Wreturn-local-addr (which runs only
	       with optimization enabled so it won't diagnose cases that
	       would be caught here when optimization is disabled).  */
	    continue;

	  bool equality = false;
	  if (is_gimple_assign (use_stmt))
	    {
	      tree_code code = gimple_assign_rhs_code (use_stmt);
	      equality = code == EQ_EXPR || code == NE_EXPR;
	    }
	  else if (gcond *cond = dyn_cast<gcond *>(use_stmt))
	    {
	      tree_code code = gimple_cond_code (cond);
	      equality = code == EQ_EXPR || code == NE_EXPR;
	    }

	  /* Warn if USE_STMT is dominated by the deallocation STMT.
	     Otherwise, add the pointer to POINTERS so that the uses
	     of any other pointers derived from it can be checked.  */
	  if (use_after_inval_p (stmt, use_stmt, check_dangling))
	    {
	      if (gimple_code (use_stmt) == GIMPLE_PHI)
		{
		  tree lhs = gimple_phi_result (use_stmt);
		  if (TREE_CODE (lhs) == SSA_NAME)
		    {
		      pointers.safe_push (lhs);
		      continue;
		    }
		}

	      basic_block use_bb = gimple_bb (use_stmt);
	      bool this_maybe
		= (maybe
		   || !dominated_by_p (CDI_POST_DOMINATORS, use_bb, stmt_bb));
	      warn_invalid_pointer (*use_p->use, use_stmt, stmt, var,
				    this_maybe, equality);
	      continue;
	    }

	  if (is_gimple_assign (use_stmt))
	    {
	      tree lhs = gimple_assign_lhs (use_stmt);
	      if (TREE_CODE (lhs) == SSA_NAME)
		{
		  tree_code rhs_code = gimple_assign_rhs_code (use_stmt);
		  if (rhs_code == POINTER_PLUS_EXPR || rhs_code == SSA_NAME)
		    pointers.safe_push (lhs);
		}
	      continue;
	    }

	  if (gcall *call = dyn_cast <gcall *>(use_stmt))
	    {
	      if (gimple_call_return_arg (call))
		if (tree lhs = gimple_call_lhs (call))
		  if (TREE_CODE (lhs) == SSA_NAME)
		    pointers.safe_push (lhs);
	      continue;
	    }
	}
    }
}

/* Check call STMT for invalid accesses.  */

void
pass_waccess::check_call (gcall *stmt)
{
  if (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    check_builtin (stmt);

  /* .ASAN_MARK doesn't access any vars, only modifies shadow memory.  */
  if (gimple_call_internal_p (stmt)
      && gimple_call_internal_fn (stmt) == IFN_ASAN_MARK)
    return;

  if (!m_early_checks_p)
    if (tree callee = gimple_call_fndecl (stmt))
      {
	/* Check for uses of the pointer passed to either a standard
	   or a user-defined deallocation function.  */
	unsigned argno = fndecl_dealloc_argno (callee);
	if (argno < (unsigned) call_nargs (stmt))
	  {
	    tree arg = call_arg (stmt, argno);
	    if (TREE_CODE (arg) == SSA_NAME)
	      check_pointer_uses (stmt, arg);
	  }
      }

  check_call_access (stmt);
  check_call_dangling (stmt);

  if (m_early_checks_p)
    return;

  maybe_check_dealloc_call (stmt);
  check_nonstring_args (stmt);
}


/* Return true of X is a DECL with automatic storage duration.  */

static inline bool
is_auto_decl (tree x)
{
  return DECL_P (x) && !DECL_EXTERNAL (x) && !TREE_STATIC (x);
}

/* Check non-call STMT for invalid accesses.  */

void
pass_waccess::check_stmt (gimple *stmt)
{
  if (m_check_dangling_p && gimple_clobber_p (stmt))
    {
      /* Ignore clobber statemts in blocks with exceptional edges.  */
      basic_block bb = gimple_bb (stmt);
      edge e = EDGE_PRED (bb, 0);
      if (e->flags & EDGE_EH)
	return;

      tree var = gimple_assign_lhs (stmt);
      m_clobbers.put (var, stmt);
      return;
    }

  if (is_gimple_assign (stmt))
    {
      /* Clobbered unnamed temporaries such as compound literals can be
	 revived.  Check for an assignment to one and remove it from
	 M_CLOBBERS.  */
      tree lhs = gimple_assign_lhs (stmt);
      while (handled_component_p (lhs))
	lhs = TREE_OPERAND (lhs, 0);

      if (is_auto_decl (lhs))
	m_clobbers.remove (lhs);
      return;
    }

  if (greturn *ret = dyn_cast <greturn *> (stmt))
    {
      if (optimize && flag_isolate_erroneous_paths_dereference)
	/* Avoid interfering with -Wreturn-local-addr (which runs only
	   with optimization enabled).  */
	return;

      tree arg = gimple_return_retval (ret);
      if (!arg || TREE_CODE (arg) != ADDR_EXPR)
	return;

      arg = TREE_OPERAND (arg, 0);
      while (handled_component_p (arg))
	arg = TREE_OPERAND (arg, 0);

      if (!is_auto_decl (arg))
	return;

      gimple **pclobber = m_clobbers.get (arg);
      if (!pclobber)
	return;

      if (!use_after_inval_p (*pclobber, stmt))
	return;

      warn_invalid_pointer (NULL_TREE, stmt, *pclobber, arg, false);
    }
}

/* Check basic block BB for invalid accesses.  */

void
pass_waccess::check_block (basic_block bb)
{
  /* Iterate over statements, looking for function calls.  */
  for (auto si = gsi_start_bb (bb); !gsi_end_p (si);
       gsi_next_nondebug (&si))
    {
      gimple *stmt = gsi_stmt (si);
      if (gcall *call = dyn_cast <gcall *> (stmt))
	check_call (call);
      else
	check_stmt (stmt);
    }
}

/* Return the argument that the call STMT to a built-in function returns
   (including with an offset) or null if it doesn't.  */

tree
pass_waccess::gimple_call_return_arg (gcall *call)
{
  /* Check for attribute fn spec to see if the function returns one
     of its arguments.  */
  attr_fnspec fnspec = gimple_call_fnspec (call);
  unsigned int argno;
  if (!fnspec.returns_arg (&argno))
    {
      if (gimple_call_num_args (call) < 1)
	return NULL_TREE;

      if (!gimple_call_builtin_p (call, BUILT_IN_NORMAL))
	return NULL_TREE;

      tree fndecl = gimple_call_fndecl (call);
      switch (DECL_FUNCTION_CODE (fndecl))
	{
	case BUILT_IN_MEMPCPY:
	case BUILT_IN_MEMPCPY_CHK:
	case BUILT_IN_MEMCHR:
	case BUILT_IN_STRCHR:
	case BUILT_IN_STRRCHR:
	case BUILT_IN_STRSTR:
	case BUILT_IN_STPCPY:
	case BUILT_IN_STPCPY_CHK:
	case BUILT_IN_STPNCPY:
	case BUILT_IN_STPNCPY_CHK:
	  argno = 0;
	  break;

	default:
	  return NULL_TREE;
	}
    }

  if (gimple_call_num_args (call) <= argno)
    return NULL_TREE;

  return gimple_call_arg (call, argno);
}

/* Return the decl referenced by the argument that the call STMT to
   a built-in function returns (including with an offset) or null if
   it doesn't.  */

tree
pass_waccess::gimple_call_return_arg_ref (gcall *call)
{
  if (tree arg = gimple_call_return_arg (call))
    {
      access_ref aref;
      if (m_ptr_qry.get_ref (arg, call, &aref, 0)
	  && DECL_P (aref.ref))
	return aref.ref;
    }

  return NULL_TREE;
}

/* Check for and diagnose all uses of the dangling pointer VAR to the auto
   object DECL whose lifetime has ended.  OBJREF is true when VAR denotes
   an access to a DECL that may have been clobbered.  */

void
pass_waccess::check_dangling_uses (tree var, tree decl, bool maybe /* = false */,
				   bool objref /* = false */)
{
  if (!decl || !is_auto_decl (decl))
    return;

  gimple **pclob = m_clobbers.get (decl);
  if (!pclob)
    return;

  if (!objref)
    {
      check_pointer_uses (*pclob, var, decl, maybe);
      return;
    }

  gimple *use_stmt = SSA_NAME_DEF_STMT (var);
  if (!use_after_inval_p (*pclob, use_stmt, true))
    return;

  basic_block use_bb = gimple_bb (use_stmt);
  basic_block clob_bb = gimple_bb (*pclob);
  maybe = maybe || !dominated_by_p (CDI_POST_DOMINATORS, use_bb, clob_bb);
  warn_invalid_pointer (var, use_stmt, *pclob, decl, maybe, false);
}

/* Diagnose stores in BB and (recursively) its predecessors of the addresses
   of local variables into nonlocal pointers that are left dangling after
   the function returns.  BBS is a bitmap of basic blocks visited.  */

void
pass_waccess::check_dangling_stores (basic_block bb,
				     hash_set<tree> &stores,
				     auto_bitmap &bbs)
{
  if (!bitmap_set_bit (bbs, bb->index))
    /* Avoid cycles. */
    return;

  /* Iterate backwards over the statements looking for a store of
     the address of a local variable into a nonlocal pointer.  */
  for (auto gsi = gsi_last_nondebug_bb (bb); ; gsi_prev_nondebug (&gsi))
    {
      gimple *stmt = gsi_stmt (gsi);
      if (!stmt)
	break;

      if (is_gimple_call (stmt)
	  && !(gimple_call_flags (stmt) & (ECF_CONST | ECF_PURE)))
	/* Avoid looking before nonconst, nonpure calls since those might
	   use the escaped locals.  */
	return;

      if (!is_gimple_assign (stmt) || gimple_clobber_p (stmt))
	continue;

      access_ref lhs_ref;
      tree lhs = gimple_assign_lhs (stmt);
      if (!m_ptr_qry.get_ref (lhs, stmt, &lhs_ref, 0))
	continue;

      if (is_auto_decl (lhs_ref.ref))
	continue;

      if (DECL_P (lhs_ref.ref))
	{
	  if (!POINTER_TYPE_P (TREE_TYPE (lhs_ref.ref))
	      || lhs_ref.deref > 0)
	    continue;
	}
      else if (TREE_CODE (lhs_ref.ref) == SSA_NAME)
	{
	  /* Avoid looking at or before stores into unknown objects.  */
	  gimple *def_stmt = SSA_NAME_DEF_STMT (lhs_ref.ref);
	  if (!gimple_nop_p (def_stmt))
	    return;
	}
      else if (TREE_CODE (lhs_ref.ref) == MEM_REF)
	{
	  tree arg = TREE_OPERAND (lhs_ref.ref, 0);
	  if (TREE_CODE (arg) == SSA_NAME)
	    {
	      gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
	      if (!gimple_nop_p (def_stmt))
		return;
	    }
	}
      else
	continue;

      if (stores.add (lhs_ref.ref))
	continue;

      /* FIXME: Handle stores of alloca() and VLA.  */
      access_ref rhs_ref;
      tree rhs = gimple_assign_rhs1 (stmt);
      if (!m_ptr_qry.get_ref (rhs, stmt, &rhs_ref, 0)
	  || rhs_ref.deref != -1)
	continue;

      if (!is_auto_decl (rhs_ref.ref))
	continue;

      location_t loc = gimple_location (stmt);
      if (warning_at (loc, OPT_Wdangling_pointer_,
		      "storing the address of local variable %qD in %qE",
		      rhs_ref.ref, lhs))
	{
	  location_t loc = DECL_SOURCE_LOCATION (rhs_ref.ref);
	  inform (loc, "%qD declared here", rhs_ref.ref);

	  if (DECL_P (lhs_ref.ref))
	    loc = DECL_SOURCE_LOCATION (lhs_ref.ref);
	  else if (EXPR_HAS_LOCATION (lhs_ref.ref))
	    loc = EXPR_LOCATION (lhs_ref.ref);

	  if (loc != UNKNOWN_LOCATION)
	    inform (loc, "%qE declared here", lhs_ref.ref);
	}
    }

  edge e;
  edge_iterator ei;
  FOR_EACH_EDGE (e, ei, bb->preds)
    {
      basic_block pred = e->src;
      check_dangling_stores (pred, stores, bbs);
    }
}

/* Diagnose stores of the addresses of local variables into nonlocal
   pointers that are left dangling after the function returns.  */

void
pass_waccess::check_dangling_stores ()
{
  auto_bitmap bbs;
  hash_set<tree> stores;
  check_dangling_stores (EXIT_BLOCK_PTR_FOR_FN (m_func), stores, bbs);
}

/* Check for and diagnose uses of dangling pointers to auto objects
   whose lifetime has ended.  */

void
pass_waccess::check_dangling_uses ()
{
  tree var;
  unsigned i;
  FOR_EACH_SSA_NAME (i, var, m_func)
    {
      /* For each SSA_NAME pointer VAR find the DECL it points to.
	 If the DECL is a clobbered local variable, check to see
	 if any of VAR's uses (or those of other pointers derived
	 from VAR) happens after the clobber.  If so, warn.  */
      tree decl = NULL_TREE;

      gimple *def_stmt = SSA_NAME_DEF_STMT (var);
      if (is_gimple_assign (def_stmt))
	{
	  tree rhs = gimple_assign_rhs1 (def_stmt);
	  if (TREE_CODE (rhs) == ADDR_EXPR)
	    {
	      if (!POINTER_TYPE_P (TREE_TYPE (var)))
		continue;
	      decl = TREE_OPERAND (rhs, 0);
	    }
	  else
	    {
	      /* For other expressions, check the base DECL to see
		 if it's been clobbered, most likely as a result of
		 inlining a reference to it.  */
	      decl = get_base_address (rhs);
	      if (DECL_P (decl))
		check_dangling_uses (var, decl, false, true);
	      continue;
	    }
	}
      else if (POINTER_TYPE_P (TREE_TYPE (var)))
	{
	  if (gcall *call = dyn_cast<gcall *>(def_stmt))
	    decl = gimple_call_return_arg_ref (call);
	  else if (gphi *phi = dyn_cast <gphi *>(def_stmt))
	    {
	      unsigned nargs = gimple_phi_num_args (phi);
	      for (unsigned i = 0; i != nargs; ++i)
		{
		  access_ref aref;
		  tree arg = gimple_phi_arg_def (phi, i);
		  if (!m_ptr_qry.get_ref (arg, phi, &aref, 0)
		      || (aref.deref == 0
			  && POINTER_TYPE_P (TREE_TYPE (aref.ref))))
		    continue;
		  check_dangling_uses (var, aref.ref, true);
		}
	      continue;
	    }
	  else
	    continue;
	}

      check_dangling_uses (var, decl);
    }
}

/* Check CALL arguments for dangling pointers (those that have been
   clobbered) and warn if found.  */

void
pass_waccess::check_call_dangling (gcall *call)
{
  unsigned nargs = gimple_call_num_args (call);
  for (unsigned i = 0; i != nargs; ++i)
    {
      tree arg = gimple_call_arg (call, i);
      if (TREE_CODE (arg) != ADDR_EXPR)
	continue;

      arg = TREE_OPERAND (arg, 0);
      if (!DECL_P (arg))
	continue;

      gimple **pclobber = m_clobbers.get (arg);
      if (!pclobber)
	continue;

      if (!use_after_inval_p (*pclobber, call))
	continue;

      warn_invalid_pointer (NULL_TREE, call, *pclobber, arg, false);
    }
}

/* Check function FUN for invalid accesses.  */

unsigned
pass_waccess::execute (function *fun)
{
  calculate_dominance_info (CDI_DOMINATORS);
  calculate_dominance_info (CDI_POST_DOMINATORS);

  /* Create a new ranger instance and associate it with FUN.  */
  m_ptr_qry.rvals = enable_ranger (fun);
  m_func = fun;

  /* Check for dangling pointers in the earliest run of the pass.
     The latest point -Wdangling-pointer should run is just before
     loop unrolling which introduces uses after clobbers.  Most cases
     can be detected without optimization; cases where the address of
     the local variable is passed to and then returned from a user-
     defined function before its lifetime ends and the returned pointer
     becomes dangling depend on inlining.  */
  m_check_dangling_p = m_early_checks_p;

  auto_bitmap bb_uids_set (&bitmap_default_obstack);
  m_bb_uids_set = bb_uids_set;

  set_gimple_stmt_max_uid (m_func, 0);

  basic_block bb;
  FOR_EACH_BB_FN (bb, fun)
    check_block (bb);

  if (m_check_dangling_p)
    {
      check_dangling_uses ();
      check_dangling_stores ();
    }

  if (dump_file)
    m_ptr_qry.dump (dump_file, (dump_flags & TDF_DETAILS) != 0);

  m_ptr_qry.flush_cache ();

  /* Release the ranger instance and replace it with a global ranger.
     Also reset the pointer since calling disable_ranger() deletes it.  */
  disable_ranger (fun);
  m_ptr_qry.rvals = NULL;

  m_clobbers.empty ();
  m_bb_uids_set = NULL;

  free_dominance_info (CDI_POST_DOMINATORS);
  free_dominance_info (CDI_DOMINATORS);
  return 0;
}

}   // namespace

/* Return a new instance of the pass.  */

gimple_opt_pass *
make_pass_warn_access (gcc::context *ctxt)
{
  return new pass_waccess (ctxt);
}
