/* String length optimization
   Copyright (C) 2011-2021 Free Software Foundation, Inc.
   Contributed by Jakub Jelinek <jakub@redhat.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "gimple-pretty-print.h"
#include "gimple-ssa-warn-restrict.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "expr.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "domwalk.h"
#include "tree-ssa-alias.h"
#include "tree-ssa-propagate.h"
#include "tree-ssa-strlen.h"
#include "tree-hash-traits.h"
#include "builtins.h"
#include "target.h"
#include "diagnostic-core.h"
#include "diagnostic.h"
#include "intl.h"
#include "attribs.h"
#include "calls.h"
#include "cfgloop.h"
#include "tree-ssa-loop.h"
#include "tree-scalar-evolution.h"
#include "vr-values.h"
#include "gimple-ssa-evrp-analyze.h"
#include "tree-ssa.h"

/* A vector indexed by SSA_NAME_VERSION.  0 means unknown, positive value
   is an index into strinfo vector, negative value stands for
   string length of a string literal (~strlen).  */
static vec<int> ssa_ver_to_stridx;

/* Number of currently active string indexes plus one.  */
static int max_stridx;

/* Set to true to optimize, false when just checking.  */
static bool strlen_optimize;

/* String information record.  */
struct strinfo
{
  /* Number of leading characters that are known to be nonzero.  This is
     also the length of the string if FULL_STRING_P.

     The values in a list of related string pointers must be consistent;
     that is, if strinfo B comes X bytes after strinfo A, it must be
     the case that A->nonzero_chars == X + B->nonzero_chars.  */
  tree nonzero_chars;
  /* Any of the corresponding pointers for querying alias oracle.  */
  tree ptr;
  /* STMT is used for two things:

     - To record the statement that should be used for delayed length
       computations.  We maintain the invariant that all related strinfos
       have delayed lengths or none do.

     - To record the malloc or calloc call that produced this result
       to optimize away malloc/memset sequences.  STMT is reset after
       a calloc-allocated object has been stored a non-zero value into.  */
  gimple *stmt;
  /* Set to the dynamic allocation statement for the object (alloca,
     calloc, malloc, or VLA).  Unlike STMT, once set for a strinfo
     object, ALLOC doesn't change.  */
  gimple *alloc;
  /* Pointer to '\0' if known, if NULL, it can be computed as
     ptr + length.  */
  tree endptr;
  /* Reference count.  Any changes to strinfo entry possibly shared
     with dominating basic blocks need unshare_strinfo first, except
     for dont_invalidate which affects only the immediately next
     maybe_invalidate.  */
  int refcount;
  /* Copy of index.  get_strinfo (si->idx) should return si;  */
  int idx;
  /* These 3 fields are for chaining related string pointers together.
     E.g. for
     bl = strlen (b); dl = strlen (d); strcpy (a, b); c = a + bl;
     strcpy (c, d); e = c + dl;
     strinfo(a) -> strinfo(c) -> strinfo(e)
     All have ->first field equal to strinfo(a)->idx and are doubly
     chained through prev/next fields.  The later strinfos are required
     to point into the same string with zero or more bytes after
     the previous pointer and all bytes in between the two pointers
     must be non-zero.  Functions like strcpy or memcpy are supposed
     to adjust all previous strinfo lengths, but not following strinfo
     lengths (those are uncertain, usually invalidated during
     maybe_invalidate, except when the alias oracle knows better).
     Functions like strcat on the other side adjust the whole
     related strinfo chain.
     They are updated lazily, so to use the chain the same first fields
     and si->prev->next == si->idx needs to be verified.  */
  int first;
  int next;
  int prev;
  /* A flag whether the string is known to be written in the current
     function.  */
  bool writable;
  /* A flag for the next maybe_invalidate that this strinfo shouldn't
     be invalidated.  Always cleared by maybe_invalidate.  */
  bool dont_invalidate;
  /* True if the string is known to be nul-terminated after NONZERO_CHARS
     characters.  False is useful when detecting strings that are built
     up via successive memcpys.  */
  bool full_string_p;
};

/* Pool for allocating strinfo_struct entries.  */
static object_allocator<strinfo> strinfo_pool ("strinfo pool");

/* Vector mapping positive string indexes to strinfo, for the
   current basic block.  The first pointer in the vector is special,
   it is either NULL, meaning the vector isn't shared, or it is
   a basic block pointer to the owner basic_block if shared.
   If some other bb wants to modify the vector, the vector needs
   to be unshared first, and only the owner bb is supposed to free it.  */
static vec<strinfo *, va_heap, vl_embed> *stridx_to_strinfo;

/* One OFFSET->IDX mapping.  */
struct stridxlist
{
  struct stridxlist *next;
  HOST_WIDE_INT offset;
  int idx;
};

/* Hash table entry, mapping a DECL to a chain of OFFSET->IDX mappings.  */
struct decl_stridxlist_map
{
  struct tree_map_base base;
  struct stridxlist list;
};

/* Hash table for mapping decls to a chained list of offset -> idx
   mappings.  */
typedef hash_map<tree_decl_hash, stridxlist> decl_to_stridxlist_htab_t;
static decl_to_stridxlist_htab_t *decl_to_stridxlist_htab;

/* Hash table mapping strlen (or strnlen with constant bound and return
   smaller than bound) calls to stridx instances describing
   the calls' arguments.  Non-null only when warn_stringop_truncation
   is non-zero.  */
typedef std::pair<int, location_t> stridx_strlenloc;
static hash_map<tree, stridx_strlenloc> *strlen_to_stridx;

/* Obstack for struct stridxlist and struct decl_stridxlist_map.  */
static struct obstack stridx_obstack;

/* Last memcpy statement if it could be adjusted if the trailing
   '\0' written is immediately overwritten, or
   *x = '\0' store that could be removed if it is immediately overwritten.  */
struct laststmt_struct
{
  gimple *stmt;
  tree len;
  int stridx;
} laststmt;

static int get_stridx_plus_constant (strinfo *, unsigned HOST_WIDE_INT, tree);
static void handle_builtin_stxncpy_strncat (bool, gimple_stmt_iterator *);

/* Sets MINMAX to either the constant value or the range VAL is in
   and returns either the constant value or VAL on success or null
   when the range couldn't be determined.  Uses RVALS when nonnull
   to determine the range, otherwise get_range_info.  */

tree
get_range (tree val, gimple *stmt, wide_int minmax[2],
	   range_query *rvals /* = NULL */)
{
  if (TREE_CODE (val) == INTEGER_CST)
    {
      minmax[0] = minmax[1] = wi::to_wide (val);
      return val;
    }

  if (TREE_CODE (val) != SSA_NAME)
    return NULL_TREE;

  if (rvals && stmt)
    {
      value_range vr;
      if (!rvals->range_of_expr (vr, val, stmt))
	return NULL_TREE;
      value_range_kind rng = vr.kind ();
      if (rng != VR_RANGE)
	return NULL_TREE;

      minmax[0] = wi::to_wide (vr.min ());
      minmax[1] = wi::to_wide (vr.max ());
      return val;
    }

  value_range_kind rng = get_range_info (val, minmax, minmax + 1);
  if (rng == VR_RANGE)
    /* This may be an inverted range whose MINMAX[1] < MINMAX[0].  */
    return val;

  if (rng == VR_ANTI_RANGE)
    {
      /* An anti-range is the same as an ordinary range with inverted
	 bounds (where MINMAX[1] < MINMAX[0] is true) that may result
	 from the conversion of a signed anti-range to unsigned.  */
      wide_int tmp = minmax[0];
      minmax[0] = minmax[1] + 1;
      minmax[1] = wi::sub (tmp, 1);
      return val;
    }

  /* Do not handle anti-ranges and instead make use of the on-demand
     VRP if/when it becomes available (hopefully in GCC 11).  */
  return NULL_TREE;
}

/* Return:

   *  +1  if SI is known to start with more than OFF nonzero characters.

   *   0  if SI is known to start with exactly OFF nonzero characters.

   *  -1  if SI either does not start with OFF nonzero characters
	  or the relationship between the number of leading nonzero
	  characters in SI and OFF is unknown.  */

static inline int
compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off)
{
  if (si->nonzero_chars
      && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
    return compare_tree_int (si->nonzero_chars, off);
  else
    return -1;
}

/* Same as above but suitable also for strings with non-constant lengths.
   Uses RVALS to determine length range.  */

static int
compare_nonzero_chars (strinfo *si, unsigned HOST_WIDE_INT off,
		       range_query *rvals)
{
  if (!si->nonzero_chars)
    return -1;

  if (TREE_CODE (si->nonzero_chars) == INTEGER_CST)
    return compare_tree_int (si->nonzero_chars, off);

  if (!rvals || TREE_CODE (si->nonzero_chars) != SSA_NAME)
    return -1;

  value_range vr;
  if (!rvals->range_of_expr (vr, si->nonzero_chars, si->stmt))
    return -1;
  value_range_kind rng = vr.kind ();
  if (rng != VR_RANGE)
    return -1;

  /* If the offset is less than the minimum length or if the bounds
     of the length range are equal return the result of the comparison
     same as in the constant case.  Otherwise return a conservative
     result.  */
  int cmpmin = compare_tree_int (vr.min (), off);
  if (cmpmin > 0 || tree_int_cst_equal (vr.min (), vr.max ()))
    return cmpmin;

  return -1;
}

/* Return true if SI is known to be a zero-length string.  */

static inline bool
zero_length_string_p (strinfo *si)
{
  return si->full_string_p && integer_zerop (si->nonzero_chars);
}

/* Return strinfo vector entry IDX.  */

static inline strinfo *
get_strinfo (int idx)
{
  if (vec_safe_length (stridx_to_strinfo) <= (unsigned int) idx)
    return NULL;
  return (*stridx_to_strinfo)[idx];
}

/* Get the next strinfo in the chain after SI, or null if none.  */

static inline strinfo *
get_next_strinfo (strinfo *si)
{
  if (si->next == 0)
    return NULL;
  strinfo *nextsi = get_strinfo (si->next);
  if (nextsi == NULL || nextsi->first != si->first || nextsi->prev != si->idx)
    return NULL;
  return nextsi;
}

/* Helper function for get_stridx.  Return the strinfo index of the address
   of EXP, which is available in PTR if nonnull.  If OFFSET_OUT, it is
   OK to return the index for some X <= &EXP and store &EXP - X in
   *OFFSET_OUT.  When RVALS is nonnull uses it to determine range
   information.  */

static int
get_addr_stridx (tree exp, tree ptr, unsigned HOST_WIDE_INT *offset_out,
		 range_query *rvals = NULL)
{
  HOST_WIDE_INT off;
  struct stridxlist *list, *last = NULL;
  tree base;

  if (!decl_to_stridxlist_htab)
    return 0;

  poly_int64 poff;
  base = get_addr_base_and_unit_offset (exp, &poff);
  if (base == NULL || !DECL_P (base) || !poff.is_constant (&off))
    return 0;

  list = decl_to_stridxlist_htab->get (base);
  if (list == NULL)
    return 0;

  do
    {
      if (list->offset == off)
	{
	  if (offset_out)
	    *offset_out = 0;
	  return list->idx;
	}
      if (list->offset > off)
	return 0;
      last = list;
      list = list->next;
    }
  while (list);

  if ((offset_out || ptr) && last && last->idx > 0)
    {
      unsigned HOST_WIDE_INT rel_off
	= (unsigned HOST_WIDE_INT) off - last->offset;
      strinfo *si = get_strinfo (last->idx);
      if (si && compare_nonzero_chars (si, rel_off, rvals) >= 0)
	{
	  if (offset_out)
	    {
	      *offset_out = rel_off;
	      return last->idx;
	    }
	  else
	    return get_stridx_plus_constant (si, rel_off, ptr);
	}
    }
  return 0;
}

/* Returns string index for EXP.  When EXP is an SSA_NAME that refers
   to a known strinfo with an offset and OFFRNG is non-null, sets
   both elements of the OFFRNG array to the range of the offset and
   returns the index of the known strinfo.  In this case the result
   must not be used in for functions that modify the string.
   When nonnull, uses RVALS to determine range information.  */

static int
get_stridx (tree exp, wide_int offrng[2] = NULL, range_query *rvals = NULL)
{
  if (offrng)
    offrng[0] = offrng[1] = wi::zero (TYPE_PRECISION (ptrdiff_type_node));

  if (TREE_CODE (exp) == SSA_NAME)
    {
      if (ssa_ver_to_stridx[SSA_NAME_VERSION (exp)])
	return ssa_ver_to_stridx[SSA_NAME_VERSION (exp)];

      tree e = exp;
      int last_idx = 0;
      HOST_WIDE_INT offset = 0;
      /* Follow a chain of at most 5 assignments.  */
      for (int i = 0; i < 5; i++)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (e);
	  if (!is_gimple_assign (def_stmt))
	    return last_idx;

	  tree_code rhs_code = gimple_assign_rhs_code (def_stmt);
	  tree ptr, off;

	  if (rhs_code == ADDR_EXPR)
	    {
	      /* Handle indices/offsets into VLAs which are implemented
	         as pointers to arrays.  */
	      ptr = gimple_assign_rhs1 (def_stmt);
	      ptr = TREE_OPERAND (ptr, 0);

	      /* Handle also VLAs of types larger than char.  */
	      if (tree eltsize = TYPE_SIZE_UNIT (TREE_TYPE (ptr)))
		{
		  if (TREE_CODE (ptr) == ARRAY_REF)
		    {
		      off = TREE_OPERAND (ptr, 1);
		      ptr = TREE_OPERAND (ptr, 0);
		      if (!integer_onep (eltsize))
			{
			  /* Scale the array index by the size of the element
			     type in the rare case that it's greater than
			     the typical 1 for char, making sure both operands
			     have the same type.  */
			  eltsize = fold_convert (ssizetype, eltsize);
			  off = fold_convert (ssizetype, off);
			  off = fold_build2 (MULT_EXPR, ssizetype, off, eltsize);
			}
		    }
		  else
		    off = integer_zero_node;
		}
	      else
		return 0;

	      if (TREE_CODE (ptr) != MEM_REF)
	        return 0;

	      /* Add the MEM_REF byte offset.  */
	      tree mem_off = TREE_OPERAND (ptr, 1);
	      off = fold_build2 (PLUS_EXPR, TREE_TYPE (off), off, mem_off);
	      ptr = TREE_OPERAND (ptr, 0);
	    }
	  else if (rhs_code == POINTER_PLUS_EXPR)
	    {
	      ptr = gimple_assign_rhs1 (def_stmt);
	      off = gimple_assign_rhs2 (def_stmt);
	    }
	  else
	    return 0;

	  if (TREE_CODE (ptr) != SSA_NAME)
	    return 0;

	  if (!tree_fits_shwi_p (off))
	    {
	      if (int idx = ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)])
		if (offrng)
		  {
		    /* Only when requested by setting OFFRNG to non-null,
		       return the index corresponding to the SSA_NAME.
		       Do this irrespective of the whether the offset
		       is known.  */
		    if (get_range (off, def_stmt, offrng, rvals))
		      {
			/* When the offset range is known, increment it
			   it by the constant offset computed in prior
			   iterations and store it in the OFFRNG array.  */
 			offrng[0] += offset;
			offrng[1] += offset;
		      }
		    else
		      {
			/* When the offset range cannot be determined
			   store [0, SIZE_MAX] and let the caller decide
			   if the offset matters.  */
			offrng[1] = wi::to_wide (TYPE_MAX_VALUE (sizetype));
			offrng[0] = wi::zero (offrng[1].get_precision ());
		      }
		    return idx;
		  }
	      return 0;
	    }

	  HOST_WIDE_INT this_off = tree_to_shwi (off);
	  if (offrng)
	    {
	      offrng[0] += wi::shwi (this_off, offrng->get_precision ());
	      offrng[1] += offrng[0];
	    }

	  if (this_off < 0)
	    return last_idx;

	  offset = (unsigned HOST_WIDE_INT) offset + this_off;
	  if (offset < 0)
	    return last_idx;

	  if (int idx = ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)])
	    {
	      strinfo *si = get_strinfo (idx);
	      if (si)
		{
		  if (compare_nonzero_chars (si, offset) >= 0)
		    return get_stridx_plus_constant (si, offset, exp);

		  if (offrng)
		    last_idx = idx;
		}
	    }
	  e = ptr;
	}

      return last_idx;
    }

  if (TREE_CODE (exp) == ADDR_EXPR)
    {
      int idx = get_addr_stridx (TREE_OPERAND (exp, 0), exp, NULL);
      if (idx != 0)
	return idx;
    }

  const char *p = c_getstr (exp);
  if (p)
    return ~(int) strlen (p);

  return 0;
}

/* Return true if strinfo vector is shared with the immediate dominator.  */

static inline bool
strinfo_shared (void)
{
  return vec_safe_length (stridx_to_strinfo)
	 && (*stridx_to_strinfo)[0] != NULL;
}

/* Unshare strinfo vector that is shared with the immediate dominator.  */

static void
unshare_strinfo_vec (void)
{
  strinfo *si;
  unsigned int i = 0;

  gcc_assert (strinfo_shared ());
  stridx_to_strinfo = vec_safe_copy (stridx_to_strinfo);
  for (i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
    if (si != NULL)
      si->refcount++;
  (*stridx_to_strinfo)[0] = NULL;
}

/* Attempt to create a string index for exp, ADDR_EXPR's operand.
   Return a pointer to the location where the string index can
   be stored (if 0) or is stored, or NULL if this can't be tracked.  */

static int *
addr_stridxptr (tree exp)
{
  HOST_WIDE_INT off;

  poly_int64 poff;
  tree base = get_addr_base_and_unit_offset (exp, &poff);
  if (base == NULL_TREE || !DECL_P (base) || !poff.is_constant (&off))
    return NULL;

  if (!decl_to_stridxlist_htab)
    {
      decl_to_stridxlist_htab
       	= new hash_map<tree_decl_hash, stridxlist> (64);
      gcc_obstack_init (&stridx_obstack);
    }

  bool existed;
  stridxlist *list = &decl_to_stridxlist_htab->get_or_insert (base, &existed);
  if (existed)
    {
      int i;
      stridxlist *before = NULL;
      for (i = 0; i < 32; i++)
	{
	  if (list->offset == off)
	    return &list->idx;
	  if (list->offset > off && before == NULL)
	    before = list;
	  if (list->next == NULL)
	    break;
	  list = list->next;
	}
      if (i == 32)
	return NULL;
      if (before)
	{
	  list = before;
	  before = XOBNEW (&stridx_obstack, struct stridxlist);
	  *before = *list;
	  list->next = before;
	  list->offset = off;
	  list->idx = 0;
	  return &list->idx;
	}
      list->next = XOBNEW (&stridx_obstack, struct stridxlist);
      list = list->next;
    }

  list->next = NULL;
  list->offset = off;
  list->idx = 0;
  return &list->idx;
}

/* Create a new string index, or return 0 if reached limit.  */

static int
new_stridx (tree exp)
{
  int idx;
  if (max_stridx >= param_max_tracked_strlens)
    return 0;
  if (TREE_CODE (exp) == SSA_NAME)
    {
      if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (exp))
	return 0;
      idx = max_stridx++;
      ssa_ver_to_stridx[SSA_NAME_VERSION (exp)] = idx;
      return idx;
    }
  if (TREE_CODE (exp) == ADDR_EXPR)
    {
      int *pidx = addr_stridxptr (TREE_OPERAND (exp, 0));
      if (pidx != NULL)
	{
	  gcc_assert (*pidx == 0);
	  *pidx = max_stridx++;
	  return *pidx;
	}
    }
  return 0;
}

/* Like new_stridx, but for ADDR_EXPR's operand instead.  */

static int
new_addr_stridx (tree exp)
{
  int *pidx;
  if (max_stridx >= param_max_tracked_strlens)
    return 0;
  pidx = addr_stridxptr (exp);
  if (pidx != NULL)
    {
      gcc_assert (*pidx == 0);
      *pidx = max_stridx++;
      return *pidx;
    }
  return 0;
}

/* Create a new strinfo.  */

static strinfo *
new_strinfo (tree ptr, int idx, tree nonzero_chars, bool full_string_p)
{
  strinfo *si = strinfo_pool.allocate ();
  si->nonzero_chars = nonzero_chars;
  STRIP_USELESS_TYPE_CONVERSION (ptr);
  si->ptr = ptr;
  si->stmt = NULL;
  si->alloc = NULL;
  si->endptr = NULL_TREE;
  si->refcount = 1;
  si->idx = idx;
  si->first = 0;
  si->prev = 0;
  si->next = 0;
  si->writable = false;
  si->dont_invalidate = false;
  si->full_string_p = full_string_p;
  return si;
}

/* Decrease strinfo refcount and free it if not referenced anymore.  */

static inline void
free_strinfo (strinfo *si)
{
  if (si && --si->refcount == 0)
    strinfo_pool.remove (si);
}

/* Set strinfo in the vector entry IDX to SI.  */

static inline void
set_strinfo (int idx, strinfo *si)
{
  if (vec_safe_length (stridx_to_strinfo) && (*stridx_to_strinfo)[0])
    unshare_strinfo_vec ();
  if (vec_safe_length (stridx_to_strinfo) <= (unsigned int) idx)
    vec_safe_grow_cleared (stridx_to_strinfo, idx + 1, true);
  (*stridx_to_strinfo)[idx] = si;
}

/* Return the first strinfo in the related strinfo chain
   if all strinfos in between belong to the chain, otherwise NULL.  */

static strinfo *
verify_related_strinfos (strinfo *origsi)
{
  strinfo *si = origsi, *psi;

  if (origsi->first == 0)
    return NULL;
  for (; si->prev; si = psi)
    {
      if (si->first != origsi->first)
	return NULL;
      psi = get_strinfo (si->prev);
      if (psi == NULL)
	return NULL;
      if (psi->next != si->idx)
	return NULL;
    }
  if (si->idx != si->first)
    return NULL;
  return si;
}

/* Set SI's endptr to ENDPTR and compute its length based on SI->ptr.
   Use LOC for folding.  */

static void
set_endptr_and_length (location_t loc, strinfo *si, tree endptr)
{
  si->endptr = endptr;
  si->stmt = NULL;
  tree start_as_size = fold_convert_loc (loc, size_type_node, si->ptr);
  tree end_as_size = fold_convert_loc (loc, size_type_node, endptr);
  si->nonzero_chars = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
				       end_as_size, start_as_size);
  si->full_string_p = true;
}

/* Return the string length, or NULL if it can't be computed.
   The length may but need not be constant.  Instead, it might be
   the result of a strlen() call.  */

static tree
get_string_length (strinfo *si)
{
  /* If the length has already been computed return it if it's exact
     (i.e., the string is nul-terminated at NONZERO_CHARS), or return
     null if it isn't.  */
  if (si->nonzero_chars)
    return si->full_string_p ? si->nonzero_chars : NULL;

  /* If the string is the result of one of the built-in calls below
     attempt to compute the length from the call statement.  */
  if (si->stmt)
    {
      gimple *stmt = si->stmt, *lenstmt;
      tree callee, lhs, fn, tem;
      location_t loc;
      gimple_stmt_iterator gsi;

      gcc_assert (is_gimple_call (stmt));
      callee = gimple_call_fndecl (stmt);
      gcc_assert (callee && fndecl_built_in_p (callee, BUILT_IN_NORMAL));
      lhs = gimple_call_lhs (stmt);
      /* unshare_strinfo is intentionally not called here.  The (delayed)
	 transformation of strcpy or strcat into stpcpy is done at the place
	 of the former strcpy/strcat call and so can affect all the strinfos
	 with the same stmt.  If they were unshared before and transformation
	 has been already done, the handling of BUILT_IN_STPCPY{,_CHK} should
	 just compute the right length.  */
      switch (DECL_FUNCTION_CODE (callee))
	{
	case BUILT_IN_STRCAT:
	case BUILT_IN_STRCAT_CHK:
	  gsi = gsi_for_stmt (stmt);
	  fn = builtin_decl_implicit (BUILT_IN_STRLEN);
	  gcc_assert (lhs == NULL_TREE);
	  tem = unshare_expr (gimple_call_arg (stmt, 0));
	  lenstmt = gimple_build_call (fn, 1, tem);
	  lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), lenstmt);
	  gimple_call_set_lhs (lenstmt, lhs);
	  gimple_set_vuse (lenstmt, gimple_vuse (stmt));
	  gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT);
	  tem = gimple_call_arg (stmt, 0);
          if (!ptrofftype_p (TREE_TYPE (lhs)))
            {
              lhs = convert_to_ptrofftype (lhs);
              lhs = force_gimple_operand_gsi (&gsi, lhs, true, NULL_TREE,
                                              true, GSI_SAME_STMT);
            }
	  lenstmt = gimple_build_assign
			(make_ssa_name (TREE_TYPE (gimple_call_arg (stmt, 0))),
			 POINTER_PLUS_EXPR,tem, lhs);
	  gsi_insert_before (&gsi, lenstmt, GSI_SAME_STMT);
	  gimple_call_set_arg (stmt, 0, gimple_assign_lhs (lenstmt));
	  lhs = NULL_TREE;
	  /* FALLTHRU */
	case BUILT_IN_STRCPY:
	case BUILT_IN_STRCPY_CHK:
	  gcc_assert (builtin_decl_implicit_p (BUILT_IN_STPCPY));
	  if (gimple_call_num_args (stmt) == 2)
	    fn = builtin_decl_implicit (BUILT_IN_STPCPY);
	  else
	    fn = builtin_decl_explicit (BUILT_IN_STPCPY_CHK);
	  gcc_assert (lhs == NULL_TREE);
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	    {
	      fprintf (dump_file, "Optimizing: ");
	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	    }
	  gimple_call_set_fndecl (stmt, fn);
	  lhs = make_ssa_name (TREE_TYPE (TREE_TYPE (fn)), stmt);
	  gimple_call_set_lhs (stmt, lhs);
	  update_stmt (stmt);
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	    {
	      fprintf (dump_file, "into: ");
	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	    }
	  /* FALLTHRU */
	case BUILT_IN_STPCPY:
	case BUILT_IN_STPCPY_CHK:
	  gcc_assert (lhs != NULL_TREE);
	  loc = gimple_location (stmt);
	  set_endptr_and_length (loc, si, lhs);
	  for (strinfo *chainsi = verify_related_strinfos (si);
	       chainsi != NULL;
	       chainsi = get_next_strinfo (chainsi))
	    if (chainsi->nonzero_chars == NULL)
	      set_endptr_and_length (loc, chainsi, lhs);
	  break;
	case BUILT_IN_ALLOCA:
	case BUILT_IN_ALLOCA_WITH_ALIGN:
	case BUILT_IN_MALLOC:
	  break;
	/* BUILT_IN_CALLOC always has si->nonzero_chars set.  */
	default:
	  gcc_unreachable ();
	  break;
	}
    }

  return si->nonzero_chars;
}

/* Dump strlen data to FP for statement STMT.  When non-null, RVALS
   points to the valuation engine used to calculate ranges, and is
   used to dump strlen range for non-constant results.  */

DEBUG_FUNCTION void
dump_strlen_info (FILE *fp, gimple *stmt, range_query *rvals)
{
  if (stmt)
    {
      fprintf (fp, "\nDumping strlen pass data after ");
      print_gimple_expr (fp, stmt, TDF_LINENO);
      fputc ('\n', fp);
    }
  else
    fprintf (fp, "\nDumping strlen pass data\n");

  fprintf (fp, "max_stridx = %i\n", max_stridx);
  fprintf (fp, "ssa_ver_to_stridx has %u elements\n",
	   ssa_ver_to_stridx.length ());
  fprintf (fp, "stridx_to_strinfo");
  if (stridx_to_strinfo)
    {
      fprintf (fp, " has %u elements\n", stridx_to_strinfo->length ());
      for (unsigned i = 0; i != stridx_to_strinfo->length (); ++i)
	{
	  if (strinfo *si = (*stridx_to_strinfo)[i])
	    {
	      if (!si->idx)
		continue;
	      fprintf (fp, "  idx = %i", si->idx);
	      if (si->ptr)
		{
		  fprintf (fp, ", ptr = ");
		  print_generic_expr (fp, si->ptr);
		}

	      if (si->nonzero_chars)
		{
		  fprintf (fp, ", nonzero_chars = ");
		  print_generic_expr (fp, si->nonzero_chars);
		  if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
		    {
		      value_range_kind rng = VR_UNDEFINED;
		      wide_int min, max;
		      if (rvals)
			{
			  value_range vr;
			  rvals->range_of_expr (vr, si->nonzero_chars,
						si->stmt);
			  rng = vr.kind ();
			  if (range_int_cst_p (&vr))
			    {
			      min = wi::to_wide (vr.min ());
			      max = wi::to_wide (vr.max ());
			    }
			  else
			    rng = VR_UNDEFINED;
			}
		      else
			rng = get_range_info (si->nonzero_chars, &min, &max);

		      if (rng == VR_RANGE || rng == VR_ANTI_RANGE)
			{
			  fprintf (fp, " %s[%llu, %llu]",
				   rng == VR_RANGE ? "" : "~",
				   (long long) min.to_uhwi (),
				   (long long) max.to_uhwi ());
			}
		    }
		}

	      fprintf (fp, ", refcount = %i", si->refcount);
	      if (si->stmt)
		{
		  fprintf (fp, ", stmt = ");
		  print_gimple_expr (fp, si->stmt, 0);
		}
	      if (si->alloc)
		{
		  fprintf (fp, ", alloc = ");
		  print_gimple_expr (fp, si->alloc, 0);
		}
	      if (si->writable)
		fprintf (fp, ", writable");
	      if (si->dont_invalidate)
		fprintf (fp, ", dont_invalidate");
	      if (si->full_string_p)
		fprintf (fp, ", full_string_p");
	      if (strinfo *next = get_next_strinfo (si))
		{
		  fprintf (fp, ", {");
		  do
		    fprintf (fp, "%i%s", next->idx, next->first ? ", " : "");
		  while ((next = get_next_strinfo (next)));
		  fprintf (fp, "}");
		}
	      fputs ("\n", fp);
	    }
	}
    }
  else
    fprintf (fp, " = null\n");

  fprintf (fp, "decl_to_stridxlist_htab");
  if (decl_to_stridxlist_htab)
    {
      fputs ("\n", fp);
      typedef decl_to_stridxlist_htab_t::iterator iter_t;
      for (iter_t it = decl_to_stridxlist_htab->begin ();
	   it != decl_to_stridxlist_htab->end (); ++it)
	{
	  tree decl = (*it).first;
	  stridxlist *list = &(*it).second;
	  fprintf (fp, "  decl = ");
	  print_generic_expr (fp, decl);
	  if (list)
	    {
	      fprintf (fp, ", offsets = {");
	      for (; list; list = list->next)
		fprintf (fp, "%lli%s", (long long) list->offset,
			 list->next ? ", " : "");
	      fputs ("}", fp);
	    }
	  fputs ("\n", fp);
	}
    }
  else
    fprintf (fp, " = null\n");

  if (laststmt.stmt)
    {
      fprintf (fp, "laststmt = ");
      print_gimple_expr (fp, laststmt.stmt, 0);
      fprintf (fp, ", len = ");
      print_generic_expr (fp, laststmt.len);
      fprintf (fp, ", stridx = %i\n", laststmt.stridx);
    }
}

/* Attempt to determine the length of the string SRC.  On success, store
   the length in *PDATA and return true.  Otherwise, return false.
   VISITED is a bitmap of visited PHI nodes.  RVALS points to the valuation
   engine used to calculate ranges.  PSSA_DEF_MAX to an SSA_NAME
   assignment limit used to prevent runaway recursion.  */

static bool
get_range_strlen_dynamic (tree src, gimple *stmt,
			  c_strlen_data *pdata, bitmap *visited,
			  range_query *rvals, unsigned *pssa_def_max)
{
  int idx = get_stridx (src);
  if (!idx)
    {
      if (TREE_CODE (src) == SSA_NAME)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (src);
	  if (gimple_code (def_stmt) == GIMPLE_PHI)
	    {
	      if (!*visited)
		*visited = BITMAP_ALLOC (NULL);

	      if (!bitmap_set_bit (*visited, SSA_NAME_VERSION (src)))
		return true;

	      if (*pssa_def_max == 0)
		return false;

	      --*pssa_def_max;

	      /* Iterate over the PHI arguments and determine the minimum
		 and maximum length/size of each and incorporate them into
		 the overall result.  */
	      gphi *phi = as_a <gphi *> (def_stmt);
	      for (unsigned i = 0; i != gimple_phi_num_args (phi); ++i)
		{
		  tree arg = gimple_phi_arg_def (phi, i);
		  if (arg == gimple_phi_result (def_stmt))
		    continue;

		  c_strlen_data argdata = { };
		  if (get_range_strlen_dynamic (arg, phi, &argdata, visited,
						rvals, pssa_def_max))
		    {
		      /* Set the DECL of an unterminated array this argument
			 refers to if one hasn't been found yet.  */
		      if (!pdata->decl && argdata.decl)
			pdata->decl = argdata.decl;

		      if (!argdata.minlen
			  || (integer_zerop (argdata.minlen)
			      && (!argdata.maxbound
				  || integer_all_onesp (argdata.maxbound))
			      && integer_all_onesp (argdata.maxlen)))
			{
			  /* Set the upper bound of the length to unbounded.  */
			  pdata->maxlen = build_all_ones_cst (size_type_node);
			  continue;
			}

		      /* Adjust the minimum and maximum length determined
			 so far and the upper bound on the array size.  */
		      if (!pdata->minlen
			  || tree_int_cst_lt (argdata.minlen, pdata->minlen))
			pdata->minlen = argdata.minlen;
		      if (!pdata->maxlen
			  || (argdata.maxlen
			      && tree_int_cst_lt (pdata->maxlen, argdata.maxlen)))
			pdata->maxlen = argdata.maxlen;
		      if (!pdata->maxbound
			  || TREE_CODE (pdata->maxbound) != INTEGER_CST
			  || (argdata.maxbound
			      && tree_int_cst_lt (pdata->maxbound,
						  argdata.maxbound)
			      && !integer_all_onesp (argdata.maxbound)))
			pdata->maxbound = argdata.maxbound;
		    }
		  else
		    pdata->maxlen = build_all_ones_cst (size_type_node);
		}

	      return true;
	    }
	}

      /* Return success regardless of the result and handle *PDATA
	 in the caller.  */
      get_range_strlen (src, pdata, 1);
      return true;
    }

  if (idx < 0)
    {
      /* SRC is a string of constant length.  */
      pdata->minlen = build_int_cst (size_type_node, ~idx);
      pdata->maxlen = pdata->minlen;
      pdata->maxbound = pdata->maxlen;
      return true;
    }

  if (strinfo *si = get_strinfo (idx))
    {
      pdata->minlen = get_string_length (si);
      if (!pdata->minlen && si->nonzero_chars)
	{
	  if (TREE_CODE (si->nonzero_chars) == INTEGER_CST)
	    pdata->minlen = si->nonzero_chars;
	  else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
	    {
	      value_range vr;
	      rvals->range_of_expr (vr, si->nonzero_chars, si->stmt);
	      if (range_int_cst_p (&vr))
		{
		  pdata->minlen = vr.min ();
		  pdata->maxlen = vr.max ();
		}
	      else
		pdata->minlen = build_zero_cst (size_type_node);
	    }
	  else
	    pdata->minlen = build_zero_cst (size_type_node);

	  tree base = si->ptr;
	  if (TREE_CODE (base) == ADDR_EXPR)
	    base = TREE_OPERAND (base, 0);

	  HOST_WIDE_INT off;
	  poly_int64 poff;
	  base = get_addr_base_and_unit_offset (base, &poff);
	  if (base
	      && DECL_P (base)
	      && TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE
	      && TYPE_SIZE_UNIT (TREE_TYPE (base))
	      && poff.is_constant (&off))
	    {
	      tree basetype = TREE_TYPE (base);
	      tree size = TYPE_SIZE_UNIT (basetype);
	      if (TREE_CODE (size) == INTEGER_CST)
		{
		  ++off;   /* Increment for the terminating nul.  */
		  tree toffset = build_int_cst (size_type_node, off);
		  pdata->maxlen = fold_build2 (MINUS_EXPR, size_type_node, size,
					       toffset);
		  pdata->maxbound = pdata->maxlen;
		}
	      else	
		pdata->maxlen = build_all_ones_cst (size_type_node);
	    }
	  else
	    pdata->maxlen = build_all_ones_cst (size_type_node);
	}
      else if (pdata->minlen && TREE_CODE (pdata->minlen) == SSA_NAME)
	{
	  value_range vr;
	  rvals->range_of_expr (vr, si->nonzero_chars, stmt);
	  if (range_int_cst_p (&vr))
	    {
	      pdata->minlen = vr.min ();
	      pdata->maxlen = vr.max ();
	      pdata->maxbound = pdata->maxlen;
	    }
	  else
	    {
	      pdata->minlen = build_zero_cst (size_type_node);
	      pdata->maxlen = build_all_ones_cst (size_type_node);
	    }
	}
      else if (pdata->minlen && TREE_CODE (pdata->minlen) == INTEGER_CST)
	{
	  pdata->maxlen = pdata->minlen;
	  pdata->maxbound = pdata->minlen;
	}
      else
	{
	  /* For PDATA->MINLEN that's a non-constant expression such
	     as PLUS_EXPR whose value range is unknown, set the bounds
	     to zero and SIZE_MAX.  */
	  pdata->minlen = build_zero_cst (size_type_node);
	  pdata->maxlen = build_all_ones_cst (size_type_node);
	}

      return true;
    }

  return false;
}

/* Analogous to get_range_strlen but for dynamically created strings,
   i.e., those created by calls to strcpy as opposed to just string
   constants.
   Try to obtain the range of the lengths of the string(s) referenced
   by SRC, or the size of the largest array SRC refers to if the range
   of lengths cannot be determined, and store all in *PDATA.  RVALS
   points to the valuation engine used to calculate ranges.  */

void
get_range_strlen_dynamic (tree src, gimple *stmt, c_strlen_data *pdata,
			  range_query *rvals)
{
  bitmap visited = NULL;
  tree maxbound = pdata->maxbound;

  unsigned limit = param_ssa_name_def_chain_limit;
  if (!get_range_strlen_dynamic (src, stmt, pdata, &visited, rvals, &limit))
    {
      /* On failure extend the length range to an impossible maximum
	 (a valid MAXLEN must be less than PTRDIFF_MAX - 1).  Other
	 members can stay unchanged regardless.  */
      pdata->minlen = ssize_int (0);
      pdata->maxlen = build_all_ones_cst (size_type_node);
    }
  else if (!pdata->minlen)
    pdata->minlen = ssize_int (0);

  /* If it's unchanged from it initial non-null value, set the conservative
     MAXBOUND to SIZE_MAX.  Otherwise leave it null (if it is null).  */
  if (maxbound && pdata->maxbound == maxbound)
    pdata->maxbound = build_all_ones_cst (size_type_node);

  if (visited)
    BITMAP_FREE (visited);
}

/* Invalidate string length information for strings whose length might
   change due to stores in STMT, except those marked DONT_INVALIDATE.
   For string-modifying statements, ZERO_WRITE is set when the statement
   wrote only zeros.
   Returns true if any STRIDX_TO_STRINFO entries were considered
   for invalidation.  */

static bool
maybe_invalidate (gimple *stmt, bool zero_write = false)
{
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "%s called for ", __func__);
      print_gimple_stmt (dump_file, stmt, TDF_LINENO);
    }

  strinfo *si;
  bool nonempty = false;

  for (unsigned i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
    {
      if (si == NULL || !POINTER_TYPE_P (TREE_TYPE (si->ptr)))
	continue;

      nonempty = true;

      /* Unconditionally reset DONT_INVALIDATE.  */
      bool dont_invalidate = si->dont_invalidate;
      si->dont_invalidate = false;

      if (dont_invalidate)
	continue;

      ao_ref r;
      tree size = NULL_TREE;
      if (si->nonzero_chars)
	{
	  /* Include the terminating nul in the size of the string
	     to consider when determining possible clobber.  */
	  tree type = TREE_TYPE (si->nonzero_chars);
	  size = fold_build2 (PLUS_EXPR, type, si->nonzero_chars,
			      build_int_cst (type, 1));
	}
      ao_ref_init_from_ptr_and_size (&r, si->ptr, size);
      if (stmt_may_clobber_ref_p_1 (stmt, &r))
	{
	  if (dump_file && (dump_flags & TDF_DETAILS))
	    {
	      fputs ("  statement may clobber object ", dump_file);
	      print_generic_expr (dump_file, si->ptr);
	      if (size && tree_fits_uhwi_p (size))
		fprintf (dump_file, " " HOST_WIDE_INT_PRINT_UNSIGNED
			 " bytes in size", tree_to_uhwi (size));
	      fputc ('\n', dump_file);
	    }

	  set_strinfo (i, NULL);
	  free_strinfo (si);
	  continue;
	}

      if (size
	  && !zero_write
	  && si->stmt
	  && is_gimple_call (si->stmt)
	  && (DECL_FUNCTION_CODE (gimple_call_fndecl (si->stmt))
	      == BUILT_IN_CALLOC))
	{
	  /* If the clobber test above considered the length of
	     the string (including the nul), then for (potentially)
	     non-zero writes that might modify storage allocated by
	     calloc consider the whole object and if it might be
	     clobbered by the statement reset the statement.  */
	  ao_ref_init_from_ptr_and_size (&r, si->ptr, NULL_TREE);
	  if (stmt_may_clobber_ref_p_1 (stmt, &r))
	    si->stmt = NULL;
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    fprintf (dump_file, "%s returns %i\n", __func__, nonempty);

  return nonempty;
}

/* Unshare strinfo record SI, if it has refcount > 1 or
   if stridx_to_strinfo vector is shared with some other
   bbs.  */

static strinfo *
unshare_strinfo (strinfo *si)
{
  strinfo *nsi;

  if (si->refcount == 1 && !strinfo_shared ())
    return si;

  nsi = new_strinfo (si->ptr, si->idx, si->nonzero_chars, si->full_string_p);
  nsi->stmt = si->stmt;
  nsi->alloc = si->alloc;
  nsi->endptr = si->endptr;
  nsi->first = si->first;
  nsi->prev = si->prev;
  nsi->next = si->next;
  nsi->writable = si->writable;
  set_strinfo (si->idx, nsi);
  free_strinfo (si);
  return nsi;
}

/* Attempt to create a new strinfo for BASESI + OFF, or find existing
   strinfo if there is any.  Return it's idx, or 0 if no strinfo has
   been created.  */

static int
get_stridx_plus_constant (strinfo *basesi, unsigned HOST_WIDE_INT off,
			  tree ptr)
{
  if (TREE_CODE (ptr) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr))
    return 0;

  if (compare_nonzero_chars (basesi, off) < 0
      || !tree_fits_uhwi_p (basesi->nonzero_chars))
    return 0;

  unsigned HOST_WIDE_INT nonzero_chars
    = tree_to_uhwi (basesi->nonzero_chars) - off;
  strinfo *si = basesi, *chainsi;
  if (si->first || si->prev || si->next)
    si = verify_related_strinfos (basesi);
  if (si == NULL
      || si->nonzero_chars == NULL_TREE
      || TREE_CODE (si->nonzero_chars) != INTEGER_CST)
    return 0;

  if (TREE_CODE (ptr) == SSA_NAME
      && ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
    ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);

  gcc_checking_assert (compare_tree_int (si->nonzero_chars, off) != -1);
  for (chainsi = si; chainsi->next; chainsi = si)
    {
      si = get_next_strinfo (chainsi);
      if (si == NULL
	  || si->nonzero_chars == NULL_TREE
	  || TREE_CODE (si->nonzero_chars) != INTEGER_CST)
	break;
      int r = compare_tree_int (si->nonzero_chars, nonzero_chars);
      if (r != 1)
	{
	  if (r == 0)
	    {
	      if (TREE_CODE (ptr) == SSA_NAME)
		ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = si->idx;
	      else
		{
		  int *pidx = addr_stridxptr (TREE_OPERAND (ptr, 0));
		  if (pidx != NULL && *pidx == 0)
		    *pidx = si->idx;
		}
	      return si->idx;
	    }
	  break;
	}
    }

  int idx = new_stridx (ptr);
  if (idx == 0)
    return 0;
  si = new_strinfo (ptr, idx, build_int_cst (size_type_node, nonzero_chars),
		    basesi->full_string_p);
  set_strinfo (idx, si);
  if (strinfo *nextsi = get_strinfo (chainsi->next))
    {
      nextsi = unshare_strinfo (nextsi);
      si->next = nextsi->idx;
      nextsi->prev = idx;
    }
  chainsi = unshare_strinfo (chainsi);
  if (chainsi->first == 0)
    chainsi->first = chainsi->idx;
  chainsi->next = idx;
  if (chainsi->endptr == NULL_TREE && zero_length_string_p (si))
    chainsi->endptr = ptr;
  si->endptr = chainsi->endptr;
  si->prev = chainsi->idx;
  si->first = chainsi->first;
  si->writable = chainsi->writable;
  return si->idx;
}

/* Note that PTR, a pointer SSA_NAME initialized in the current stmt, points
   to a zero-length string and if possible chain it to a related strinfo
   chain whose part is or might be CHAINSI.  */

static strinfo *
zero_length_string (tree ptr, strinfo *chainsi)
{
  strinfo *si;
  int idx;
  if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
    ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
  gcc_checking_assert (TREE_CODE (ptr) == SSA_NAME
		       && ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] == 0);

  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ptr))
    return NULL;
  if (chainsi != NULL)
    {
      si = verify_related_strinfos (chainsi);
      if (si)
	{
	  do
	    {
	      /* We shouldn't mix delayed and non-delayed lengths.  */
	      gcc_assert (si->full_string_p);
	      if (si->endptr == NULL_TREE)
		{
		  si = unshare_strinfo (si);
		  si->endptr = ptr;
		}
	      chainsi = si;
	      si = get_next_strinfo (si);
	    }
	  while (si != NULL);
	  if (zero_length_string_p (chainsi))
	    {
	      if (chainsi->next)
		{
		  chainsi = unshare_strinfo (chainsi);
		  chainsi->next = 0;
		}
	      ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = chainsi->idx;
	      return chainsi;
	    }
	}
      else
	{
	  /* We shouldn't mix delayed and non-delayed lengths.  */
	  gcc_assert (chainsi->full_string_p);
	  if (chainsi->first || chainsi->prev || chainsi->next)
	    {
	      chainsi = unshare_strinfo (chainsi);
	      chainsi->first = 0;
	      chainsi->prev = 0;
	      chainsi->next = 0;
	    }
	}
    }
  idx = new_stridx (ptr);
  if (idx == 0)
    return NULL;
  si = new_strinfo (ptr, idx, build_int_cst (size_type_node, 0), true);
  set_strinfo (idx, si);
  si->endptr = ptr;
  if (chainsi != NULL)
    {
      chainsi = unshare_strinfo (chainsi);
      if (chainsi->first == 0)
	chainsi->first = chainsi->idx;
      chainsi->next = idx;
      if (chainsi->endptr == NULL_TREE)
	chainsi->endptr = ptr;
      si->prev = chainsi->idx;
      si->first = chainsi->first;
      si->writable = chainsi->writable;
    }
  return si;
}

/* For strinfo ORIGSI whose length has been just updated, adjust other
   related strinfos so that they match the new ORIGSI.  This involves:

   - adding ADJ to the nonzero_chars fields
   - copying full_string_p from the new ORIGSI.  */

static void
adjust_related_strinfos (location_t loc, strinfo *origsi, tree adj)
{
  strinfo *si = verify_related_strinfos (origsi);

  if (si == NULL)
    return;

  while (1)
    {
      strinfo *nsi;

      if (si != origsi)
	{
	  tree tem;

	  si = unshare_strinfo (si);
	  /* We shouldn't see delayed lengths here; the caller must
	     have calculated the old length in order to calculate
	     the adjustment.  */
	  gcc_assert (si->nonzero_chars);
	  tem = fold_convert_loc (loc, TREE_TYPE (si->nonzero_chars), adj);
	  si->nonzero_chars = fold_build2_loc (loc, PLUS_EXPR,
					       TREE_TYPE (si->nonzero_chars),
					       si->nonzero_chars, tem);
	  si->full_string_p = origsi->full_string_p;

	  si->endptr = NULL_TREE;
	  si->dont_invalidate = true;
	}
      nsi = get_next_strinfo (si);
      if (nsi == NULL)
	return;
      si = nsi;
    }
}

/* Find if there are other SSA_NAME pointers equal to PTR
   for which we don't track their string lengths yet.  If so, use
   IDX for them.  */

static void
find_equal_ptrs (tree ptr, int idx)
{
  if (TREE_CODE (ptr) != SSA_NAME)
    return;
  while (1)
    {
      gimple *stmt = SSA_NAME_DEF_STMT (ptr);
      if (!is_gimple_assign (stmt))
	return;
      ptr = gimple_assign_rhs1 (stmt);
      switch (gimple_assign_rhs_code (stmt))
	{
	case SSA_NAME:
	  break;
	CASE_CONVERT:
	  if (!POINTER_TYPE_P (TREE_TYPE (ptr)))
	    return;
	  if (TREE_CODE (ptr) == SSA_NAME)
	    break;
	  if (TREE_CODE (ptr) != ADDR_EXPR)
	    return;
	  /* FALLTHRU */
	case ADDR_EXPR:
	  {
	    int *pidx = addr_stridxptr (TREE_OPERAND (ptr, 0));
	    if (pidx != NULL && *pidx == 0)
	      *pidx = idx;
	    return;
	  }
	default:
	  return;
	}

      /* We might find an endptr created in this pass.  Grow the
	 vector in that case.  */
      if (ssa_ver_to_stridx.length () <= SSA_NAME_VERSION (ptr))
	ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);

      if (ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] != 0)
	return;
      ssa_ver_to_stridx[SSA_NAME_VERSION (ptr)] = idx;
    }
}

/* Return true if STMT is a call to a builtin function with the right
   arguments and attributes that should be considered for optimization
   by this pass.  */

static bool
valid_builtin_call (gimple *stmt)
{
  if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    return false;

  tree callee = gimple_call_fndecl (stmt);
  tree decl = builtin_decl_explicit (DECL_FUNCTION_CODE (callee));
  if (decl
      && decl != callee
      && !gimple_builtin_call_types_compatible_p (stmt, decl))
    return false;

  switch (DECL_FUNCTION_CODE (callee))
    {
    case BUILT_IN_MEMCMP:
    case BUILT_IN_MEMCMP_EQ:
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRNCMP:
    case BUILT_IN_STRCHR:
    case BUILT_IN_STRLEN:
    case BUILT_IN_STRNLEN:
      /* The above functions should be pure.  Punt if they aren't.  */
      if (gimple_vdef (stmt) || gimple_vuse (stmt) == NULL_TREE)
	return false;
      break;

    case BUILT_IN_ALLOCA:
    case BUILT_IN_ALLOCA_WITH_ALIGN:
    case BUILT_IN_CALLOC:
    case BUILT_IN_MALLOC:
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMCPY_CHK:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMPCPY_CHK:
    case BUILT_IN_MEMSET:
    case BUILT_IN_STPCPY:
    case BUILT_IN_STPCPY_CHK:
    case BUILT_IN_STPNCPY:
    case BUILT_IN_STPNCPY_CHK:
    case BUILT_IN_STRCAT:
    case BUILT_IN_STRCAT_CHK:
    case BUILT_IN_STRCPY:
    case BUILT_IN_STRCPY_CHK:
    case BUILT_IN_STRNCAT:
    case BUILT_IN_STRNCAT_CHK:
    case BUILT_IN_STRNCPY:
    case BUILT_IN_STRNCPY_CHK:
      /* The above functions should be neither const nor pure.  Punt if they
	 aren't.  */
      if (gimple_vdef (stmt) == NULL_TREE || gimple_vuse (stmt) == NULL_TREE)
	return false;
      break;

    default:
      break;
    }

  return true;
}

/* If the last .MEM setter statement before STMT is
   memcpy (x, y, strlen (y) + 1), the only .MEM use of it is STMT
   and STMT is known to overwrite x[strlen (x)], adjust the last memcpy to
   just memcpy (x, y, strlen (y)).  SI must be the zero length
   strinfo.  */

static void
adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat,
		  pointer_query &ptr_qry)
{
  tree vuse, callee, len;
  struct laststmt_struct last = laststmt;
  strinfo *lastsi, *firstsi;
  unsigned len_arg_no = 2;

  laststmt.stmt = NULL;
  laststmt.len = NULL_TREE;
  laststmt.stridx = 0;

  if (last.stmt == NULL)
    return;

  vuse = gimple_vuse (stmt);
  if (vuse == NULL_TREE
      || SSA_NAME_DEF_STMT (vuse) != last.stmt
      || !has_single_use (vuse))
    return;

  gcc_assert (last.stridx > 0);
  lastsi = get_strinfo (last.stridx);
  if (lastsi == NULL)
    return;

  if (lastsi != si)
    {
      if (lastsi->first == 0 || lastsi->first != si->first)
	return;

      firstsi = verify_related_strinfos (si);
      if (firstsi == NULL)
	return;
      while (firstsi != lastsi)
	{
	  firstsi = get_next_strinfo (firstsi);
	  if (firstsi == NULL)
	    return;
	}
    }

  if (!is_strcat && !zero_length_string_p (si))
    return;

  if (is_gimple_assign (last.stmt))
    {
      gimple_stmt_iterator gsi;

      if (!integer_zerop (gimple_assign_rhs1 (last.stmt)))
	return;
      if (stmt_could_throw_p (cfun, last.stmt))
	return;
      gsi = gsi_for_stmt (last.stmt);
      unlink_stmt_vdef (last.stmt);
      release_defs (last.stmt);
      gsi_remove (&gsi, true);
      return;
    }

  if (!valid_builtin_call (last.stmt))
    return;

  callee = gimple_call_fndecl (last.stmt);
  switch (DECL_FUNCTION_CODE (callee))
    {
    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMCPY_CHK:
      break;
    default:
      return;
    }

  len = gimple_call_arg (last.stmt, len_arg_no);
  if (tree_fits_uhwi_p (len))
    {
      if (!tree_fits_uhwi_p (last.len)
	  || integer_zerop (len)
	  || tree_to_uhwi (len) != tree_to_uhwi (last.len) + 1)
	return;
      /* Don't adjust the length if it is divisible by 4, it is more efficient
	 to store the extra '\0' in that case.  */
      if ((tree_to_uhwi (len) & 3) == 0)
	return;

      /* Don't fold away an out of bounds access, as this defeats proper
	 warnings.  */
      tree dst = gimple_call_arg (last.stmt, 0);

      access_ref aref;
      tree size = compute_objsize (dst, 1, &aref, &ptr_qry);
      if (size && tree_int_cst_lt (size, len))
	return;
    }
  else if (TREE_CODE (len) == SSA_NAME)
    {
      gimple *def_stmt = SSA_NAME_DEF_STMT (len);
      if (!is_gimple_assign (def_stmt)
	  || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
	  || gimple_assign_rhs1 (def_stmt) != last.len
	  || !integer_onep (gimple_assign_rhs2 (def_stmt)))
	return;
    }
  else
    return;

  gimple_call_set_arg (last.stmt, len_arg_no, last.len);
  update_stmt (last.stmt);
}

/* For an LHS that is an SSA_NAME that is the result of a strlen()
   call, or when BOUND is non-null, of a strnlen() call, set LHS
   range info to [0, min (MAX, BOUND)] when the range includes more
   than one value and return LHS.  Otherwise, when the range
   [MIN, MAX] is such that MIN == MAX, return the tree representation
   of (MIN). The latter allows callers to fold suitable strnlen() calls
   to constants.  */

tree
set_strlen_range (tree lhs, wide_int min, wide_int max,
		  tree bound /* = NULL_TREE */)
{
  if (TREE_CODE (lhs) != SSA_NAME
      || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
    return NULL_TREE;

  if (bound)
    {
      /* For strnlen, adjust MIN and MAX as necessary.  If the bound
	 is less than the size of the array set MAX to it.  It it's
	 greater than MAX and MAX is non-zero bump MAX down to account
	 for the necessary terminating nul.  Otherwise leave it alone.  */
      if (TREE_CODE (bound) == INTEGER_CST)
	{
	  wide_int wibnd = wi::to_wide (bound);
	  int cmp = wi::cmpu (wibnd, max);
	  if (cmp < 0)
	    max = wibnd;
	  else if (cmp && wi::ne_p (max, min))
	    --max;
	}
      else if (TREE_CODE (bound) == SSA_NAME)
	{
	  wide_int minbound, maxbound;
	  // FIXME: Use range_query instead of global ranges.
	  value_range_kind rng = get_range_info (bound, &minbound, &maxbound);
	  if (rng == VR_RANGE)
	    {
	      /* For a bound in a known range, adjust the range determined
		 above as necessary.  For a bound in some anti-range or
		 in an unknown range, use the range determined by callers.  */
	      if (wi::ltu_p (minbound, min))
		min = minbound;
	      if (wi::ltu_p (maxbound, max))
		max = maxbound;
	    }
	}
    }

  if (min == max)
    return wide_int_to_tree (size_type_node, min);

  set_range_info (lhs, VR_RANGE, min, max);
  return lhs;
}

/* For an LHS that is an SSA_NAME and for strlen() or strnlen() argument
   SRC, set LHS range info to [0, min (N, BOUND)] if SRC refers to
   a character array A[N] with unknown length bounded by N, and for
   strnlen(), by min (N, BOUND).  */

static tree
maybe_set_strlen_range (tree lhs, tree src, tree bound)
{
  if (TREE_CODE (lhs) != SSA_NAME
      || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
    return NULL_TREE;

  if (TREE_CODE (src) == SSA_NAME)
    {
      gimple *def = SSA_NAME_DEF_STMT (src);
      if (is_gimple_assign (def)
	  && gimple_assign_rhs_code (def) == ADDR_EXPR)
	src = gimple_assign_rhs1 (def);
    }

  /* The longest string is PTRDIFF_MAX - 1 bytes including the final
     NUL so that the difference between a pointer to just past it and
     one to its beginning is positive.  */
  wide_int max = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2;

  if (TREE_CODE (src) == ADDR_EXPR)
    {
      /* The last array member of a struct can be bigger than its size
	 suggests if it's treated as a poor-man's flexible array member.  */
      src = TREE_OPERAND (src, 0);
      if (TREE_CODE (src) != MEM_REF
	  && !array_at_struct_end_p (src))
	{
	  tree type = TREE_TYPE (src);
	  tree size = TYPE_SIZE_UNIT (type);
	  if (size
	      && TREE_CODE (size) == INTEGER_CST
	      && !integer_zerop (size))
	    {
	      /* Even though such uses of strlen would be undefined,
		 avoid relying on arrays of arrays in case some genius
		 decides to call strlen on an unterminated array element
		 that's followed by a terminated one.  Likewise, avoid
		 assuming that a struct array member is necessarily
		 nul-terminated (the nul may be in the member that
		 follows).  In those cases, assume that the length
		 of the string stored in such an array is bounded
		 by the size of the enclosing object if one can be
		 determined.  */
	      tree base = get_base_address (src);
	      if (VAR_P (base))
		{
		  if (tree size = DECL_SIZE_UNIT (base))
		    if (size
			&& TREE_CODE (size) == INTEGER_CST
			&& TREE_CODE (TREE_TYPE (base)) != POINTER_TYPE)
		      max = wi::to_wide (size);
		}
	    }

	  /* For strlen() the upper bound above is equal to
	     the longest string that can be stored in the array
	     (i.e., it accounts for the terminating nul.  For
	     strnlen() bump up the maximum by one since the array
	     need not be nul-terminated.  */
	  if (!bound && max != 0)
	    --max;
	}
    }

  wide_int min = wi::zero (max.get_precision ());
  return set_strlen_range (lhs, min, max, bound);
}

/* Diagnose buffer overflow by a STMT writing LEN + PLUS_ONE bytes,
   either into a region allocated for the object SI when non-null,
   or into an object designated by the LHS of STMT otherwise.
   When nonnull uses RVALS to determine range information.
   RAWMEM may be set by memcpy and other raw memory functions
   to allow accesses across subobject boundaries.  */

static void
maybe_warn_overflow (gimple *stmt, tree len, pointer_query &ptr_qry,
		     strinfo *si = NULL, bool plus_one = false,
		     bool rawmem = false)
{
  if (!len || gimple_no_warning_p (stmt))
    return;

  /* The DECL of the function performing the write if it is done
     by one.  */
  tree writefn = NULL_TREE;
  /* The destination expression involved in the store STMT.  */
  tree dest = NULL_TREE;

  if (is_gimple_assign (stmt))
    dest = gimple_assign_lhs (stmt);
  else if (is_gimple_call (stmt))
    {
      dest = gimple_call_arg (stmt, 0);
      writefn = gimple_call_fndecl (stmt);
    }
  else
    return;

  if (TREE_NO_WARNING (dest))
    return;

  const int ostype = rawmem ? 0 : 1;

  /* Use maximum precision to avoid overflow in the addition below.
     Make sure all operands have the same precision to keep wide_int
     from ICE'ing.  */

  access_ref aref;
  /* The size of the destination region (which is smaller than
     the destination object for stores at a non-zero offset).  */
  tree destsize = compute_objsize (dest, ostype, &aref, &ptr_qry);

  if (!destsize)
    {
      aref.sizrng[0] = 0;
      aref.sizrng[1] = wi::to_offset (max_object_size ());
    }

  /* Return early if the DESTSIZE size expression is the same as LEN
     and the offset into the destination is zero.  This might happen
     in the case of a pair of malloc and memset calls to allocate
     an object and clear it as if by calloc.  */
  if (destsize == len && !plus_one
      && aref.offrng[0] == 0 && aref.offrng[0] == aref.offrng[1])
    return;

  wide_int rng[2];
  if (!get_range (len, stmt, rng, ptr_qry.rvals))
    return;

  widest_int lenrng[2] =
    { widest_int::from (rng[0], SIGNED), widest_int::from (rng[1], SIGNED) };

  if (plus_one)
    {
      lenrng[0] += 1;
      lenrng[1] += 1;
    }

  /* The size of the remaining space in the destination computed
     as the size of the latter minus the offset into it.  */
  widest_int spcrng[2];
  {
    offset_int remrng[2];
    remrng[1] = aref.size_remaining (remrng);
    spcrng[0] = remrng[0] == -1 ? 0 : widest_int::from (remrng[0], UNSIGNED);
    spcrng[1] = widest_int::from (remrng[1], UNSIGNED);
  }

  if (wi::leu_p (lenrng[0], spcrng[0])
      && wi::leu_p (lenrng[1], spcrng[1]))
    return;

  if (lenrng[0] == spcrng[1]
      && (len != destsize
	  || !si || !is_strlen_related_p (si->ptr, len)))
    return;

  location_t loc = gimple_or_expr_nonartificial_location (stmt, dest);
  bool warned = false;
  if (wi::leu_p (lenrng[0], spcrng[1]))
    {
      if (len != destsize
	  && (!si || !is_strlen_related_p (si->ptr, len)))
	return;

      warned = (writefn
		? warning_at (loc, OPT_Wstringop_overflow_,
			      "%G%qD writing one too many bytes into a region "
			      "of a size that depends on %<strlen%>",
			      stmt, writefn)
		: warning_at (loc, OPT_Wstringop_overflow_,
			      "%Gwriting one too many bytes into a region "
			      "of a size that depends on %<strlen%>",
			      stmt));
    }
  else if (lenrng[0] == lenrng[1])
    {
      if (spcrng[0] == spcrng[1])
	warned = (writefn
		  ? warning_n (loc, OPT_Wstringop_overflow_,
			       lenrng[0].to_uhwi (),
			       "%G%qD writing %wu byte into a region "
			       "of size %wu",
			       "%G%qD writing %wu bytes into a region "
			       "of size %wu",
			       stmt, writefn, lenrng[0].to_uhwi (),
			       spcrng[0].to_uhwi ())
		  : warning_n (loc, OPT_Wstringop_overflow_,
			       lenrng[0].to_uhwi (),
			       "%Gwriting %wu byte into a region "
			       "of size %wu",
			       "%Gwriting %wu bytes into a region "
			       "of size %wu",
			       stmt, lenrng[0].to_uhwi (),
			       spcrng[0].to_uhwi ()));
      else
	warned = (writefn
		  ? warning_n (loc, OPT_Wstringop_overflow_,
			       lenrng[0].to_uhwi (),
			       "%G%qD writing %wu byte into a region "
			       "of size between %wu and %wu",
			       "%G%qD writing %wu bytes into a region "
			       "of size between %wu and %wu",
			       stmt, writefn, lenrng[0].to_uhwi (),
			       spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
		  : warning_n (loc, OPT_Wstringop_overflow_,
			       lenrng[0].to_uhwi (),
			       "%Gwriting %wu byte into a region "
			       "of size between %wu and %wu",
			       "%Gwriting %wu bytes into a region "
			       "of size between %wu and %wu",
			       stmt, lenrng[0].to_uhwi (),
			       spcrng[0].to_uhwi (), spcrng[1].to_uhwi ()));
    }
  else if (spcrng[0] == spcrng[1])
    warned = (writefn
	      ? warning_at (loc, OPT_Wstringop_overflow_,
			    "%G%qD writing between %wu and %wu bytes "
			    "into a region of size %wu",
			    stmt, writefn, lenrng[0].to_uhwi (),
			    lenrng[1].to_uhwi (),
			    spcrng[0].to_uhwi ())
	      : warning_at (loc, OPT_Wstringop_overflow_,
			    "%Gwriting between %wu and %wu bytes "
			    "into a region of size %wu",
			    stmt, lenrng[0].to_uhwi (),
			    lenrng[1].to_uhwi (),
			    spcrng[0].to_uhwi ()));
  else
    warned = (writefn
	      ? warning_at (loc, OPT_Wstringop_overflow_,
			    "%G%qD writing between %wu and %wu bytes "
			    "into a region of size between %wu and %wu",
			    stmt, writefn, lenrng[0].to_uhwi (),
			    lenrng[1].to_uhwi (),
			    spcrng[0].to_uhwi (), spcrng[1].to_uhwi ())
	      : warning_at (loc, OPT_Wstringop_overflow_,
			    "%Gwriting between %wu and %wu bytes "
			    "into a region of size between %wu and %wu",
			    stmt, lenrng[0].to_uhwi (),
			    lenrng[1].to_uhwi (),
			    spcrng[0].to_uhwi (), spcrng[1].to_uhwi ()));

  if (!warned)
    return;

  gimple_set_no_warning (stmt, true);

  aref.inform_access (access_write_only);
}

/* Convenience wrapper for the above.  */

static inline void
maybe_warn_overflow (gimple *stmt, unsigned HOST_WIDE_INT len,
		     pointer_query &ptr_qry, strinfo *si = NULL,
		     bool plus_one = false, bool rawmem = false)
{
  maybe_warn_overflow (stmt, build_int_cst (size_type_node, len), ptr_qry,
		       si, plus_one, rawmem);
}

/* Handle a strlen call.  If strlen of the argument is known, replace
   the strlen call with the known value, otherwise remember that strlen
   of the argument is stored in the lhs SSA_NAME.  */

static void
handle_builtin_strlen (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_call_lhs (stmt);

  if (lhs == NULL_TREE)
    return;

  location_t loc = gimple_location (stmt);
  tree callee = gimple_call_fndecl (stmt);
  tree src = gimple_call_arg (stmt, 0);
  tree bound = (DECL_FUNCTION_CODE (callee) == BUILT_IN_STRNLEN
		? gimple_call_arg (stmt, 1) : NULL_TREE);
  int idx = get_stridx (src);
  if (idx || (bound && integer_zerop (bound)))
    {
      strinfo *si = NULL;
      tree rhs;

      if (idx < 0)
	rhs = build_int_cst (TREE_TYPE (lhs), ~idx);
      else if (idx == 0)
	rhs = bound;
      else
	{
	  rhs = NULL_TREE;
	  si = get_strinfo (idx);
	  if (si != NULL)
	    {
	      rhs = get_string_length (si);
	      /* For strnlen, if bound is constant, even if si is not known
		 to be zero terminated, if we know at least bound bytes are
		 not zero, the return value will be bound.  */
	      if (rhs == NULL_TREE
		  && bound != NULL_TREE
		  && TREE_CODE (bound) == INTEGER_CST
		  && si->nonzero_chars != NULL_TREE
		  && TREE_CODE (si->nonzero_chars) == INTEGER_CST
		  && tree_int_cst_le (bound, si->nonzero_chars))
		rhs = bound;
	    }
	}
      if (rhs != NULL_TREE)
	{
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	    {
	      fprintf (dump_file, "Optimizing: ");
	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	    }
	  rhs = unshare_expr (rhs);
	  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
	    rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);

	  if (bound)
	    rhs = fold_build2_loc (loc, MIN_EXPR, TREE_TYPE (rhs), rhs, bound);

	  if (!update_call_from_tree (gsi, rhs))
	    gimplify_and_update_call_from_tree (gsi, rhs);
	  stmt = gsi_stmt (*gsi);
	  update_stmt (stmt);
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	    {
	      fprintf (dump_file, "into: ");
	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	    }

	  if (si != NULL
	      /* Don't update anything for strnlen.  */
	      && bound == NULL_TREE
	      && TREE_CODE (si->nonzero_chars) != SSA_NAME
	      && TREE_CODE (si->nonzero_chars) != INTEGER_CST
	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
	    {
	      si = unshare_strinfo (si);
	      si->nonzero_chars = lhs;
	      gcc_assert (si->full_string_p);
	    }

	  if (strlen_to_stridx
	      && (bound == NULL_TREE
		  /* For strnlen record this only if the call is proven
		     to return the same value as strlen would.  */
		  || (TREE_CODE (bound) == INTEGER_CST
		      && TREE_CODE (rhs) == INTEGER_CST
		      && tree_int_cst_lt (rhs, bound))))
	    strlen_to_stridx->put (lhs, stridx_strlenloc (idx, loc));

	  return;
	}
    }
  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    return;

  if (idx == 0)
    idx = new_stridx (src);
  else
    {
      strinfo *si = get_strinfo (idx);
      if (si != NULL)
	{
	  if (!si->full_string_p && !si->stmt)
	    {
	      /* Until now we only had a lower bound on the string length.
		 Install LHS as the actual length.  */
	      si = unshare_strinfo (si);
	      tree old = si->nonzero_chars;
	      si->nonzero_chars = lhs;
	      si->full_string_p = true;
	      if (old && TREE_CODE (old) == INTEGER_CST)
		{
		  old = fold_convert_loc (loc, TREE_TYPE (lhs), old);
		  tree adj = fold_build2_loc (loc, MINUS_EXPR,
					      TREE_TYPE (lhs), lhs, old);
		  adjust_related_strinfos (loc, si, adj);
		  /* Use the constant minimum length as the lower bound
		     of the non-constant length.  */
		  wide_int min = wi::to_wide (old);
		  wide_int max
		    = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node)) - 2;
		  set_strlen_range (lhs, min, max);
		}
	      else
		{
		  si->first = 0;
		  si->prev = 0;
		  si->next = 0;
		}
	    }
	  return;
	}
    }
  if (idx)
    {
      if (!bound)
	{
	  /* Only store the new length information for calls to strlen(),
	     not for those to strnlen().  */
	  strinfo *si = new_strinfo (src, idx, lhs, true);
	  set_strinfo (idx, si);
	  find_equal_ptrs (src, idx);
	}

      /* For SRC that is an array of N elements, set LHS's range
	 to [0, min (N, BOUND)].  A constant return value means
	 the range would have consisted of a single value.  In
	 that case, fold the result into the returned constant.  */
      if (tree ret = maybe_set_strlen_range (lhs, src, bound))
	if (TREE_CODE (ret) == INTEGER_CST)
	  {
	    if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	      {
		fprintf (dump_file, "Optimizing: ");
		print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	      }
	    if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (ret)))
	      ret = fold_convert_loc (loc, TREE_TYPE (lhs), ret);
	    if (!update_call_from_tree (gsi, ret))
	      gimplify_and_update_call_from_tree (gsi, ret);
	    stmt = gsi_stmt (*gsi);
	    update_stmt (stmt);
	    if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	      {
		fprintf (dump_file, "into: ");
		print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	      }
	  }

      if (strlen_to_stridx && !bound)
	strlen_to_stridx->put (lhs, stridx_strlenloc (idx, loc));
    }
}

/* Handle a strchr call.  If strlen of the first argument is known, replace
   the strchr (x, 0) call with the endptr or x + strlen, otherwise remember
   that lhs of the call is endptr and strlen of the argument is endptr - x.  */

static void
handle_builtin_strchr (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_call_lhs (stmt);

  if (lhs == NULL_TREE)
    return;

  if (!integer_zerop (gimple_call_arg (stmt, 1)))
    return;

  tree src = gimple_call_arg (stmt, 0);

  /* Avoid folding if the first argument is not a nul-terminated array.
     Defer warning until later.  */
  if (!check_nul_terminated_array (NULL_TREE, src))
    return;

  int idx = get_stridx (src);
  if (idx)
    {
      strinfo *si = NULL;
      tree rhs;

      if (idx < 0)
	rhs = build_int_cst (size_type_node, ~idx);
      else
	{
	  rhs = NULL_TREE;
	  si = get_strinfo (idx);
	  if (si != NULL)
	    rhs = get_string_length (si);
	}
      if (rhs != NULL_TREE)
	{
	  location_t loc = gimple_location (stmt);

	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	    {
	      fprintf (dump_file, "Optimizing: ");
	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	    }
	  if (si != NULL && si->endptr != NULL_TREE)
	    {
	      rhs = unshare_expr (si->endptr);
	      if (!useless_type_conversion_p (TREE_TYPE (lhs),
					      TREE_TYPE (rhs)))
		rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
	    }
	  else
	    {
	      rhs = fold_convert_loc (loc, sizetype, unshare_expr (rhs));
	      rhs = fold_build2_loc (loc, POINTER_PLUS_EXPR,
				     TREE_TYPE (src), src, rhs);
	      if (!useless_type_conversion_p (TREE_TYPE (lhs),
					      TREE_TYPE (rhs)))
		rhs = fold_convert_loc (loc, TREE_TYPE (lhs), rhs);
	    }
	  if (!update_call_from_tree (gsi, rhs))
	    gimplify_and_update_call_from_tree (gsi, rhs);
	  stmt = gsi_stmt (*gsi);
	  update_stmt (stmt);
	  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	    {
	      fprintf (dump_file, "into: ");
	      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	    }
	  if (si != NULL
	      && si->endptr == NULL_TREE
	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
	    {
	      si = unshare_strinfo (si);
	      si->endptr = lhs;
	    }
	  zero_length_string (lhs, si);
	  return;
	}
    }
  if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs))
    return;
  if (TREE_CODE (src) != SSA_NAME || !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (src))
    {
      if (idx == 0)
	idx = new_stridx (src);
      else if (get_strinfo (idx) != NULL)
	{
	  zero_length_string (lhs, NULL);
	  return;
	}
      if (idx)
	{
	  location_t loc = gimple_location (stmt);
	  tree lhsu = fold_convert_loc (loc, size_type_node, lhs);
	  tree srcu = fold_convert_loc (loc, size_type_node, src);
	  tree length = fold_build2_loc (loc, MINUS_EXPR,
					 size_type_node, lhsu, srcu);
	  strinfo *si = new_strinfo (src, idx, length, true);
	  si->endptr = lhs;
	  set_strinfo (idx, si);
	  find_equal_ptrs (src, idx);
	  zero_length_string (lhs, si);
	}
    }
  else
    zero_length_string (lhs, NULL);
}

/* Handle a strcpy-like ({st{r,p}cpy,__st{r,p}cpy_chk}) call.
   If strlen of the second argument is known, strlen of the first argument
   is the same after this call.  Furthermore, attempt to convert it to
   memcpy.  Uses RVALS to determine range information.  */

static void
handle_builtin_strcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
		       pointer_query &ptr_qry)
{
  int idx, didx;
  tree src, dst, srclen, len, lhs, type, fn, oldlen;
  bool success;
  gimple *stmt = gsi_stmt (*gsi);
  strinfo *si, *dsi, *olddsi, *zsi;
  location_t loc;

  src = gimple_call_arg (stmt, 1);
  dst = gimple_call_arg (stmt, 0);
  lhs = gimple_call_lhs (stmt);
  idx = get_stridx (src);
  si = NULL;
  if (idx > 0)
    si = get_strinfo (idx);

  didx = get_stridx (dst);
  olddsi = NULL;
  oldlen = NULL_TREE;
  if (didx > 0)
    olddsi = get_strinfo (didx);
  else if (didx < 0)
    return;

  if (olddsi != NULL)
    adjust_last_stmt (olddsi, stmt, false, ptr_qry);

  srclen = NULL_TREE;
  if (si != NULL)
    srclen = get_string_length (si);
  else if (idx < 0)
    srclen = build_int_cst (size_type_node, ~idx);

  maybe_warn_overflow (stmt, srclen, ptr_qry, olddsi, true);

  if (olddsi != NULL)
    adjust_last_stmt (olddsi, stmt, false, ptr_qry);

  loc = gimple_location (stmt);
  if (srclen == NULL_TREE)
    switch (bcode)
      {
      case BUILT_IN_STRCPY:
      case BUILT_IN_STRCPY_CHK:
	if (lhs != NULL_TREE || !builtin_decl_implicit_p (BUILT_IN_STPCPY))
	  return;
	break;
      case BUILT_IN_STPCPY:
      case BUILT_IN_STPCPY_CHK:
	if (lhs == NULL_TREE)
	  return;
	else
	  {
	    tree lhsuint = fold_convert_loc (loc, size_type_node, lhs);
	    srclen = fold_convert_loc (loc, size_type_node, dst);
	    srclen = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
				      lhsuint, srclen);
	  }
	break;
      default:
	gcc_unreachable ();
      }

  if (didx == 0)
    {
      didx = new_stridx (dst);
      if (didx == 0)
	return;
    }
  if (olddsi != NULL)
    {
      oldlen = olddsi->nonzero_chars;
      dsi = unshare_strinfo (olddsi);
      dsi->nonzero_chars = srclen;
      dsi->full_string_p = (srclen != NULL_TREE);
      /* Break the chain, so adjust_related_strinfo on later pointers in
	 the chain won't adjust this one anymore.  */
      dsi->next = 0;
      dsi->stmt = NULL;
      dsi->endptr = NULL_TREE;
    }
  else
    {
      dsi = new_strinfo (dst, didx, srclen, srclen != NULL_TREE);
      set_strinfo (didx, dsi);
      find_equal_ptrs (dst, didx);
    }
  dsi->writable = true;
  dsi->dont_invalidate = true;

  if (dsi->nonzero_chars == NULL_TREE)
    {
      strinfo *chainsi;

      /* If string length of src is unknown, use delayed length
	 computation.  If string length of dst will be needed, it
	 can be computed by transforming this strcpy call into
	 stpcpy and subtracting dst from the return value.  */

      /* Look for earlier strings whose length could be determined if
	 this strcpy is turned into an stpcpy.  */

      if (dsi->prev != 0 && (chainsi = verify_related_strinfos (dsi)) != NULL)
	{
	  for (; chainsi && chainsi != dsi; chainsi = get_strinfo (chainsi->next))
	    {
	      /* When setting a stmt for delayed length computation
		 prevent all strinfos through dsi from being
		 invalidated.  */
	      chainsi = unshare_strinfo (chainsi);
	      chainsi->stmt = stmt;
	      chainsi->nonzero_chars = NULL_TREE;
	      chainsi->full_string_p = false;
	      chainsi->endptr = NULL_TREE;
	      chainsi->dont_invalidate = true;
	    }
	}
      dsi->stmt = stmt;

      /* Try to detect overlap before returning.  This catches cases
	 like strcpy (d, d + n) where n is non-constant whose range
	 is such that (n <= strlen (d) holds).

	 OLDDSI->NONZERO_chars may have been reset by this point with
	 oldlen holding it original value.  */
      if (olddsi && oldlen)
	{
	  /* Add 1 for the terminating NUL.  */
	  tree type = TREE_TYPE (oldlen);
	  oldlen = fold_build2 (PLUS_EXPR, type, oldlen,
				build_int_cst (type, 1));
	  check_bounds_or_overlap (stmt, olddsi->ptr, src, oldlen, NULL_TREE);
	}

      return;
    }

  if (olddsi != NULL)
    {
      tree adj = NULL_TREE;
      if (oldlen == NULL_TREE)
	;
      else if (integer_zerop (oldlen))
	adj = srclen;
      else if (TREE_CODE (oldlen) == INTEGER_CST
	       || TREE_CODE (srclen) == INTEGER_CST)
	adj = fold_build2_loc (loc, MINUS_EXPR,
			       TREE_TYPE (srclen), srclen,
			       fold_convert_loc (loc, TREE_TYPE (srclen),
						 oldlen));
      if (adj != NULL_TREE)
	adjust_related_strinfos (loc, dsi, adj);
      else
	dsi->prev = 0;
    }
  /* strcpy src may not overlap dst, so src doesn't need to be
     invalidated either.  */
  if (si != NULL)
    si->dont_invalidate = true;

  fn = NULL_TREE;
  zsi = NULL;
  switch (bcode)
    {
    case BUILT_IN_STRCPY:
      fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
      if (lhs)
	ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
      break;
    case BUILT_IN_STRCPY_CHK:
      fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
      if (lhs)
	ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
      break;
    case BUILT_IN_STPCPY:
      /* This would need adjustment of the lhs (subtract one),
	 or detection that the trailing '\0' doesn't need to be
	 written, if it will be immediately overwritten.
      fn = builtin_decl_explicit (BUILT_IN_MEMPCPY);  */
      if (lhs)
	{
	  dsi->endptr = lhs;
	  zsi = zero_length_string (lhs, dsi);
	}
      break;
    case BUILT_IN_STPCPY_CHK:
      /* This would need adjustment of the lhs (subtract one),
	 or detection that the trailing '\0' doesn't need to be
	 written, if it will be immediately overwritten.
      fn = builtin_decl_explicit (BUILT_IN_MEMPCPY_CHK);  */
      if (lhs)
	{
	  dsi->endptr = lhs;
	  zsi = zero_length_string (lhs, dsi);
	}
      break;
    default:
      gcc_unreachable ();
    }
  if (zsi != NULL)
    zsi->dont_invalidate = true;

  if (fn)
    {
      tree args = TYPE_ARG_TYPES (TREE_TYPE (fn));
      type = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));
    }
  else
    type = size_type_node;

  len = fold_convert_loc (loc, type, unshare_expr (srclen));
  len = fold_build2_loc (loc, PLUS_EXPR, type, len, build_int_cst (type, 1));

  /* Set the no-warning bit on the transformed statement?  */
  bool set_no_warning = false;

  if (const strinfo *chksi = olddsi ? olddsi : dsi)
    if (si
	&& check_bounds_or_overlap (stmt, chksi->ptr, si->ptr, NULL_TREE, len))
      {
	gimple_set_no_warning (stmt, true);
	set_no_warning = true;
      }

  if (fn == NULL_TREE)
    return;

  len = force_gimple_operand_gsi (gsi, len, true, NULL_TREE, true,
				  GSI_SAME_STMT);
  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
    {
      fprintf (dump_file, "Optimizing: ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    }
  if (gimple_call_num_args (stmt) == 2)
    success = update_gimple_call (gsi, fn, 3, dst, src, len);
  else
    success = update_gimple_call (gsi, fn, 4, dst, src, len,
				  gimple_call_arg (stmt, 2));
  if (success)
    {
      stmt = gsi_stmt (*gsi);
      update_stmt (stmt);
      if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	{
	  fprintf (dump_file, "into: ");
	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	}
      /* Allow adjust_last_stmt to decrease this memcpy's size.  */
      laststmt.stmt = stmt;
      laststmt.len = srclen;
      laststmt.stridx = dsi->idx;
    }
  else if (dump_file && (dump_flags & TDF_DETAILS) != 0)
    fprintf (dump_file, "not possible.\n");

  if (set_no_warning)
    gimple_set_no_warning (stmt, true);
}

/* Check the size argument to the built-in forms of stpncpy and strncpy
   for out-of-bounds offsets or overlapping access, and to see if the
   size argument is derived from a call to strlen() on the source argument,
   and if so, issue an appropriate warning.  */

static void
handle_builtin_strncat (built_in_function, gimple_stmt_iterator *gsi)
{
  /* Same as stxncpy().  */
  handle_builtin_stxncpy_strncat (true, gsi);
}

/* Return true if LEN depends on a call to strlen(SRC) in an interesting
   way.  LEN can either be an integer expression, or a pointer (to char).
   When it is the latter (such as in recursive calls to self) it is
   assumed to be the argument in some call to strlen() whose relationship
   to SRC is being ascertained.  */

bool
is_strlen_related_p (tree src, tree len)
{
  if (TREE_CODE (TREE_TYPE (len)) == POINTER_TYPE
      && operand_equal_p (src, len, 0))
    return true;

  if (TREE_CODE (len) != SSA_NAME)
    return false;

  if (TREE_CODE (src) == SSA_NAME)
    {
      gimple *srcdef = SSA_NAME_DEF_STMT (src);
      if (is_gimple_assign (srcdef))
	{
	  /* Handle bitwise AND used in conversions from wider size_t
	     to narrower unsigned types.  */
	  tree_code code = gimple_assign_rhs_code (srcdef);
	  if (code == BIT_AND_EXPR
	      || code == NOP_EXPR)
	    return is_strlen_related_p (gimple_assign_rhs1 (srcdef), len);

	  return false;
	}

      if (gimple_call_builtin_p (srcdef, BUILT_IN_NORMAL))
	{
	  /* If SRC is the result of a call to an allocation function
	     or strlen, use the function's argument instead.  */
	  tree func = gimple_call_fndecl (srcdef);
	  built_in_function code = DECL_FUNCTION_CODE (func);
	  if (code == BUILT_IN_ALLOCA
	      || code == BUILT_IN_ALLOCA_WITH_ALIGN
	      || code == BUILT_IN_MALLOC
	      || code == BUILT_IN_STRLEN)
	    return is_strlen_related_p (gimple_call_arg (srcdef, 0), len);

	  /* FIXME: Handle other functions with attribute alloc_size.  */
	  return false;
	}
    }

  gimple *lendef = SSA_NAME_DEF_STMT (len);
  if (!lendef)
    return false;

  if (is_gimple_call (lendef))
    {
      tree func = gimple_call_fndecl (lendef);
      if (!valid_builtin_call (lendef)
	  || DECL_FUNCTION_CODE (func) != BUILT_IN_STRLEN)
	return false;

      tree arg = gimple_call_arg (lendef, 0);
      return is_strlen_related_p (src, arg);
    }

  if (!is_gimple_assign (lendef))
    return false;

  tree_code code = gimple_assign_rhs_code (lendef);
  tree rhs1 = gimple_assign_rhs1 (lendef);
  tree rhstype = TREE_TYPE (rhs1);

  if ((TREE_CODE (rhstype) == POINTER_TYPE && code == POINTER_PLUS_EXPR)
      || (INTEGRAL_TYPE_P (rhstype)
	  && (code == BIT_AND_EXPR
	      || code == NOP_EXPR)))
    {
      /* Pointer plus (an integer), and truncation are considered among
	 the (potentially) related expressions to strlen.  */
      return is_strlen_related_p (src, rhs1);
    }

  if (tree rhs2 = gimple_assign_rhs2 (lendef))
    {
      /* Integer subtraction is considered strlen-related when both
	 arguments are integers and second one is strlen-related.  */
      rhstype = TREE_TYPE (rhs2);
      if (INTEGRAL_TYPE_P (rhstype) && code == MINUS_EXPR)
	return is_strlen_related_p (src, rhs2);
    }

  return false;
}

/* Called by handle_builtin_stxncpy_strncat and by
   gimple_fold_builtin_strncpy in gimple-fold.c.
   Check to see if the specified bound is a) equal to the size of
   the destination DST and if so, b) if it's immediately followed by
   DST[CNT - 1] = '\0'.  If a) holds and b) does not, warn.  Otherwise,
   do nothing.  Return true if diagnostic has been issued.

   The purpose is to diagnose calls to strncpy and stpncpy that do
   not nul-terminate the copy while allowing for the idiom where
   such a call is immediately followed by setting the last element
   to nul, as in:
     char a[32];
     strncpy (a, s, sizeof a);
     a[sizeof a - 1] = '\0';
*/

bool
maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt,
			  pointer_query *ptr_qry /* = NULL */)
{
  gimple *stmt = gsi_stmt (gsi);
  if (gimple_no_warning_p (stmt))
    return false;

  wide_int cntrange[2];

  // FIXME: Use range_query instead of global ranges.
  enum value_range_kind rng = get_range_info (cnt, cntrange, cntrange + 1);
  if (rng == VR_RANGE)
    ;
  else if (rng == VR_ANTI_RANGE)
    {
      wide_int maxobjsize = wi::to_wide (TYPE_MAX_VALUE (ptrdiff_type_node));

      if (wi::ltu_p (cntrange[1], maxobjsize))
	{
	  cntrange[0] = cntrange[1] + 1;
	  cntrange[1] = maxobjsize;
	}
      else
	{
	  cntrange[1] = cntrange[0] - 1;
	  cntrange[0] = wi::zero (TYPE_PRECISION (TREE_TYPE (cnt)));
	}
    }
  else
    return false;

  /* Negative value is the constant string length.  If it's less than
     the lower bound there is no truncation.  Avoid calling get_stridx()
     when ssa_ver_to_stridx is empty.  That implies the caller isn't
     running under the control of this pass and ssa_ver_to_stridx hasn't
     been created yet.  */
  int sidx = ssa_ver_to_stridx.length () ? get_stridx (src) : 0;
  if (sidx < 0 && wi::gtu_p (cntrange[0], ~sidx))
    return false;

  tree dst = gimple_call_arg (stmt, 0);
  tree dstdecl = dst;
  if (TREE_CODE (dstdecl) == ADDR_EXPR)
    dstdecl = TREE_OPERAND (dstdecl, 0);

  tree ref = NULL_TREE;

  if (!sidx)
    {
      /* If the source is a non-string return early to avoid warning
	 for possible truncation (if the truncation is certain SIDX
	 is non-zero).  */
      tree srcdecl = gimple_call_arg (stmt, 1);
      if (TREE_CODE (srcdecl) == ADDR_EXPR)
	srcdecl = TREE_OPERAND (srcdecl, 0);
      if (get_attr_nonstring_decl (srcdecl, &ref))
	return false;
    }

  /* Likewise, if the destination refers to an array/pointer declared
     nonstring return early.  */
  if (get_attr_nonstring_decl (dstdecl, &ref))
    return false;

  /* Look for dst[i] = '\0'; after the stxncpy() call and if found
     avoid the truncation warning.  */
  gsi_next_nondebug (&gsi);
  gimple *next_stmt = gsi_stmt (gsi);
  if (!next_stmt)
    {
      /* When there is no statement in the same basic block check
	 the immediate successor block.  */
      if (basic_block bb = gimple_bb (stmt))
	{
	  if (single_succ_p (bb))
	    {
	      /* For simplicity, ignore blocks with multiple outgoing
		 edges for now and only consider successor blocks along
		 normal edges.  */
	      edge e = EDGE_SUCC (bb, 0);
	      if (!(e->flags & EDGE_ABNORMAL))
		{
		  gsi = gsi_start_bb (e->dest);
		  next_stmt = gsi_stmt (gsi);
		  if (next_stmt && is_gimple_debug (next_stmt))
		    {
		      gsi_next_nondebug (&gsi);
		      next_stmt = gsi_stmt (gsi);
		    }
		}
	    }
	}
    }

  if (next_stmt && is_gimple_assign (next_stmt))
    {
      tree lhs = gimple_assign_lhs (next_stmt);
      tree_code code = TREE_CODE (lhs);
      if (code == ARRAY_REF || code == MEM_REF)
	lhs = TREE_OPERAND (lhs, 0);

      tree func = gimple_call_fndecl (stmt);
      if (DECL_FUNCTION_CODE (func) == BUILT_IN_STPNCPY)
	{
	  tree ret = gimple_call_lhs (stmt);
	  if (ret && operand_equal_p (ret, lhs, 0))
	    return false;
	}

      /* Determine the base address and offset of the reference,
	 ignoring the innermost array index.  */
      if (TREE_CODE (ref) == ARRAY_REF)
	ref = TREE_OPERAND (ref, 0);

      poly_int64 dstoff;
      tree dstbase = get_addr_base_and_unit_offset (ref, &dstoff);

      poly_int64 lhsoff;
      tree lhsbase = get_addr_base_and_unit_offset (lhs, &lhsoff);
      if (lhsbase
	  && dstbase
	  && known_eq (dstoff, lhsoff)
	  && operand_equal_p (dstbase, lhsbase, 0))
	return false;
    }

  int prec = TYPE_PRECISION (TREE_TYPE (cnt));
  wide_int lenrange[2];
  if (strinfo *sisrc = sidx > 0 ? get_strinfo (sidx) : NULL)
    {
      lenrange[0] = (sisrc->nonzero_chars
		     && TREE_CODE (sisrc->nonzero_chars) == INTEGER_CST
		     ? wi::to_wide (sisrc->nonzero_chars)
		     : wi::zero (prec));
      lenrange[1] = lenrange[0];
    }
  else if (sidx < 0)
    lenrange[0] = lenrange[1] = wi::shwi (~sidx, prec);
  else
    {
      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 = src;
      get_range_strlen (src, &lendata, /* eltsize = */1);
      if (TREE_CODE (lendata.minlen) == INTEGER_CST
	  && TREE_CODE (lendata.maxbound) == INTEGER_CST)
	{
	  /* When LENDATA.MAXLEN is unknown, reset LENDATA.MINLEN
	     which stores the length of the shortest known string.  */
	  if (integer_all_onesp (lendata.maxlen))
	    lenrange[0] = wi::shwi (0, prec);
	  else
	    lenrange[0] = wi::to_wide (lendata.minlen, prec);
	  lenrange[1] = wi::to_wide (lendata.maxbound, prec);
	}
      else
	{
	  lenrange[0] = wi::shwi (0, prec);
	  lenrange[1] = wi::shwi (-1, prec);
	}
    }

  location_t callloc = gimple_or_expr_nonartificial_location (stmt, dst);
  tree func = gimple_call_fndecl (stmt);

  if (lenrange[0] != 0 || !wi::neg_p (lenrange[1]))
    {
      /* If the longest source string is shorter than the lower bound
	 of the specified count the copy is definitely nul-terminated.  */
      if (wi::ltu_p (lenrange[1], cntrange[0]))
	return false;

      if (wi::neg_p (lenrange[1]))
	{
	  /* The length of one of the strings is unknown but at least
	     one has non-zero length and that length is stored in
	     LENRANGE[1].  Swap the bounds to force a "may be truncated"
	     warning below.  */
	  lenrange[1] = lenrange[0];
	  lenrange[0] = wi::shwi (0, prec);
	}

      /* Set to true for strncat whose bound is derived from the length
	 of the destination (the expected usage pattern).  */
      bool cat_dstlen_bounded = false;
      if (DECL_FUNCTION_CODE (func) == BUILT_IN_STRNCAT)
	cat_dstlen_bounded = is_strlen_related_p (dst, cnt);

      if (lenrange[0] == cntrange[1] && cntrange[0] == cntrange[1])
	return warning_n (callloc, OPT_Wstringop_truncation,
			  cntrange[0].to_uhwi (),
			  "%G%qD output truncated before terminating "
			  "nul copying %E byte from a string of the "
			  "same length",
			  "%G%qD output truncated before terminating nul "
			  "copying %E bytes from a string of the same "
			  "length",
			  stmt, func, cnt);
      else if (!cat_dstlen_bounded)
	{
	  if (wi::geu_p (lenrange[0], cntrange[1]))
	    {
	      /* The shortest string is longer than the upper bound of
		 the count so the truncation is certain.  */
	      if (cntrange[0] == cntrange[1])
		return warning_n (callloc, OPT_Wstringop_truncation,
				  cntrange[0].to_uhwi (),
				  "%G%qD output truncated copying %E byte "
				  "from a string of length %wu",
				  "%G%qD output truncated copying %E bytes "
				  "from a string of length %wu",
				  stmt, func, cnt, lenrange[0].to_uhwi ());

	      return warning_at (callloc, OPT_Wstringop_truncation,
				 "%G%qD output truncated copying between %wu "
				 "and %wu bytes from a string of length %wu",
				 stmt, func, cntrange[0].to_uhwi (),
				 cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
	    }
	  else if (wi::geu_p (lenrange[1], cntrange[1]))
	    {
	      /* The longest string is longer than the upper bound of
		 the count so the truncation is possible.  */
	      if (cntrange[0] == cntrange[1])
		return warning_n (callloc, OPT_Wstringop_truncation,
				  cntrange[0].to_uhwi (),
				  "%G%qD output may be truncated copying %E "
				  "byte from a string of length %wu",
				  "%G%qD output may be truncated copying %E "
				  "bytes from a string of length %wu",
				  stmt, func, cnt, lenrange[1].to_uhwi ());

	      return warning_at (callloc, OPT_Wstringop_truncation,
				 "%G%qD output may be truncated copying between "
				 "%wu and %wu bytes from a string of length %wu",
				 stmt, func, cntrange[0].to_uhwi (),
				 cntrange[1].to_uhwi (), lenrange[1].to_uhwi ());
	    }
	}

      if (!cat_dstlen_bounded
	  && cntrange[0] != cntrange[1]
	  && wi::leu_p (cntrange[0], lenrange[0])
	  && wi::leu_p (cntrange[1], lenrange[0] + 1))
	{
	  /* If the source (including the terminating nul) is longer than
	     the lower bound of the specified count but shorter than the
	     upper bound the copy may (but need not) be truncated.  */
	  return warning_at (callloc, OPT_Wstringop_truncation,
			     "%G%qD output may be truncated copying between "
			     "%wu and %wu bytes from a string of length %wu",
			     stmt, func, cntrange[0].to_uhwi (),
			     cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
	}
    }

  access_ref aref;
  if (tree dstsize = compute_objsize (dst, 1, &aref, ptr_qry))
    {
      /* The source length is unknown.  Try to determine the destination
	 size and see if it matches the specified bound.  If not, bail.
	 Otherwise go on to see if it should be diagnosed for possible
	 truncation.  */
      if (!dstsize)
	return false;

      if (wi::to_wide (dstsize) != cntrange[1])
	return false;

      /* Avoid warning for strncpy(a, b, N) calls where the following
	 equalities hold:
	   N == sizeof a && N == sizeof b */
      if (tree srcsize = compute_objsize (src, 1, &aref, ptr_qry))
	if (wi::to_wide (srcsize) == cntrange[1])
	  return false;

      if (cntrange[0] == cntrange[1])
	return warning_at (callloc, OPT_Wstringop_truncation,
			   "%G%qD specified bound %E equals destination size",
			   stmt, func, cnt);
    }

  return false;
}

/* Check the arguments to the built-in forms of stpncpy, strncpy, and
   strncat, for out-of-bounds offsets or overlapping access, and to see
   if the size is derived from calling strlen() on the source argument,
   and if so, issue the appropriate warning.
   APPEND_P is true for strncat.  */

static void
handle_builtin_stxncpy_strncat (bool append_p, gimple_stmt_iterator *gsi)
{
  if (!strlen_to_stridx)
    return;

  gimple *stmt = gsi_stmt (*gsi);

  tree dst = gimple_call_arg (stmt, 0);
  tree src = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);
  tree dstsize = NULL_TREE, srcsize = NULL_TREE;

  int didx = get_stridx (dst);
  if (strinfo *sidst = didx > 0 ? get_strinfo (didx) : NULL)
    {
      /* Compute the size of the destination string including the nul
	 if it is known to be nul-terminated.  */
      if (sidst->nonzero_chars)
	{
	  if (sidst->full_string_p)
	    {
	      /* String is known to be nul-terminated.  */
	      tree type = TREE_TYPE (sidst->nonzero_chars);
	      dstsize = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
				     build_int_cst (type, 1));
	    }
	  else
	    dstsize = sidst->nonzero_chars;
	}

      dst = sidst->ptr;
    }

  int sidx = get_stridx (src);
  strinfo *sisrc = sidx > 0 ? get_strinfo (sidx) : NULL;
  if (sisrc)
    {
      /* strncat() and strncpy() can modify the source string by writing
	 over the terminating nul so SISRC->DONT_INVALIDATE must be left
	 clear.  */

      /* Compute the size of the source string including the terminating
	 nul if its known to be nul-terminated.  */
      if (sisrc->nonzero_chars)
	{
	  if (sisrc->full_string_p)
	    {
	      tree type = TREE_TYPE (sisrc->nonzero_chars);
	      srcsize = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
				     build_int_cst (type, 1));
	    }
	  else
	    srcsize = sisrc->nonzero_chars;
	}

	src = sisrc->ptr;
    }
  else
    srcsize = NULL_TREE;

  if (check_bounds_or_overlap (stmt, dst, src, dstsize, srcsize))
    {
      gimple_set_no_warning (stmt, true);
      return;
    }

  /* If the length argument was computed from strlen(S) for some string
     S retrieve the strinfo index for the string (PSS->FIRST) along with
     the location of the strlen() call (PSS->SECOND).  */
  stridx_strlenloc *pss = strlen_to_stridx->get (len);
  if (!pss || pss->first <= 0)
    {
      if (maybe_diag_stxncpy_trunc (*gsi, src, len))
	gimple_set_no_warning (stmt, true);

      return;
    }

  /* Retrieve the strinfo data for the string S that LEN was computed
     from as some function F of strlen (S) (i.e., LEN need not be equal
     to strlen(S)).  */
  strinfo *silen = get_strinfo (pss->first);

  location_t callloc = gimple_or_expr_nonartificial_location (stmt, dst);

  tree func = gimple_call_fndecl (stmt);

  bool warned = false;

  /* When -Wstringop-truncation is set, try to determine truncation
     before diagnosing possible overflow.  Truncation is implied by
     the LEN argument being equal to strlen(SRC), regardless of
     whether its value is known.  Otherwise, issue the more generic
     -Wstringop-overflow which triggers for LEN arguments that in
     any meaningful way depend on strlen(SRC).  */
  if (!append_p
      && sisrc == silen
      && is_strlen_related_p (src, len)
      && warning_at (callloc, OPT_Wstringop_truncation,
		     "%G%qD output truncated before terminating nul "
		     "copying as many bytes from a string as its length",
		     stmt, func))
    warned = true;
  else if (silen && is_strlen_related_p (src, silen->ptr))
    warned = warning_at (callloc, OPT_Wstringop_overflow_,
			 "%G%qD specified bound depends on the length "
			 "of the source argument",
			 stmt, func);
  if (warned)
    {
      location_t strlenloc = pss->second;
      if (strlenloc != UNKNOWN_LOCATION && strlenloc != callloc)
	inform (strlenloc, "length computed here");
    }
}

/* Handle a memcpy-like ({mem{,p}cpy,__mem{,p}cpy_chk}) call.
   If strlen of the second argument is known and length of the third argument
   is that plus one, strlen of the first argument is the same after this
   call.  Uses RVALS to determine range information.  */

static void
handle_builtin_memcpy (enum built_in_function bcode, gimple_stmt_iterator *gsi,
		       pointer_query &ptr_qry)
{
  tree lhs, oldlen, newlen;
  gimple *stmt = gsi_stmt (*gsi);
  strinfo *si, *dsi;

  tree len = gimple_call_arg (stmt, 2);
  tree src = gimple_call_arg (stmt, 1);
  tree dst = gimple_call_arg (stmt, 0);

  int didx = get_stridx (dst);
  strinfo *olddsi = NULL;
  if (didx > 0)
    olddsi = get_strinfo (didx);
  else if (didx < 0)
    return;

  if (olddsi != NULL
      && !integer_zerop (len))
    {
      maybe_warn_overflow (stmt, len, ptr_qry, olddsi, false, false);
      adjust_last_stmt (olddsi, stmt, false, ptr_qry);
    }

  int idx = get_stridx (src);
  if (idx == 0)
    return;

  bool full_string_p;
  if (idx > 0)
    {
      gimple *def_stmt;

      /* Handle memcpy (x, y, l) where l's relationship with strlen (y)
	 is known.  */
      si = get_strinfo (idx);
      if (si == NULL || si->nonzero_chars == NULL_TREE)
	return;
      if (TREE_CODE (len) == INTEGER_CST
	  && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
	{
	  if (tree_int_cst_le (len, si->nonzero_chars))
	    {
	      /* Copying LEN nonzero characters, where LEN is constant.  */
	      newlen = len;
	      full_string_p = false;
	    }
	  else
	    {
	      /* Copying the whole of the analyzed part of SI.  */
	      newlen = si->nonzero_chars;
	      full_string_p = si->full_string_p;
	    }
	}
      else
	{
	  if (!si->full_string_p)
	    return;
	  if (TREE_CODE (len) != SSA_NAME)
	    return;
	  def_stmt = SSA_NAME_DEF_STMT (len);
	  if (!is_gimple_assign (def_stmt)
	      || gimple_assign_rhs_code (def_stmt) != PLUS_EXPR
	      || gimple_assign_rhs1 (def_stmt) != si->nonzero_chars
	      || !integer_onep (gimple_assign_rhs2 (def_stmt)))
	    return;
	  /* Copying variable-length string SI (and no more).  */
	  newlen = si->nonzero_chars;
	  full_string_p = true;
	}
    }
  else
    {
      si = NULL;
      /* Handle memcpy (x, "abcd", 5) or
	 memcpy (x, "abc\0uvw", 7).  */
      if (!tree_fits_uhwi_p (len))
	return;

      unsigned HOST_WIDE_INT clen = tree_to_uhwi (len);
      unsigned HOST_WIDE_INT nonzero_chars = ~idx;
      newlen = build_int_cst (size_type_node, MIN (nonzero_chars, clen));
      full_string_p = clen > nonzero_chars;
    }

  if (!full_string_p
      && olddsi
      && olddsi->nonzero_chars
      && TREE_CODE (olddsi->nonzero_chars) == INTEGER_CST
      && tree_int_cst_le (newlen, olddsi->nonzero_chars))
    {
      /* The SRC substring being written strictly overlaps
	 a subsequence of the existing string OLDDSI.  */
      newlen = olddsi->nonzero_chars;
      full_string_p = olddsi->full_string_p;
    }

  if (olddsi != NULL && TREE_CODE (len) == SSA_NAME)
    adjust_last_stmt (olddsi, stmt, false, ptr_qry);

  if (didx == 0)
    {
      didx = new_stridx (dst);
      if (didx == 0)
	return;
    }
  oldlen = NULL_TREE;
  if (olddsi != NULL)
    {
      dsi = unshare_strinfo (olddsi);
      oldlen = olddsi->nonzero_chars;
      dsi->nonzero_chars = newlen;
      dsi->full_string_p = full_string_p;
      /* Break the chain, so adjust_related_strinfo on later pointers in
	 the chain won't adjust this one anymore.  */
      dsi->next = 0;
      dsi->stmt = NULL;
      dsi->endptr = NULL_TREE;
    }
  else
    {
      dsi = new_strinfo (dst, didx, newlen, full_string_p);
      set_strinfo (didx, dsi);
      find_equal_ptrs (dst, didx);
    }
  dsi->writable = true;
  dsi->dont_invalidate = true;
  if (olddsi != NULL)
    {
      tree adj = NULL_TREE;
      location_t loc = gimple_location (stmt);
      if (oldlen == NULL_TREE)
	;
      else if (integer_zerop (oldlen))
	adj = newlen;
      else if (TREE_CODE (oldlen) == INTEGER_CST
	       || TREE_CODE (newlen) == INTEGER_CST)
	adj = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (newlen), newlen,
			       fold_convert_loc (loc, TREE_TYPE (newlen),
						 oldlen));
      if (adj != NULL_TREE)
	adjust_related_strinfos (loc, dsi, adj);
      else
	dsi->prev = 0;
    }
  /* memcpy src may not overlap dst, so src doesn't need to be
     invalidated either.  */
  if (si != NULL)
    si->dont_invalidate = true;

  if (full_string_p)
    {
      lhs = gimple_call_lhs (stmt);
      switch (bcode)
	{
	case BUILT_IN_MEMCPY:
	case BUILT_IN_MEMCPY_CHK:
	  /* Allow adjust_last_stmt to decrease this memcpy's size.  */
	  laststmt.stmt = stmt;
	  laststmt.len = dsi->nonzero_chars;
	  laststmt.stridx = dsi->idx;
	  if (lhs)
	    ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = didx;
	  break;
	case BUILT_IN_MEMPCPY:
	case BUILT_IN_MEMPCPY_CHK:
	  break;
	default:
	  gcc_unreachable ();
	}
    }
}

/* Handle a strcat-like ({strcat,__strcat_chk}) call.
   If strlen of the second argument is known, strlen of the first argument
   is increased by the length of the second argument.  Furthermore, attempt
   to convert it to memcpy/strcpy if the length of the first argument
   is known.  */

static void
handle_builtin_strcat (enum built_in_function bcode, gimple_stmt_iterator *gsi,
		       pointer_query &ptr_qry)
{
  int idx, didx;
  tree srclen, args, type, fn, objsz, endptr;
  bool success;
  gimple *stmt = gsi_stmt (*gsi);
  strinfo *si, *dsi;
  location_t loc = gimple_location (stmt);

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

  /* Bail if the source is the same as destination.  It will be diagnosed
     elsewhere.  */
  if (operand_equal_p (src, dst, 0))
    return;

  tree lhs = gimple_call_lhs (stmt);

  didx = get_stridx (dst);
  if (didx < 0)
    return;

  dsi = NULL;
  if (didx > 0)
    dsi = get_strinfo (didx);

  srclen = NULL_TREE;
  si = NULL;
  idx = get_stridx (src);
  if (idx < 0)
    srclen = build_int_cst (size_type_node, ~idx);
  else if (idx > 0)
    {
      si = get_strinfo (idx);
      if (si != NULL)
	srclen = get_string_length (si);
    }

  /* Set the no-warning bit on the transformed statement?  */
  bool set_no_warning = false;

  if (dsi == NULL || get_string_length (dsi) == NULL_TREE)
    {
      {
	  /* The concatenation always involves copying at least one byte
	     (the terminating nul), even if the source string is empty.
	     If the source is unknown assume it's one character long and
	     used that as both sizes.  */
	tree slen = srclen;
	if (slen)
	  {
	    tree type = TREE_TYPE (slen);
	    slen = fold_build2 (PLUS_EXPR, type, slen, build_int_cst (type, 1));
	  }

	tree sptr = si && si->ptr ? si->ptr : src;

	if (check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE, slen))
	  {
	    gimple_set_no_warning (stmt, true);
	    set_no_warning = true;
	  }
      }

      /* strcat (p, q) can be transformed into
	 tmp = p + strlen (p); endptr = stpcpy (tmp, q);
	 with length endptr - p if we need to compute the length
	 later on.  Don't do this transformation if we don't need
	 it.  */
      if (builtin_decl_implicit_p (BUILT_IN_STPCPY) && lhs == NULL_TREE)
	{
	  if (didx == 0)
	    {
	      didx = new_stridx (dst);
	      if (didx == 0)
		return;
	    }
	  if (dsi == NULL)
	    {
	      dsi = new_strinfo (dst, didx, NULL_TREE, false);
	      set_strinfo (didx, dsi);
	      find_equal_ptrs (dst, didx);
	    }
	  else
	    {
	      dsi = unshare_strinfo (dsi);
	      dsi->nonzero_chars = NULL_TREE;
	      dsi->full_string_p = false;
	      dsi->next = 0;
	      dsi->endptr = NULL_TREE;
	    }
	  dsi->writable = true;
	  dsi->stmt = stmt;
	  dsi->dont_invalidate = true;
	}
      return;
    }

  tree dstlen = dsi->nonzero_chars;
  endptr = dsi->endptr;

  dsi = unshare_strinfo (dsi);
  dsi->endptr = NULL_TREE;
  dsi->stmt = NULL;
  dsi->writable = true;

  if (srclen != NULL_TREE)
    {
      dsi->nonzero_chars = fold_build2_loc (loc, PLUS_EXPR,
					    TREE_TYPE (dsi->nonzero_chars),
					    dsi->nonzero_chars, srclen);
      gcc_assert (dsi->full_string_p);
      adjust_related_strinfos (loc, dsi, srclen);
      dsi->dont_invalidate = true;
    }
  else
    {
      dsi->nonzero_chars = NULL;
      dsi->full_string_p = false;
      if (lhs == NULL_TREE && builtin_decl_implicit_p (BUILT_IN_STPCPY))
	dsi->dont_invalidate = true;
    }

  if (si != NULL)
    /* strcat src may not overlap dst, so src doesn't need to be
       invalidated either.  */
    si->dont_invalidate = true;

  /* For now.  Could remove the lhs from the call and add
     lhs = dst; afterwards.  */
  if (lhs)
    return;

  fn = NULL_TREE;
  objsz = NULL_TREE;
  switch (bcode)
    {
    case BUILT_IN_STRCAT:
      if (srclen != NULL_TREE)
	fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
      else
	fn = builtin_decl_implicit (BUILT_IN_STRCPY);
      break;
    case BUILT_IN_STRCAT_CHK:
      if (srclen != NULL_TREE)
	fn = builtin_decl_explicit (BUILT_IN_MEMCPY_CHK);
      else
	fn = builtin_decl_explicit (BUILT_IN_STRCPY_CHK);
      objsz = gimple_call_arg (stmt, 2);
      break;
    default:
      gcc_unreachable ();
    }

  if (fn == NULL_TREE)
    return;

  if (dsi && dstlen)
    {
      tree type = TREE_TYPE (dstlen);

      /* Compute the size of the source sequence, including the nul.  */
      tree srcsize = srclen ? srclen : size_zero_node;
      tree one = build_int_cst (type, 1);
      srcsize = fold_build2 (PLUS_EXPR, type, srcsize, one);
      tree dstsize = fold_build2 (PLUS_EXPR, type, dstlen, one);
      tree sptr = si && si->ptr ? si->ptr : src;

      if (check_bounds_or_overlap (stmt, dst, sptr, dstsize, srcsize))
	{
	  gimple_set_no_warning (stmt, true);
	  set_no_warning = true;
	}
    }

  tree len = NULL_TREE;
  if (srclen != NULL_TREE)
    {
      args = TYPE_ARG_TYPES (TREE_TYPE (fn));
      type = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)));

      len = fold_convert_loc (loc, type, unshare_expr (srclen));
      len = fold_build2_loc (loc, PLUS_EXPR, type, len,
			     build_int_cst (type, 1));
      len = force_gimple_operand_gsi (gsi, len, true, NULL_TREE, true,
				      GSI_SAME_STMT);
    }
  if (endptr)
    dst = fold_convert_loc (loc, TREE_TYPE (dst), unshare_expr (endptr));
  else
    dst = fold_build2_loc (loc, POINTER_PLUS_EXPR, TREE_TYPE (dst), dst,
			   fold_convert_loc (loc, sizetype,
					     unshare_expr (dstlen)));
  dst = force_gimple_operand_gsi (gsi, dst, true, NULL_TREE, true,
				  GSI_SAME_STMT);
  if (objsz)
    {
      objsz = fold_build2_loc (loc, MINUS_EXPR, TREE_TYPE (objsz), objsz,
			       fold_convert_loc (loc, TREE_TYPE (objsz),
						 unshare_expr (dstlen)));
      objsz = force_gimple_operand_gsi (gsi, objsz, true, NULL_TREE, true,
					GSI_SAME_STMT);
    }
  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
    {
      fprintf (dump_file, "Optimizing: ");
      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
    }
  if (srclen != NULL_TREE)
    success = update_gimple_call (gsi, fn, 3 + (objsz != NULL_TREE),
				  dst, src, len, objsz);
  else
    success = update_gimple_call (gsi, fn, 2 + (objsz != NULL_TREE),
				  dst, src, objsz);
  if (success)
    {
      stmt = gsi_stmt (*gsi);
      update_stmt (stmt);
      if (dump_file && (dump_flags & TDF_DETAILS) != 0)
	{
	  fprintf (dump_file, "into: ");
	  print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
	}
      /* If srclen == NULL, note that current string length can be
	 computed by transforming this strcpy into stpcpy.  */
      if (srclen == NULL_TREE && dsi->dont_invalidate)
	dsi->stmt = stmt;
      adjust_last_stmt (dsi, stmt, true, ptr_qry);
      if (srclen != NULL_TREE)
	{
	  laststmt.stmt = stmt;
	  laststmt.len = srclen;
	  laststmt.stridx = dsi->idx;
	}
    }
  else if (dump_file && (dump_flags & TDF_DETAILS) != 0)
    fprintf (dump_file, "not possible.\n");

  if (set_no_warning)
    gimple_set_no_warning (stmt, true);
}

/* Handle a call to an allocation function like alloca, malloc or calloc,
   or an ordinary allocation function declared with attribute alloc_size.  */

static void
handle_alloc_call (enum built_in_function bcode, gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_call_lhs (stmt);
  if (lhs == NULL_TREE)
    return;

  gcc_assert (get_stridx (lhs) == 0);
  int idx = new_stridx (lhs);
  tree length = NULL_TREE;
  if (bcode == BUILT_IN_CALLOC)
    length = build_int_cst (size_type_node, 0);
  strinfo *si = new_strinfo (lhs, idx, length, length != NULL_TREE);
  if (bcode == BUILT_IN_CALLOC)
    {
      /* Only set STMT for calloc and malloc.  */
      si->stmt = stmt;
      /* Only set ENDPTR for calloc.  */
      si->endptr = lhs;
    }
  else if (bcode == BUILT_IN_MALLOC)
    si->stmt = stmt;

  /* Set ALLOC is set for all allocation functions.  */
  si->alloc = stmt;
  set_strinfo (idx, si);
  si->writable = true;
  si->dont_invalidate = true;
}

/* Handle a call to memset.
   After a call to calloc, memset(,0,) is unnecessary.
   memset(malloc(n),0,n) is calloc(n,1).
   return true when the call is transformed, false otherwise.
   When nonnull uses RVALS to determine range information.  */

static bool
handle_builtin_memset (gimple_stmt_iterator *gsi, bool *zero_write,
		       pointer_query &ptr_qry)
{
  gimple *memset_stmt = gsi_stmt (*gsi);
  tree ptr = gimple_call_arg (memset_stmt, 0);
  /* Set to the non-constant offset added to PTR.  */
  wide_int offrng[2];
  int idx1 = get_stridx (ptr, offrng, ptr_qry.rvals);
  if (idx1 <= 0)
    return false;
  strinfo *si1 = get_strinfo (idx1);
  if (!si1)
    return false;
  gimple *alloc_stmt = si1->alloc;
  if (!alloc_stmt || !is_gimple_call (alloc_stmt))
    return false;
  tree callee1 = gimple_call_fndecl (alloc_stmt);
  if (!valid_builtin_call (alloc_stmt))
    return false;
  tree alloc_size = gimple_call_arg (alloc_stmt, 0);
  tree memset_size = gimple_call_arg (memset_stmt, 2);

  /* Check for overflow.  */
  maybe_warn_overflow (memset_stmt, memset_size, ptr_qry, NULL, false, false);

  /* Bail when there is no statement associated with the destination
     (the statement may be null even when SI1->ALLOC is not).  */
  if (!si1->stmt)
    return false;

  /* Avoid optimizing if store is at a variable offset from the beginning
     of the allocated object.  */
  if (offrng[0] != 0 || offrng[0] != offrng[1])
    return false;

  /* Bail when the call writes a non-zero value.  */
  if (!integer_zerop (gimple_call_arg (memset_stmt, 1)))
    return false;

  /* Let the caller know the memset call cleared the destination.  */
  *zero_write = true;

  enum built_in_function code1 = DECL_FUNCTION_CODE (callee1);
  if (code1 == BUILT_IN_CALLOC)
    /* Not touching alloc_stmt */ ;
  else if (code1 == BUILT_IN_MALLOC
	   && operand_equal_p (memset_size, alloc_size, 0))
    {
      /* Replace the malloc + memset calls with calloc.  */
      gimple_stmt_iterator gsi1 = gsi_for_stmt (si1->stmt);
      update_gimple_call (&gsi1, builtin_decl_implicit (BUILT_IN_CALLOC), 2,
			  alloc_size, build_one_cst (size_type_node));
      si1->nonzero_chars = build_int_cst (size_type_node, 0);
      si1->full_string_p = true;
      si1->stmt = gsi_stmt (gsi1);
    }
  else
    return false;
  tree lhs = gimple_call_lhs (memset_stmt);
  unlink_stmt_vdef (memset_stmt);
  if (lhs)
    {
      gimple *assign = gimple_build_assign (lhs, ptr);
      gsi_replace (gsi, assign, false);
    }
  else
    {
      gsi_remove (gsi, true);
      release_defs (memset_stmt);
    }

  return true;
}

/* Return first such statement if RES is used in statements testing its
   equality to zero, and null otherwise.  If EXCLUSIVE is true, return
   nonnull if and only RES is used in such expressions exclusively and
   in none other.  */

static gimple *
use_in_zero_equality (tree res, bool exclusive = true)
{
  gimple *first_use = NULL;

  use_operand_p use_p;
  imm_use_iterator iter;

  FOR_EACH_IMM_USE_FAST (use_p, iter, res)
    {
      gimple *use_stmt = USE_STMT (use_p);

      if (is_gimple_debug (use_stmt))
        continue;

      if (gimple_code (use_stmt) == GIMPLE_ASSIGN)
	{
	  tree_code code = gimple_assign_rhs_code (use_stmt);
	  if (code == COND_EXPR)
	    {
	      tree cond_expr = gimple_assign_rhs1 (use_stmt);
	      if ((TREE_CODE (cond_expr) != EQ_EXPR
		   && (TREE_CODE (cond_expr) != NE_EXPR))
		  || !integer_zerop (TREE_OPERAND (cond_expr, 1)))
		{
		  if (exclusive)
		    return NULL;
		  continue;
		}
	    }
	  else if (code == EQ_EXPR || code == NE_EXPR)
	    {
	      if (!integer_zerop (gimple_assign_rhs2 (use_stmt)))
		{
		  if (exclusive)
		    return NULL;
		  continue;
		}
            }
	  else if (exclusive)
	    return NULL;
	  else
	    continue;
	}
      else if (gimple_code (use_stmt) == GIMPLE_COND)
	{
	  tree_code code = gimple_cond_code (use_stmt);
	  if ((code != EQ_EXPR && code != NE_EXPR)
	      || !integer_zerop (gimple_cond_rhs (use_stmt)))
	    {
	      if (exclusive)
		return NULL;
	      continue;
	    }
	}
      else if (exclusive)
	return NULL;
      else
	continue;

      if (!first_use)
	first_use = use_stmt;
    }

  return first_use;
}

/* Handle a call to memcmp.  We try to handle small comparisons by
   converting them to load and compare, and replacing the call to memcmp
   with a __builtin_memcmp_eq call where possible.
   return true when call is transformed, return false otherwise.  */

static bool
handle_builtin_memcmp (gimple_stmt_iterator *gsi)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree res = gimple_call_lhs (stmt);

  if (!res || !use_in_zero_equality (res))
    return false;

  tree arg1 = gimple_call_arg (stmt, 0);
  tree arg2 = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);
  unsigned HOST_WIDE_INT leni;

  if (tree_fits_uhwi_p (len)
      && (leni = tree_to_uhwi (len)) <= GET_MODE_SIZE (word_mode)
      && pow2p_hwi (leni))
    {
      leni *= CHAR_TYPE_SIZE;
      unsigned align1 = get_pointer_alignment (arg1);
      unsigned align2 = get_pointer_alignment (arg2);
      unsigned align = MIN (align1, align2);
      scalar_int_mode mode;
      if (int_mode_for_size (leni, 1).exists (&mode)
	  && (align >= leni || !targetm.slow_unaligned_access (mode, align)))
	{
	  location_t loc = gimple_location (stmt);
	  tree type, off;
	  type = build_nonstandard_integer_type (leni, 1);
	  gcc_assert (known_eq (GET_MODE_BITSIZE (TYPE_MODE (type)), leni));
	  tree ptrtype = build_pointer_type_for_mode (char_type_node,
						      ptr_mode, true);
	  off = build_int_cst (ptrtype, 0);
	  arg1 = build2_loc (loc, MEM_REF, type, arg1, off);
	  arg2 = build2_loc (loc, MEM_REF, type, arg2, off);
	  tree tem1 = fold_const_aggregate_ref (arg1);
	  if (tem1)
	    arg1 = tem1;
	  tree tem2 = fold_const_aggregate_ref (arg2);
	  if (tem2)
	    arg2 = tem2;
	  res = fold_convert_loc (loc, TREE_TYPE (res),
				  fold_build2_loc (loc, NE_EXPR,
						   boolean_type_node,
						   arg1, arg2));
	  gimplify_and_update_call_from_tree (gsi, res);
	  return true;
	}
    }

  gimple_call_set_fndecl (stmt, builtin_decl_explicit (BUILT_IN_MEMCMP_EQ));
  return true;
}

/* Given strinfo IDX for ARG, sets LENRNG[] to the range of lengths
   of the string(s) referenced by ARG if it can be determined.
   If the length cannot be determined, sets *SIZE to the size of
   the array the string is stored in, if any.  If no such array is
   known, sets *SIZE to -1.  When the strings are nul-terminated sets
   *NULTERM to true, otherwise to false.  When nonnull uses RVALS to
   determine range information. Returns true on success.  */

static bool
get_len_or_size (gimple *stmt, tree arg, int idx,
		 unsigned HOST_WIDE_INT lenrng[2],
		 unsigned HOST_WIDE_INT *size, bool *nulterm,
		 range_query *rvals)
{
  /* Invalidate.  */
  *size = HOST_WIDE_INT_M1U;

  if (idx < 0)
    {
      /* IDX is the inverted constant string length.  */
      lenrng[0] = ~idx;
      lenrng[1] = lenrng[0];
      *nulterm = true;
      return true;
    }

  /* Set so that both LEN and ~LEN are invalid lengths, i.e., maximum
     possible length + 1.  */
  lenrng[0] = lenrng[1] = HOST_WIDE_INT_MAX;

  if (strinfo *si = idx ? get_strinfo (idx) : NULL)
    {
      /* FIXME: Handle all this in_range_strlen_dynamic.  */
      if (!si->nonzero_chars)
	;
      else if (tree_fits_uhwi_p (si->nonzero_chars))
	{
	  lenrng[0] = tree_to_uhwi (si->nonzero_chars);
	  *nulterm = si->full_string_p;
	  /* Set the upper bound only if the string is known to be
	     nul-terminated, otherwise leave it at maximum + 1.  */
	  if (*nulterm)
	    lenrng[1] = lenrng[0];
	}
      else if (TREE_CODE (si->nonzero_chars) == SSA_NAME)
	{
	  wide_int min, max;
	  // FIXME: Use range_query instead of global ranges.
	  value_range_kind rng = get_range_info (si->nonzero_chars, &min, &max);
	  if (rng == VR_RANGE)
	    {
	      lenrng[0] = min.to_uhwi ();
	      lenrng[1] = max.to_uhwi ();
	      *nulterm = si->full_string_p;
	    }
	}
    }

  if (lenrng[0] != HOST_WIDE_INT_MAX)
    return true;

  /* Compute the minimum and maximum real or possible lengths.  */
  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_dynamic (arg, stmt, &lendata, rvals);

  unsigned HOST_WIDE_INT maxbound = HOST_WIDE_INT_M1U;
  if (tree_fits_uhwi_p (lendata.maxbound)
      && !integer_all_onesp (lendata.maxbound))
    maxbound = tree_to_uhwi (lendata.maxbound);

  if (tree_fits_uhwi_p (lendata.minlen) && tree_fits_uhwi_p (lendata.maxlen))
    {
      unsigned HOST_WIDE_INT minlen = tree_to_uhwi (lendata.minlen);
      unsigned HOST_WIDE_INT maxlen = tree_to_uhwi (lendata.maxlen);

      /* The longest string in this data model.  */
      const unsigned HOST_WIDE_INT lenmax
	= tree_to_uhwi (max_object_size ()) - 2;

      if (maxbound == HOST_WIDE_INT_M1U)
	{
	  lenrng[0] = minlen;
	  lenrng[1] = maxlen;
	  *nulterm = minlen == maxlen;
	}
      else if (maxlen < lenmax)
	{
	  *size = maxbound + 1;
	  *nulterm = false;
	}
      else
	return false;

      return true;
    }

  if (maxbound != HOST_WIDE_INT_M1U
      && lendata.maxlen
      && !integer_all_onesp (lendata.maxlen))
    {
      /* Set *SIZE to LENDATA.MAXBOUND which is a conservative estimate
	 of the longest string based on the sizes of the arrays referenced
	 by ARG.  */
      *size = maxbound + 1;
      *nulterm = false;
      return true;
    }

  return false;
}

/* If IDX1 and IDX2 refer to strings A and B of unequal lengths, return
   the result of 0 == strncmp (A, B, BOUND) (which is the same as strcmp
   for a sufficiently large BOUND).  If the result is based on the length
   of one string being greater than the longest string that would fit in
   the array pointer to by the argument, set *PLEN and *PSIZE to
   the corresponding length (or its complement when the string is known
   to be at least as long and need not be nul-terminated) and size.
   Otherwise return null.  */

static tree
strxcmp_eqz_result (gimple *stmt, tree arg1, int idx1, tree arg2, int idx2,
		    unsigned HOST_WIDE_INT bound, unsigned HOST_WIDE_INT len[2],
		    unsigned HOST_WIDE_INT *psize, range_query *rvals)
{
  /* Determine the range the length of each string is in and whether it's
     known to be nul-terminated, or the size of the array it's stored in.  */
  bool nul1, nul2;
  unsigned HOST_WIDE_INT siz1, siz2;
  unsigned HOST_WIDE_INT len1rng[2], len2rng[2];
  if (!get_len_or_size (stmt, arg1, idx1, len1rng, &siz1, &nul1, rvals)
      || !get_len_or_size (stmt, arg2, idx2, len2rng, &siz2, &nul2, rvals))
    return NULL_TREE;

  /* BOUND is set to HWI_M1U for strcmp and less to strncmp, and LENiRNG
     to HWI_MAX when invalid.  Adjust the length of each string to consider
     to be no more than BOUND.  */
  if (len1rng[0] < HOST_WIDE_INT_MAX && len1rng[0] > bound)
    len1rng[0] = bound;
  if (len1rng[1] < HOST_WIDE_INT_MAX && len1rng[1] > bound)
    len1rng[1] = bound;
  if (len2rng[0] < HOST_WIDE_INT_MAX && len2rng[0] > bound)
    len2rng[0] = bound;
  if (len2rng[1] < HOST_WIDE_INT_MAX && len2rng[1] > bound)
    len2rng[1] = bound;

  /* Two empty strings are equal.  */
  if (len1rng[1] == 0 && len2rng[1] == 0)
    return integer_one_node;

  /* The strings are definitely unequal when the lower bound of the length
     of one of them is greater than the length of the longest string that
     would fit into the other array.  */
  if (len1rng[0] == HOST_WIDE_INT_MAX
      && len2rng[0] != HOST_WIDE_INT_MAX
      && ((len2rng[0] < bound && len2rng[0] >= siz1)
	  || len2rng[0] > siz1))
    {
      *psize = siz1;
      len[0] = len1rng[0];
      /* Set LEN[0] to the lower bound of ARG1's length when it's
	 nul-terminated or to the complement of its minimum length
	 otherwise,  */
      len[1] = nul2 ? len2rng[0] : ~len2rng[0];
      return integer_zero_node;
    }

  if (len2rng[0] == HOST_WIDE_INT_MAX
      && len1rng[0] != HOST_WIDE_INT_MAX
      && ((len1rng[0] < bound && len1rng[0] >= siz2)
	  || len1rng[0] > siz2))
    {
      *psize = siz2;
      len[0] = nul1 ? len1rng[0] : ~len1rng[0];
      len[1] = len2rng[0];
      return integer_zero_node;
    }

  /* The strings are also definitely unequal when their lengths are unequal
     and at least one is nul-terminated.  */
  if (len1rng[0] != HOST_WIDE_INT_MAX
      && len2rng[0] != HOST_WIDE_INT_MAX
      && ((len1rng[1] < len2rng[0] && nul1)
	  || (len2rng[1] < len1rng[0] && nul2)))
    {
      if (bound <= len1rng[0] || bound <= len2rng[0])
	*psize = bound;
      else
	*psize = HOST_WIDE_INT_M1U;

      len[0] = len1rng[0];
      len[1] = len2rng[0];
      return integer_zero_node;
    }

  /* The string lengths may be equal or unequal.  Even when equal and
     both strings nul-terminated, without the string contents there's
     no way to determine whether they are equal.  */
  return NULL_TREE;
}

/* Diagnose pointless calls to strcmp or strncmp STMT with string
   arguments of lengths LEN or size SIZ and (for strncmp) BOUND,
   whose result is used in equality expressions that evaluate to
   a constant due to one argument being longer than the size of
   the other.  */

static void
maybe_warn_pointless_strcmp (gimple *stmt, HOST_WIDE_INT bound,
			     unsigned HOST_WIDE_INT len[2],
			     unsigned HOST_WIDE_INT siz)
{
  tree lhs = gimple_call_lhs (stmt);
  gimple *use = use_in_zero_equality (lhs, /* exclusive = */ false);
  if (!use)
    return;

  bool at_least = false;

  /* Excessive LEN[i] indicates a lower bound.  */
  if (len[0] > HOST_WIDE_INT_MAX)
    {
      at_least = true;
      len[0] = ~len[0];
    }

  if (len[1] > HOST_WIDE_INT_MAX)
    {
      at_least = true;
      len[1] = ~len[1];
    }

  unsigned HOST_WIDE_INT minlen = MIN (len[0], len[1]);

  /* FIXME: Include a note pointing to the declaration of the smaller
     array.  */
  location_t stmt_loc = gimple_or_expr_nonartificial_location (stmt, lhs);

  tree callee = gimple_call_fndecl (stmt);
  bool warned = false;
  if (siz <= minlen && bound == -1)
    warned = warning_at (stmt_loc, OPT_Wstring_compare,
			 (at_least
			  ? G_("%G%qD of a string of length %wu or more and "
			       "an array of size %wu evaluates to nonzero")
			  : G_("%G%qD of a string of length %wu and an array "
			       "of size %wu evaluates to nonzero")),
			 stmt, callee, minlen, siz);
  else if (!at_least && siz <= HOST_WIDE_INT_MAX)
    {
      if (len[0] != HOST_WIDE_INT_MAX && len[1] != HOST_WIDE_INT_MAX)
	warned = warning_at (stmt_loc, OPT_Wstring_compare,
			     "%G%qD of strings of length %wu and %wu "
			     "and bound of %wu evaluates to nonzero",
			     stmt, callee, len[0], len[1], bound);
      else
	warned = warning_at (stmt_loc, OPT_Wstring_compare,
			     "%G%qD of a string of length %wu, an array "
			     "of size %wu and bound of %wu evaluates to "
			     "nonzero",
			     stmt, callee, minlen, siz, bound);
    }

  if (!warned)
    return;

  location_t use_loc = gimple_location (use);
  if (LOCATION_LINE (stmt_loc) != LOCATION_LINE (use_loc))
    inform (use_loc, "in this expression");
}


/* Optimize a call to strcmp or strncmp either by folding it to a constant
   when possible or by transforming the latter to the former.  Warn about
   calls where the length of one argument is greater than the size of
   the array to which the other argument points if the latter's length
   is not known.  Return true when the call has been transformed into
   another and false otherwise.  */

static bool
handle_builtin_string_cmp (gimple_stmt_iterator *gsi, range_query *rvals)
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (*gsi));
  tree lhs = gimple_call_lhs (stmt);

  if (!lhs)
    return false;

  tree arg1 = gimple_call_arg (stmt, 0);
  tree arg2 = gimple_call_arg (stmt, 1);
  int idx1 = get_stridx (arg1);
  int idx2 = get_stridx (arg2);

  /* For strncmp set to the value of the third argument if known.  */
  HOST_WIDE_INT bound = -1;
  tree len = NULL_TREE;
  /* Extract the strncmp bound.  */
  if (gimple_call_num_args (stmt) == 3)
    {
      len = gimple_call_arg (stmt, 2);
      if (tree_fits_shwi_p (len))
        bound = tree_to_shwi (len);

      /* If the bound argument is NOT known, do nothing.  */
      if (bound < 0)
	return false;
    }

  /* Avoid folding if either argument is not a nul-terminated array.
     Defer warning until later.  */
  if (!check_nul_terminated_array (NULL_TREE, arg1, len)
      || !check_nul_terminated_array (NULL_TREE, arg2, len))
    return false;

  {
    /* Set to the length of one argument (or its complement if it's
       the lower bound of a range) and the size of the array storing
       the other if the result is based on the former being equal to
       or greater than the latter.  */
    unsigned HOST_WIDE_INT len[2] = { HOST_WIDE_INT_MAX, HOST_WIDE_INT_MAX };
    unsigned HOST_WIDE_INT siz = HOST_WIDE_INT_M1U;

    /* Try to determine if the two strings are either definitely equal
       or definitely unequal and if so, either fold the result to zero
       (when equal) or set the range of the result to ~[0, 0] otherwise.  */
    if (tree eqz = strxcmp_eqz_result (stmt, arg1, idx1, arg2, idx2, bound,
				       len, &siz, rvals))
      {
	if (integer_zerop (eqz))
	  {
	    maybe_warn_pointless_strcmp (stmt, bound, len, siz);

	    /* When the lengths of the first two string arguments are
	       known to be unequal set the range of the result to non-zero.
	       This allows the call to be eliminated if its result is only
	       used in tests for equality to zero.  */
	    wide_int zero = wi::zero (TYPE_PRECISION (TREE_TYPE (lhs)));
	    set_range_info (lhs, VR_ANTI_RANGE, zero, zero);
	    return false;
	  }
	/* When the two strings are definitely equal (such as when they
	   are both empty) fold the call to the constant result.  */
	replace_call_with_value (gsi, integer_zero_node);
	return true;
      }
  }

  /* Return if nothing is known about the strings pointed to by ARG1
     and ARG2.  */
  if (idx1 == 0 && idx2 == 0)
    return false;

  /* Determine either the length or the size of each of the strings,
     whichever is available.  */
  HOST_WIDE_INT cstlen1 = -1, cstlen2 = -1;
  HOST_WIDE_INT arysiz1 = -1, arysiz2 = -1;

  {
    unsigned HOST_WIDE_INT len1rng[2], len2rng[2];
    unsigned HOST_WIDE_INT arsz1, arsz2;
    bool nulterm[2];

    if (!get_len_or_size (stmt, arg1, idx1, len1rng, &arsz1, nulterm, rvals)
	|| !get_len_or_size (stmt, arg2, idx2, len2rng, &arsz2, nulterm + 1,
			     rvals))
      return false;

    if (len1rng[0] == len1rng[1] && len1rng[0] < HOST_WIDE_INT_MAX)
      cstlen1 = len1rng[0];
    else if (arsz1 < HOST_WIDE_INT_M1U)
      arysiz1 = arsz1;

    if (len2rng[0] == len2rng[1] && len2rng[0] < HOST_WIDE_INT_MAX)
      cstlen2 = len2rng[0];
    else if (arsz2 < HOST_WIDE_INT_M1U)
      arysiz2 = arsz2;
  }

  /* Bail if neither the string length nor the size of the array
     it is stored in can be determined.  */
  if ((cstlen1 < 0 && arysiz1 < 0)
      || (cstlen2 < 0 && arysiz2 < 0)
      || (cstlen1 < 0 && cstlen2 < 0))
    return false;

  if (cstlen1 >= 0)
    ++cstlen1;
  if (cstlen2 >= 0)
    ++cstlen2;

  /* The exact number of characters to compare.  */
  HOST_WIDE_INT cmpsiz;
  if (cstlen1 >= 0 && cstlen2 >= 0)
    cmpsiz = MIN (cstlen1, cstlen2);
  else if (cstlen1 >= 0)
    cmpsiz = cstlen1;
  else
    cmpsiz = cstlen2;
  if (bound >= 0)
    cmpsiz = MIN (cmpsiz, bound);
  /* The size of the array in which the unknown string is stored.  */
  HOST_WIDE_INT varsiz = arysiz1 < 0 ? arysiz2 : arysiz1;

  if ((varsiz < 0 || cmpsiz < varsiz) && use_in_zero_equality (lhs))
    {
      /* If the known length is less than the size of the other array
	 and the strcmp result is only used to test equality to zero,
	 transform the call to the equivalent _eq call.  */
      if (tree fn = builtin_decl_implicit (bound < 0 ? BUILT_IN_STRCMP_EQ
					   : BUILT_IN_STRNCMP_EQ))
	{
	  tree n = build_int_cst (size_type_node, cmpsiz);
	  update_gimple_call (gsi, fn, 3, arg1, arg2, n);
	  return true;
	}
    }

  return false;
}

/* Handle a POINTER_PLUS_EXPR statement.
   For p = "abcd" + 2; compute associated length, or if
   p = q + off is pointing to a '\0' character of a string, call
   zero_length_string on it.  */

static void
handle_pointer_plus (gimple_stmt_iterator *gsi)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_assign_lhs (stmt), off;
  int idx = get_stridx (gimple_assign_rhs1 (stmt));
  strinfo *si, *zsi;

  if (idx == 0)
    return;

  if (idx < 0)
    {
      tree off = gimple_assign_rhs2 (stmt);
      if (tree_fits_uhwi_p (off)
	  && tree_to_uhwi (off) <= (unsigned HOST_WIDE_INT) ~idx)
	ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)]
	    = ~(~idx - (int) tree_to_uhwi (off));
      return;
    }

  si = get_strinfo (idx);
  if (si == NULL || si->nonzero_chars == NULL_TREE)
    return;

  off = gimple_assign_rhs2 (stmt);
  zsi = NULL;
  if (si->full_string_p && operand_equal_p (si->nonzero_chars, off, 0))
    zsi = zero_length_string (lhs, si);
  else if (TREE_CODE (off) == SSA_NAME)
    {
      gimple *def_stmt = SSA_NAME_DEF_STMT (off);
      if (gimple_assign_single_p (def_stmt)
	  && si->full_string_p
	  && operand_equal_p (si->nonzero_chars,
			      gimple_assign_rhs1 (def_stmt), 0))
	zsi = zero_length_string (lhs, si);
    }
  if (zsi != NULL
      && si->endptr != NULL_TREE
      && si->endptr != lhs
      && TREE_CODE (si->endptr) == SSA_NAME)
    {
      enum tree_code rhs_code
	= useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (si->endptr))
	  ? SSA_NAME : NOP_EXPR;
      gimple_assign_set_rhs_with_ops (gsi, rhs_code, si->endptr);
      gcc_assert (gsi_stmt (*gsi) == stmt);
      update_stmt (stmt);
    }
}

static bool
count_nonzero_bytes_addr (tree, unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
			  unsigned [3], bool *, bool *, bool *,
			  range_query *, ssa_name_limit_t &);

/* Determines the minimum and maximum number of leading non-zero bytes
   in the representation of EXP and set LENRANGE[0] and LENRANGE[1]
   to each.
   Sets LENRANGE[2] to the total size of the access (which may be less
   than LENRANGE[1] when what's being referenced by EXP is a pointer
   rather than an array).
   Sets *NULTERM if the representation contains a zero byte, and sets
   *ALLNUL if all the bytes are zero.
   OFFSET and NBYTES are the offset into the representation and
   the size of the access to it determined from an ADDR_EXPR (i.e.,
   a pointer) or MEM_REF or zero for other expressions.
   Uses RVALS to determine range information.
   Avoids recursing deeper than the limits in SNLIM allow.
   Returns true on success and false otherwise.  */

static bool
count_nonzero_bytes (tree exp, unsigned HOST_WIDE_INT offset,
		     unsigned HOST_WIDE_INT nbytes,
		     unsigned lenrange[3], bool *nulterm,
		     bool *allnul, bool *allnonnul, range_query *rvals,
		     ssa_name_limit_t &snlim)
{
  if (TREE_CODE (exp) == SSA_NAME)
    {
      /* Handle non-zero single-character stores specially.  */
      tree type = TREE_TYPE (exp);
      if (TREE_CODE (type) == INTEGER_TYPE
	  && TYPE_MODE (type) == TYPE_MODE (char_type_node)
	  && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node)
	  && tree_expr_nonzero_p (exp))
	{
	  /* If the character EXP is known to be non-zero (even if its
	     exact value is not known) recurse once to set the range
	     for an arbitrary constant.  */
	  exp = build_int_cst (type, 1);
	  return count_nonzero_bytes (exp, offset, 1, lenrange,
				      nulterm, allnul, allnonnul, rvals, snlim);
	}

      gimple *stmt = SSA_NAME_DEF_STMT (exp);
      if (gimple_assign_single_p (stmt))
	{
	  exp = gimple_assign_rhs1 (stmt);
	  if (TREE_CODE (exp) != MEM_REF)
	    return false;
	  /* Handle MEM_REF below.  */
	}
      else if (gimple_code (stmt) == GIMPLE_PHI)
	{
	  /* Avoid processing an SSA_NAME that has already been visited
	     or if an SSA_NAME limit has been reached.  Indicate success
	     if the former and failure if the latter.  */
	  if (int res = snlim.next_phi (exp))
	    return res > 0;

	  /* Determine the minimum and maximum from the PHI arguments.  */
	  unsigned int n = gimple_phi_num_args (stmt);
	  for (unsigned i = 0; i != n; i++)
	    {
	      tree def = gimple_phi_arg_def (stmt, i);
	      if (!count_nonzero_bytes (def, offset, nbytes, lenrange, nulterm,
					allnul, allnonnul, rvals, snlim))
		return false;
	    }

	  return true;
	}
    }

  if (TREE_CODE (exp) == MEM_REF)
    {
      if (nbytes)
	return false;

      tree arg = TREE_OPERAND (exp, 0);
      tree off = TREE_OPERAND (exp, 1);

      if (TREE_CODE (off) != INTEGER_CST || !tree_fits_uhwi_p (off))
	return false;

      unsigned HOST_WIDE_INT wioff = tree_to_uhwi (off);
      if (INT_MAX < wioff)
	return false;

      offset += wioff;
      if (INT_MAX < offset)
	return false;

      /* The size of the MEM_REF access determines the number of bytes.  */
      tree type = TREE_TYPE (exp);
      tree typesize = TYPE_SIZE_UNIT (type);
      if (!typesize || !tree_fits_uhwi_p (typesize))
	return false;
      nbytes = tree_to_uhwi (typesize);
      if (!nbytes)
	return false;

      /* Handle MEM_REF = SSA_NAME types of assignments.  */
      return count_nonzero_bytes_addr (arg, offset, nbytes, lenrange, nulterm,
				       allnul, allnonnul, rvals, snlim);
    }

  if (VAR_P (exp) || TREE_CODE (exp) == CONST_DECL)
    {
      exp = ctor_for_folding (exp);
      if (!exp)
	return false;
    }

  const char *prep = NULL;
  if (TREE_CODE (exp) == STRING_CST)
    {
      unsigned nchars = TREE_STRING_LENGTH (exp);
      if (nchars < offset)
	return false;

      if (!nbytes)
	/* If NBYTES hasn't been determined earlier, either from ADDR_EXPR
	   (i.e., it's the size of a pointer), or from MEM_REF (as the size
	   of the access), set it here to the size of the string, including
	   all internal and trailing nuls if the string has any.  */
	nbytes = nchars - offset;
      else if (nchars - offset < nbytes)
	return false;

      prep = TREE_STRING_POINTER (exp) + offset;
    }

  unsigned char buf[256];
  if (!prep)
    {
      if (CHAR_BIT != 8 || BITS_PER_UNIT != 8)
	return false;
      /* If the pointer to representation hasn't been set above
	 for STRING_CST point it at the buffer.  */
      prep = reinterpret_cast <char *>(buf);
      /* Try to extract the representation of the constant object
	 or expression starting from the offset.  */
      unsigned repsize = native_encode_expr (exp, buf, sizeof buf, offset);
      if (repsize < nbytes)
	{
	  /* This should only happen when REPSIZE is zero because EXP
	     doesn't denote an object with a known initializer, except
	     perhaps when the reference reads past its end.  */
	  lenrange[0] = 0;
	  prep = NULL;
	}
      else if (!nbytes)
	nbytes = repsize;
      else if (nbytes < repsize)
	return false;
    }

  if (!nbytes)
    return false;

  /* Compute the number of leading nonzero bytes in the representation
     and update the minimum and maximum.  */
  unsigned n = prep ? strnlen (prep, nbytes) : nbytes;

  if (n < lenrange[0])
    lenrange[0] = n;
  if (lenrange[1] < n)
    lenrange[1] = n;

  /* Set the size of the representation.  */
  if (lenrange[2] < nbytes)
    lenrange[2] = nbytes;

  /* Clear NULTERM if none of the bytes is zero.  */
  if (n == nbytes)
    *nulterm = false;

  if (n)
    {
      /* When the initial number of non-zero bytes N is non-zero, reset
	 *ALLNUL; if N is less than that the size of the representation
	 also clear *ALLNONNUL.  */
      *allnul = false;
      if (n < nbytes)
	*allnonnul = false;
    }
  else if (*allnul || *allnonnul)
    {
      *allnonnul = false;

      if (*allnul)
	{
	  /* When either ALLNUL is set and N is zero, also determine
	     whether all subsequent bytes after the first one (which
	     is nul) are zero or nonzero and clear ALLNUL if not.  */
	  for (const char *p = prep; p != prep + nbytes; ++p)
	    if (*p)
	      {
		*allnul = false;
		break;
	      }
	}
    }

  return true;
}

/* Like count_nonzero_bytes, but instead of counting bytes in EXP, count
   bytes that are pointed to by EXP, which should be a pointer.  */

static bool
count_nonzero_bytes_addr (tree exp, unsigned HOST_WIDE_INT offset,
			  unsigned HOST_WIDE_INT nbytes,
			  unsigned lenrange[3], bool *nulterm,
			  bool *allnul, bool *allnonnul,
			  range_query *rvals, ssa_name_limit_t &snlim)
{
  int idx = get_stridx (exp);
  if (idx > 0)
    {
      strinfo *si = get_strinfo (idx);
      if (!si)
	return false;

      /* Handle both constant lengths as well non-constant lengths
	 in some range.  */
      unsigned HOST_WIDE_INT minlen, maxlen;
      if (tree_fits_shwi_p (si->nonzero_chars))
	minlen = maxlen = tree_to_shwi (si->nonzero_chars);
      else if (si->nonzero_chars
	       && TREE_CODE (si->nonzero_chars) == SSA_NAME)
	{
	  value_range vr;
	  rvals->range_of_expr (vr, si->nonzero_chars, si->stmt);
	  if (vr.kind () != VR_RANGE)
	    return false;

	  minlen = tree_to_uhwi (vr.min ());
	  maxlen = tree_to_uhwi (vr.max ());
	}
      else
	return false;

      if (maxlen < offset)
	return false;

      minlen = minlen < offset ? 0 : minlen - offset;
      maxlen -= offset;
      if (maxlen + 1 < nbytes)
	return false;

      if (nbytes <= minlen)
	*nulterm = false;

      if (nbytes < minlen)
	{
	  minlen = nbytes;
	  if (nbytes < maxlen)
	    maxlen = nbytes;
	}

      if (minlen < lenrange[0])
	lenrange[0] = minlen;
      if (lenrange[1] < maxlen)
	lenrange[1] = maxlen;

      if (lenrange[2] < nbytes)
	lenrange[2] = nbytes;

      /* Since only the length of the string are known and not its contents,
	 clear ALLNUL and ALLNONNUL purely on the basis of the length.  */
      *allnul = false;
      if (minlen < nbytes)
	*allnonnul = false;

      return true;
    }

  if (TREE_CODE (exp) == ADDR_EXPR)
    return count_nonzero_bytes (TREE_OPERAND (exp, 0), offset, nbytes,
				lenrange, nulterm, allnul, allnonnul, rvals,
				snlim);

  if (TREE_CODE (exp) == SSA_NAME)
    {
      gimple *stmt = SSA_NAME_DEF_STMT (exp);
      if (gimple_code (stmt) == GIMPLE_PHI)
	{
	  /* Avoid processing an SSA_NAME that has already been visited
	     or if an SSA_NAME limit has been reached.  Indicate success
	     if the former and failure if the latter.  */
	  if (int res = snlim.next_phi (exp))
	    return res > 0;

	  /* Determine the minimum and maximum from the PHI arguments.  */
	  unsigned int n = gimple_phi_num_args (stmt);
	  for (unsigned i = 0; i != n; i++)
	    {
	      tree def = gimple_phi_arg_def (stmt, i);
	      if (!count_nonzero_bytes_addr (def, offset, nbytes, lenrange,
					     nulterm, allnul, allnonnul, rvals,
					     snlim))
		return false;
	    }

	  return true;
	}
    }

  /* Otherwise we don't know anything.  */
  lenrange[0] = 0;
  if (lenrange[1] < nbytes)
    lenrange[1] = nbytes;
  if (lenrange[2] < nbytes)
    lenrange[2] = nbytes;
  *nulterm = false;
  *allnul = false;
  *allnonnul = false;
  return true;
}

/* Same as above except with an implicit SSA_NAME limit.  RVALS is used
   to determine ranges of dynamically computed string lengths (the results
   of strlen).  */

static bool
count_nonzero_bytes (tree exp, unsigned lenrange[3], bool *nulterm,
		     bool *allnul, bool *allnonnul, range_query *rvals)
{
  /* Set to optimistic values so the caller doesn't have to worry about
     initializing these and to what.  On success, the function will clear
     these if it determines their values are different but being recursive
     it never sets either to true.  On failure, their values are
     unspecified.  */
  *nulterm = true;
  *allnul = true;
  *allnonnul = true;

  ssa_name_limit_t snlim;
  return count_nonzero_bytes (exp, 0, 0, lenrange, nulterm, allnul, allnonnul,
			      rvals, snlim);
}

/* Handle a single or multibyte store other than by a built-in function,
   either via a single character assignment or by multi-byte assignment
   either via MEM_REF or via a type other than char (such as in
   '*(int*)a = 12345').  Return true to let the caller advance *GSI to
   the next statement in the basic block and false otherwise.  */

static bool
handle_store (gimple_stmt_iterator *gsi, bool *zero_write,
	      pointer_query &ptr_qry)
{
  int idx = -1;
  strinfo *si = NULL;
  gimple *stmt = gsi_stmt (*gsi);
  tree ssaname = NULL_TREE, lhs = gimple_assign_lhs (stmt);
  tree rhs = gimple_assign_rhs1 (stmt);

  range_query *const rvals = ptr_qry.rvals;

  /* The offset of the first byte in LHS modified by the store.  */
  unsigned HOST_WIDE_INT offset = 0;

  if (TREE_CODE (lhs) == MEM_REF
      && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
    {
      tree mem_offset = TREE_OPERAND (lhs, 1);
      if (tree_fits_uhwi_p (mem_offset))
	{
	  /* Get the strinfo for the base, and use it if it starts with at
	     least OFFSET nonzero characters.  This is trivially true if
	     OFFSET is zero.  */
	  offset = tree_to_uhwi (mem_offset);
	  idx = get_stridx (TREE_OPERAND (lhs, 0));
	  if (idx > 0)
	    si = get_strinfo (idx);
	  if (offset == 0)
	    ssaname = TREE_OPERAND (lhs, 0);
	  else if (si == NULL || compare_nonzero_chars (si, offset, rvals) < 0)
	    {
	      *zero_write = initializer_zerop (rhs);

	      bool dummy;
	      unsigned lenrange[] = { UINT_MAX, 0, 0 };
	      if (count_nonzero_bytes (rhs, lenrange, &dummy, &dummy, &dummy,
				       rvals))
		maybe_warn_overflow (stmt, lenrange[2], ptr_qry);

	      return true;
	    }
	}
    }
  else
    {
      idx = get_addr_stridx (lhs, NULL_TREE, &offset, rvals);
      if (idx > 0)
	si = get_strinfo (idx);
    }

  /* Minimum and maximum leading non-zero bytes and the size of the store.  */
  unsigned lenrange[] = { UINT_MAX, 0, 0 };

  /* Set to the minimum length of the string being assigned if known.  */
  unsigned HOST_WIDE_INT rhs_minlen;

  /* STORING_NONZERO_P is true iff not all stored characters are zero.
     STORING_ALL_NONZERO_P is true if all stored characters are zero.
     STORING_ALL_ZEROS_P is true iff all stored characters are zero.
     Both are false when it's impossible to determine which is true.  */
  bool storing_nonzero_p;
  bool storing_all_nonzero_p;
  bool storing_all_zeros_p;
  /* FULL_STRING_P is set when the stored sequence of characters form
     a nul-terminated string.  */
  bool full_string_p;

  const bool ranges_valid
    = count_nonzero_bytes (rhs, lenrange, &full_string_p,
			   &storing_all_zeros_p, &storing_all_nonzero_p,
			   rvals);
  if (ranges_valid)
    {
      rhs_minlen = lenrange[0];
      storing_nonzero_p = lenrange[1] > 0;
      *zero_write = storing_all_zeros_p;

      maybe_warn_overflow (stmt, lenrange[2], ptr_qry);
    }
  else
    {
      rhs_minlen = HOST_WIDE_INT_M1U;
      full_string_p = false;
      storing_nonzero_p = false;
      storing_all_zeros_p = false;
      storing_all_nonzero_p = false;
    }

  if (si != NULL)
    {
      /* The corresponding element is set to 1 if the first and last
	 element, respectively, of the sequence of characters being
	 written over the string described by SI ends before
	 the terminating nul (if it has one), to zero if the nul is
	 being overwritten but not beyond, or negative otherwise.  */
      int store_before_nul[2];
      if (ranges_valid)
	{
	  /* The offset of the last stored byte.  */
	  unsigned HOST_WIDE_INT endoff = offset + lenrange[2] - 1;
	  store_before_nul[0] = compare_nonzero_chars (si, offset, rvals);
	  if (endoff == offset)
	    store_before_nul[1] = store_before_nul[0];
	  else
	    store_before_nul[1] = compare_nonzero_chars (si, endoff, rvals);
	}
      else
	{
	  store_before_nul[0] = compare_nonzero_chars (si, offset, rvals);
	  store_before_nul[1] = store_before_nul[0];
	  gcc_assert (offset == 0 || store_before_nul[0] >= 0);
	}

      if (storing_all_zeros_p
	  && store_before_nul[0] == 0
	  && store_before_nul[1] == 0
	  && si->full_string_p)
	{
	  /* When overwriting a '\0' with a '\0', the store can be removed
	     if we know it has been stored in the current function.  */
	  if (!stmt_could_throw_p (cfun, stmt) && si->writable)
	    {
	      unlink_stmt_vdef (stmt);
	      release_defs (stmt);
	      gsi_remove (gsi, true);
	      return false;
	    }
	  else
	    {
	      si->writable = true;
	      gsi_next (gsi);
	      return false;
	    }
	}

      if (store_before_nul[1] > 0
	  && storing_nonzero_p
	  && lenrange[0] == lenrange[1]
	  && lenrange[0] == lenrange[2]
	  && TREE_CODE (TREE_TYPE (rhs)) == INTEGER_TYPE)
	{
	  /* Handle a store of one or more non-nul characters that ends
	     before the terminating nul of the destination and so does
	     not affect its length
	     If si->nonzero_chars > OFFSET, we aren't overwriting '\0',
	     and if we aren't storing '\0', we know that the length of
	     the string and any other zero terminated string in memory
	     remains the same.  In that case we move to the next gimple
	     statement and return to signal the caller that it shouldn't
	     invalidate anything.

	     This is beneficial for cases like:

	     char p[20];
	     void foo (char *q)
	     {
	       strcpy (p, "foobar");
	       size_t len = strlen (p);     // can be folded to 6
	       size_t len2 = strlen (q);    // has to be computed
	       p[0] = 'X';
	       size_t len3 = strlen (p);    // can be folded to 6
	       size_t len4 = strlen (q);    // can be folded to len2
	       bar (len, len2, len3, len4);
	       } */
	  gsi_next (gsi);
	  return false;
	}

      if (storing_all_zeros_p
	  || storing_nonzero_p
	  || (offset != 0 && store_before_nul[1] > 0))
	{
	  /* When STORING_NONZERO_P, we know that the string will start
	     with at least OFFSET + 1 nonzero characters.  If storing
	     a single character, set si->NONZERO_CHARS to the result.
	     If storing multiple characters, try to determine the number
	     of leading non-zero characters and set si->NONZERO_CHARS to
	     the result instead.

	     When STORING_ALL_ZEROS_P, we know that the string is now
	     OFFSET characters long.

	     Otherwise, we're storing an unknown value at offset OFFSET,
	     so need to clip the nonzero_chars to OFFSET.
	     Use the minimum length of the string (or individual character)
	     being stored if it's known.  Otherwise, STORING_NONZERO_P
	     guarantees it's at least 1.  */
	  HOST_WIDE_INT len
	    = storing_nonzero_p && ranges_valid ? lenrange[0] : 1;
	  location_t loc = gimple_location (stmt);
	  tree oldlen = si->nonzero_chars;
	  if (store_before_nul[1] == 0 && si->full_string_p)
	    /* We're overwriting the nul terminator with a nonzero or
	       unknown character.  If the previous stmt was a memcpy,
	       its length may be decreased.  */
	    adjust_last_stmt (si, stmt, false, ptr_qry);
	  si = unshare_strinfo (si);
	  if (storing_nonzero_p)
	    {
	      gcc_assert (len >= 0);
	      si->nonzero_chars = build_int_cst (size_type_node, offset + len);
	    }
	  else
	    si->nonzero_chars = build_int_cst (size_type_node, offset);

	  /* Set FULL_STRING_P only if the length of the strings being
	     written is the same, and clear it if the strings have
	     different lengths.  In the latter case the length stored
	     in si->NONZERO_CHARS becomes the lower bound.
	     FIXME: Handle the upper bound of the length if possible.  */
	  si->full_string_p = full_string_p && lenrange[0] == lenrange[1];

	  if (storing_all_zeros_p
	      && ssaname
	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname))
	    si->endptr = ssaname;
	  else
	    si->endptr = NULL;
	  si->next = 0;
	  si->stmt = NULL;
	  si->writable = true;
	  si->dont_invalidate = true;
	  if (oldlen)
	    {
	      tree adj = fold_build2_loc (loc, MINUS_EXPR, size_type_node,
					  si->nonzero_chars, oldlen);
	      adjust_related_strinfos (loc, si, adj);
	    }
	  else
	    si->prev = 0;
	}
    }
  else if (idx == 0 && (storing_all_zeros_p || storing_nonzero_p))
    {
      if (ssaname)
	idx = new_stridx (ssaname);
      else
	idx = new_addr_stridx (lhs);
      if (idx != 0)
	{
	  tree ptr = (ssaname ? ssaname : build_fold_addr_expr (lhs));

	  HOST_WIDE_INT slen;
	  if (storing_all_zeros_p)
	    slen = 0;
	  else if (storing_nonzero_p && ranges_valid)
	    {
	      /* FIXME: Handle the upper bound of the length when
		 LENRANGE[0] != LENRANGE[1].  */
	      slen = lenrange[0];
	      if (lenrange[0] != lenrange[1])
		/* Set the minimum length but ignore the maximum
		   for now.  */
		full_string_p = false;
	    }
	  else
	    slen = -1;

	  tree len = (slen <= 0
		      ? size_zero_node
		      : build_int_cst (size_type_node, slen));
	  si = new_strinfo (ptr, idx, len, slen >= 0 && full_string_p);
	  set_strinfo (idx, si);
	  if (storing_all_zeros_p
	      && ssaname
	      && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ssaname))
	    si->endptr = ssaname;
	  si->dont_invalidate = true;
	  si->writable = true;
	}
    }
  else if (idx == 0
	   && rhs_minlen < HOST_WIDE_INT_M1U
	   && ssaname == NULL_TREE
	   && TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE)
    {
      HOST_WIDE_INT a = int_size_in_bytes (TREE_TYPE (lhs));
      if (a > 0 && (unsigned HOST_WIDE_INT) a > rhs_minlen)
	{
	  int idx = new_addr_stridx (lhs);
	  if (idx != 0)
	    {
	      si = new_strinfo (build_fold_addr_expr (lhs), idx,
				build_int_cst (size_type_node, rhs_minlen),
				full_string_p);
	      set_strinfo (idx, si);
	      si->dont_invalidate = true;
	    }
	}
    }

  if (si != NULL && offset == 0 && storing_all_zeros_p && lenrange[2] == 1)
    {
      /* For single-byte stores only, allow adjust_last_stmt to remove
	 the statement if the stored '\0' is immediately overwritten.  */
      laststmt.stmt = stmt;
      laststmt.len = build_int_cst (size_type_node, 1);
      laststmt.stridx = si->idx;
    }
  return true;
}

/* Try to fold strstr (s, t) eq/ne s to strncmp (s, t, strlen (t)) eq/ne 0.  */

static void
fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt)
{
  if (TREE_CODE (rhs1) != SSA_NAME
      || TREE_CODE (rhs2) != SSA_NAME)
    return;

  gimple *call_stmt = NULL;
  for (int pass = 0; pass < 2; pass++)
    {
      gimple *g = SSA_NAME_DEF_STMT (rhs1);
      if (gimple_call_builtin_p (g, BUILT_IN_STRSTR)
	  && has_single_use (rhs1)
	  && gimple_call_arg (g, 0) == rhs2)
	{
	  call_stmt = g;
	  break;
	}
      std::swap (rhs1, rhs2);
    }

  if (call_stmt)
    {
      tree arg0 = gimple_call_arg (call_stmt, 0);

      if (arg0 == rhs2)
	{
	  tree arg1 = gimple_call_arg (call_stmt, 1);
	  tree arg1_len = NULL_TREE;
	  int idx = get_stridx (arg1);

	  if (idx)
	    {
	      if (idx < 0)
		arg1_len = build_int_cst (size_type_node, ~idx);
	      else
		{
		  strinfo *si = get_strinfo (idx);
		  if (si)
		    arg1_len = get_string_length (si);
		}
	    }

	  if (arg1_len != NULL_TREE)
	    {
	      gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt);
	      tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP);

	      if (!is_gimple_val (arg1_len))
		{
		  tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len));
		  gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp,
							    arg1_len);
		  gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT);
		  arg1_len = arg1_len_tmp;
		}

	      gcall *strncmp_call = gimple_build_call (strncmp_decl, 3,
						      arg0, arg1, arg1_len);
	      tree strncmp_lhs = make_ssa_name (integer_type_node);
	      gimple_set_vuse (strncmp_call, gimple_vuse (call_stmt));
	      gimple_call_set_lhs (strncmp_call, strncmp_lhs);
	      gsi_remove (&gsi, true);
	      gsi_insert_before (&gsi, strncmp_call, GSI_SAME_STMT);
	      tree zero = build_zero_cst (TREE_TYPE (strncmp_lhs));

	      if (is_gimple_assign (stmt))
		{
		  if (gimple_assign_rhs_code (stmt) == COND_EXPR)
		    {
		      tree cond = gimple_assign_rhs1 (stmt);
		      TREE_OPERAND (cond, 0) = strncmp_lhs;
		      TREE_OPERAND (cond, 1) = zero;
		    }
		  else
		    {
		      gimple_assign_set_rhs1 (stmt, strncmp_lhs);
		      gimple_assign_set_rhs2 (stmt, zero);
		    }
		}
	      else
		{
		  gcond *cond = as_a<gcond *> (stmt);
		  gimple_cond_set_lhs (cond, strncmp_lhs);
		  gimple_cond_set_rhs (cond, zero);
		}
	      update_stmt (stmt);
	    }
	}
    }
}

/* Return true if TYPE corresponds to a narrow character type.  */

static bool
is_char_type (tree type)
{
  return (TREE_CODE (type) == INTEGER_TYPE
	  && TYPE_MODE (type) == TYPE_MODE (char_type_node)
	  && TYPE_PRECISION (type) == TYPE_PRECISION (char_type_node));
}

/* Check the built-in call at GSI for validity and optimize it.
   Uses RVALS to determine range information.
   Return true to let the caller advance *GSI to the next statement
   in the basic block and false otherwise.  */

static bool
strlen_check_and_optimize_call (gimple_stmt_iterator *gsi, bool *zero_write,
				pointer_query &ptr_qry)
{
  gimple *stmt = gsi_stmt (*gsi);

  if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    {
      tree fntype = gimple_call_fntype (stmt);
      if (fntype && lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype)))
	handle_alloc_call (BUILT_IN_NONE, gsi);
    }

  /* When not optimizing we must be checking printf calls which
     we do even for user-defined functions when they are declared
     with attribute format.  */
  if (!flag_optimize_strlen
      || !strlen_optimize
      || !valid_builtin_call (stmt))
    return !handle_printf_call (gsi, ptr_qry);

  tree callee = gimple_call_fndecl (stmt);
  switch (DECL_FUNCTION_CODE (callee))
    {
    case BUILT_IN_STRLEN:
    case BUILT_IN_STRNLEN:
      handle_builtin_strlen (gsi);
      break;
    case BUILT_IN_STRCHR:
      handle_builtin_strchr (gsi);
      break;
    case BUILT_IN_STRCPY:
    case BUILT_IN_STRCPY_CHK:
    case BUILT_IN_STPCPY:
    case BUILT_IN_STPCPY_CHK:
      handle_builtin_strcpy (DECL_FUNCTION_CODE (callee), gsi, ptr_qry);
      break;

    case BUILT_IN_STRNCAT:
    case BUILT_IN_STRNCAT_CHK:
      handle_builtin_strncat (DECL_FUNCTION_CODE (callee), gsi);
      break;

    case BUILT_IN_STPNCPY:
    case BUILT_IN_STPNCPY_CHK:
    case BUILT_IN_STRNCPY:
    case BUILT_IN_STRNCPY_CHK:
      handle_builtin_stxncpy_strncat (false, gsi);
      break;

    case BUILT_IN_MEMCPY:
    case BUILT_IN_MEMCPY_CHK:
    case BUILT_IN_MEMPCPY:
    case BUILT_IN_MEMPCPY_CHK:
      handle_builtin_memcpy (DECL_FUNCTION_CODE (callee), gsi, ptr_qry);
      break;
    case BUILT_IN_STRCAT:
    case BUILT_IN_STRCAT_CHK:
      handle_builtin_strcat (DECL_FUNCTION_CODE (callee), gsi, ptr_qry);
      break;
    case BUILT_IN_ALLOCA:
    case BUILT_IN_ALLOCA_WITH_ALIGN:
    case BUILT_IN_MALLOC:
    case BUILT_IN_CALLOC:
      handle_alloc_call (DECL_FUNCTION_CODE (callee), gsi);
      break;
    case BUILT_IN_MEMSET:
      if (handle_builtin_memset (gsi, zero_write, ptr_qry))
	return false;
      break;
    case BUILT_IN_MEMCMP:
      if (handle_builtin_memcmp (gsi))
	return false;
      break;
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRNCMP:
      if (handle_builtin_string_cmp (gsi, ptr_qry.rvals))
	return false;
      break;
    default:
      if (handle_printf_call (gsi, ptr_qry))
	return false;
      break;
    }

  return true;
}

/* Handle an assignment statement at *GSI to a LHS of integral type.
   If GSI's basic block needs clean-up of EH, set *CLEANUP_EH to true.  */

static void
handle_integral_assign (gimple_stmt_iterator *gsi, bool *cleanup_eh,
			range_query *rvals)
{
  gimple *stmt = gsi_stmt (*gsi);
  tree lhs = gimple_assign_lhs (stmt);
  tree lhs_type = TREE_TYPE (lhs);

  enum tree_code code = gimple_assign_rhs_code (stmt);
  if (code == COND_EXPR)
    {
      tree cond = gimple_assign_rhs1 (stmt);
      enum tree_code cond_code = TREE_CODE (cond);

      if (cond_code == EQ_EXPR || cond_code == NE_EXPR)
	fold_strstr_to_strncmp (TREE_OPERAND (cond, 0),
				TREE_OPERAND (cond, 1), stmt);
    }
  else if (code == EQ_EXPR || code == NE_EXPR)
    fold_strstr_to_strncmp (gimple_assign_rhs1 (stmt),
			    gimple_assign_rhs2 (stmt), stmt);
  else if (gimple_assign_load_p (stmt)
	   && TREE_CODE (lhs_type) == INTEGER_TYPE
	   && TYPE_MODE (lhs_type) == TYPE_MODE (char_type_node)
	   && (TYPE_PRECISION (lhs_type)
	       == TYPE_PRECISION (char_type_node))
	   && !gimple_has_volatile_ops (stmt))
    {
      tree off = integer_zero_node;
      unsigned HOST_WIDE_INT coff = 0;
      int idx = 0;
      tree rhs1 = gimple_assign_rhs1 (stmt);
      if (code == MEM_REF)
	{
	  idx = get_stridx (TREE_OPERAND (rhs1, 0));
	  if (idx > 0)
	    {
	      strinfo *si = get_strinfo (idx);
	      if (si
		  && si->nonzero_chars
		  && TREE_CODE (si->nonzero_chars) == INTEGER_CST
		  && (wi::to_widest (si->nonzero_chars)
		      >= wi::to_widest (off)))
		off = TREE_OPERAND (rhs1, 1);
	      else
		/* This case is not useful.  See if get_addr_stridx
		   returns something usable.  */
		idx = 0;
	    }
	}
      if (idx <= 0)
	idx = get_addr_stridx (rhs1, NULL_TREE, &coff);
      if (idx > 0)
	{
	  strinfo *si = get_strinfo (idx);
	  if (si
	      && si->nonzero_chars
	      && TREE_CODE (si->nonzero_chars) == INTEGER_CST)
	    {
	      widest_int w1 = wi::to_widest (si->nonzero_chars);
	      widest_int w2 = wi::to_widest (off) + coff;
	      if (w1 == w2
		  && si->full_string_p)
		{
		  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
		    {
		      fprintf (dump_file, "Optimizing: ");
		      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
		    }

		  /* Reading the final '\0' character.  */
		  tree zero = build_int_cst (lhs_type, 0);
		  gimple_set_vuse (stmt, NULL_TREE);
		  gimple_assign_set_rhs_from_tree (gsi, zero);
		  *cleanup_eh
		    |= maybe_clean_or_replace_eh_stmt (stmt,
						       gsi_stmt (*gsi));
		  stmt = gsi_stmt (*gsi);
		  update_stmt (stmt);

		  if (dump_file && (dump_flags & TDF_DETAILS) != 0)
		    {
		      fprintf (dump_file, "into: ");
		      print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
		    }
		}
	      else if (w1 > w2)
		{
		  /* Reading a character before the final '\0'
		     character.  Just set the value range to ~[0, 0]
		     if we don't have anything better.  */
		  wide_int min, max;
		  signop sign = TYPE_SIGN (lhs_type);
		  int prec = TYPE_PRECISION (lhs_type);
		  // FIXME: Use range_query instead of global ranges.
		  value_range_kind vr = get_range_info (lhs, &min, &max);
		  if (vr == VR_VARYING
		      || (vr == VR_RANGE
			  && min == wi::min_value (prec, sign)
			  && max == wi::max_value (prec, sign)))
		    set_range_info (lhs, VR_ANTI_RANGE,
				    wi::zero (prec), wi::zero (prec));
		}
	    }
	}
    }
  else if (code == MEM_REF && TREE_CODE (lhs) == SSA_NAME)
    {
      if (int idx = new_stridx (lhs))
	{
	  /* Record multi-byte assignments from MEM_REFs.  */
	  bool storing_all_nonzero_p;
	  bool storing_all_zeros_p;
	  bool full_string_p;
	  unsigned lenrange[] = { UINT_MAX, 0, 0 };
	  tree rhs = gimple_assign_rhs1 (stmt);
	  const bool ranges_valid
	    = count_nonzero_bytes (rhs, lenrange, &full_string_p,
				   &storing_all_zeros_p, &storing_all_nonzero_p,
				   rvals);
	  if (ranges_valid)
	    {
	      tree length = build_int_cst (sizetype, lenrange[0]);
	      strinfo *si = new_strinfo (lhs, idx, length, full_string_p);
	      set_strinfo (idx, si);
	      si->writable = true;
	      si->dont_invalidate = true;
	    }
	}
    }

  if (strlen_to_stridx)
    {
      tree rhs1 = gimple_assign_rhs1 (stmt);
      if (stridx_strlenloc *ps = strlen_to_stridx->get (rhs1))
	strlen_to_stridx->put (lhs, stridx_strlenloc (*ps));
    }
}

/* Attempt to check for validity of the performed access a single statement
   at *GSI using string length knowledge, and to optimize it.
   If the given basic block needs clean-up of EH, CLEANUP_EH is set to
   true.  Return true to let the caller advance *GSI to the next statement
   in the basic block and false otherwise.  */

static bool
check_and_optimize_stmt (gimple_stmt_iterator *gsi, bool *cleanup_eh,
			 pointer_query &ptr_qry)
{
  gimple *stmt = gsi_stmt (*gsi);

  /* For statements that modify a string, set to true if the write
     is only zeros.  */
  bool zero_write = false;

  if (is_gimple_call (stmt))
    {
      if (!strlen_check_and_optimize_call (gsi, &zero_write, ptr_qry))
	return false;
    }
  else if (!flag_optimize_strlen || !strlen_optimize)
    return true;
  else if (is_gimple_assign (stmt) && !gimple_clobber_p (stmt))
    {
      /* Handle non-clobbering assignment.  */
      tree lhs = gimple_assign_lhs (stmt);
      tree lhs_type = TREE_TYPE (lhs);

      if (TREE_CODE (lhs) == SSA_NAME && POINTER_TYPE_P (lhs_type))
	{
	  if (gimple_assign_single_p (stmt)
	      || (gimple_assign_cast_p (stmt)
		  && POINTER_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (stmt)))))
	    {
	      int idx = get_stridx (gimple_assign_rhs1 (stmt));
	      ssa_ver_to_stridx[SSA_NAME_VERSION (lhs)] = idx;
	    }
	  else if (gimple_assign_rhs_code (stmt) == POINTER_PLUS_EXPR)
	    handle_pointer_plus (gsi);
	}
      else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (lhs_type))
	/* Handle assignment to a character.  */
	handle_integral_assign (gsi, cleanup_eh, ptr_qry.rvals);
      else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
	{
	  tree type = TREE_TYPE (lhs);
	  if (TREE_CODE (type) == ARRAY_TYPE)
	    type = TREE_TYPE (type);

	bool is_char_store = is_char_type (type);
	if (!is_char_store && TREE_CODE (lhs) == MEM_REF)
	  {
	    /* To consider stores into char objects via integer types
	       other than char but not those to non-character objects,
	       determine the type of the destination rather than just
	       the type of the access.  */
	    for (int i = 0; i != 2; ++i)
	      {
		tree ref = TREE_OPERAND (lhs, i);
		type = TREE_TYPE (ref);
		if (TREE_CODE (type) == POINTER_TYPE)
		  type = TREE_TYPE (type);
		if (TREE_CODE (type) == ARRAY_TYPE)
		  type = TREE_TYPE (type);
		if (is_char_type (type))
		  {
		    is_char_store = true;
		    break;
		  }
	      }
	  }

	  /* Handle a single or multibyte assignment.  */
	  if (is_char_store && !handle_store (gsi, &zero_write, ptr_qry))
	    return false;
	}
    }
  else if (gcond *cond = dyn_cast<gcond *> (stmt))
    {
      enum tree_code code = gimple_cond_code (cond);
      if (code == EQ_EXPR || code == NE_EXPR)
	fold_strstr_to_strncmp (gimple_cond_lhs (stmt),
				gimple_cond_rhs (stmt), stmt);
    }

  if (gimple_vdef (stmt))
    maybe_invalidate (stmt, zero_write);
  return true;
}

/* Recursively call maybe_invalidate on stmts that might be executed
   in between dombb and current bb and that contain a vdef.  Stop when
   *count stmts are inspected, or if the whole strinfo vector has
   been invalidated.  */

static void
do_invalidate (basic_block dombb, gimple *phi, bitmap visited, int *count)
{
  unsigned int i, n = gimple_phi_num_args (phi);

  for (i = 0; i < n; i++)
    {
      tree vuse = gimple_phi_arg_def (phi, i);
      gimple *stmt = SSA_NAME_DEF_STMT (vuse);
      basic_block bb = gimple_bb (stmt);
      if (bb == NULL
	  || bb == dombb
	  || !bitmap_set_bit (visited, bb->index)
	  || !dominated_by_p (CDI_DOMINATORS, bb, dombb))
	continue;
      while (1)
	{
	  if (gimple_code (stmt) == GIMPLE_PHI)
	    {
	      do_invalidate (dombb, stmt, visited, count);
	      if (*count == 0)
		return;
	      break;
	    }
	  if (--*count == 0)
	    return;
	  if (!maybe_invalidate (stmt))
	    {
	      *count = 0;
	      return;
	    }
	  vuse = gimple_vuse (stmt);
	  stmt = SSA_NAME_DEF_STMT (vuse);
	  if (gimple_bb (stmt) != bb)
	    {
	      bb = gimple_bb (stmt);
	      if (bb == NULL
		  || bb == dombb
		  || !bitmap_set_bit (visited, bb->index)
		  || !dominated_by_p (CDI_DOMINATORS, bb, dombb))
		break;
	    }
	}
    }
}

class strlen_dom_walker : public dom_walker
{
public:
  strlen_dom_walker (cdi_direction direction)
    : dom_walker (direction),
    evrp (false),
    ptr_qry (&evrp, &var_cache),
    var_cache (),
    m_cleanup_cfg (false)
  { }

  virtual edge before_dom_children (basic_block);
  virtual void after_dom_children (basic_block);

  /* EVRP analyzer used for printf argument range processing, and
     to track strlen results across integer variable assignments.  */
  evrp_range_analyzer evrp;

  /* A pointer_query object and its cache to store information about
     pointers and their targets in.  */
  pointer_query ptr_qry;
  pointer_query::cache_type var_cache;

  /* Flag that will trigger TODO_cleanup_cfg to be returned in strlen
     execute function.  */
  bool m_cleanup_cfg;
};

/* Callback for walk_dominator_tree.  Attempt to optimize various
   string ops by remembering string lengths pointed by pointer SSA_NAMEs.  */

edge
strlen_dom_walker::before_dom_children (basic_block bb)
{
  evrp.enter (bb);

  basic_block dombb = get_immediate_dominator (CDI_DOMINATORS, bb);

  if (dombb == NULL)
    stridx_to_strinfo = NULL;
  else
    {
      stridx_to_strinfo = ((vec<strinfo *, va_heap, vl_embed> *) dombb->aux);
      if (stridx_to_strinfo)
	{
	  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
	       gsi_next (&gsi))
	    {
	      gphi *phi = gsi.phi ();
	      if (virtual_operand_p (gimple_phi_result (phi)))
		{
		  bitmap visited = BITMAP_ALLOC (NULL);
		  int count_vdef = 100;
		  do_invalidate (dombb, phi, visited, &count_vdef);
		  BITMAP_FREE (visited);
		  if (count_vdef == 0)
		    {
		      /* If there were too many vdefs in between immediate
			 dominator and current bb, invalidate everything.
			 If stridx_to_strinfo has been unshared, we need
			 to free it, otherwise just set it to NULL.  */
		      if (!strinfo_shared ())
			{
			  unsigned int i;
			  strinfo *si;

			  for (i = 1;
			       vec_safe_iterate (stridx_to_strinfo, i, &si);
			       ++i)
			    {
			      free_strinfo (si);
			      (*stridx_to_strinfo)[i] = NULL;
			    }
			}
		      else
			stridx_to_strinfo = NULL;
		    }
		  break;
		}
	    }
	}
    }

  /* If all PHI arguments have the same string index, the PHI result
     has it as well.  */
  for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
       gsi_next (&gsi))
    {
      gphi *phi = gsi.phi ();
      tree result = gimple_phi_result (phi);
      if (!virtual_operand_p (result) && POINTER_TYPE_P (TREE_TYPE (result)))
	{
	  int idx = get_stridx (gimple_phi_arg_def (phi, 0));
	  if (idx != 0)
	    {
	      unsigned int i, n = gimple_phi_num_args (phi);
	      for (i = 1; i < n; i++)
		if (idx != get_stridx (gimple_phi_arg_def (phi, i)))
		  break;
	      if (i == n)
		ssa_ver_to_stridx[SSA_NAME_VERSION (result)] = idx;
	    }
	}
    }

  bool cleanup_eh = false;

  /* Attempt to optimize individual statements.  */
  for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi); )
    {
      gimple *stmt = gsi_stmt (gsi);

      /* First record ranges generated by this statement so they
	 can be used by printf argument processing.  */
      evrp.record_ranges_from_stmt (stmt, false);

      /* Reset search depth preformance counter.  */
      ptr_qry.depth = 0;

      if (check_and_optimize_stmt (&gsi, &cleanup_eh, ptr_qry))
	gsi_next (&gsi);
    }

  if (cleanup_eh && gimple_purge_dead_eh_edges (bb))
      m_cleanup_cfg = true;

  bb->aux = stridx_to_strinfo;
  if (vec_safe_length (stridx_to_strinfo) && !strinfo_shared ())
    (*stridx_to_strinfo)[0] = (strinfo *) bb;
  return NULL;
}

/* Callback for walk_dominator_tree.  Free strinfo vector if it is
   owned by the current bb, clear bb->aux.  */

void
strlen_dom_walker::after_dom_children (basic_block bb)
{
  evrp.leave (bb);

  if (bb->aux)
    {
      stridx_to_strinfo = ((vec<strinfo *, va_heap, vl_embed> *) bb->aux);
      if (vec_safe_length (stridx_to_strinfo)
	  && (*stridx_to_strinfo)[0] == (strinfo *) bb)
	{
	  unsigned int i;
	  strinfo *si;

	  for (i = 1; vec_safe_iterate (stridx_to_strinfo, i, &si); ++i)
	    free_strinfo (si);
	  vec_free (stridx_to_strinfo);
	}
      bb->aux = NULL;
    }
}

namespace {

static unsigned int
printf_strlen_execute (function *fun, bool warn_only)
{
  strlen_optimize = !warn_only;

  calculate_dominance_info (CDI_DOMINATORS);

  bool use_scev = optimize > 0 && flag_printf_return_value;
  if (use_scev)
    {
      loop_optimizer_init (LOOPS_NORMAL);
      scev_initialize ();
    }

  gcc_assert (!strlen_to_stridx);
  if (warn_stringop_overflow || warn_stringop_truncation)
    strlen_to_stridx = new hash_map<tree, stridx_strlenloc> ();

  /* This has to happen after initializing the loop optimizer
     and initializing SCEV as they create new SSA_NAMEs.  */
  ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names, true);
  max_stridx = 1;

  /* String length optimization is implemented as a walk of the dominator
     tree and a forward walk of statements within each block.  */
  strlen_dom_walker walker (CDI_DOMINATORS);
  walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      unsigned nused = 0;
      unsigned nidxs = walker.ptr_qry.var_cache->indices.length ();
      for (unsigned i = 0; i != nidxs; ++i)
	if (walker.ptr_qry.var_cache->indices[i])
	  ++nused;

      fprintf (dump_file, "pointer_query counters\n"
	       "  index cache size:  %u\n"
	       "  utilization:       %u%%\n"
	       "  access cache size: %u\n"
	       "  hits:              %u\n"
	       "  misses:            %u\n"
	       "  failures:          %u\n"
	       "  max_depth:         %u\n",
	       nidxs,
	       nidxs == 0 ? 0 : (nused * 100) / nidxs,
	       walker.ptr_qry.var_cache->access_refs.length (),
	       walker.ptr_qry.hits, walker.ptr_qry.misses,
	       walker.ptr_qry.failures, walker.ptr_qry.max_depth);
    }

  ssa_ver_to_stridx.release ();
  strinfo_pool.release ();
  if (decl_to_stridxlist_htab)
    {
      obstack_free (&stridx_obstack, NULL);
      delete decl_to_stridxlist_htab;
      decl_to_stridxlist_htab = NULL;
    }
  laststmt.stmt = NULL;
  laststmt.len = NULL_TREE;
  laststmt.stridx = 0;

  if (strlen_to_stridx)
    {
      strlen_to_stridx->empty ();
      delete strlen_to_stridx;
      strlen_to_stridx = NULL;
    }

  if (use_scev)
    {
      scev_finalize ();
      loop_optimizer_finalize ();
    }

  return walker.m_cleanup_cfg ? TODO_cleanup_cfg : 0;
}

/* This file defines two passes: one for warnings that runs only when
   optimization is disabled, and another that implements optimizations
   and also issues warnings.  */

const pass_data pass_data_warn_printf =
{
  GIMPLE_PASS, /* type */
  "warn-printf", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  /* Normally an optimization pass would require PROP_ssa but because
     this pass runs early, with no optimization, to do sprintf format
     checking, it only requires PROP_cfg.  */
  PROP_cfg, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_warn_printf : public gimple_opt_pass
{
public:
  pass_warn_printf (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_warn_printf, ctxt)
  {}

  virtual bool gate (function *);
  virtual unsigned int execute (function *fun)
  {
    return printf_strlen_execute (fun, true);
  }
};


/* Return true to run the warning pass only when not optimizing and
   iff either -Wformat-overflow or -Wformat-truncation is specified.  */

bool
pass_warn_printf::gate (function *)
{
  return !optimize && (warn_format_overflow > 0 || warn_format_trunc > 0);
}

const pass_data pass_data_strlen =
{
  GIMPLE_PASS, /* type */
  "strlen", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_TREE_STRLEN, /* tv_id */
  PROP_cfg | PROP_ssa, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_strlen : public gimple_opt_pass
{
public:
  pass_strlen (gcc::context *ctxt)
    : gimple_opt_pass (pass_data_strlen, ctxt)
  {}

  opt_pass * clone () { return new pass_strlen (m_ctxt); }

  virtual bool gate (function *);
  virtual unsigned int execute (function *fun)
  {
    return printf_strlen_execute (fun, false);
  }
};

/* Return true to run the pass only when the sprintf and/or strlen
   optimizations are enabled and -Wformat-overflow or -Wformat-truncation
   are specified.  */

bool
pass_strlen::gate (function *)
{
  return ((warn_format_overflow > 0
	   || warn_format_trunc > 0
	   || warn_restrict > 0
	   || flag_optimize_strlen > 0
	   || flag_printf_return_value)
	  && optimize > 0);
}

} // anon namespace

gimple_opt_pass *
make_pass_warn_printf (gcc::context *ctxt)
{
  return new pass_warn_printf (ctxt);
}

gimple_opt_pass *
make_pass_strlen (gcc::context *ctxt)
{
  return new pass_strlen (ctxt);
}
