/* Pass to detect and issue warnings for violations of the restrict
   qualifier.
   Copyright (C) 2017-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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "pointer-query.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-iterator.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-cfg.h"
#include "tree-object-size.h"
#include "calls.h"
#include "cfgloop.h"
#include "intl.h"
#include "gimple-range.h"

namespace {

const pass_data pass_data_wrestrict = {
  GIMPLE_PASS,
  "wrestrict",
  OPTGROUP_NONE,
  TV_NONE,
  PROP_cfg, /* Properties_required.  */
  0,	    /* properties_provided.  */
  0,	    /* properties_destroyed.  */
  0,	    /* properties_start */
  0,	    /* properties_finish */
};

/* Pass to detect violations of strict aliasing requirements in calls
   to built-in string and raw memory functions.  */
class pass_wrestrict : public gimple_opt_pass
{
 public:
  pass_wrestrict (gcc::context *);

  bool gate (function *) final override;
  unsigned int execute (function *) final override;

  void check_call (gimple *);

  void check_block (basic_block);

  /* A pointer_query object to store information about pointers and
     their targets in.  */
  pointer_query m_ptr_qry;
};

pass_wrestrict::pass_wrestrict (gcc::context *ctxt)
  : gimple_opt_pass (pass_data_wrestrict, ctxt),
    m_ptr_qry ()
{ }

bool
pass_wrestrict::gate (function *fun ATTRIBUTE_UNUSED)
{
  return warn_array_bounds || warn_restrict || warn_stringop_overflow;
}

void
pass_wrestrict::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 (&si))
    {
      gimple *stmt = gsi_stmt (si);
      if (!is_gimple_call (stmt))
	continue;

      check_call (stmt);
    }
}

unsigned
pass_wrestrict::execute (function *fun)
{
  /* Create a new ranger instance and associate it with FUN.  */
  m_ptr_qry.rvals = enable_ranger (fun);

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

  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;

  return 0;
}

/* Description of a memory reference by a built-in function.  This
   is similar to ao_ref but made especially suitable for -Wrestrict
   and not for optimization.  */
class builtin_memref
{
public:
  /* The original pointer argument to the built-in function.  */
  tree ptr;
  /* The referenced subobject or NULL if not available, and the base
     object of the memory reference or NULL.  */
  tree ref;
  tree base;

  /* The size of the BASE object, PTRDIFF_MAX if indeterminate,
     and negative until (possibly lazily) initialized.  */
  offset_int basesize;
  /* Same for the subobject.  */
  offset_int refsize;

  /* The non-negative offset of the referenced subobject.  Used to avoid
     warnings for (apparently) possibly but not definitively overlapping
     accesses to member arrays.  Negative when unknown/invalid.  */
  offset_int refoff;

  /* The offset range relative to the base.  */
  offset_int offrange[2];
  /* The size range of the access to this reference.  */
  offset_int sizrange[2];

  /* Cached result of get_max_objsize().  */
  const offset_int maxobjsize;

  /* True for "bounded" string functions like strncat, and strncpy
     and their variants that specify either an exact or upper bound
     on the size of the accesses they perform.  For strncat both
     the source and destination references are bounded.  For strncpy
     only the destination reference is.  */
  bool strbounded_p;

  builtin_memref (pointer_query &, gimple *, tree, tree);

  tree offset_out_of_bounds (int, offset_int[3]) const;

private:
  /* Call statement to the built-in.  */
  gimple *stmt;

  pointer_query &m_ptr_qry;

  /* Ctor helper to set or extend OFFRANGE based on argument.  */
  void extend_offset_range (tree);

  /*  Ctor helper to determine BASE and OFFRANGE from argument.  */
  void set_base_and_offset (tree);
};

/* Description of a memory access by a raw memory or string built-in
   function involving a pair of builtin_memref's.  */
class builtin_access
{
 public:
  /* Destination and source memory reference.  */
  builtin_memref* const dstref;
  builtin_memref* const srcref;
  /* The size range of the access.  It's the greater of the accesses
     to the two references.  */
  HOST_WIDE_INT sizrange[2];

  /* The minimum and maximum offset of an overlap of the access
     (if it does, in fact, overlap), and the size of the overlap.  */
  HOST_WIDE_INT ovloff[2];
  HOST_WIDE_INT ovlsiz[2];

  /* True to consider valid only accesses to the smallest subobject
     and false for raw memory functions.  */
  bool strict () const
  {
    return (detect_overlap != &builtin_access::generic_overlap
	    && detect_overlap != &builtin_access::no_overlap);
  }

  builtin_access (pointer_query &, gimple *,
		  builtin_memref &, builtin_memref &);

  /* Entry point to determine overlap.  */
  bool overlap ();

  offset_int write_off (tree) const;

  void dump (FILE *) const;

 private:
  /* Implementation functions used to determine overlap.  */
  bool generic_overlap ();
  bool strcat_overlap ();
  bool strcpy_overlap ();

  bool no_overlap ()
  {
    return false;
  }

  offset_int overlap_size (const offset_int [2], const offset_int[2],
			   offset_int [2]);

 private:
  /* Temporaries used to compute the final result.  */
  offset_int dstoff[2];
  offset_int srcoff[2];
  offset_int dstsiz[2];
  offset_int srcsiz[2];

  /* Pointer to a member function to call to determine overlap.  */
  bool (builtin_access::*detect_overlap) ();
};

/* Initialize a memory reference representation from a pointer EXPR and
   a size SIZE in bytes.  If SIZE is NULL_TREE then the size is assumed
   to be unknown.  STMT is the statement in which expr appears in.  */

builtin_memref::builtin_memref (pointer_query &ptrqry, gimple *stmt, tree expr,
				tree size)
: ptr (expr),
  ref (),
  base (),
  basesize (-1),
  refsize (-1),
  refoff (HOST_WIDE_INT_MIN),
  offrange (),
  sizrange (),
  maxobjsize (tree_to_shwi (max_object_size ())),
  strbounded_p (),
  stmt (stmt),
  m_ptr_qry (ptrqry)
{
  /* Unfortunately, wide_int default ctor is a no-op so array members
     of the type must be set individually.  */
  offrange[0] = offrange[1] = 0;
  sizrange[0] = sizrange[1] = 0;

  if (!expr)
    return;

  /* Find the BASE object or pointer referenced by EXPR and set
     the offset range OFFRANGE in the process.  */
  set_base_and_offset (expr);

  if (size)
    {
      tree range[2];
      /* Determine the size range, allowing for the result to be [0, 0]
	 for SIZE in the anti-range ~[0, N] where N >= PTRDIFF_MAX.  */
      get_size_range (m_ptr_qry.rvals, size, stmt, range, SR_ALLOW_ZERO);
      sizrange[0] = wi::to_offset (range[0]);
      sizrange[1] = wi::to_offset (range[1]);
      /* get_size_range returns SIZE_MAX for the maximum size.
	 Constrain it to the real maximum of PTRDIFF_MAX.  */
      if (sizrange[0] <= maxobjsize && sizrange[1] > maxobjsize)
	sizrange[1] = maxobjsize;
    }
  else
    sizrange[1] = maxobjsize;

  if (!DECL_P (base))
    return;

  /* If the offset could be in the range of the referenced object
     constrain its bounds so neither exceeds those of the object.  */
  if (offrange[0] < 0 && offrange[1] > 0)
    offrange[0] = 0;

  offset_int maxoff = maxobjsize;
  tree basetype = TREE_TYPE (base);
  if (TREE_CODE (basetype) == ARRAY_TYPE)
    {
      if (ref && array_at_struct_end_p (ref))
	;   /* Use the maximum possible offset for last member arrays.  */
      else if (tree basesize = TYPE_SIZE_UNIT (basetype))
	if (TREE_CODE (basesize) == INTEGER_CST)
	  /* Size could be non-constant for a variable-length type such
	     as a struct with a VLA member (a GCC extension).  */
	  maxoff = wi::to_offset (basesize);
    }

  if (offrange[0] >= 0)
    {
      if (offrange[1] < 0)
	offrange[1] = offrange[0] <= maxoff ? maxoff : maxobjsize;
      else if (offrange[0] <= maxoff && offrange[1] > maxoff)
	offrange[1] = maxoff;
    }
}

/* Based on the initial length of the destination STARTLEN, returns
   the offset of the first write access from the beginning of
   the destination.  Nonzero only for strcat-type of calls.  */

offset_int builtin_access::write_off (tree startlen) const
{
  if (detect_overlap != &builtin_access::strcat_overlap
      || !startlen || TREE_CODE (startlen) != INTEGER_CST)
    return 0;

  return wi::to_offset (startlen);
}

/* Ctor helper to set or extend OFFRANGE based on the OFFSET argument.
   Pointer offsets are represented as unsigned sizetype but must be
   treated as signed.  */

void
builtin_memref::extend_offset_range (tree offset)
{
  if (TREE_CODE (offset) == INTEGER_CST)
    {
      offset_int off = int_cst_value (offset);
      if (off != 0)
	{
	  offrange[0] += off;
	  offrange[1] += off;
	}
      return;
    }

  if (TREE_CODE (offset) == SSA_NAME)
    {
      /* A pointer offset is represented as sizetype but treated
	 as signed.  */
      wide_int min, max;
      value_range_kind rng = VR_VARYING;
      value_range vr;
      if (m_ptr_qry.rvals->range_of_expr (vr, offset, stmt))
	{
	  rng = vr.kind ();
	  if (!vr.undefined_p ())
	    {
	      min = wi::to_wide (vr.min ());
	      max = wi::to_wide (vr.max ());
	    }
	}

      if (rng == VR_ANTI_RANGE && wi::lts_p (max, min))
	{
	  /* Convert an anti-range whose upper bound is less than
	     its lower bound to a signed range.  */
	  offrange[0] += offset_int::from (max + 1, SIGNED);
	  offrange[1] += offset_int::from (min - 1, SIGNED);
	  return;
	}

      if (rng == VR_RANGE
	  && (DECL_P (base) || wi::lts_p (min, max)))
	{
	  /* Preserve the bounds of the range for an offset into
	     a known object (it may be adjusted later relative to
	     a constant offset from its beginning).  Otherwise use
	     the bounds only when they are ascending when treated
	     as signed.  */
	  offrange[0] += offset_int::from (min, SIGNED);
	  offrange[1] += offset_int::from (max, SIGNED);
	  return;
	}

      /* Handle an anti-range the same as no range at all.  */
      gimple *stmt = SSA_NAME_DEF_STMT (offset);
      tree type;
      if (is_gimple_assign (stmt)
	  && (type = TREE_TYPE (gimple_assign_rhs1 (stmt)))
	  && INTEGRAL_TYPE_P (type))
	{
	  tree_code code = gimple_assign_rhs_code (stmt);
	  if (code == NOP_EXPR)
	    {
	      /* Use the bounds of the type of the NOP_EXPR operand
		 even if it's signed.  The result doesn't trigger
		 warnings but makes their output more readable.  */
	      offrange[0] += wi::to_offset (TYPE_MIN_VALUE (type));
	      offrange[1] += wi::to_offset (TYPE_MAX_VALUE (type));
	      return;
	    }
	}
    }

  const offset_int maxoff = tree_to_shwi (max_object_size ()) >> 1;
  const offset_int minoff = -maxoff - 1;

  offrange[0] += minoff;
  offrange[1] += maxoff;
}

/* Determines the base object or pointer of the reference EXPR
   and the offset range from the beginning of the base.  */

void
builtin_memref::set_base_and_offset (tree expr)
{
  tree offset = NULL_TREE;

  if (TREE_CODE (expr) == SSA_NAME)
    {
      /* Try to tease the offset out of the pointer.  */
      gimple *stmt = SSA_NAME_DEF_STMT (expr);
      if (!base
	  && gimple_assign_single_p (stmt)
	  && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
	expr = gimple_assign_rhs1 (stmt);
      else if (is_gimple_assign (stmt))
	{
	  tree_code code = gimple_assign_rhs_code (stmt);
	  if (CONVERT_EXPR_CODE_P (code))
	    {
	      tree rhs = gimple_assign_rhs1 (stmt);
	      if (POINTER_TYPE_P (TREE_TYPE (rhs)))
		expr = gimple_assign_rhs1 (stmt);
	      else
		{
		  base = expr;
		  return;
		}
	    }
	  else if (code == POINTER_PLUS_EXPR)
	    {
	      expr = gimple_assign_rhs1 (stmt);
	      offset = gimple_assign_rhs2 (stmt);
	    }
	  else
	    {
	      base = expr;
	      return;
	    }
	}
      else
	{
	  /* FIXME: Handle PHI nodes in case like:
	     _12 = &MEM[(void *)&a + 2B] + _10;

	     <bb> [local count: 1073741824]:
	     # prephitmp_13 = PHI <_12, &MEM[(void *)&a + 2B]>
	     memcpy (prephitmp_13, p_7(D), 6);  */
	  base = expr;
	  return;
	}
    }

  if (TREE_CODE (expr) == ADDR_EXPR)
    expr = TREE_OPERAND (expr, 0);

  /* Stash the reference for offset validation.  */
  ref = expr;

  poly_int64 bitsize, bitpos;
  tree var_off;
  machine_mode mode;
  int sign, reverse, vol;

  /* Determine the base object or pointer of the reference and
     the constant bit offset from the beginning of the base.
     If the offset has a non-constant component, it will be in
     VAR_OFF.  MODE, SIGN, REVERSE, and VOL are write only and
     unused here.  */
  base = get_inner_reference (expr, &bitsize, &bitpos, &var_off,
			      &mode, &sign, &reverse, &vol);

  /* get_inner_reference is not expected to return null.  */
  gcc_assert (base != NULL);

  if (offset)
    extend_offset_range (offset);

  poly_int64 bytepos = exact_div (bitpos, BITS_PER_UNIT);

  /* Convert the poly_int64 offset to offset_int.  The offset
     should be constant but be prepared for it not to be just in
     case.  */
  offset_int cstoff;
  if (bytepos.is_constant (&cstoff))
    {
      offrange[0] += cstoff;
      offrange[1] += cstoff;

      /* Besides the reference saved above, also stash the offset
	 for validation.  */
      if (TREE_CODE (expr) == COMPONENT_REF)
	refoff = cstoff;
    }
  else
    offrange[1] += maxobjsize;

  if (var_off)
    {
      if (TREE_CODE (var_off) == INTEGER_CST)
	{
	  cstoff = wi::to_offset (var_off);
	  offrange[0] += cstoff;
	  offrange[1] += cstoff;
	}
      else
	offrange[1] += maxobjsize;
    }

  if (TREE_CODE (base) == MEM_REF)
    {
      tree memrefoff = fold_convert (ptrdiff_type_node, TREE_OPERAND (base, 1));
      extend_offset_range (memrefoff);

      if (refoff != HOST_WIDE_INT_MIN
      	  && TREE_CODE (expr) == COMPONENT_REF)
      	{
	  /* Bump up the offset of the referenced subobject to reflect
	     the offset to the enclosing object.  For example, so that
	     in
	       struct S { char a, b[3]; } s[2];
	       strcpy (s[1].b, "1234");
	     REFOFF is set to s[1].b - (char*)s.  */
	  offset_int off = tree_to_shwi (memrefoff);
	  refoff += off;

	  if (!integer_zerop (memrefoff)
	      && !COMPLETE_TYPE_P (TREE_TYPE (expr))
	      && multiple_of_p (sizetype, memrefoff,
				TYPE_SIZE_UNIT (TREE_TYPE (base)), true))
	    /* A non-zero offset into an array of struct with flexible array
	       members implies that the array is empty because there is no
	       way to initialize such a member when it belongs to an array.
	       This must be some sort of a bug.  */
	    refsize = 0;
	}

      base = TREE_OPERAND (base, 0);
    }

  if (TREE_CODE (ref) == COMPONENT_REF)
    if (tree size = component_ref_size (ref))
      if (TREE_CODE (size) == INTEGER_CST)
	refsize = wi::to_offset (size);

  if (TREE_CODE (base) == SSA_NAME)
    set_base_and_offset (base);
}

/* Return error_mark_node if the signed offset exceeds the bounds
   of the address space (PTRDIFF_MAX).  Otherwise, return either BASE
   or REF when the offset exceeds the bounds of the BASE or REF object,
   and set OOBOFF to the past-the-end offset formed by the reference,
   including its size.  OOBOFF is initially setto the range of offsets,
   and OOBOFF[2] to the offset of the first write access (nonzero for
   the strcat family).  When STRICT is nonzero use REF size, when
   available, otherwise use BASE size.  When STRICT is greater than 1,
   use the size of the last array member as the bound, otherwise treat
   such a member as a flexible array member.  Return NULL when the offset
   is in bounds.  */

tree
builtin_memref::offset_out_of_bounds (int strict, offset_int ooboff[3]) const
{
  if (!ptr)
    return NULL_TREE;

  /* The offset of the first write access or zero.  */
  offset_int wroff = ooboff[2];

  /* A temporary, possibly adjusted, copy of the offset range.  */
  offset_int offrng[2] = { ooboff[0], ooboff[1] };

  if (DECL_P (base) && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE)
    {
      /* Check for offset in an anti-range with a negative lower bound.
	 For such a range, consider only the non-negative subrange.  */
      if (offrng[1] < offrng[0] && offrng[1] < 0)
  	offrng[1] = maxobjsize;
    }

  /* Conservative offset of the last byte of the referenced object.  */
  offset_int endoff;

  /* The bounds need not be ordered.  Set HIB to use as the index
     of the larger of the bounds and LOB as the opposite.  */
  bool hib = wi::les_p (offrng[0], offrng[1]);
  bool lob = !hib;

  /* Set to the size remaining in the object after subtracting
     REFOFF.  It may become negative as a result of negative indices
     into the enclosing object, such as in:
       extern struct S { char a[4], b[3], c[1]; } *p;
       strcpy (p[-3].b, "123");  */
  offset_int size = basesize;
  tree obj = base;

  const bool decl_p = DECL_P (obj);

  if (basesize < 0)
    {
      endoff = offrng[lob] + (sizrange[0] - wroff);

      /* For a reference through a pointer to an object of unknown size
	 all initial offsets are considered valid, positive as well as
	 negative, since the pointer itself can point past the beginning
	 of the object.  However, the sum of the lower bound of the offset
	 and that of the size must be less than or equal than PTRDIFF_MAX.  */
      if (endoff > maxobjsize)
	return error_mark_node;

      /* When the referenced subobject is known, the end offset must be
	 within its bounds.  Otherwise there is nothing to do.  */
      if (strict
	  && !decl_p
	  && ref
	  && refsize >= 0
	  && TREE_CODE (ref) == COMPONENT_REF)
	{
	  /* If REFOFF is negative, SIZE will become negative here.  */
	  size = refoff + refsize;
	  obj = ref;
	}
      else
	return NULL_TREE;
    }

  /* A reference to an object of known size must be within the bounds
     of either the base object or the subobject (see above for when
     a subobject can be used).  */
  if ((decl_p && offrng[hib] < 0) || offrng[lob] > size)
    return obj;

  /* The extent of the reference must also be within the bounds of
     the base object (if known) or the subobject or the maximum object
     size otherwise.  */
  endoff = offrng[lob] + sizrange[0];
  if (endoff > maxobjsize)
    return error_mark_node;

  if (strict
      && decl_p
      && ref
      && refsize >= 0
      && TREE_CODE (ref) == COMPONENT_REF)
    {
      /* If the reference is to a member subobject of a declared object,
	 the offset must be within the bounds of the subobject.  */
      size = refoff + refsize;
      obj = ref;
    }

  if (endoff <= size)
    return NULL_TREE;

  /* Set the out-of-bounds offset range to be one greater than
     that delimited by the reference including its size.  */
  ooboff[lob] = size;

  if (endoff > ooboff[lob])
    ooboff[hib] = endoff - 1;
  else
    ooboff[hib] = offrng[lob] + sizrange[1];

  return obj;
}

/* Create an association between the memory references DST and SRC
   for access by a call EXPR to a memory or string built-in funtion.  */

builtin_access::builtin_access (pointer_query &ptrqry, gimple *call,
				builtin_memref &dst,
				builtin_memref &src)
: dstref (&dst), srcref (&src), sizrange (), ovloff (), ovlsiz (),
  dstoff (), srcoff (), dstsiz (), srcsiz ()
{
  dstoff[0] = dst.offrange[0];
  dstoff[1] = dst.offrange[1];

  /* Zero out since the offset_int ctors invoked above are no-op.  */
  srcoff[0] = srcoff[1] = 0;
  dstsiz[0] = dstsiz[1] = 0;
  srcsiz[0] = srcsiz[1] = 0;

  /* Object Size Type to use to determine the size of the destination
     and source objects.  Overridden below for raw memory functions.  */
  int ostype = 1;

  /* True when the size of one reference depends on the offset of
     itself or the other.  */
  bool depends_p = true;

  /* True when the size of the destination reference DSTREF has been
     determined from SRCREF and so needs to be adjusted by the latter's
     offset.  Only meaningful for bounded string functions like strncpy.  */
  bool dstadjust_p = false;

  /* The size argument number (depends on the built-in).  */
  unsigned sizeargno = 2;

  tree func = gimple_call_fndecl (call);
  switch (DECL_FUNCTION_CODE (func))
    {
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMCPY_CHK:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMPCPY_CHK:
      ostype = 0;
      depends_p = false;
      detect_overlap = &builtin_access::generic_overlap;
      break;

    case BUILT_IN_MEMMOVE:
    case BUILT_IN_MEMMOVE_CHK:
      /* For memmove there is never any overlap to check for.  */
      ostype = 0;
      depends_p = false;
      detect_overlap = &builtin_access::no_overlap;
      break;

    case BUILT_IN_MEMSET:
    case BUILT_IN_MEMSET_CHK:
      /* For memset there is never any overlap to check for.  */
      ostype = 0;
      depends_p = false;
      detect_overlap = &builtin_access::no_overlap;
      break;

    case BUILT_IN_STPNCPY:
    case BUILT_IN_STPNCPY_CHK:
    case BUILT_IN_STRNCPY:
    case BUILT_IN_STRNCPY_CHK:
      dstref->strbounded_p = true;
      detect_overlap = &builtin_access::strcpy_overlap;
      break;

    case BUILT_IN_STPCPY:
    case BUILT_IN_STPCPY_CHK:
    case BUILT_IN_STRCPY:
    case BUILT_IN_STRCPY_CHK:
      detect_overlap = &builtin_access::strcpy_overlap;
      break;

    case BUILT_IN_STRCAT:
    case BUILT_IN_STRCAT_CHK:
      detect_overlap = &builtin_access::strcat_overlap;
      break;

    case BUILT_IN_STRNCAT:
    case BUILT_IN_STRNCAT_CHK:
      dstref->strbounded_p = true;
      srcref->strbounded_p = true;
      detect_overlap = &builtin_access::strcat_overlap;
      break;

    default:
      /* Handle other string functions here whose access may need
	 to be validated for in-bounds offsets and non-overlapping
	 copies.  */
      return;
    }

  /* Try to determine the size of the base object.  compute_objsize
     expects a pointer so create one if BASE is a non-pointer object.  */
  if (dst.basesize < 0)
    {
      access_ref aref;
      if (ptrqry.get_ref (dst.base, call, &aref, ostype) && aref.base0)
	dst.basesize = aref.sizrng[1];
      else
	dst.basesize = HOST_WIDE_INT_MIN;
    }

  if (src.base && src.basesize < 0)
    {
      access_ref aref;
      if (ptrqry.get_ref (src.base, call, &aref, ostype) && aref.base0)
	src.basesize = aref.sizrng[1];
      else
	src.basesize = HOST_WIDE_INT_MIN;
    }

  const offset_int maxobjsize = dst.maxobjsize;

  /* Make adjustments for references to the same object by string
     built-in functions to reflect the constraints imposed by
     the function.  */

  /* For bounded string functions determine the range of the bound
     on the access.  For others, the range stays unbounded.  */
  offset_int bounds[2] = { maxobjsize, maxobjsize };
  if (dstref->strbounded_p)
    {
      unsigned nargs = gimple_call_num_args (call);
      if (nargs <= sizeargno)
	return;

      tree size = gimple_call_arg (call, sizeargno);
      tree range[2];
      if (get_size_range (ptrqry.rvals, size, call, range, true))
	{
	  bounds[0] = wi::to_offset (range[0]);
	  bounds[1] = wi::to_offset (range[1]);
	}

      /* If both references' size ranges are indeterminate use the last
	 (size) argument from the function call as a substitute.  This
	 may only be necessary for strncpy (but not for memcpy where
	 the size range would have been already determined this way).  */
      if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize
	  && srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
	{
	  dstref->sizrange[0] = bounds[0];
	  dstref->sizrange[1] = bounds[1];
	}
    }

  bool dstsize_set = false;
  /* The size range of one reference involving the same base object
     can be determined from the size range of the other reference.
     This makes it possible to compute accurate offsets for warnings
     involving functions like strcpy where the length of just one of
     the two arguments is known (determined by tree-ssa-strlen).  */
  if (dstref->sizrange[0] == 0 && dstref->sizrange[1] == maxobjsize)
    {
      /* When the destination size is unknown set it to the size of
	 the source.  */
      dstref->sizrange[0] = srcref->sizrange[0];
      dstref->sizrange[1] = srcref->sizrange[1];
      dstsize_set = true;
    }
  else if (srcref->sizrange[0] == 0 && srcref->sizrange[1] == maxobjsize)
    {
      /* When the size of the source access is unknown set it to the size
	 of the destination first and adjust it later if necessary.  */
      srcref->sizrange[0] = dstref->sizrange[0];
      srcref->sizrange[1] = dstref->sizrange[1];

      if (depends_p)
	{
	  if (dstref->strbounded_p)
	    {
	      /* Read access by strncpy is constrained by the third
		 argument but except for a zero bound is at least one.  */
	      srcref->sizrange[0] = bounds[1] > 0 ? 1 : 0;
	      offset_int bound = wi::umin (srcref->basesize, bounds[1]);
	      if (bound < srcref->sizrange[1])
		srcref->sizrange[1] = bound;
	    }
	  /* For string functions, adjust the size range of the source
	     reference by the inverse boundaries of the offset (because
	     the higher the offset into the string the shorter its
	     length).  */
	  if (srcref->offrange[1] >= 0
	      && srcref->offrange[1] < srcref->sizrange[0])
	    srcref->sizrange[0] -= srcref->offrange[1];
	  else
	    srcref->sizrange[0] = 1;

	  if (srcref->offrange[0] > 0)
	    {
	      if (srcref->offrange[0] < srcref->sizrange[1])
		srcref->sizrange[1] -= srcref->offrange[0];
	      else
		srcref->sizrange[1] = 0;
	    }

	  dstadjust_p = true;
	}
    }

  if (detect_overlap == &builtin_access::generic_overlap)
    {
      if (dstref->strbounded_p)
	{
	  dstref->sizrange[0] = bounds[0];
	  dstref->sizrange[1] = bounds[1];

	  if (dstref->sizrange[0] < srcref->sizrange[0])
	    srcref->sizrange[0] = dstref->sizrange[0];

	  if (dstref->sizrange[1] < srcref->sizrange[1])
	    srcref->sizrange[1] = dstref->sizrange[1];
	}
    }
  else if (detect_overlap == &builtin_access::strcpy_overlap)
    {
      if (!dstref->strbounded_p)
	{
	  /* For strcpy, adjust the destination size range to match that
	     of the source computed above.  */
	  if (depends_p && dstadjust_p)
	    {
	      dstref->sizrange[0] = srcref->sizrange[0];
	      dstref->sizrange[1] = srcref->sizrange[1];
	    }
	}
    }
  else if (!dstsize_set && detect_overlap == &builtin_access::strcat_overlap)
    {
      dstref->sizrange[0] += srcref->sizrange[0] - 1;
      dstref->sizrange[1] += srcref->sizrange[1] - 1;
    }

  if (dstref->strbounded_p)
    {
      /* For strncpy, adjust the destination size range to match that
	 of the source computed above.  */
      dstref->sizrange[0] = bounds[0];
      dstref->sizrange[1] = bounds[1];

      if (bounds[0] < srcref->sizrange[0])
	srcref->sizrange[0] = bounds[0];

      if (bounds[1] < srcref->sizrange[1])
	srcref->sizrange[1] = bounds[1];
    }
}

offset_int
builtin_access::overlap_size (const offset_int a[2], const offset_int b[2],
			      offset_int *off)
{
  const offset_int *p = a;
  const offset_int *q = b;

  /* Point P at the bigger of the two ranges and Q at the smaller.  */
  if (wi::lts_p (a[1] - a[0], b[1] - b[0]))
    {
      p = b;
      q = a;
    }

  if (p[0] < q[0])
    {
      if (p[1] < q[0])
	return 0;

      *off = q[0];
      return wi::smin (p[1], q[1]) - q[0];
    }

  if (q[1] < p[0])
    return 0;

  off[0] = p[0];
  return q[1] - p[0];
}

/* Return true if the bounded mempry (memcpy amd similar) or string function
   access (strncpy and similar) ACS overlaps.  */

bool
builtin_access::generic_overlap ()
{
  builtin_access &acs = *this;
  const builtin_memref *dstref = acs.dstref;
  const builtin_memref *srcref = acs.srcref;

  gcc_assert (dstref->base == srcref->base);

  const offset_int maxobjsize = acs.dstref->maxobjsize;

  offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;

  /* Adjust the larger bounds of the offsets (which may be the first
     element if the lower bound is larger than the upper bound) to
     make them valid for the smallest access (if possible) but no smaller
     than the smaller bounds.  */
  gcc_assert (wi::les_p (acs.dstoff[0], acs.dstoff[1]));

  if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
    acs.dstoff[1] = maxsize - acs.dstsiz[0];
  if (acs.dstoff[1] < acs.dstoff[0])
    acs.dstoff[1] = acs.dstoff[0];

  gcc_assert (wi::les_p (acs.srcoff[0], acs.srcoff[1]));

  if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
    acs.srcoff[1] = maxsize - acs.srcsiz[0];
  if (acs.srcoff[1] < acs.srcoff[0])
    acs.srcoff[1] = acs.srcoff[0];

  /* Determine the minimum and maximum space for the access given
     the offsets.  */
  offset_int space[2];
  space[0] = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
  space[1] = space[0];

  offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
  if (acs.srcsiz[0] > 0)
    {
      if (d < space[0])
	space[0] = d;

      if (space[1] < d)
	space[1] = d;
    }
  else
    space[1] = acs.dstsiz[1];

  d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
  if (d < space[0])
    space[0] = d;

  if (space[1] < d)
    space[1] = d;

  /* Treat raw memory functions both of whose references are bounded
     as special and permit uncertain overlaps to go undetected.  For
     all kinds of constant offset and constant size accesses, if
     overlap isn't certain it is not possible.  */
  bool overlap_possible = space[0] < acs.dstsiz[1];
  if (!overlap_possible)
    return false;

  bool overlap_certain = space[1] < acs.dstsiz[0];

  /* True when the size of one reference depends on the offset of
     the other.  */
  bool depends_p = detect_overlap != &builtin_access::generic_overlap;

  if (!overlap_certain)
    {
      if (!dstref->strbounded_p && !depends_p)
	/* Memcpy only considers certain overlap.  */
	return false;

      /* There's no way to distinguish an access to the same member
	 of a structure from one to two distinct members of the same
	 structure.  Give up to avoid excessive false positives.  */
      tree basetype = TREE_TYPE (dstref->base);

      if (POINTER_TYPE_P (basetype))
	basetype = TREE_TYPE (basetype);
      else
	while (TREE_CODE (basetype) == ARRAY_TYPE)
	  basetype = TREE_TYPE (basetype);

      if (RECORD_OR_UNION_TYPE_P (basetype))
	return false;
    }

  /* True for stpcpy and strcpy.  */
  bool stxcpy_p = (!dstref->strbounded_p
		   && detect_overlap == &builtin_access::strcpy_overlap);

  if (dstref->refoff >= 0
      && srcref->refoff >= 0
      && dstref->refoff != srcref->refoff
      && (stxcpy_p || dstref->strbounded_p || srcref->strbounded_p))
    return false;

  offset_int siz[2] = { maxobjsize + 1, 0 };

  ovloff[0] = HOST_WIDE_INT_MAX;
  ovloff[1] = HOST_WIDE_INT_MIN;

  if (stxcpy_p)
    {
      /* Iterate over the extreme locations (on the horizontal axis formed
	 by their offsets) and sizes of two regions and find their smallest
	 and largest overlap and the corresponding offsets.  */
      for (unsigned i = 0; i != 2; ++i)
	{
	  const offset_int a[2] = {
	    acs.dstoff[i], acs.dstoff[i] + acs.dstsiz[!i]
	  };

	  const offset_int b[2] = {
	    acs.srcoff[i], acs.srcoff[i] + acs.srcsiz[!i]
	  };

	  offset_int off;
	  offset_int sz = overlap_size (a, b, &off);
	  if (sz < siz[0])
	    siz[0] = sz;

	  if (siz[1] <= sz)
	    siz[1] = sz;

	  if (sz != 0)
	    {
	      if (wi::lts_p (off, ovloff[0]))
		ovloff[0] = off.to_shwi ();
	      if (wi::lts_p (ovloff[1], off))
		ovloff[1] = off.to_shwi ();
	    }
	}
    }
  else
    {
      /* Iterate over the extreme locations (on the horizontal axis
	 formed by their offsets) and sizes of the two regions and
	 find their smallest and largest overlap and the corresponding
	 offsets.  */

      for (unsigned io = 0; io != 2; ++io)
	for (unsigned is = 0; is != 2; ++is)
	  {
	    const offset_int a[2] = {
	      acs.dstoff[io], acs.dstoff[io] + acs.dstsiz[is]
	    };

	    for (unsigned jo = 0; jo != 2; ++jo)
	      for (unsigned js = 0; js != 2; ++js)
		{
		  const offset_int b[2] = {
		    acs.srcoff[jo], acs.srcoff[jo] + acs.srcsiz[js]
		  };

		  offset_int off;
		  offset_int sz = overlap_size (a, b, &off);
		  if (sz < siz[0])
		    siz[0] = sz;

		  if (siz[1] <= sz)
		    siz[1] = sz;

		  if (sz != 0)
		    {
		      if (wi::lts_p (off, ovloff[0]))
			ovloff[0] = off.to_shwi ();
		      if (wi::lts_p (ovloff[1], off))
			ovloff[1] = off.to_shwi ();
		    }
		}
	  }
    }

  ovlsiz[0] = siz[0].to_shwi ();
  ovlsiz[1] = siz[1].to_shwi ();

  /* Adjust the overlap offset range to reflect the overlap size range.  */
  if (ovlsiz[0] == 0 && ovlsiz[1] > 1)
    ovloff[1] = ovloff[0] + ovlsiz[1] - 1;

  return true;
}

/* Return true if the strcat-like access overlaps.  */

bool
builtin_access::strcat_overlap ()
{
  builtin_access &acs = *this;
  const builtin_memref *dstref = acs.dstref;
  const builtin_memref *srcref = acs.srcref;

  gcc_assert (dstref->base == srcref->base);

  const offset_int maxobjsize = acs.dstref->maxobjsize;

  gcc_assert (dstref->base && dstref->base == srcref->base);

  /* Adjust for strcat-like accesses.  */

  /* As a special case for strcat, set the DSTREF offsets to the length
     of the destination string since the function starts writing over
     its terminating nul, and set the destination size to 1 for the length
     of the nul.  */
  acs.dstoff[0] += dstsiz[0] - srcref->sizrange[0];
  acs.dstoff[1] += dstsiz[1] - srcref->sizrange[1];

  bool strfunc_unknown_args = acs.dstsiz[0] == 0 && acs.dstsiz[1] != 0;

  /* The lower bound is zero when the size is unknown because then
     overlap is not certain.  */
  acs.dstsiz[0] = strfunc_unknown_args ? 0 : 1;
  acs.dstsiz[1] = 1;

  offset_int maxsize = dstref->basesize < 0 ? maxobjsize : dstref->basesize;

  /* For references to the same base object, determine if there's a pair
     of valid offsets into the two references such that access between
     them doesn't overlap.  Adjust both upper bounds to be valid for
     the smaller size (i.e., at most MAXSIZE - SIZE).  */

  if (maxsize < acs.dstoff[1] + acs.dstsiz[0])
    acs.dstoff[1] = maxsize - acs.dstsiz[0];

  if (maxsize < acs.srcoff[1] + acs.srcsiz[0])
    acs.srcoff[1] = maxsize - acs.srcsiz[0];

  /* Check to see if there's enough space for both accesses without
     overlap.  Determine the optimistic (maximum) amount of available
     space.  */
  offset_int space;
  if (acs.dstoff[0] <= acs.srcoff[0])
    {
      if (acs.dstoff[1] < acs.srcoff[1])
	space = acs.srcoff[1] + acs.srcsiz[0] - acs.dstoff[0];
      else
	space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];
    }
  else
    space = acs.dstoff[1] + acs.dstsiz[0] - acs.srcoff[0];

  /* Overlap is certain if the distance between the farthest offsets
     of the opposite accesses is less than the sum of the lower bounds
     of the sizes of the two accesses.  */
  bool overlap_certain = space < acs.dstsiz[0] + acs.srcsiz[0];

  /* For a constant-offset, constant size access, consider the largest
     distance between the offset bounds and the lower bound of the access
     size.  If the overlap isn't certain return success.  */
  if (!overlap_certain
      && acs.dstoff[0] == acs.dstoff[1]
      && acs.srcoff[0] == acs.srcoff[1]
      && acs.dstsiz[0] == acs.dstsiz[1]
      && acs.srcsiz[0] == acs.srcsiz[1])
    return false;

  /* Overlap is not certain but may be possible.  */

  offset_int access_min = acs.dstsiz[0] + acs.srcsiz[0];

  /* Determine the conservative (minimum) amount of space.  */
  space = wi::abs (acs.dstoff[0] - acs.srcoff[0]);
  offset_int d = wi::abs (acs.dstoff[0] - acs.srcoff[1]);
  if (d < space)
    space = d;
  d = wi::abs (acs.dstoff[1] - acs.srcoff[0]);
  if (d < space)
    space = d;

  /* For a strict test (used for strcpy and similar with unknown or
     variable bounds or sizes), consider the smallest distance between
     the offset bounds and either the upper bound of the access size
     if known, or the lower bound otherwise.  */
  if (access_min <= space && (access_min != 0 || !strfunc_unknown_args))
    return false;

  /* When strcat overlap is certain it is always a single byte:
     the terminating NUL, regardless of offsets and sizes.  When
     overlap is only possible its range is [0, 1].  */
  acs.ovlsiz[0] = dstref->sizrange[0] == dstref->sizrange[1] ? 1 : 0;
  acs.ovlsiz[1] = 1;

  offset_int endoff
    = dstref->offrange[0] + (dstref->sizrange[0] - srcref->sizrange[0]);
  if (endoff <= srcref->offrange[0])
    acs.ovloff[0] = wi::smin (maxobjsize, srcref->offrange[0]).to_shwi ();
  else
    acs.ovloff[0] = wi::smin (maxobjsize, endoff).to_shwi ();

  acs.sizrange[0] = wi::smax (wi::abs (endoff - srcref->offrange[0]) + 1,
			      srcref->sizrange[0]).to_shwi ();
  if (dstref->offrange[0] == dstref->offrange[1])
    {
      if (srcref->offrange[0] == srcref->offrange[1])
	acs.ovloff[1] = acs.ovloff[0];
      else
	acs.ovloff[1]
	  = wi::smin (maxobjsize,
		      srcref->offrange[1] + srcref->sizrange[1]).to_shwi ();
    }
  else
    acs.ovloff[1]
      = wi::smin (maxobjsize,
		  dstref->offrange[1] + dstref->sizrange[1]).to_shwi ();

  if (acs.sizrange[0] == 0)
    acs.sizrange[0] = 1;
  acs.sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
  return true;
}

/* Return true if the strcpy-like access overlaps.  */

bool
builtin_access::strcpy_overlap ()
{
  return generic_overlap ();
}

/* For a BASE of array type, clamp REFOFF to at most [0, BASE_SIZE]
   if known, or [0, MAXOBJSIZE] otherwise.  */

static void
clamp_offset (tree base, offset_int refoff[2], offset_int maxobjsize)
{
  if (!base || TREE_CODE (TREE_TYPE (base)) != ARRAY_TYPE)
    return;

  if (refoff[0] < 0 && refoff[1] >= 0)
    refoff[0] = 0;

  if (refoff[1] < refoff[0])
    {
      offset_int maxsize =  maxobjsize;
      if (tree size = TYPE_SIZE_UNIT (TREE_TYPE (base)))
	maxsize = wi::to_offset (size);

      refoff[1] = wi::umin (refoff[1], maxsize);
    }
}

/* Return true if DSTREF and SRCREF describe accesses that either overlap
   one another or that, in order not to overlap, would imply that the size
   of the referenced object(s) exceeds the maximum size of an object.  Set
   Otherwise, if DSTREF and SRCREF do not definitely overlap (even though
   they may overlap in a way that's not apparent from the available data),
   return false.  */

bool
builtin_access::overlap ()
{
  builtin_access &acs = *this;

  const offset_int maxobjsize = dstref->maxobjsize;

  acs.sizrange[0] = wi::smax (dstref->sizrange[0],
			      srcref->sizrange[0]).to_shwi ();
  acs.sizrange[1] = wi::smax (dstref->sizrange[1],
			      srcref->sizrange[1]).to_shwi ();

  /* Check to see if the two references refer to regions that are
     too large not to overlap in the address space (whose maximum
     size is PTRDIFF_MAX).  */
  offset_int size = dstref->sizrange[0] + srcref->sizrange[0];
  if (maxobjsize < size)
    {
      acs.ovloff[0] = (maxobjsize - dstref->sizrange[0]).to_shwi ();
      acs.ovlsiz[0] = (size - maxobjsize).to_shwi ();
      return true;
    }

  /* If both base objects aren't known return the maximum possible
     offset that would make them not overlap.  */
  if (!dstref->base || !srcref->base)
    return false;

  /* If the base object is an array adjust the bounds of the offset
     to be non-negative and within the bounds of the array if possible.  */
  clamp_offset (dstref->base, acs.dstoff, maxobjsize);

  acs.srcoff[0] = srcref->offrange[0];
  acs.srcoff[1] = srcref->offrange[1];

  clamp_offset (srcref->base, acs.srcoff, maxobjsize);

  /* When the upper bound of the offset is less than the lower bound
     the former is the result of a negative offset being represented
     as a large positive value or vice versa.  The resulting range is
     a union of two subranges: [MIN, UB] and [LB, MAX].  Since such
     a union is not representable using the current data structure
     replace it with the full range of offsets.  */
  if (acs.dstoff[1] < acs.dstoff[0])
    {
      acs.dstoff[0] = -maxobjsize - 1;
      acs.dstoff[1] = maxobjsize;
    }

  /* Validate the offset and size of each reference on its own first.
     This is independent of whether or not the base objects are the
     same.  Normally, this would have already been detected and
     diagnosed by -Warray-bounds, unless it has been disabled.  */
  offset_int maxoff = acs.dstoff[0] + dstref->sizrange[0];
  if (maxobjsize < maxoff)
    {
      acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
      acs.ovloff[0] = acs.dstoff[0].to_shwi () - acs.ovlsiz[0];
      return true;
    }

  /* Repeat the same as above but for the source offsets.  */
  if (acs.srcoff[1] < acs.srcoff[0])
    {
      acs.srcoff[0] = -maxobjsize - 1;
      acs.srcoff[1] = maxobjsize;
    }

  maxoff = acs.srcoff[0] + srcref->sizrange[0];
  if (maxobjsize < maxoff)
    {
      acs.ovlsiz[0] = (maxoff - maxobjsize).to_shwi ();
      acs.ovlsiz[1] = (acs.srcoff[0] + srcref->sizrange[1]
		       - maxobjsize).to_shwi ();
      acs.ovloff[0] = acs.srcoff[0].to_shwi () - acs.ovlsiz[0];
      return true;
    }

  if (dstref->base != srcref->base)
    return false;

  acs.dstsiz[0] = dstref->sizrange[0];
  acs.dstsiz[1] = dstref->sizrange[1];

  acs.srcsiz[0] = srcref->sizrange[0];
  acs.srcsiz[1] = srcref->sizrange[1];

  /* Call the appropriate function to determine the overlap.  */
  if ((this->*detect_overlap) ())
    {
      if (!sizrange[1])
	{
	  /* Unless the access size range has already been set, do so here.  */
	  sizrange[0] = wi::smax (acs.dstsiz[0], srcref->sizrange[0]).to_shwi ();
	  sizrange[1] = wi::smax (acs.dstsiz[1], srcref->sizrange[1]).to_shwi ();
	}
      return true;
    }

  return false;
}

/* Attempt to detect and diagnose an overlapping copy in a call expression
   EXPR involving an access ACS to a built-in memory or string function.
   Return true when one has been detected, false otherwise.  */

static bool
maybe_diag_overlap (location_t loc, gimple *call, builtin_access &acs)
{
  if (!acs.overlap ())
    return false;

  if (warning_suppressed_p (call, OPT_Wrestrict))
    return true;

  /* For convenience.  */
  const builtin_memref &dstref = *acs.dstref;
  const builtin_memref &srcref = *acs.srcref;

  /* Determine the range of offsets and sizes of the overlap if it
     exists and issue diagnostics.  */
  HOST_WIDE_INT *ovloff = acs.ovloff;
  HOST_WIDE_INT *ovlsiz = acs.ovlsiz;
  HOST_WIDE_INT *sizrange = acs.sizrange;

  tree func = gimple_call_fndecl (call);

  /* To avoid a combinatorial explosion of diagnostics format the offsets
     or their ranges as strings and use them in the warning calls below.  */
  char offstr[3][64];

  if (dstref.offrange[0] == dstref.offrange[1]
      || dstref.offrange[1] > HOST_WIDE_INT_MAX)
    sprintf (offstr[0], HOST_WIDE_INT_PRINT_DEC,
	     dstref.offrange[0].to_shwi ());
  else
    sprintf (offstr[0],
	     "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
	     dstref.offrange[0].to_shwi (),
	     dstref.offrange[1].to_shwi ());

  if (srcref.offrange[0] == srcref.offrange[1]
      || srcref.offrange[1] > HOST_WIDE_INT_MAX)
    sprintf (offstr[1],
	     HOST_WIDE_INT_PRINT_DEC,
	     srcref.offrange[0].to_shwi ());
  else
    sprintf (offstr[1],
	     "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
	     srcref.offrange[0].to_shwi (),
	     srcref.offrange[1].to_shwi ());

  if (ovloff[0] == ovloff[1] || !ovloff[1])
    sprintf (offstr[2], HOST_WIDE_INT_PRINT_DEC, ovloff[0]);
  else
    sprintf (offstr[2],
	     "[" HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC "]",
	     ovloff[0], ovloff[1]);

  const offset_int maxobjsize = dstref.maxobjsize;
  bool must_overlap = ovlsiz[0] > 0;

  if (ovlsiz[1] == 0)
    ovlsiz[1] = ovlsiz[0];

  if (must_overlap)
    {
      /* Issue definitive "overlaps" diagnostic in this block.  */

      if (sizrange[0] == sizrange[1])
	{
	  if (ovlsiz[0] == ovlsiz[1])
	    warning_at (loc, OPT_Wrestrict,
			sizrange[0] == 1
			? (ovlsiz[0] == 1
			   ? G_("%qD accessing %wu byte at offsets %s "
				"and %s overlaps %wu byte at offset %s")
			   :  G_("%qD accessing %wu byte at offsets %s "
				 "and %s overlaps %wu bytes at offset "
				 "%s"))
			: (ovlsiz[0] == 1
			   ? G_("%qD accessing %wu bytes at offsets %s "
				"and %s overlaps %wu byte at offset %s")
			   : G_("%qD accessing %wu bytes at offsets %s "
				"and %s overlaps %wu bytes at offset "
				"%s")),
			func, sizrange[0],
			offstr[0], offstr[1], ovlsiz[0], offstr[2]);
	  else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
	    warning_n (loc, OPT_Wrestrict, sizrange[0],
		       "%qD accessing %wu byte at offsets %s "
		       "and %s overlaps between %wu and %wu bytes "
		       "at offset %s",
		       "%qD accessing %wu bytes at offsets %s "
		       "and %s overlaps between %wu and %wu bytes "
		       "at offset %s",
		       func, sizrange[0], offstr[0], offstr[1],
		       ovlsiz[0], ovlsiz[1], offstr[2]);
	  else
	    warning_n (loc, OPT_Wrestrict, sizrange[0],
		       "%qD accessing %wu byte at offsets %s and "
		       "%s overlaps %wu or more bytes at offset %s",
		       "%qD accessing %wu bytes at offsets %s and "
		       "%s overlaps %wu or more bytes at offset %s",
		       func, sizrange[0],
		       offstr[0], offstr[1], ovlsiz[0], offstr[2]);
	  return true;
	}

      if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
	{
	  if (ovlsiz[0] == ovlsiz[1])
	    warning_n (loc, OPT_Wrestrict, ovlsiz[0],
		       "%qD accessing between %wu and %wu bytes "
		       "at offsets %s and %s overlaps %wu byte at "
		       "offset %s",
		       "%qD accessing between %wu and %wu bytes "
		       "at offsets %s and %s overlaps %wu bytes "
		       "at offset %s",
		       func, sizrange[0], sizrange[1],
		       offstr[0], offstr[1], ovlsiz[0], offstr[2]);
	  else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
	    warning_at (loc, OPT_Wrestrict,
			"%qD accessing between %wu and %wu bytes at "
			"offsets %s and %s overlaps between %wu and %wu "
			"bytes at offset %s",
			func, sizrange[0], sizrange[1],
			offstr[0], offstr[1], ovlsiz[0], ovlsiz[1],
			offstr[2]);
	  else
	    warning_at (loc, OPT_Wrestrict,
			"%qD accessing between %wu and %wu bytes at "
			"offsets %s and %s overlaps %wu or more bytes "
			"at offset %s",
			func, sizrange[0], sizrange[1],
			offstr[0], offstr[1], ovlsiz[0], offstr[2]);
	  return true;
	}

      if (ovlsiz[0] != ovlsiz[1])
	ovlsiz[1] = maxobjsize.to_shwi ();

      if (ovlsiz[0] == ovlsiz[1])
	warning_n (loc, OPT_Wrestrict, ovlsiz[0],
		   "%qD accessing %wu or more bytes at offsets "
		   "%s and %s overlaps %wu byte at offset %s",
		   "%qD accessing %wu or more bytes at offsets "
		   "%s and %s overlaps %wu bytes at offset %s",
		   func, sizrange[0], offstr[0], offstr[1],
		   ovlsiz[0], offstr[2]);
      else if (ovlsiz[1] >= 0 && ovlsiz[1] < maxobjsize.to_shwi ())
	warning_at (loc, OPT_Wrestrict,
		    "%qD accessing %wu or more bytes at offsets %s "
		    "and %s overlaps between %wu and %wu bytes "
		    "at offset %s",
		    func, sizrange[0], offstr[0], offstr[1],
		    ovlsiz[0], ovlsiz[1], offstr[2]);
      else
	warning_at (loc, OPT_Wrestrict,
		    "%qD accessing %wu or more bytes at offsets %s "
		    "and %s overlaps %wu or more bytes at offset %s",
		    func, sizrange[0], offstr[0], offstr[1],
		    ovlsiz[0], offstr[2]);
      return true;
    }

  /* Use more concise wording when one of the offsets is unbounded
     to avoid confusing the user with large and mostly meaningless
     numbers.  */
  bool open_range;
  if (DECL_P (dstref.base) && TREE_CODE (TREE_TYPE (dstref.base)) == ARRAY_TYPE)
    open_range = ((dstref.offrange[0] == 0
		   && dstref.offrange[1] == maxobjsize)
		  || (srcref.offrange[0] == 0
		      && srcref.offrange[1] == maxobjsize));
  else
    open_range = ((dstref.offrange[0] == -maxobjsize - 1
		   && dstref.offrange[1] == maxobjsize)
		  || (srcref.offrange[0] == -maxobjsize - 1
		      && srcref.offrange[1] == maxobjsize));

  if (sizrange[0] == sizrange[1] || sizrange[1] == 1)
    {
      if (ovlsiz[1] == 1)
	{
	  if (open_range)
	    warning_n (loc, OPT_Wrestrict, sizrange[1],
		       "%qD accessing %wu byte may overlap "
		       "%wu byte",
		       "%qD accessing %wu bytes may overlap "
		       "%wu byte",
		       func, sizrange[1], ovlsiz[1]);
	  else
	    warning_n (loc, OPT_Wrestrict, sizrange[1],
		       "%qD accessing %wu byte at offsets %s "
		       "and %s may overlap %wu byte at offset %s",
		       "%qD accessing %wu bytes at offsets %s "
		       "and %s may overlap %wu byte at offset %s",
		       func, sizrange[1], offstr[0], offstr[1],
		       ovlsiz[1], offstr[2]);
	  return true;
	}

      if (open_range)
	warning_n (loc, OPT_Wrestrict, sizrange[1],
		   "%qD accessing %wu byte may overlap "
		   "up to %wu bytes",
		   "%qD accessing %wu bytes may overlap "
		   "up to %wu bytes",
		   func, sizrange[1], ovlsiz[1]);
      else
	warning_n (loc, OPT_Wrestrict, sizrange[1],
		   "%qD accessing %wu byte at offsets %s and "
		   "%s may overlap up to %wu bytes at offset %s",
		   "%qD accessing %wu bytes at offsets %s and "
		   "%s may overlap up to %wu bytes at offset %s",
		   func, sizrange[1], offstr[0], offstr[1],
		   ovlsiz[1], offstr[2]);
      return true;
    }

  if (sizrange[1] >= 0 && sizrange[1] < maxobjsize.to_shwi ())
    {
      if (open_range)
	warning_n (loc, OPT_Wrestrict, ovlsiz[1],
		   "%qD accessing between %wu and %wu bytes "
		   "may overlap %wu byte",
		   "%qD accessing between %wu and %wu bytes "
		   "may overlap up to %wu bytes",
		   func, sizrange[0], sizrange[1], ovlsiz[1]);
      else
	warning_n (loc, OPT_Wrestrict, ovlsiz[1],
		   "%qD accessing between %wu and %wu bytes "
		   "at offsets %s and %s may overlap %wu byte "
		   "at offset %s",
		   "%qD accessing between %wu and %wu bytes "
		   "at offsets %s and %s may overlap up to %wu "
		   "bytes at offset %s",
		   func, sizrange[0], sizrange[1],
		   offstr[0], offstr[1], ovlsiz[1], offstr[2]);
      return true;
    }

  warning_n (loc, OPT_Wrestrict, ovlsiz[1],
	     "%qD accessing %wu or more bytes at offsets %s "
	     "and %s may overlap %wu byte at offset %s",
	     "%qD accessing %wu or more bytes at offsets %s "
	     "and %s may overlap up to %wu bytes at offset %s",
	     func, sizrange[0], offstr[0], offstr[1],
	     ovlsiz[1], offstr[2]);

  return true;
}

/* Validate REF size and offsets in an expression passed as an argument
   to a CALL to a built-in function FUNC to make sure they are within
   the bounds of the referenced object if its size is known, or
   PTRDIFF_MAX otherwise.  DO_WARN is true when a diagnostic should
   be issued, false otherwise.
   Both initial values of the offsets and their final value computed
   by the function by incrementing the initial value by the size are
   validated.  Return the warning number if the offsets are not valid
   and a diagnostic has been issued, or would have been issued if
   DO_WARN had been true, otherwise an invalid warning number.  */

static opt_code
maybe_diag_access_bounds (gimple *call, tree func, int strict,
			  const builtin_memref &ref, offset_int wroff,
			  bool do_warn)
{
  location_t loc = gimple_location (call);
  const offset_int maxobjsize = ref.maxobjsize;

  /* Check for excessive size first and regardless of warning options
     since the result is used to make codegen decisions.  */
  if (ref.sizrange[0] > maxobjsize)
    {
      const opt_code opt = OPT_Wstringop_overflow_;
      /* Return true without issuing a warning.  */
      if (!do_warn)
	return opt;

      if (ref.ref && warning_suppressed_p (ref.ref, OPT_Wstringop_overflow_))
	return no_warning;

      bool warned = false;
      if (warn_stringop_overflow)
	{
	  if (ref.sizrange[0] == ref.sizrange[1])
	    warned = warning_at (loc, opt,
				 "%qD specified bound %wu "
				 "exceeds maximum object size %wu",
				 func, ref.sizrange[0].to_uhwi (),
				 maxobjsize.to_uhwi ());
	  else
	    warned = warning_at (loc, opt,
				 "%qD specified bound between %wu and %wu "
				 "exceeds maximum object size %wu",
				 func, ref.sizrange[0].to_uhwi (),
				 ref.sizrange[1].to_uhwi (),
				 maxobjsize.to_uhwi ());
	  return warned ? opt : no_warning;
	}
    }

  /* Check for out-bounds pointers regardless of warning options since
     the result is used to make codegen decisions.  An excessive WROFF
     can only come up as a result of an invalid strncat bound and is
     diagnosed separately using a more meaningful warning.  */
  if (maxobjsize < wroff)
    wroff = 0;
  offset_int ooboff[] = { ref.offrange[0], ref.offrange[1], wroff };
  tree oobref = ref.offset_out_of_bounds (strict, ooboff);
  if (!oobref)
    return no_warning;

  const opt_code opt = OPT_Warray_bounds;
  /* Return true without issuing a warning.  */
  if (!do_warn)
    return opt;

  if (!warn_array_bounds)
    return no_warning;

  if (warning_suppressed_p (ref.ptr, opt)
      || (ref.ref && warning_suppressed_p (ref.ref, opt)))
    return no_warning;

  char rangestr[2][64];
  if (ooboff[0] == ooboff[1]
      || (ooboff[0] != ref.offrange[0]
	  && ooboff[0].to_shwi () >= ooboff[1].to_shwi ()))
    sprintf (rangestr[0], "%lli", (long long) ooboff[0].to_shwi ());
  else
    sprintf (rangestr[0], "[%lli, %lli]",
	     (long long) ooboff[0].to_shwi (),
	     (long long) ooboff[1].to_shwi ());

  bool warned = false;

  if (oobref == error_mark_node)
    {
      if (ref.sizrange[0] == ref.sizrange[1])
	sprintf (rangestr[1], "%llu",
		 (unsigned long long) ref.sizrange[0].to_shwi ());
      else
	sprintf (rangestr[1], "[%lli, %lli]",
		 (unsigned long long) ref.sizrange[0].to_uhwi (),
		 (unsigned long long) ref.sizrange[1].to_uhwi ());

      tree type;

      if (DECL_P (ref.base)
	  && TREE_CODE (type = TREE_TYPE (ref.base)) == ARRAY_TYPE)
	{
	  auto_diagnostic_group d;
	  if (warning_at (loc, opt,
			  "%qD pointer overflow between offset %s "
			  "and size %s accessing array %qD with type %qT",
			  func, rangestr[0], rangestr[1], ref.base, type))
	    {
	      inform (DECL_SOURCE_LOCATION (ref.base),
		      "array %qD declared here", ref.base);
	      warned = true;
	    }
	  else
	    warned = warning_at (loc, opt,
				 "%qD pointer overflow between offset %s "
				 "and size %s",
				 func, rangestr[0], rangestr[1]);
	}
      else
	warned = warning_at (loc, opt,
			     "%qD pointer overflow between offset %s "
			     "and size %s",
			     func, rangestr[0], rangestr[1]);
    }
  else if (oobref == ref.base)
    {
      /* True when the offset formed by an access to the reference
	 is out of bounds, rather than the initial offset wich is
	 in bounds.  This implies access past the end.  */
      bool form = ooboff[0] != ref.offrange[0];

      if (DECL_P (ref.base))
	{
	  auto_diagnostic_group d;
	  if ((ref.basesize < maxobjsize
	       && warning_at (loc, opt,
			      form
			      ? G_("%qD forming offset %s is out of "
				   "the bounds [0, %wu] of object %qD with "
				   "type %qT")
			      : G_("%qD offset %s is out of the bounds "
				   "[0, %wu] of object %qD with type %qT"),
			      func, rangestr[0], ref.basesize.to_uhwi (),
			      ref.base, TREE_TYPE (ref.base)))
	      || warning_at (loc, opt,
			     form
			     ? G_("%qD forming offset %s is out of "
				  "the bounds of object %qD with type %qT")
			     : G_("%qD offset %s is out of the bounds "
				  "of object %qD with type %qT"),
			     func, rangestr[0],
			     ref.base, TREE_TYPE (ref.base)))
	    {
	      inform (DECL_SOURCE_LOCATION (ref.base),
		      "%qD declared here", ref.base);
	      warned = true;
	    }
	}
      else if (ref.basesize < maxobjsize)
	warned = warning_at (loc, opt,
			     form
			     ? G_("%qD forming offset %s is out "
				  "of the bounds [0, %wu]")
			     : G_("%qD offset %s is out "
				  "of the bounds [0, %wu]"),
			     func, rangestr[0], ref.basesize.to_uhwi ());
      else
	warned = warning_at (loc, opt,
			     form
			     ? G_("%qD forming offset %s is out of bounds")
			     : G_("%qD offset %s is out of bounds"),
			     func, rangestr[0]);
    }
  else if (TREE_CODE (ref.ref) == MEM_REF)
    {
      tree refop = TREE_OPERAND (ref.ref, 0);
      tree type = TREE_TYPE (refop);
      if (POINTER_TYPE_P (type))
	type = TREE_TYPE (type);
      type = TYPE_MAIN_VARIANT (type);

      if (warning_at (loc, opt,
		      "%qD offset %s from the object at %qE is out "
		      "of the bounds of %qT",
		      func, rangestr[0], ref.base, type))
	{
	  if (TREE_CODE (ref.ref) == COMPONENT_REF)
	    refop = TREE_OPERAND (ref.ref, 1);
	  if (DECL_P (refop))
	    inform (DECL_SOURCE_LOCATION (refop),
		    "subobject %qD declared here", refop);
	  warned = true;
	}
    }
  else
    {
      tree refop = TREE_OPERAND (ref.ref, 0);
      tree type = TYPE_MAIN_VARIANT (TREE_TYPE (ref.ref));

      if (warning_at (loc, opt,
		      "%qD offset %s from the object at %qE is out "
		      "of the bounds of referenced subobject %qD with "
		      "type %qT at offset %wi",
		      func, rangestr[0], ref.base,
		      TREE_OPERAND (ref.ref, 1), type,
		      ref.refoff.to_shwi ()))
	{
	  if (TREE_CODE (ref.ref) == COMPONENT_REF)
	    refop = TREE_OPERAND (ref.ref, 1);
	  if (DECL_P (refop))
	    inform (DECL_SOURCE_LOCATION (refop),
		    "subobject %qD declared here", refop);
	  warned = true;
	}
    }

  return warned ? opt : no_warning;
}

/* Check a CALL statement for restrict-violations and issue warnings
   if/when appropriate.  */

void
pass_wrestrict::check_call (gimple *call)
{
  /* Avoid checking the call if it has already been diagnosed for
     some reason.  */
  if (warning_suppressed_p (call, OPT_Wrestrict))
    return;

  tree func = gimple_call_fndecl (call);
  if (!func || !fndecl_built_in_p (func, BUILT_IN_NORMAL))
    return;

  /* Argument number to extract from the call (depends on the built-in
     and its kind).  */
  unsigned dst_idx = -1;
  unsigned src_idx = -1;
  unsigned bnd_idx = -1;

  /* Is this CALL to a string function (as opposed to one to a raw
     memory function).  */
  bool strfun = true;

  switch (DECL_FUNCTION_CODE (func))
    {
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMCPY_CHK:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMPCPY_CHK:
    case BUILT_IN_MEMMOVE:
    case BUILT_IN_MEMMOVE_CHK:
      strfun = false;
      /* Fall through.  */

    case BUILT_IN_STPNCPY:
    case BUILT_IN_STPNCPY_CHK:
    case BUILT_IN_STRNCAT:
    case BUILT_IN_STRNCAT_CHK:
    case BUILT_IN_STRNCPY:
    case BUILT_IN_STRNCPY_CHK:
      dst_idx = 0;
      src_idx = 1;
      bnd_idx = 2;
      break;

    case BUILT_IN_MEMSET:
    case BUILT_IN_MEMSET_CHK:
      dst_idx = 0;
      bnd_idx = 2;
      break;

    case BUILT_IN_STPCPY:
    case BUILT_IN_STPCPY_CHK:
    case BUILT_IN_STRCPY:
    case BUILT_IN_STRCPY_CHK:
    case BUILT_IN_STRCAT:
    case BUILT_IN_STRCAT_CHK:
      dst_idx = 0;
      src_idx = 1;
      break;

    default:
      /* Handle other string functions here whose access may need
	 to be validated for in-bounds offsets and non-overlapping
	 copies.  */
      return;
    }

  unsigned nargs = gimple_call_num_args (call);

  tree dst = dst_idx < nargs ? gimple_call_arg (call, dst_idx) : NULL_TREE;
  tree src = src_idx < nargs ? gimple_call_arg (call, src_idx) : NULL_TREE;
  tree dstwr = bnd_idx < nargs ? gimple_call_arg (call, bnd_idx) : NULL_TREE;

  /* For string functions with an unspecified or unknown bound,
     assume the size of the access is one.  */
  if (!dstwr && strfun)
    dstwr = size_one_node;

  /* DST and SRC can be null for a call with an insufficient number
     of arguments to a built-in function declared without a protype.  */
  if (!dst || (src_idx < nargs && !src))
    return;

  /* DST, SRC, or DSTWR can also have the wrong type in a call to
     a function declared without a prototype.  Avoid checking such
     invalid calls.  */
  if (TREE_CODE (TREE_TYPE (dst)) != POINTER_TYPE
      || (src && TREE_CODE (TREE_TYPE (src)) != POINTER_TYPE)
      || (dstwr && !INTEGRAL_TYPE_P (TREE_TYPE (dstwr))))
    return;

  opt_code opt = check_bounds_or_overlap (m_ptr_qry, call, dst, src, dstwr,
					  NULL_TREE);
  /* Avoid diagnosing the call again.  */
  suppress_warning (call, opt);
}

} /* anonymous namespace */

/* Attempt to detect and diagnose invalid offset bounds and (except for
   memmove) overlapping copy in a call expression EXPR from SRC to DST
   and DSTSIZE and SRCSIZE bytes, respectively.  Both DSTSIZE and
   SRCSIZE may be NULL.  DO_WARN is false to detect either problem
   without issue a warning.  Return the OPT_Wxxx constant corresponding
   to the warning if one has been detected and zero otherwise.  */

opt_code
check_bounds_or_overlap (gimple *call, tree dst, tree src, tree dstsize,
			 tree srcsize, bool bounds_only /* = false */,
			 bool do_warn /* = true */)
{
  pointer_query ptrqry (get_range_query (cfun));
  return check_bounds_or_overlap (ptrqry,
				  call, dst, src, dstsize, srcsize,
				  bounds_only, do_warn);
}

opt_code
check_bounds_or_overlap (pointer_query &ptrqry,
			 gimple *call, tree dst, tree src, tree dstsize,
			 tree srcsize, bool bounds_only /* = false */,
			 bool do_warn /* = true */)
{
  tree func = gimple_call_fndecl (call);

  builtin_memref dstref (ptrqry, call, dst, dstsize);
  builtin_memref srcref (ptrqry, call, src, srcsize);

  /* Create a descriptor of the access.  This may adjust both DSTREF
     and SRCREF based on one another and the kind of the access.  */
  builtin_access acs (ptrqry, call, dstref, srcref);

  /* Set STRICT to the value of the -Warray-bounds=N argument for
     string functions or when N > 1.  */
  int strict = (acs.strict () || warn_array_bounds > 1 ? warn_array_bounds : 0);

  /* The starting offset of the destination write access.  Nonzero only
     for the strcat family of functions.  */
  offset_int wroff = acs.write_off (dstsize);

  /* Validate offsets to each reference before the access first to make
     sure they are within the bounds of the destination object if its
     size is known, or PTRDIFF_MAX otherwise.  */
  opt_code opt
    = maybe_diag_access_bounds (call, func, strict, dstref, wroff, do_warn);
  if (opt == no_warning)
    opt = maybe_diag_access_bounds (call, func, strict, srcref, 0, do_warn);

  if (opt != no_warning)
    {
      if (do_warn)
	suppress_warning (call, opt);
      return opt;
    }

  if (!warn_restrict || bounds_only || !src)
    return no_warning;

  if (!bounds_only)
    {
      switch (DECL_FUNCTION_CODE (func))
	{
	case BUILT_IN_MEMMOVE:
	case BUILT_IN_MEMMOVE_CHK:
	case BUILT_IN_MEMSET:
	case BUILT_IN_MEMSET_CHK:
	  return no_warning;
	default:
	  break;
	}
    }

  location_t loc = gimple_location (call);
  if (operand_equal_p (dst, src, 0))
    {
      /* Issue -Wrestrict unless the pointers are null (those do
	 not point to objects and so do not indicate an overlap;
	 such calls could be the result of sanitization and jump
	 threading).  */
      if (!integer_zerop (dst) && !warning_suppressed_p (call, OPT_Wrestrict))
	{
	  warning_at (loc, OPT_Wrestrict,
		      "%qD source argument is the same as destination",
		      func);
	  suppress_warning (call, OPT_Wrestrict);
	  return OPT_Wrestrict;
	}

      return no_warning;
    }

  /* Return false when overlap has been detected.  */
  if (maybe_diag_overlap (loc, call, acs))
    {
      suppress_warning (call, OPT_Wrestrict);
      return OPT_Wrestrict;
    }

  return no_warning;
}

gimple_opt_pass *
make_pass_warn_restrict (gcc::context *ctxt)
{
  return new pass_wrestrict (ctxt);
}

DEBUG_FUNCTION void
dump_builtin_memref (FILE *fp, const builtin_memref &ref)
{
  fprintf (fp, "\n    ptr = ");
  print_generic_expr (fp, ref.ptr, TDF_LINENO);
  fprintf (fp, "\n    ref = ");
  if (ref.ref)
    print_generic_expr (fp, ref.ref, TDF_LINENO);
  else
    fputs ("null", fp);
  fprintf (fp, "\n    base = ");
  print_generic_expr (fp, ref.base, TDF_LINENO);
  fprintf (fp,
	   "\n    basesize = %lli"
	   "\n    refsize = %lli"
	   "\n    refoff = %lli"
	   "\n    offrange = [%lli, %lli]"
	   "\n    sizrange = [%lli, %lli]"
	   "\n    strbounded_p = %s\n",
	   (long long)ref.basesize.to_shwi (),
	   (long long)ref.refsize.to_shwi (),
	   (long long)ref.refoff.to_shwi (),
	   (long long)ref.offrange[0].to_shwi (),
	   (long long)ref.offrange[1].to_shwi (),
	   (long long)ref.sizrange[0].to_shwi (),
	   (long long)ref.sizrange[1].to_shwi (),
	   ref.strbounded_p ? "true" : "false");
}

void
builtin_access::dump (FILE *fp) const
{
  fprintf (fp, "  dstref:");
  dump_builtin_memref (fp, *dstref);
  fprintf (fp, "\n  srcref:");
  dump_builtin_memref (fp, *srcref);

  fprintf (fp,
	   "  sizrange = [%lli, %lli]\n"
	   "  ovloff = [%lli, %lli]\n"
	   "  ovlsiz = [%lli, %lli]\n"
	   "  dstoff = [%lli, %lli]\n"
	   "  dstsiz = [%lli, %lli]\n"
	   "  srcoff = [%lli, %lli]\n"
	   "  srcsiz = [%lli, %lli]\n",
	   (long long)sizrange[0], (long long)sizrange[1],
	   (long long)ovloff[0], (long long)ovloff[1],
	   (long long)ovlsiz[0], (long long)ovlsiz[1],
	   (long long)dstoff[0].to_shwi (), (long long)dstoff[1].to_shwi (),
	   (long long)dstsiz[0].to_shwi (), (long long)dstsiz[1].to_shwi (),
	   (long long)srcoff[0].to_shwi (), (long long)srcoff[1].to_shwi (),
	   (long long)srcsiz[0].to_shwi (), (long long)srcsiz[1].to_shwi ());
}

DEBUG_FUNCTION void
dump_builtin_access (FILE *fp, gimple *stmt, const builtin_access &acs)
{
  if (stmt)
    {
      fprintf (fp, "\nDumping builtin_access for ");
      print_gimple_expr (fp, stmt, TDF_LINENO);
      fputs (":\n", fp);
    }

  acs.dump (fp);
}

DEBUG_FUNCTION void
debug (gimple *stmt, const builtin_access &acs)
{
  dump_builtin_access (stdout, stmt, acs);
}
