/* 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-access.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 "pointer-query.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);

/* 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 or CFUN for
   range info, whichever is nonnull.  */

tree
get_range (tree val, gimple *stmt, wide_int minmax[2],
	   range_query *rvals /* = NULL */)
{
  if (!rvals)
    {
      if (!cfun)
	/* When called from front ends for global initializers CFUN
	   may be null.  */
	return NULL_TREE;

      rvals = get_range_query (cfun);
    }

  value_range vr;
  if (!rvals->range_of_expr (vr, val, stmt))
    return NULL_TREE;

  value_range_kind rng = vr.kind ();
  if (rng == VR_RANGE)
    {
      /* Only handle straight ranges.  */
      minmax[0] = wi::to_wide (vr.min ());
      minmax[1] = wi::to_wide (vr.max ());
      return val;
    }

  return NULL_TREE;
}

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

  ~strlen_pass ();

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

  bool check_and_optimize_stmt (bool *cleanup_eh);
  bool check_and_optimize_call (bool *zero_write);
  bool handle_assign (tree lhs, bool *zero_write);
  bool handle_store (bool *zero_write);
  void handle_pointer_plus ();
  void handle_builtin_strlen ();
  void handle_builtin_strchr ();
  void handle_builtin_strcpy (built_in_function);
  void handle_integral_assign (bool *cleanup_eh);
  void handle_builtin_stxncpy_strncat (bool append_p);
  void handle_builtin_memcpy (built_in_function bcode);
  void handle_builtin_strcat (built_in_function bcode);
  void handle_builtin_strncat (built_in_function);
  bool handle_builtin_memset (bool *zero_write);
  bool handle_builtin_memcmp ();
  bool handle_builtin_string_cmp ();
  void handle_alloc_call (built_in_function);
  void maybe_warn_overflow (gimple *stmt, bool call_lhs, tree len,
			    strinfo *si = NULL, bool plus_one = false,
			    bool rawmem = false);
  void maybe_warn_overflow (gimple *stmt, bool call_lhs,
			    unsigned HOST_WIDE_INT len,
			    strinfo *si = NULL,
			    bool plus_one = false, bool rawmem = false);
  void adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat);
  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);
  bool count_nonzero_bytes (tree expr_or_type,
			    unsigned lenrange[3], bool *nulterm,
			    bool *allnul, bool *allnonnul);
  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,
			    ssa_name_limit_t &snlim);
  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,
				 ssa_name_limit_t &snlim);
  bool get_len_or_size (gimple *stmt, tree arg, int idx,
			unsigned HOST_WIDE_INT lenrng[2],
			unsigned HOST_WIDE_INT *size, bool *nulterm);

  /* 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;

  gimple_stmt_iterator m_gsi;

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

/* 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 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
			{
			  value_range vr;
			  get_range_query (cfun)
			    ->range_of_expr (vr, si->nonzero_chars);
			  rng = vr.kind ();
			  if (!vr.undefined_p ())
			    {
			      min = wi::to_wide (vr.min ());
			      max = wi::to_wide (vr.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 = si->nonzero_chars;
      ao_ref_init_from_ptr_and_size (&r, si->ptr, size);
      /* Include the terminating nul in the size of the string
	 to consider when determining possible clobber.  But do not
	 add it to 'size' since we don't know whether it would
	 actually fit the allocated area.  */
      if (known_size_p (r.size))
	{
	  if (known_le (r.size, HOST_WIDE_INT_MAX - BITS_PER_UNIT))
	    r.max_size += BITS_PER_UNIT;
	  else
	    r.max_size = -1;
	}
      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.  */

void
strlen_pass::adjust_last_stmt (strinfo *si, gimple *stmt, bool is_strcat)
{
  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, stmt, 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)
	{
	  value_range r;
	  get_range_query (cfun)->range_of_expr (r, bound);
	  if (!r.undefined_p ())
	    {
	      /* 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 (r.lower_bound (), min))
		min = r.lower_bound ();
	      if (wi::ltu_p (r.upper_bound (), max))
		max = r.upper_bound ();
	    }
	}
    }

  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.
   For a call STMT, when CALL_LHS is set use its left hand side
   as the destination, otherwise use argument zero.
   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.  */

void
strlen_pass::maybe_warn_overflow (gimple *stmt, bool call_lhs, tree len,
				  strinfo *si, bool plus_one, bool rawmem)
{
  if (!len || warning_suppressed_p (stmt, OPT_Wstringop_overflow_))
    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 or call STMT.  */
  tree dest = NULL_TREE;

  if (is_gimple_assign (stmt))
    dest = gimple_assign_lhs (stmt);
  else if (is_gimple_call (stmt))
    {
      if (call_lhs)
	dest = gimple_call_lhs (stmt);
      else
	{
	  gcc_assert (gimple_call_builtin_p (stmt, BUILT_IN_NORMAL));
	  dest = gimple_call_arg (stmt, 0);
	}

      if (!dest)
	return;
      writefn = gimple_call_fndecl (stmt);
    }
  else
    return;

  if (warning_suppressed_p (dest, OPT_Wstringop_overflow_))
    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, stmt, 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;

  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 || rawmem || !is_strlen_related_p (si->ptr, len)))
	return;

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

  if (!warned)
    return;

  suppress_warning (stmt, OPT_Wstringop_overflow_);

  aref.inform_access (access_write_only);
}

/* Convenience wrapper for the above.  */

void
strlen_pass::maybe_warn_overflow (gimple *stmt, bool call_lhs,
				  unsigned HOST_WIDE_INT len,
				  strinfo *si, bool plus_one, bool rawmem)
{
  tree tlen = build_int_cst (size_type_node, len);
  maybe_warn_overflow (stmt, call_lhs, tlen, 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.  */

void
strlen_pass::handle_builtin_strlen ()
{
  gimple *stmt = gsi_stmt (m_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);

	  gimplify_and_update_call_from_tree (&m_gsi, rhs);
	  stmt = gsi_stmt (m_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);
	    gimplify_and_update_call_from_tree (&m_gsi, ret);
	    stmt = gsi_stmt (m_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.  */

void
strlen_pass::handle_builtin_strchr ()
{
  gimple *stmt = gsi_stmt (m_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);
	    }
	  gimplify_and_update_call_from_tree (&m_gsi, rhs);
	  stmt = gsi_stmt (m_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.  */

void
strlen_pass::handle_builtin_strcpy (built_in_function bcode)
{
  int idx, didx;
  tree src, dst, srclen, len, lhs, type, fn, oldlen;
  bool success;
  gimple *stmt = gsi_stmt (m_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);

  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, false, srclen, olddsi, true);

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

  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));

  /* Disable warning for the transformed statement?  */
  opt_code no_warning_opt = no_warning;

  if (const strinfo *chksi = si ? olddsi ? olddsi : dsi : NULL)
    {
      no_warning_opt = check_bounds_or_overlap (stmt, chksi->ptr, si->ptr,
						NULL_TREE, len);
      if (no_warning_opt)
	suppress_warning (stmt, no_warning_opt);
    }

  if (fn == NULL_TREE)
    return;

  len = force_gimple_operand_gsi (&m_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 (&m_gsi, fn, 3, dst, src, len);
  else
    success = update_gimple_call (&m_gsi, fn, 4, dst, src, len,
				  gimple_call_arg (stmt, 2));
  if (success)
    {
      stmt = gsi_stmt (m_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 (no_warning_opt)
    suppress_warning (stmt, no_warning_opt);
}

/* 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.  */

void
strlen_pass::handle_builtin_strncat (built_in_function)
{
  /* Same as stxncpy().  */
  handle_builtin_stxncpy_strncat (true);
}

/* 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 (warning_suppressed_p (stmt, OPT_Wstringop_truncation))
    return false;

  wide_int cntrange[2];
  value_range r;
  if (!get_range_query (cfun)->range_of_expr (r, cnt)
      || r.varying_p ()
      || r.undefined_p ())
    return false;

  cntrange[0] = wi::to_wide (r.min ());
  cntrange[1] = wi::to_wide (r.max ());
  if (r.kind () == 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)));
	}
    }

  /* 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 (),
			  "%qD output truncated before terminating "
			  "nul copying %E byte from a string of the "
			  "same length",
			  "%qD output truncated before terminating nul "
			  "copying %E bytes from a string of the same "
			  "length",
			  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 (),
				  "%qD output truncated copying %E byte "
				  "from a string of length %wu",
				  "%qD output truncated copying %E bytes "
				  "from a string of length %wu",
				  func, cnt, lenrange[0].to_uhwi ());

	      return warning_at (callloc, OPT_Wstringop_truncation,
				 "%qD output truncated copying between %wu "
				 "and %wu bytes from a string of length %wu",
				 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 (),
				  "%qD output may be truncated copying %E "
				  "byte from a string of length %wu",
				  "%qD output may be truncated copying %E "
				  "bytes from a string of length %wu",
				  func, cnt, lenrange[1].to_uhwi ());

	      return warning_at (callloc, OPT_Wstringop_truncation,
				 "%qD output may be truncated copying between "
				 "%wu and %wu bytes from a string of length %wu",
				 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,
			     "%qD output may be truncated copying between "
			     "%wu and %wu bytes from a string of length %wu",
			     func, cntrange[0].to_uhwi (),
			     cntrange[1].to_uhwi (), lenrange[0].to_uhwi ());
	}
    }

  access_ref aref;
  if (tree dstsize = compute_objsize (dst, stmt, 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, stmt, 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,
			   "%qD specified bound %E equals destination size",
			   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.  */

void
strlen_pass::handle_builtin_stxncpy_strncat (bool append_p)
{
  if (!strlen_to_stridx)
    return;

  gimple *stmt = gsi_stmt (m_gsi);

  tree dst = gimple_call_arg (stmt, 0);
  tree src = gimple_call_arg (stmt, 1);
  tree len = gimple_call_arg (stmt, 2);
  /* An upper bound of the size of the destination.  */
  tree dstsize = NULL_TREE;
  /* The length of the destination and source strings (plus 1 for those
     whose FULL_STRING_P is set, i.e., whose length is exact rather than
     a lower bound).  */
  tree dstlenp1 = NULL_TREE, srclenp1 = 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);
	      dstlenp1 = fold_build2 (PLUS_EXPR, type, sidst->nonzero_chars,
				     build_int_cst (type, 1));
	    }
	  else
	    dstlenp1 = sidst->nonzero_chars;
	}
      else if (TREE_CODE (sidst->ptr) == SSA_NAME)
	{
	  gimple *def_stmt = SSA_NAME_DEF_STMT (sidst->ptr);
	  dstsize = gimple_call_alloc_size (def_stmt);
	}

      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);
	      srclenp1 = fold_build2 (PLUS_EXPR, type, sisrc->nonzero_chars,
				     build_int_cst (type, 1));
	    }
	  else
	    srclenp1 = sisrc->nonzero_chars;
	}

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

  opt_code opt = check_bounds_or_overlap (stmt, dst, src, dstlenp1, srclenp1);
  if (opt != no_warning)
    {
      suppress_warning (stmt, opt);
      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 (m_gsi, src, len))
	suppress_warning (stmt, OPT_Wstringop_truncation);

      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, when appending, or
     when copying into a destination of known size, 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,
		     "%qD output truncated before terminating nul "
		     "copying as many bytes from a string as its length",
		     func))
    warned = true;
  else if ((append_p || !dstsize || len == dstlenp1)
	   && silen && is_strlen_related_p (src, silen->ptr))
    {
      /* Issue -Wstringop-overflow when appending or when writing into
	 a destination of a known size.  Otherwise, when copying into
	 a destination of an unknown size, it's truncation.  */
      opt_code opt = (append_p || dstsize
		      ? OPT_Wstringop_overflow_ : OPT_Wstringop_truncation);
      warned = warning_at (callloc, opt,
			   "%qD specified bound depends on the length "
			   "of the source argument",
			   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.  */

void
strlen_pass::handle_builtin_memcpy (built_in_function bcode)
{
  tree lhs, oldlen, newlen;
  gimple *stmt = gsi_stmt (m_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, false, len, olddsi, false, true);
      adjust_last_stmt (olddsi, stmt, false);
    }

  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);

  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.  */

void
strlen_pass::handle_builtin_strcat (built_in_function bcode)
{
  int idx, didx;
  tree srclen, args, type, fn, objsz, endptr;
  bool success;
  gimple *stmt = gsi_stmt (m_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);
    }

  /* Disable warning for the transformed statement?  */
  opt_code no_warning_opt = no_warning;

  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;
	no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, NULL_TREE,
						  slen);
	if (no_warning_opt)
	  suppress_warning (stmt, no_warning_opt);
      }

      /* 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;

      no_warning_opt = check_bounds_or_overlap (stmt, dst, sptr, dstsize,
						srcsize);
      if (no_warning_opt)
	suppress_warning (stmt, no_warning_opt);
    }

  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 (&m_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 (&m_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 (&m_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 (&m_gsi, fn, 3 + (objsz != NULL_TREE),
				  dst, src, len, objsz);
  else
    success = update_gimple_call (&m_gsi, fn, 2 + (objsz != NULL_TREE),
				  dst, src, objsz);
  if (success)
    {
      stmt = gsi_stmt (m_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);
      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 (no_warning_opt)
    suppress_warning (stmt, no_warning_opt);
}

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

void
strlen_pass::handle_alloc_call (built_in_function bcode)
{
  gimple *stmt = gsi_stmt (m_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.  */

bool
strlen_pass::handle_builtin_memset (bool *zero_write)
{
  gimple *memset_stmt = gsi_stmt (m_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, false, memset_size, NULL, false, true);

  /* 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 (&m_gsi, assign, false);
    }
  else
    {
      gsi_remove (&m_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.  */

bool
strlen_pass::handle_builtin_memcmp ()
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (m_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 (&m_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.  */

bool
strlen_pass::get_len_or_size (gimple *stmt, tree arg, int idx,
			      unsigned HOST_WIDE_INT lenrng[2],
			      unsigned HOST_WIDE_INT *size, bool *nulterm)
{
  /* 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)
	{
	  value_range r;
	  get_range_query (cfun)->range_of_expr (r, si->nonzero_chars);
	  if (r.kind () == VR_RANGE)
	    {
	      lenrng[0] = r.lower_bound ().to_uhwi ();
	      lenrng[1] = r.upper_bound ().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, ptr_qry.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.  */

tree
strlen_pass::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)
{
  /* 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)
      || !get_len_or_size (stmt, arg2, idx2, len2rng, &siz2, &nul2))
    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_("%qD of a string of length %wu or more and "
			       "an array of size %wu evaluates to nonzero")
			  : G_("%qD of a string of length %wu and an array "
			       "of size %wu evaluates to nonzero")),
			 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,
			     "%qD of strings of length %wu and %wu "
			     "and bound of %wu evaluates to nonzero",
			     callee, len[0], len[1], bound);
      else
	warned = warning_at (stmt_loc, OPT_Wstring_compare,
			     "%qD of a string of length %wu, an array "
			     "of size %wu and bound of %wu evaluates to "
			     "nonzero",
			     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.  */

bool
strlen_pass::handle_builtin_string_cmp ()
{
  gcall *stmt = as_a <gcall *> (gsi_stmt (m_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))
      {
	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 (&m_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)
	|| !get_len_or_size (stmt, arg2, idx2, len2rng, &arsz2, nulterm + 1))
      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 (&m_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.  */

void
strlen_pass::handle_pointer_plus ()
{
  gimple *stmt = gsi_stmt (m_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 (&m_gsi, rhs_code, si->endptr);
      gcc_assert (gsi_stmt (m_gsi) == stmt);
      update_stmt (stmt);
    }
}

/* Set LENRANGE to the number of nonzero bytes for a store of TYPE and
   clear all flags.  Return true on success and false on failure.  */

static bool
nonzero_bytes_for_type (tree type, unsigned lenrange[3],
			bool *nulterm, bool *allnul, bool *allnonnul)
{
  /* Use the size of the type of the expression as the size of the store,
     and set the upper bound of the length range to that of the size.
     Nothing is known about the contents so clear all flags.  */
  tree typesize = TYPE_SIZE_UNIT (type);
  if (!type)
    return false;

  if (!tree_fits_uhwi_p (typesize))
    return false;

  unsigned HOST_WIDE_INT sz = tree_to_uhwi (typesize);
  if (sz > UINT_MAX)
    return false;

  lenrange[2] = sz;
  lenrange[1] = lenrange[2] ? lenrange[2] - 1 : 0;
  lenrange[0] = 0;
  *nulterm = false;
  *allnul = false;
  *allnonnul = false;
  return true;
}

/* Recursively determine the minimum and maximum number of leading nonzero
   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, sets *ALLNUL
   if all the bytes are zero, and *ALLNONNUL is all are nonzero.
   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.  */

bool
strlen_pass::count_nonzero_bytes (tree exp,
				  unsigned HOST_WIDE_INT offset,
				  unsigned HOST_WIDE_INT nbytes,
				  unsigned lenrange[3], bool *nulterm,
				  bool *allnul, bool *allnonnul,
				  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, snlim);
	}

      gimple *stmt = SSA_NAME_DEF_STMT (exp);
      if (gimple_assign_single_p (stmt))
	{
	  exp = gimple_assign_rhs1 (stmt);
	  if (!DECL_P (exp)
	      && TREE_CODE (exp) != CONSTRUCTOR
	      && TREE_CODE (exp) != MEM_REF)
	    return false;
	  /* Handle DECLs, CONSTRUCTOR and 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, snlim))
		return false;
	    }

	  return true;
	}
    }

  if (TREE_CODE (exp) == CONSTRUCTOR)
    {
      if (nbytes)
	/* If NBYTES has already been determined by an outer MEM_REF
	   fail rather than overwriting it (this shouldn't happen).  */
	return false;

      tree type = TREE_TYPE (exp);
      tree size = TYPE_SIZE_UNIT (type);
      if (!size || !tree_fits_uhwi_p (size))
	return false;

      unsigned HOST_WIDE_INT byte_size = tree_to_uhwi (size);
      if (byte_size < offset)
	return false;

      nbytes = byte_size - offset;
    }

  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, snlim);
    }

  if (VAR_P (exp) || TREE_CODE (exp) == CONST_DECL)
    {
      /* If EXP can be folded into a constant use the result.  Otherwise
	 proceed to use EXP to determine a range of the result.  */
      if (tree fold_exp = ctor_for_folding (exp))
	if (fold_exp != error_mark_node)
	  exp = fold_exp;
    }

  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 nonzero_bytes_for_type (TREE_TYPE (exp), lenrange,
				   nulterm, allnul, allnonnul);

  /* 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.  */

bool
strlen_pass::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,
				       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;
	  ptr_qry.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, 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,
					     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.  When EXPR_OR_TYPE
   is a type rather than an expression use its size to compute the range.
   RVALS is used to determine ranges of dynamically computed string lengths
   (the results of strlen).  */

bool
strlen_pass::count_nonzero_bytes (tree expr_or_type,
				  unsigned lenrange[3], bool *nulterm,
				  bool *allnul, bool *allnonnul)
{
  if (TYPE_P (expr_or_type))
    return nonzero_bytes_for_type (expr_or_type, lenrange,
				   nulterm, allnul, allnonnul);

  /* 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;
  tree expr = expr_or_type;
  return count_nonzero_bytes (expr, 0, 0, lenrange, nulterm, allnul, allnonnul,
			      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.  */

bool
strlen_pass::handle_store (bool *zero_write)
{
  gimple *stmt = gsi_stmt (m_gsi);
  /* The LHS and RHS of the store.  The RHS is null if STMT is a function
     call.  STORETYPE is the type of the store (determined from either
     the RHS of the assignment statement or the LHS of a function call.  */
  tree lhs, rhs, storetype;
  if (is_gimple_assign (stmt))
    {
      lhs = gimple_assign_lhs (stmt);
      rhs = gimple_assign_rhs1 (stmt);
      storetype = TREE_TYPE (rhs);
    }
  else if (is_gimple_call (stmt))
    {
      lhs = gimple_call_lhs (stmt);
      rhs = NULL_TREE;
      storetype = TREE_TYPE (lhs);
    }
  else
    return true;

  tree ssaname = NULL_TREE;
  strinfo *si = NULL;
  int idx = -1;

  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 = rhs ? initializer_zerop (rhs) : false;

	      bool dummy;
	      unsigned lenrange[] = { UINT_MAX, 0, 0 };
	      if (count_nonzero_bytes (rhs ? rhs : storetype, lenrange,
				       &dummy, &dummy, &dummy))
		maybe_warn_overflow (stmt, true, lenrange[2]);

	      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 ? rhs : storetype, lenrange, &full_string_p,
			   &storing_all_zeros_p, &storing_all_nonzero_p);

  if (ranges_valid)
    {
      rhs_minlen = lenrange[0];
      storing_nonzero_p = lenrange[1] > 0;
      *zero_write = storing_all_zeros_p;

      maybe_warn_overflow (stmt, true, lenrange[2]);
    }
  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 (&m_gsi, true);
	      return false;
	    }
	  else
	    {
	      si->writable = true;
	      gsi_next (&m_gsi);
	      return false;
	    }
	}

      if (store_before_nul[1] > 0
	  && storing_nonzero_p
	  && lenrange[0] == lenrange[1]
	  && lenrange[0] == lenrange[2]
	  && TREE_CODE (storetype) == 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 (&m_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);
	  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.  */

bool
strlen_pass::check_and_optimize_call (bool *zero_write)
{
  gimple *stmt = gsi_stmt (m_gsi);

  if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
    {
      tree fntype = gimple_call_fntype (stmt);
      if (!fntype)
	return true;

      if (lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (fntype)))
	{
	  handle_alloc_call (BUILT_IN_NONE);
	  return true;
	}

      if (tree lhs = gimple_call_lhs (stmt))
	handle_assign (lhs, zero_write);

      /* Proceed to handle user-defined formatting functions.  */
    }

  /* 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 (&m_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 ();
      break;
    case BUILT_IN_STRCHR:
      handle_builtin_strchr ();
      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));
      break;

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

    case BUILT_IN_STPNCPY:
    case BUILT_IN_STPNCPY_CHK:
    case BUILT_IN_STRNCPY:
    case BUILT_IN_STRNCPY_CHK:
      handle_builtin_stxncpy_strncat (false);
      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));
      break;
    case BUILT_IN_STRCAT:
    case BUILT_IN_STRCAT_CHK:
      handle_builtin_strcat (DECL_FUNCTION_CODE (callee));
      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));
      break;
    case BUILT_IN_MEMSET:
      if (handle_builtin_memset (zero_write))
	return false;
      break;
    case BUILT_IN_MEMCMP:
      if (handle_builtin_memcmp ())
	return false;
      break;
    case BUILT_IN_STRCMP:
    case BUILT_IN_STRNCMP:
      if (handle_builtin_string_cmp ())
	return false;
      break;
    default:
      if (handle_printf_call (&m_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.  */

void
strlen_pass::handle_integral_assign (bool *cleanup_eh)
{
  gimple *stmt = gsi_stmt (m_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 (&m_gsi, zero);
		  *cleanup_eh
		    |= maybe_clean_or_replace_eh_stmt (stmt,
						       gsi_stmt (m_gsi));
		  stmt = gsi_stmt (m_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.  */
		  value_range r;
		  if (!get_range_query (cfun)->range_of_expr (r, lhs)
		      || r.varying_p ())
		    {
		      r.set_nonzero (lhs_type);
		      set_range_info (lhs, r);
		    }
		}
	    }
	}
    }
  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);
	  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));
    }
}

/* Handle assignment statement at *GSI to LHS.  Set *ZERO_WRITE if
   the assignent stores all zero bytes..  */

bool
strlen_pass::handle_assign (tree lhs, bool *zero_write)
{
  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 (zero_write))
    return false;

  return true;
}


/* 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.  */

bool
strlen_pass::check_and_optimize_stmt (bool *cleanup_eh)
{
  gimple *stmt = gsi_stmt (m_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 (!check_and_optimize_call (&zero_write))
	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 ();
	}
      else if (TREE_CODE (lhs) == SSA_NAME && INTEGRAL_TYPE_P (lhs_type))
	/* Handle assignment to a character.  */
	handle_integral_assign (cleanup_eh);
      else if (TREE_CODE (lhs) != SSA_NAME && !TREE_SIDE_EFFECTS (lhs))
	if (!handle_assign (lhs, &zero_write))
	  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;
	    }
	}
    }
}

/* Release pointer_query cache.  */

strlen_pass::~strlen_pass ()
{
  ptr_qry.flush_cache ();
}

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

edge
strlen_pass::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 (m_gsi = gsi_start_bb (bb); !gsi_end_p (m_gsi); )
    {
      gimple *stmt = gsi_stmt (m_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 (&cleanup_eh))
	gsi_next (&m_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_pass::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_pass walker (CDI_DOMINATORS);
  walker.walk (ENTRY_BLOCK_PTR_FOR_FN (fun));

  if (dump_file && (dump_flags & TDF_DETAILS))
    walker.ptr_qry.dump (dump_file);

  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);
}
