/* Copyright (C) 2016-2021 Free Software Foundation, Inc.
   Contributed by Martin Sebor <msebor@redhat.com>.

This file is part of GCC.

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

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

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

/* This file implements the printf-return-value pass.  The pass does
   two things: 1) it analyzes calls to formatted output functions like
   sprintf looking for possible buffer overflows and calls to bounded
   functions like snprintf for early truncation (and under the control
   of the -Wformat-length option issues warnings), and 2) under the
   control of the -fprintf-return-value option it folds the return
   value of safe calls into constants, making it possible to eliminate
   code that depends on the value of those constants.

   For all functions (bounded or not) the pass uses the size of the
   destination object.  That means that it will diagnose calls to
   snprintf not on the basis of the size specified by the function's
   second argument but rather on the basis of the size the first
   argument points to (if possible).  For bound-checking built-ins
   like __builtin___snprintf_chk the pass uses the size typically
   determined by __builtin_object_size and passed to the built-in
   by the Glibc inline wrapper.

   The pass handles all forms standard sprintf format directives,
   including character, integer, floating point, pointer, and strings,
   with the standard C flags, widths, and precisions.  For integers
   and strings it computes the length of output itself.  For floating
   point it uses MPFR to format known constants with up and down
   rounding and uses the resulting range of output lengths.  For
   strings it uses the length of string literals and the sizes of
   character arrays that a character pointer may point to as a bound
   on the longest string.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "gimple-fold.h"
#include "gimple-pretty-print.h"
#include "diagnostic-core.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "tree-ssa.h"
#include "tree-object-size.h"
#include "tree-cfg.h"
#include "tree-ssa-propagate.h"
#include "calls.h"
#include "cfgloop.h"
#include "tree-scalar-evolution.h"
#include "tree-ssa-loop.h"
#include "intl.h"
#include "langhooks.h"

#include "attribs.h"
#include "builtins.h"
#include "pointer-query.h"
#include "stor-layout.h"

#include "realmpfr.h"
#include "target.h"

#include "cpplib.h"
#include "input.h"
#include "toplev.h"
#include "substring-locations.h"
#include "diagnostic.h"
#include "domwalk.h"
#include "alloc-pool.h"
#include "vr-values.h"
#include "tree-ssa-strlen.h"
#include "tree-dfa.h"

/* The likely worst case value of MB_LEN_MAX for the target, large enough
   for UTF-8.  Ideally, this would be obtained by a target hook if it were
   to be used for optimization but it's good enough as is for warnings.  */
#define target_mb_len_max()   6

/* The maximum number of bytes a single non-string directive can result
   in.  This is the result of printf("%.*Lf", INT_MAX, -LDBL_MAX) for
   LDBL_MAX_10_EXP of 4932.  */
#define IEEE_MAX_10_EXP    4932
#define target_dir_max()   (target_int_max () + IEEE_MAX_10_EXP + 2)

namespace {

/* Set to the warning level for the current function which is equal
   either to warn_format_trunc for bounded functions or to
   warn_format_overflow otherwise.  */

static int warn_level;

/* The minimum, maximum, likely, and unlikely maximum number of bytes
   of output either a formatting function or an individual directive
   can result in.  */

struct result_range
{
  /* The absolute minimum number of bytes.  The result of a successful
     conversion is guaranteed to be no less than this.  (An erroneous
     conversion can be indicated by MIN > HOST_WIDE_INT_MAX.)  */
  unsigned HOST_WIDE_INT min;
  /* The likely maximum result that is used in diagnostics.  In most
     cases MAX is the same as the worst case UNLIKELY result.  */
  unsigned HOST_WIDE_INT max;
  /* The likely result used to trigger diagnostics.  For conversions
     that result in a range of bytes [MIN, MAX], LIKELY is somewhere
     in that range.  */
  unsigned HOST_WIDE_INT likely;
  /* In rare cases (e.g., for multibyte characters) UNLIKELY gives
     the worst cases maximum result of a directive.  In most cases
     UNLIKELY == MAX.  UNLIKELY is used to control the return value
     optimization but not in diagnostics.  */
  unsigned HOST_WIDE_INT unlikely;
};

/* Return the value of INT_MIN for the target.  */

static inline HOST_WIDE_INT
target_int_min ()
{
  return tree_to_shwi (TYPE_MIN_VALUE (integer_type_node));
}

/* Return the value of INT_MAX for the target.  */

static inline unsigned HOST_WIDE_INT
target_int_max ()
{
  return tree_to_uhwi (TYPE_MAX_VALUE (integer_type_node));
}

/* Return the value of SIZE_MAX for the target.  */

static inline unsigned HOST_WIDE_INT
target_size_max ()
{
  return tree_to_uhwi (TYPE_MAX_VALUE (size_type_node));
}

/* A straightforward mapping from the execution character set to the host
   character set indexed by execution character.  */

static char target_to_host_charmap[256];

/* Initialize a mapping from the execution character set to the host
   character set.  */

static bool
init_target_to_host_charmap ()
{
  /* If the percent sign is non-zero the mapping has already been
     initialized.  */
  if (target_to_host_charmap['%'])
    return true;

  /* Initialize the target_percent character (done elsewhere).  */
  if (!init_target_chars ())
    return false;

  /* The subset of the source character set used by printf conversion
     specifications (strictly speaking, not all letters are used but
     they are included here for the sake of simplicity).  The dollar
     sign must be included even though it's not in the basic source
     character set.  */
  const char srcset[] = " 0123456789!\"#%&'()*+,-./:;<=>?[\\]^_{|}~$"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

  /* Set the mapping for all characters to some ordinary value (i,e.,
     not none used in printf conversion specifications) and overwrite
     those that are used by conversion specifications with their
     corresponding values.  */
  memset (target_to_host_charmap + 1, '?', sizeof target_to_host_charmap - 1);

  /* Are the two sets of characters the same?  */
  bool all_same_p = true;

  for (const char *pc = srcset; *pc; ++pc)
    {
      /* Slice off the high end bits in case target characters are
	 signed.  All values are expected to be non-nul, otherwise
	 there's a problem.  */
      if (unsigned char tc = lang_hooks.to_target_charset (*pc))
	{
	  target_to_host_charmap[tc] = *pc;
	  if (tc != *pc)
	    all_same_p = false;
	}
      else
	return false;

    }

  /* Set the first element to a non-zero value if the mapping
     is 1-to-1, otherwise leave it clear (NUL is assumed to be
     the same in both character sets).  */
  target_to_host_charmap[0] = all_same_p;

  return true;
}

/* Return the host source character corresponding to the character
   CH in the execution character set if one exists, or some innocuous
   (non-special, non-nul) source character otherwise.  */

static inline unsigned char
target_to_host (unsigned char ch)
{
  return target_to_host_charmap[ch];
}

/* Convert an initial substring of the string TARGSTR consisting of
   characters in the execution character set into a string in the
   source character set on the host and store up to HOSTSZ characters
   in the buffer pointed to by HOSTR.  Return HOSTR.  */

static const char*
target_to_host (char *hostr, size_t hostsz, const char *targstr)
{
  /* Make sure the buffer is reasonably big.  */
  gcc_assert (hostsz > 4);

  /* The interesting subset of source and execution characters are
     the same so no conversion is necessary.  However, truncate
     overlong strings just like the translated strings are.  */
  if (target_to_host_charmap['\0'] == 1)
    {
      size_t len = strlen (targstr);
      if (len >= hostsz)
	{
	  memcpy (hostr, targstr, hostsz - 4);
	  strcpy (hostr + hostsz - 4, "...");
	}
      else
	memcpy (hostr, targstr, len + 1);
      return hostr;
    }

  /* Convert the initial substring of TARGSTR to the corresponding
     characters in the host set, appending "..." if TARGSTR is too
     long to fit.  Using the static buffer assumes the function is
     not called in between sequence points (which it isn't).  */
  for (char *ph = hostr; ; ++targstr)
    {
      *ph++ = target_to_host (*targstr);
      if (!*targstr)
	break;

      if (size_t (ph - hostr) == hostsz)
	{
	  strcpy (ph - 4, "...");
	  break;
	}
    }

  return hostr;
}

/* Convert the sequence of decimal digits in the execution character
   starting at *PS to a HOST_WIDE_INT, analogously to strtol.  Return
   the result and set *PS to one past the last converted character.
   On range error set ERANGE to the digit that caused it.  */

static inline HOST_WIDE_INT
target_strtowi (const char **ps, const char **erange)
{
  unsigned HOST_WIDE_INT val = 0;
  for ( ; ; ++*ps)
    {
      unsigned char c = target_to_host (**ps);
      if (ISDIGIT (c))
	{
	  c -= '0';

	  /* Check for overflow.  */
	  if (val > ((unsigned HOST_WIDE_INT) HOST_WIDE_INT_MAX - c) / 10LU)
	    {
	      val = HOST_WIDE_INT_MAX;
	      *erange = *ps;

	      /* Skip the remaining digits.  */
	      do
		c = target_to_host (*++*ps);
	      while (ISDIGIT (c));
	      break;
	    }
	  else
	    val = val * 10 + c;
	}
      else
	break;
    }

  return val;
}

/* Given FORMAT, set *PLOC to the source location of the format string
   and return the format string if it is known or null otherwise.  */

static const char*
get_format_string (tree format, location_t *ploc)
{
  *ploc = EXPR_LOC_OR_LOC (format, input_location);

  return c_getstr (format);
}

/* For convenience and brevity, shorter named entrypoints of
   format_string_diagnostic_t::emit_warning_va and
   format_string_diagnostic_t::emit_warning_n_va.
   These have to be functions with the attribute so that exgettext
   works properly.  */

static bool
ATTRIBUTE_GCC_DIAG (5, 6)
fmtwarn (const substring_loc &fmt_loc, location_t param_loc,
	 const char *corrected_substring, opt_code opt,
	 const char *gmsgid, ...)
{
  format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
				   corrected_substring);
  va_list ap;
  va_start (ap, gmsgid);
  bool warned = diag.emit_warning_va (opt, gmsgid, &ap);
  va_end (ap);

  return warned;
}

static bool
ATTRIBUTE_GCC_DIAG (6, 8) ATTRIBUTE_GCC_DIAG (7, 8)
fmtwarn_n (const substring_loc &fmt_loc, location_t param_loc,
	   const char *corrected_substring, opt_code opt,
	   unsigned HOST_WIDE_INT n,
	   const char *singular_gmsgid, const char *plural_gmsgid, ...)
{
  format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
				   corrected_substring);
  va_list ap;
  va_start (ap, plural_gmsgid);
  bool warned = diag.emit_warning_n_va (opt, n, singular_gmsgid, plural_gmsgid,
					&ap);
  va_end (ap);

  return warned;
}

/* Format length modifiers.  */

enum format_lengths
{
  FMT_LEN_none,
  FMT_LEN_hh,    // char argument
  FMT_LEN_h,     // short
  FMT_LEN_l,     // long
  FMT_LEN_ll,    // long long
  FMT_LEN_L,     // long double (and GNU long long)
  FMT_LEN_z,     // size_t
  FMT_LEN_t,     // ptrdiff_t
  FMT_LEN_j      // intmax_t
};


/* Description of the result of conversion either of a single directive
   or the whole format string.  */

class fmtresult
{
public:
  /* Construct a FMTRESULT object with all counters initialized
     to MIN.  KNOWNRANGE is set when MIN is valid.  */
  fmtresult (unsigned HOST_WIDE_INT min = HOST_WIDE_INT_MAX)
  : argmin (), argmax (), dst_offset (HOST_WIDE_INT_MIN), nonstr (),
    knownrange (min < HOST_WIDE_INT_MAX),
    mayfail (), nullp ()
  {
    range.min = min;
    range.max = min;
    range.likely = min;
    range.unlikely = min;
  }

  /* Construct a FMTRESULT object with MIN, MAX, and LIKELY counters.
     KNOWNRANGE is set when both MIN and MAX are valid.   */
  fmtresult (unsigned HOST_WIDE_INT min, unsigned HOST_WIDE_INT max,
	     unsigned HOST_WIDE_INT likely = HOST_WIDE_INT_MAX)
  : argmin (), argmax (), dst_offset (HOST_WIDE_INT_MIN), nonstr (),
    knownrange (min < HOST_WIDE_INT_MAX && max < HOST_WIDE_INT_MAX),
    mayfail (), nullp ()
  {
    range.min = min;
    range.max = max;
    range.likely = max < likely ? min : likely;
    range.unlikely = max;
  }

  /* Adjust result upward to reflect the RANGE of values the specified
     width or precision is known to be in.  */
  fmtresult& adjust_for_width_or_precision (const HOST_WIDE_INT[2],
					    tree = NULL_TREE,
					    unsigned = 0, unsigned = 0);

  /* Return the maximum number of decimal digits a value of TYPE
     formats as on output.  */
  static unsigned type_max_digits (tree, int);

  /* The range a directive's argument is in.  */
  tree argmin, argmax;

  /* The starting offset into the destination of the formatted function
     call of the %s argument that points into (aliases with) the same
     destination array.  */
  HOST_WIDE_INT dst_offset;

  /* The minimum and maximum number of bytes that a directive
     results in on output for an argument in the range above.  */
  result_range range;

  /* Non-nul when the argument of a string directive is not a nul
     terminated string.  */
  tree nonstr;

  /* True when the range above is obtained from a known value of
     a directive's argument or its bounds and not the result of
     heuristics that depend on warning levels.  */
  bool knownrange;

  /* True for a directive that may fail (such as wide character
     directives).  */
  bool mayfail;

  /* True when the argument is a null pointer.  */
  bool nullp;
};

/* Adjust result upward to reflect the range ADJUST of values the
   specified width or precision is known to be in.  When non-null,
   TYPE denotes the type of the directive whose result is being
   adjusted, BASE gives the base of the directive (octal, decimal,
   or hex), and ADJ denotes the additional adjustment to the LIKELY
   counter that may need to be added when ADJUST is a range.  */

fmtresult&
fmtresult::adjust_for_width_or_precision (const HOST_WIDE_INT adjust[2],
					  tree type /* = NULL_TREE */,
					  unsigned base /* = 0 */,
					  unsigned adj /* = 0 */)
{
  bool minadjusted = false;

  /* Adjust the minimum and likely counters.  */
  if (adjust[0] >= 0)
    {
      if (range.min < (unsigned HOST_WIDE_INT)adjust[0])
	{
	  range.min = adjust[0];
	  minadjusted = true;
	}

      /* Adjust the likely counter.  */
      if (range.likely < range.min)
	range.likely = range.min;
    }
  else if (adjust[0] == target_int_min ()
	   && (unsigned HOST_WIDE_INT)adjust[1] == target_int_max ())
    knownrange = false;

  /* Adjust the maximum counter.  */
  if (adjust[1] > 0)
    {
      if (range.max < (unsigned HOST_WIDE_INT)adjust[1])
	{
	  range.max = adjust[1];

	  /* Set KNOWNRANGE if both the minimum and maximum have been
	     adjusted.  Otherwise leave it at what it was before.  */
	  knownrange = minadjusted;
	}
    }

  if (warn_level > 1 && type)
    {
      /* For large non-constant width or precision whose range spans
	 the maximum number of digits produced by the directive for
	 any argument, set the likely number of bytes to be at most
	 the number digits plus other adjustment determined by the
	 caller (one for sign or two for the hexadecimal "0x"
	 prefix).  */
      unsigned dirdigs = type_max_digits (type, base);
      if (adjust[0] < dirdigs && dirdigs < adjust[1]
	  && range.likely < dirdigs)
	range.likely = dirdigs + adj;
    }
  else if (range.likely < (range.min ? range.min : 1))
    {
      /* Conservatively, set LIKELY to at least MIN but no less than
	 1 unless MAX is zero.  */
      range.likely = (range.min
		      ? range.min
		      : range.max && (range.max < HOST_WIDE_INT_MAX
				      || warn_level > 1) ? 1 : 0);
    }

  /* Finally adjust the unlikely counter to be at least as large as
     the maximum.  */
  if (range.unlikely < range.max)
    range.unlikely = range.max;

  return *this;
}

/* Return the maximum number of digits a value of TYPE formats in
   BASE on output, not counting base prefix .  */

unsigned
fmtresult::type_max_digits (tree type, int base)
{
  unsigned prec = TYPE_PRECISION (type);
  switch (base)
    {
    case 8:
      return (prec + 2) / 3;
    case 10:
      /* Decimal approximation: yields 3, 5, 10, and 20 for precision
	 of 8, 16, 32, and 64 bits.  */
      return prec * 301 / 1000 + 1;
    case 16:
      return prec / 4;
    }

  gcc_unreachable ();
}

static bool
get_int_range (tree, gimple *, HOST_WIDE_INT *, HOST_WIDE_INT *,
	       bool, HOST_WIDE_INT, range_query *);

struct call_info;

/* Description of a format directive.  A directive is either a plain
   string or a conversion specification that starts with '%'.  */

struct directive
{
  directive (const call_info *inf, unsigned dno)
    : info (inf), dirno (dno), argno (), beg (), len (), flags (),
    width (), prec (),  modifier (), specifier (), arg (), fmtfunc ()
  { }

  /* Reference to the info structure describing the call that this
     directive is a part of.  */
  const call_info *info;

  /* The 1-based directive number (for debugging).  */
  unsigned dirno;

  /* The zero-based argument number of the directive's argument ARG in
     the function's argument list.  */
  unsigned argno;

  /* The first character of the directive and its length.  */
  const char *beg;
  size_t len;

  /* A bitmap of flags, one for each character.  */
  unsigned flags[256 / sizeof (int)];

  /* The range of values of the specified width, or -1 if not specified.  */
  HOST_WIDE_INT width[2];
  /* The range of values of the specified precision, or -1 if not
     specified.  */
  HOST_WIDE_INT prec[2];

  /* Length modifier.  */
  format_lengths modifier;

  /* Format specifier character.  */
  char specifier;

  /* The argument of the directive or null when the directive doesn't
     take one or when none is available (such as for vararg functions).  */
  tree arg;

  /* Format conversion function that given a directive and an argument
     returns the formatting result.  */
  fmtresult (*fmtfunc) (const directive &, tree, range_query *);

  /* Return True when the format flag CHR has been used.  */
  bool get_flag (char chr) const
  {
    unsigned char c = chr & 0xff;
    return (flags[c / (CHAR_BIT * sizeof *flags)]
	    & (1U << (c % (CHAR_BIT * sizeof *flags))));
  }

  /* Make a record of the format flag CHR having been used.  */
  void set_flag (char chr)
  {
    unsigned char c = chr & 0xff;
    flags[c / (CHAR_BIT * sizeof *flags)]
      |= (1U << (c % (CHAR_BIT * sizeof *flags)));
  }

  /* Reset the format flag CHR.  */
  void clear_flag (char chr)
  {
    unsigned char c = chr & 0xff;
    flags[c / (CHAR_BIT * sizeof *flags)]
      &= ~(1U << (c % (CHAR_BIT * sizeof *flags)));
  }

  /* Set both bounds of the width range to VAL.  */
  void set_width (HOST_WIDE_INT val)
  {
    width[0] = width[1] = val;
  }

  /* Set the width range according to ARG, with both bounds being
     no less than 0.  For a constant ARG set both bounds to its value
     or 0, whichever is greater.  For a non-constant ARG in some range
     set width to its range adjusting each bound to -1 if it's less.
     For an indeterminate ARG set width to [0, INT_MAX].  */
  void set_width (tree arg, range_query *);

  /* Set both bounds of the precision range to VAL.  */
  void set_precision (HOST_WIDE_INT val)
  {
    prec[0] = prec[1] = val;
  }

  /* Set the precision range according to ARG, with both bounds being
     no less than -1.  For a constant ARG set both bounds to its value
     or -1 whichever is greater.  For a non-constant ARG in some range
     set precision to its range adjusting each bound to -1 if it's less.
     For an indeterminate ARG set precision to [-1, INT_MAX].  */
  void set_precision (tree arg, range_query *query);

  /* Return true if both width and precision are known to be
     either constant or in some range, false otherwise.  */
  bool known_width_and_precision () const
  {
    return ((width[1] < 0
	     || (unsigned HOST_WIDE_INT)width[1] <= target_int_max ())
	    && (prec[1] < 0
		|| (unsigned HOST_WIDE_INT)prec[1] < target_int_max ()));
  }
};

/* The result of a call to a formatted function.  */

struct format_result
{
  format_result ()
    : range (), aliases (), alias_count (), knownrange (), posunder4k (),
    floating (), warned () { /* No-op.  */ }

  ~format_result ()
  {
    XDELETEVEC (aliases);
  }

  /* Range of characters written by the formatted function.
     Setting the minimum to HOST_WIDE_INT_MAX disables all
     length tracking for the remainder of the format string.  */
  result_range range;

  struct alias_info
  {
    directive dir;          /* The directive that aliases the destination.  */
    HOST_WIDE_INT offset;   /* The offset at which it aliases it.  */
    result_range range;     /* The raw result of the directive.  */
  };

  /* An array of directives whose pointer argument aliases a part
     of the destination object of the formatted function.  */
  alias_info *aliases;
  unsigned alias_count;

  /* True when the range above is obtained from known values of
     directive arguments, or bounds on the amount of output such
     as width and precision, and not the result of  heuristics that
     depend on warning levels.  It's used to issue stricter diagnostics
     in cases where strings of unknown lengths are bounded by the arrays
     they are determined to refer to.  KNOWNRANGE must not be used for
     the return value optimization.  */
  bool knownrange;

  /* True if no individual directive could fail or result in more than
     4095 bytes of output (the total NUMBER_CHARS_{MIN,MAX} might be
     greater).  Implementations are not required to handle directives
     that produce more than 4K bytes (leading to undefined behavior)
     and so when one is found it disables the return value optimization.
     Similarly, directives that can fail (such as wide character
     directives) disable the optimization.  */
  bool posunder4k;

  /* True when a floating point directive has been seen in the format
     string.  */
  bool floating;

  /* True when an intermediate result has caused a warning.  Used to
     avoid issuing duplicate warnings while finishing the processing
     of a call.  WARNED also disables the return value optimization.  */
  bool warned;

  /* Preincrement the number of output characters by 1.  */
  format_result& operator++ ()
  {
    return *this += 1;
  }

  /* Postincrement the number of output characters by 1.  */
  format_result operator++ (int)
  {
    format_result prev (*this);
    *this += 1;
    return prev;
  }

  /* Increment the number of output characters by N.  */
  format_result& operator+= (unsigned HOST_WIDE_INT);

  /* Add a directive to the sequence of those with potentially aliasing
     arguments.  */
  void append_alias (const directive &, HOST_WIDE_INT, const result_range &);

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

format_result&
format_result::operator+= (unsigned HOST_WIDE_INT n)
{
  gcc_assert (n < HOST_WIDE_INT_MAX);

  if (range.min < HOST_WIDE_INT_MAX)
    range.min += n;

  if (range.max < HOST_WIDE_INT_MAX)
    range.max += n;

  if (range.likely < HOST_WIDE_INT_MAX)
    range.likely += n;

  if (range.unlikely < HOST_WIDE_INT_MAX)
    range.unlikely += n;

  return *this;
}

void
format_result::append_alias (const directive &d, HOST_WIDE_INT off,
			     const result_range &resrng)
{
  unsigned cnt = alias_count + 1;
  alias_info *ar = XNEWVEC (alias_info, cnt);

  for (unsigned i = 0; i != alias_count; ++i)
    ar[i] = aliases[i];

  ar[alias_count].dir = d;
  ar[alias_count].offset = off;
  ar[alias_count].range = resrng;

  XDELETEVEC (aliases);

  alias_count = cnt;
  aliases = ar;
}

/* Return the logarithm of X in BASE.  */

static int
ilog (unsigned HOST_WIDE_INT x, int base)
{
  int res = 0;
  do
    {
      ++res;
      x /= base;
    } while (x);
  return res;
}

/* Return the number of bytes resulting from converting into a string
   the INTEGER_CST tree node X in BASE with a minimum of PREC digits.
   PLUS indicates whether 1 for a plus sign should be added for positive
   numbers, and PREFIX whether the length of an octal ('O') or hexadecimal
   ('0x') prefix should be added for nonzero numbers.  Return -1 if X cannot
   be represented.  */

static HOST_WIDE_INT
tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
{
  unsigned HOST_WIDE_INT absval;

  HOST_WIDE_INT res;

  if (TYPE_UNSIGNED (TREE_TYPE (x)))
    {
      if (tree_fits_uhwi_p (x))
	{
	  absval = tree_to_uhwi (x);
	  res = plus;
	}
      else
	return -1;
    }
  else
    {
      if (tree_fits_shwi_p (x))
	{
	  HOST_WIDE_INT i = tree_to_shwi (x);
         if (HOST_WIDE_INT_MIN == i)
           {
             /* Avoid undefined behavior due to negating a minimum.  */
             absval = HOST_WIDE_INT_MAX;
             res = 1;
           }
         else if (i < 0)
	   {
	     absval = -i;
	     res = 1;
	   }
	 else
	   {
	     absval = i;
	     res = plus;
	   }
	}
      else
	return -1;
    }

  int ndigs = ilog (absval, base);

  res += prec < ndigs ? ndigs : prec;

  /* Adjust a non-zero value for the base prefix, either hexadecimal,
     or, unless precision has resulted in a leading zero, also octal.  */
  if (prefix && absval && (base == 16 || prec <= ndigs))
    {
      if (base == 8)
	res += 1;
      else if (base == 16)
	res += 2;
    }

  return res;
}

/* Description of a call to a formatted function.  */

struct call_info
{
  /* Function call statement.  */
  gimple *callstmt;

  /* Function called.  */
  tree func;

  /* Called built-in function code.  */
  built_in_function fncode;

  /* The "origin" of the destination pointer argument, which is either
     the DECL of the destination buffer being written into or a pointer
     that points to it, plus some offset.  */
  tree dst_origin;

  /* For a destination pointing to a struct array member, the offset of
     the member.  */
  HOST_WIDE_INT dst_field;

  /* The offset into the destination buffer.  */
  HOST_WIDE_INT dst_offset;

  /* Format argument and format string extracted from it.  */
  tree format;
  const char *fmtstr;

  /* The location of the format argument.  */
  location_t fmtloc;

  /* The destination object size for __builtin___xxx_chk functions
     typically determined by __builtin_object_size, or -1 if unknown.  */
  unsigned HOST_WIDE_INT objsize;

  /* Number of the first variable argument.  */
  unsigned HOST_WIDE_INT argidx;

  /* True for functions like snprintf that specify the size of
     the destination, false for others like sprintf that don't.  */
  bool bounded;

  /* True for bounded functions like snprintf that specify a zero-size
     buffer as a request to compute the size of output without actually
     writing any.  NOWRITE is cleared in response to the %n directive
     which has side-effects similar to writing output.  */
  bool nowrite;

  /* Return true if the called function's return value is used.  */
  bool retval_used () const
  {
    return gimple_get_lhs (callstmt);
  }

  /* Return the warning option corresponding to the called function.  */
  opt_code warnopt () const
  {
    return bounded ? OPT_Wformat_truncation_ : OPT_Wformat_overflow_;
  }

  /* Return true for calls to file formatted functions.  */
  bool is_file_func () const
  {
    return (fncode == BUILT_IN_FPRINTF
	    || fncode == BUILT_IN_FPRINTF_CHK
	    || fncode == BUILT_IN_FPRINTF_UNLOCKED
	    || fncode == BUILT_IN_VFPRINTF
	    || fncode == BUILT_IN_VFPRINTF_CHK);
  }

  /* Return true for calls to string formatted functions.  */
  bool is_string_func () const
  {
    return (fncode == BUILT_IN_SPRINTF
	    || fncode == BUILT_IN_SPRINTF_CHK
	    || fncode == BUILT_IN_SNPRINTF
	    || fncode == BUILT_IN_SNPRINTF_CHK
	    || fncode == BUILT_IN_VSPRINTF
	    || fncode == BUILT_IN_VSPRINTF_CHK
	    || fncode == BUILT_IN_VSNPRINTF
	    || fncode == BUILT_IN_VSNPRINTF_CHK);
  }
};

void
directive::set_width (tree arg, range_query *query)
{
  get_int_range (arg, info->callstmt, width, width + 1, true, 0, query);
}

void
directive::set_precision (tree arg, range_query *query)
{
  get_int_range (arg, info->callstmt, prec, prec + 1, false, -1, query);
}

/* Return the result of formatting a no-op directive (such as '%n').  */

static fmtresult
format_none (const directive &, tree, range_query *)
{
  fmtresult res (0);
  return res;
}

/* Return the result of formatting the '%%' directive.  */

static fmtresult
format_percent (const directive &, tree, range_query *)
{
  fmtresult res (1);
  return res;
}


/* Compute intmax_type_node and uintmax_type_node similarly to how
   tree.c builds size_type_node.  */

static void
build_intmax_type_nodes (tree *pintmax, tree *puintmax)
{
  if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
    {
      *pintmax = integer_type_node;
      *puintmax = unsigned_type_node;
    }
  else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
    {
      *pintmax = long_integer_type_node;
      *puintmax = long_unsigned_type_node;
    }
  else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
    {
      *pintmax = long_long_integer_type_node;
      *puintmax = long_long_unsigned_type_node;
    }
  else
    {
      for (int i = 0; i < NUM_INT_N_ENTS; i++)
	if (int_n_enabled_p[i])
	  {
	    char name[50], altname[50];
	    sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
	    sprintf (altname, "__int%d__ unsigned", int_n_data[i].bitsize);

	    if (strcmp (name, UINTMAX_TYPE) == 0
		|| strcmp (altname, UINTMAX_TYPE) == 0)
	      {
	        *pintmax = int_n_trees[i].signed_type;
	        *puintmax = int_n_trees[i].unsigned_type;
		return;
	      }
	  }
      gcc_unreachable ();
    }
}

/* Determine the range [*PMIN, *PMAX] that the expression ARG is
   in and that is representable in type int.
   Return true when the range is a subrange of that of int.
   When ARG is null it is as if it had the full range of int.
   When ABSOLUTE is true the range reflects the absolute value of
   the argument.  When ABSOLUTE is false, negative bounds of
   the determined range are replaced with NEGBOUND.  */

static bool
get_int_range (tree arg, gimple *stmt,
	       HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
	       bool absolute, HOST_WIDE_INT negbound,
	       range_query *query)
{
  /* The type of the result.  */
  const_tree type = integer_type_node;

  bool knownrange = false;

  if (!arg)
    {
      *pmin = tree_to_shwi (TYPE_MIN_VALUE (type));
      *pmax = tree_to_shwi (TYPE_MAX_VALUE (type));
    }
  else if (TREE_CODE (arg) == INTEGER_CST
	   && TYPE_PRECISION (TREE_TYPE (arg)) <= TYPE_PRECISION (type))
    {
      /* For a constant argument return its value adjusted as specified
	 by NEGATIVE and NEGBOUND and return true to indicate that the
	 result is known.  */
      *pmin = tree_fits_shwi_p (arg) ? tree_to_shwi (arg) : tree_to_uhwi (arg);
      *pmax = *pmin;
      knownrange = true;
    }
  else
    {
      /* True if the argument's range cannot be determined.  */
      bool unknown = true;

      tree argtype = TREE_TYPE (arg);

      /* Ignore invalid arguments with greater precision that that
	 of the expected type (e.g., in sprintf("%*i", 12LL, i)).
	 They will have been detected and diagnosed by -Wformat and
	 so it's not important to complicate this code to try to deal
	 with them again.  */
      if (TREE_CODE (arg) == SSA_NAME
	  && INTEGRAL_TYPE_P (argtype)
	  && TYPE_PRECISION (argtype) <= TYPE_PRECISION (type))
	{
	  /* Try to determine the range of values of the integer argument.  */
	  value_range vr;
	  query->range_of_expr (vr, arg, stmt);

	  if (!vr.undefined_p () && !vr.varying_p ())
	    {
	      HOST_WIDE_INT type_min
		= (TYPE_UNSIGNED (argtype)
		   ? tree_to_uhwi (TYPE_MIN_VALUE (argtype))
		   : tree_to_shwi (TYPE_MIN_VALUE (argtype)));

	      HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype));

	      tree type = TREE_TYPE (arg);
	      tree tmin = wide_int_to_tree (type, vr.lower_bound ());
	      tree tmax = wide_int_to_tree (type, vr.upper_bound ());
	      *pmin = TREE_INT_CST_LOW (tmin);
	      *pmax = TREE_INT_CST_LOW (tmax);

	      if (*pmin < *pmax)
		{
		  /* Return true if the adjusted range is a subrange of
		     the full range of the argument's type.  *PMAX may
		     be less than *PMIN when the argument is unsigned
		     and its upper bound is in excess of TYPE_MAX.  In
		     that (invalid) case disregard the range and use that
		     of the expected type instead.  */
		  knownrange = type_min < *pmin || *pmax < type_max;

		  unknown = false;
		}
	    }
	}

      /* Handle an argument with an unknown range as if none had been
	 provided.  */
      if (unknown)
	return get_int_range (NULL_TREE, NULL, pmin, pmax, absolute,
			      negbound, query);
    }

  /* Adjust each bound as specified by ABSOLUTE and NEGBOUND.  */
  if (absolute)
    {
      if (*pmin < 0)
	{
	  if (*pmin == *pmax)
	    *pmin = *pmax = -*pmin;
	  else
	    {
	      /* Make sure signed overlow is avoided.  */
	      gcc_assert (*pmin != HOST_WIDE_INT_MIN);

	      HOST_WIDE_INT tmp = -*pmin;
	      *pmin = 0;
	      if (*pmax < tmp)
		*pmax = tmp;
	    }
	}
    }
  else if (*pmin < negbound)
    *pmin = negbound;

  return knownrange;
}

/* With the range [*ARGMIN, *ARGMAX] of an integer directive's actual
   argument, due to the conversion from either *ARGMIN or *ARGMAX to
   the type of the directive's formal argument it's possible for both
   to result in the same number of bytes or a range of bytes that's
   less than the number of bytes that would result from formatting
   some other value in the range [*ARGMIN, *ARGMAX].  This can be
   determined by checking for the actual argument being in the range
   of the type of the directive.  If it isn't it must be assumed to
   take on the full range of the directive's type.
   Return true when the range has been adjusted to the full range
   of DIRTYPE, and false otherwise.  */

static bool
adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax)
{
  tree argtype = TREE_TYPE (*argmin);
  unsigned argprec = TYPE_PRECISION (argtype);
  unsigned dirprec = TYPE_PRECISION (dirtype);

  /* If the actual argument and the directive's argument have the same
     precision and sign there can be no overflow and so there is nothing
     to adjust.  */
  if (argprec == dirprec && TYPE_SIGN (argtype) == TYPE_SIGN (dirtype))
    return false;

  /* The logic below was inspired/lifted from the CONVERT_EXPR_CODE_P
     branch in the extract_range_from_unary_expr function in tree-vrp.c.  */

  if (TREE_CODE (*argmin) == INTEGER_CST
      && TREE_CODE (*argmax) == INTEGER_CST
      && (dirprec >= argprec
	  || integer_zerop (int_const_binop (RSHIFT_EXPR,
					     int_const_binop (MINUS_EXPR,
							      *argmax,
							      *argmin),
					     size_int (dirprec)))))
    {
      *argmin = force_fit_type (dirtype, wi::to_widest (*argmin), 0, false);
      *argmax = force_fit_type (dirtype, wi::to_widest (*argmax), 0, false);

      /* If *ARGMIN is still less than *ARGMAX the conversion above
	 is safe.  Otherwise, it has overflowed and would be unsafe.  */
      if (tree_int_cst_le (*argmin, *argmax))
	return false;
    }

  *argmin = TYPE_MIN_VALUE (dirtype);
  *argmax = TYPE_MAX_VALUE (dirtype);
  return true;
}

/* Return a range representing the minimum and maximum number of bytes
   that the format directive DIR will output for any argument given
   the WIDTH and PRECISION (extracted from DIR).  This function is
   used when the directive argument or its value isn't known.  */

static fmtresult
format_integer (const directive &dir, tree arg, range_query *query)
{
  tree intmax_type_node;
  tree uintmax_type_node;

  /* Base to format the number in.  */
  int base;

  /* True when a conversion is preceded by a prefix indicating the base
     of the argument (octal or hexadecimal).  */
  bool maybebase = dir.get_flag ('#');

  /* True when a signed conversion is preceded by a sign or space.  */
  bool maybesign = false;

  /* True for signed conversions (i.e., 'd' and 'i').  */
  bool sign = false;

  switch (dir.specifier)
    {
    case 'd':
    case 'i':
      /* Space and '+' are  only meaningful for signed conversions.  */
      maybesign = dir.get_flag (' ') | dir.get_flag ('+');
      sign = true;
      base = 10;
      break;
    case 'u':
      base = 10;
      break;
    case 'o':
      base = 8;
      break;
    case 'X':
    case 'x':
      base = 16;
      break;
    default:
      gcc_unreachable ();
    }

  /* The type of the "formal" argument expected by the directive.  */
  tree dirtype = NULL_TREE;

  /* Determine the expected type of the argument from the length
     modifier.  */
  switch (dir.modifier)
    {
    case FMT_LEN_none:
      if (dir.specifier == 'p')
	dirtype = ptr_type_node;
      else
	dirtype = sign ? integer_type_node : unsigned_type_node;
      break;

    case FMT_LEN_h:
      dirtype = sign ? short_integer_type_node : short_unsigned_type_node;
      break;

    case FMT_LEN_hh:
      dirtype = sign ? signed_char_type_node : unsigned_char_type_node;
      break;

    case FMT_LEN_l:
      dirtype = sign ? long_integer_type_node : long_unsigned_type_node;
      break;

    case FMT_LEN_L:
    case FMT_LEN_ll:
      dirtype = (sign
		 ? long_long_integer_type_node
		 : long_long_unsigned_type_node);
      break;

    case FMT_LEN_z:
      dirtype = signed_or_unsigned_type_for (!sign, size_type_node);
      break;

    case FMT_LEN_t:
      dirtype = signed_or_unsigned_type_for (!sign, ptrdiff_type_node);
      break;

    case FMT_LEN_j:
      build_intmax_type_nodes (&intmax_type_node, &uintmax_type_node);
      dirtype = sign ? intmax_type_node : uintmax_type_node;
      break;

    default:
      return fmtresult ();
    }

  /* The type of the argument to the directive, either deduced from
     the actual non-constant argument if one is known, or from
     the directive itself when none has been provided because it's
     a va_list.  */
  tree argtype = NULL_TREE;

  if (!arg)
    {
      /* When the argument has not been provided, use the type of
	 the directive's argument as an approximation.  This will
	 result in false positives for directives like %i with
	 arguments with smaller precision (such as short or char).  */
      argtype = dirtype;
    }
  else if (TREE_CODE (arg) == INTEGER_CST)
    {
      /* When a constant argument has been provided use its value
	 rather than type to determine the length of the output.  */
      fmtresult res;

      if ((dir.prec[0] <= 0 && dir.prec[1] >= 0) && integer_zerop (arg))
	{
	  /* As a special case, a precision of zero with a zero argument
	     results in zero bytes except in base 8 when the '#' flag is
	     specified, and for signed conversions in base 8 and 10 when
	     either the space or '+' flag has been specified and it results
	     in just one byte (with width having the normal effect).  This
	     must extend to the case of a specified precision with
	     an unknown value because it can be zero.  */
	  res.range.min = ((base == 8 && dir.get_flag ('#')) || maybesign);
	  if (res.range.min == 0 && dir.prec[0] != dir.prec[1])
	    {
	      res.range.max = 1;
	      res.range.likely = 1;
	    }
	  else
	    {
	      res.range.max = res.range.min;
	      res.range.likely = res.range.min;
	    }
	}
      else
	{
	  /* Convert the argument to the type of the directive.  */
	  arg = fold_convert (dirtype, arg);

	  res.range.min = tree_digits (arg, base, dir.prec[0],
				       maybesign, maybebase);
	  if (dir.prec[0] == dir.prec[1])
	    res.range.max = res.range.min;
	  else
	    res.range.max = tree_digits (arg, base, dir.prec[1],
					 maybesign, maybebase);
	  res.range.likely = res.range.min;
	  res.knownrange = true;
	}

      res.range.unlikely = res.range.max;

      /* Bump up the counters if WIDTH is greater than LEN.  */
      res.adjust_for_width_or_precision (dir.width, dirtype, base,
					 (sign | maybebase) + (base == 16));
      /* Bump up the counters again if PRECision is greater still.  */
      res.adjust_for_width_or_precision (dir.prec, dirtype, base,
					 (sign | maybebase) + (base == 16));

      return res;
    }
  else if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
	   || TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE)
    /* Determine the type of the provided non-constant argument.  */
    argtype = TREE_TYPE (arg);
  else
    /* Don't bother with invalid arguments since they likely would
       have already been diagnosed, and disable any further checking
       of the format string by returning [-1, -1].  */
    return fmtresult ();

  fmtresult res;

  /* Using either the range the non-constant argument is in, or its
     type (either "formal" or actual), create a range of values that
     constrain the length of output given the warning level.  */
  tree argmin = NULL_TREE;
  tree argmax = NULL_TREE;

  if (arg
      && TREE_CODE (arg) == SSA_NAME
      && INTEGRAL_TYPE_P (argtype))
    {
      /* Try to determine the range of values of the integer argument
	 (range information is not available for pointers).  */
      value_range vr;
      query->range_of_expr (vr, arg, dir.info->callstmt);

      if (!vr.varying_p () && !vr.undefined_p ())
	{
	  argmin = wide_int_to_tree (TREE_TYPE (arg), vr.lower_bound ());
	  argmax = wide_int_to_tree (TREE_TYPE (arg), vr.upper_bound ());

	  /* Set KNOWNRANGE if the argument is in a known subrange
	     of the directive's type and neither width nor precision
	     is unknown.  (KNOWNRANGE may be reset below).  */
	  res.knownrange
	    = ((!tree_int_cst_equal (TYPE_MIN_VALUE (dirtype), argmin)
		|| !tree_int_cst_equal (TYPE_MAX_VALUE (dirtype), argmax))
	       && dir.known_width_and_precision ());

	  res.argmin = argmin;
	  res.argmax = argmax;
	}
      else
	{
	  /* The argument here may be the result of promoting the actual
	     argument to int.  Try to determine the type of the actual
	     argument before promotion and narrow down its range that
	     way.  */
	  gimple *def = SSA_NAME_DEF_STMT (arg);
	  if (is_gimple_assign (def))
	    {
	      tree_code code = gimple_assign_rhs_code (def);
	      if (code == INTEGER_CST)
		{
		  arg = gimple_assign_rhs1 (def);
		  return format_integer (dir, arg, query);
		}

	      if (code == NOP_EXPR)
		{
		  tree type = TREE_TYPE (gimple_assign_rhs1 (def));
		  if (INTEGRAL_TYPE_P (type)
		      || TREE_CODE (type) == POINTER_TYPE)
		    argtype = type;
		}
	    }
	}
    }

  if (!argmin)
    {
      if (TREE_CODE (argtype) == POINTER_TYPE)
	{
	  argmin = build_int_cst (pointer_sized_int_node, 0);
	  argmax = build_all_ones_cst (pointer_sized_int_node);
	}
      else
	{
	  argmin = TYPE_MIN_VALUE (argtype);
	  argmax = TYPE_MAX_VALUE (argtype);
	}
    }

  /* Clear KNOWNRANGE if the range has been adjusted to the maximum
     of the directive.  If it has been cleared then since ARGMIN and/or
     ARGMAX have been adjusted also adjust the corresponding ARGMIN and
     ARGMAX in the result to include in diagnostics.  */
  if (adjust_range_for_overflow (dirtype, &argmin, &argmax))
    {
      res.knownrange = false;
      res.argmin = argmin;
      res.argmax = argmax;
    }

  /* Recursively compute the minimum and maximum from the known range.  */
  if (TYPE_UNSIGNED (dirtype) || tree_int_cst_sgn (argmin) >= 0)
    {
      /* For unsigned conversions/directives or signed when
	 the minimum is positive, use the minimum and maximum to compute
	 the shortest and longest output, respectively.  */
      res.range.min = format_integer (dir, argmin, query).range.min;
      res.range.max = format_integer (dir, argmax, query).range.max;
    }
  else if (tree_int_cst_sgn (argmax) < 0)
    {
      /* For signed conversions/directives if maximum is negative,
	 use the minimum as the longest output and maximum as the
	 shortest output.  */
      res.range.min = format_integer (dir, argmax, query).range.min;
      res.range.max = format_integer (dir, argmin, query).range.max;
    }
  else
    {
      /* Otherwise, 0 is inside of the range and minimum negative.  Use 0
	 as the shortest output and for the longest output compute the
	 length of the output of both minimum and maximum and pick the
	 longer.  */
      unsigned HOST_WIDE_INT max1
	= format_integer (dir, argmin, query).range.max;
      unsigned HOST_WIDE_INT max2
	= format_integer (dir, argmax, query).range.max;
      res.range.min
	= format_integer (dir, integer_zero_node, query).range.min;
      res.range.max = MAX (max1, max2);
    }

  /* If the range is known, use the maximum as the likely length.  */
  if (res.knownrange)
    res.range.likely = res.range.max;
  else
    {
      /* Otherwise, use the minimum.  Except for the case where for %#x or
         %#o the minimum is just for a single value in the range (0) and
         for all other values it is something longer, like 0x1 or 01.
	  Use the length for value 1 in that case instead as the likely
	  length.  */
      res.range.likely = res.range.min;
      if (maybebase
	  && base != 10
	  && (tree_int_cst_sgn (argmin) < 0 || tree_int_cst_sgn (argmax) > 0))
	{
	  if (res.range.min == 1)
	    res.range.likely += base == 8 ? 1 : 2;
	  else if (res.range.min == 2
		   && base == 16
		   && (dir.width[0] == 2 || dir.prec[0] == 2))
	    ++res.range.likely;
	}
    }

  res.range.unlikely = res.range.max;
  res.adjust_for_width_or_precision (dir.width, dirtype, base,
				     (sign | maybebase) + (base == 16));
  res.adjust_for_width_or_precision (dir.prec, dirtype, base,
				     (sign | maybebase) + (base == 16));

  return res;
}

/* Return the number of bytes that a format directive consisting of FLAGS,
   PRECision, format SPECification, and MPFR rounding specifier RNDSPEC,
   would result for argument X under ideal conditions (i.e., if PREC
   weren't excessive).  MPFR 3.1 allocates large amounts of memory for
   values of PREC with large magnitude and can fail (see MPFR bug #21056).
   This function works around those problems.  */

static unsigned HOST_WIDE_INT
get_mpfr_format_length (mpfr_ptr x, const char *flags, HOST_WIDE_INT prec,
			char spec, char rndspec)
{
  char fmtstr[40];

  HOST_WIDE_INT len = strlen (flags);

  fmtstr[0] = '%';
  memcpy (fmtstr + 1, flags, len);
  memcpy (fmtstr + 1 + len, ".*R", 3);
  fmtstr[len + 4] = rndspec;
  fmtstr[len + 5] = spec;
  fmtstr[len + 6] = '\0';

  spec = TOUPPER (spec);
  if (spec == 'E' || spec == 'F')
    {
      /* For %e, specify the precision explicitly since mpfr_sprintf
	 does its own thing just to be different (see MPFR bug 21088).  */
      if (prec < 0)
	prec = 6;
    }
  else
    {
      /* Avoid passing negative precisions with larger magnitude to MPFR
	 to avoid exposing its bugs.  (A negative precision is supposed
	 to be ignored.)  */
      if (prec < 0)
	prec = -1;
    }

  HOST_WIDE_INT p = prec;

  if (spec == 'G' && !strchr (flags, '#'))
    {
      /* For G/g without the pound flag, precision gives the maximum number
	 of significant digits which is bounded by LDBL_MAX_10_EXP, or, for
	 a 128 bit IEEE extended precision, 4932.  Using twice as much here
	 should be more than sufficient for any real format.  */
      if ((IEEE_MAX_10_EXP * 2) < prec)
	prec = IEEE_MAX_10_EXP * 2;
      p = prec;
    }
  else
    {
      /* Cap precision arbitrarily at 1KB and add the difference
	 (if any) to the MPFR result.  */
      if (prec > 1024)
	p = 1024;
    }

  len = mpfr_snprintf (NULL, 0, fmtstr, (int)p, x);

  /* Handle the unlikely (impossible?) error by returning more than
     the maximum dictated by the function's return type.  */
  if (len < 0)
    return target_dir_max () + 1;

  /* Adjust the return value by the difference.  */
  if (p < prec)
    len += prec - p;

  return len;
}

/* Return the number of bytes to format using the format specifier
   SPEC and the precision PREC the largest value in the real floating
   TYPE.  */

static unsigned HOST_WIDE_INT
format_floating_max (tree type, char spec, HOST_WIDE_INT prec)
{
  machine_mode mode = TYPE_MODE (type);

  /* IBM Extended mode.  */
  if (MODE_COMPOSITE_P (mode))
    mode = DFmode;

  /* Get the real type format description for the target.  */
  const real_format *rfmt = REAL_MODE_FORMAT (mode);
  REAL_VALUE_TYPE rv;

  real_maxval (&rv, 0, mode);

  /* Convert the GCC real value representation with the precision
     of the real type to the mpfr_t format with the GCC default
     round-to-nearest mode.  */
  mpfr_t x;
  mpfr_init2 (x, rfmt->p);
  mpfr_from_real (x, &rv, MPFR_RNDN);

  /* Return a value one greater to account for the leading minus sign.  */
  unsigned HOST_WIDE_INT r
    = 1 + get_mpfr_format_length (x, "", prec, spec, 'D');
  mpfr_clear (x);
  return r;
}

/* Return a range representing the minimum and maximum number of bytes
   that the directive DIR will output for any argument.  PREC gives
   the adjusted precision range to account for negative precisions
   meaning the default 6.  This function is used when the directive
   argument or its value isn't known.  */

static fmtresult
format_floating (const directive &dir, const HOST_WIDE_INT prec[2])
{
  tree type;

  switch (dir.modifier)
    {
    case FMT_LEN_l:
    case FMT_LEN_none:
      type = double_type_node;
      break;

    case FMT_LEN_L:
      type = long_double_type_node;
      break;

    case FMT_LEN_ll:
      type = long_double_type_node;
      break;

    default:
      return fmtresult ();
    }

  /* The minimum and maximum number of bytes produced by the directive.  */
  fmtresult res;

  /* The minimum output as determined by flags.  It's always at least 1.
     When plus or space are set the output is preceded by either a sign
     or a space.  */
  unsigned flagmin = (1 /* for the first digit */
		      + (dir.get_flag ('+') | dir.get_flag (' ')));

  /* The minimum is 3 for "inf" and "nan" for all specifiers, plus 1
     for the plus sign/space with the '+' and ' ' flags, respectively,
     unless reduced below.  */
  res.range.min = 2 + flagmin;

  /* When the pound flag is set the decimal point is included in output
     regardless of precision.  Whether or not a decimal point is included
     otherwise depends on the specification and precision.  */
  bool radix = dir.get_flag ('#');

  switch (dir.specifier)
    {
    case 'A':
    case 'a':
      {
	HOST_WIDE_INT minprec = 6 + !radix /* decimal point */;
	if (dir.prec[0] <= 0)
	  minprec = 0;
	else if (dir.prec[0] > 0)
	  minprec = dir.prec[0] + !radix /* decimal point */;

	res.range.likely = (2 /* 0x */
			    + flagmin
			    + radix
			    + minprec
			    + 3 /* p+0 */);

	res.range.max = format_floating_max (type, 'a', prec[1]);

	/* The unlikely maximum accounts for the longest multibyte
	   decimal point character.  */
	res.range.unlikely = res.range.max;
	if (dir.prec[1] > 0)
	  res.range.unlikely += target_mb_len_max () - 1;

	break;
      }

    case 'E':
    case 'e':
      {
	/* Minimum output attributable to precision and, when it's
	   non-zero, decimal point.  */
	HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0;

	/* The likely minimum output is "[-+]1.234567e+00" regardless
	   of the value of the actual argument.  */
	res.range.likely = (flagmin
			    + radix
			    + minprec
			    + 2 /* e+ */ + 2);

	res.range.max = format_floating_max (type, 'e', prec[1]);

	/* The unlikely maximum accounts for the longest multibyte
	   decimal point character.  */
	if (dir.prec[0] != dir.prec[1]
	    || dir.prec[0] == -1 || dir.prec[0] > 0)
	  res.range.unlikely = res.range.max + target_mb_len_max () -1;
	else
	  res.range.unlikely = res.range.max;
	break;
      }

    case 'F':
    case 'f':
      {
	/* Minimum output attributable to precision and, when it's non-zero,
	   decimal point.  */
	HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0;

	/* For finite numbers (i.e., not infinity or NaN) the lower bound
	   when precision isn't specified is 8 bytes ("1.23456" since
	   precision is taken to be 6).  When precision is zero, the lower
	   bound is 1 byte (e.g., "1").  Otherwise, when precision is greater
	   than zero, then the lower bound is 2 plus precision (plus flags).
	   But in all cases, the lower bound is no greater than 3.  */
	unsigned HOST_WIDE_INT min = flagmin + radix + minprec;
	if (min < res.range.min)
	  res.range.min = min;

	/* Compute the upper bound for -TYPE_MAX.  */
	res.range.max = format_floating_max (type, 'f', prec[1]);

	/* The minimum output with unknown precision is a single byte
	   (e.g., "0") but the more likely output is 3 bytes ("0.0").  */
	if (dir.prec[0] < 0 && dir.prec[1] > 0)
	  res.range.likely = 3;
	else
	  res.range.likely = min;

	/* The unlikely maximum accounts for the longest multibyte
	   decimal point character.  */
	if (dir.prec[0] != dir.prec[1]
	    || dir.prec[0] == -1 || dir.prec[0] > 0)
	  res.range.unlikely = res.range.max + target_mb_len_max () - 1;
	break;
      }

    case 'G':
    case 'g':
      {
	/* The %g output depends on precision and the exponent of
	   the argument.  Since the value of the argument isn't known
	   the lower bound on the range of bytes (not counting flags
	   or width) is 1 plus radix (i.e., either "0" or "0." for
	   "%g" and "%#g", respectively, with a zero argument).  */
	unsigned HOST_WIDE_INT min = flagmin + radix;
	if (min < res.range.min)
	  res.range.min = min;

	char spec = 'g';
	HOST_WIDE_INT maxprec = dir.prec[1];
	if (radix && maxprec)
	  {
	    /* When the pound flag (radix) is set, trailing zeros aren't
	       trimmed and so the longest output is the same as for %e,
	       except with precision minus 1 (as specified in C11).  */
	    spec = 'e';
	    if (maxprec > 0)
	      --maxprec;
	    else if (maxprec < 0)
	      maxprec = 5;
	  }
	else
	  maxprec = prec[1];

	res.range.max = format_floating_max (type, spec, maxprec);

	/* The likely output is either the maximum computed above
	   minus 1 (assuming the maximum is positive) when precision
	   is known (or unspecified), or the same minimum as for %e
	   (which is computed for a non-negative argument).  Unlike
	   for the other specifiers above the likely output isn't
	   the minimum because for %g that's 1 which is unlikely.  */
	if (dir.prec[1] < 0
	    || (unsigned HOST_WIDE_INT)dir.prec[1] < target_int_max ())
	  res.range.likely = res.range.max - 1;
	else
	  {
	    HOST_WIDE_INT minprec = 6 + !radix /* decimal point */;
	    res.range.likely = (flagmin
				+ radix
				+ minprec
				+ 2 /* e+ */ + 2);
	  }

	/* The unlikely maximum accounts for the longest multibyte
	   decimal point character.  */
	res.range.unlikely = res.range.max + target_mb_len_max () - 1;
	break;
      }

    default:
      return fmtresult ();
    }

  /* Bump up the byte counters if WIDTH is greater.  */
  res.adjust_for_width_or_precision (dir.width);
  return res;
}

/* Return a range representing the minimum and maximum number of bytes
   that the directive DIR will write on output for the floating argument
   ARG.  */

static fmtresult
format_floating (const directive &dir, tree arg, range_query *)
{
  HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] };
  tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll
	       ? long_double_type_node : double_type_node);

  /* For an indeterminate precision the lower bound must be assumed
     to be zero.  */
  if (TOUPPER (dir.specifier) == 'A')
    {
      /* Get the number of fractional decimal digits needed to represent
	 the argument without a loss of accuracy.  */
      unsigned fmtprec
	= REAL_MODE_FORMAT (TYPE_MODE (type))->p;

      /* The precision of the IEEE 754 double format is 53.
	 The precision of all other GCC binary double formats
	 is 56 or less.  */
      unsigned maxprec = fmtprec <= 56 ? 13 : 15;

      /* For %a, leave the minimum precision unspecified to let
	 MFPR trim trailing zeros (as it and many other systems
	 including Glibc happen to do) and set the maximum
	 precision to reflect what it would be with trailing zeros
	 present (as Solaris and derived systems do).  */
      if (dir.prec[1] < 0)
	{
	  /* Both bounds are negative implies that precision has
	     not been specified.  */
	  prec[0] = maxprec;
	  prec[1] = -1;
	}
      else if (dir.prec[0] < 0)
	{
	  /* With a negative lower bound and a non-negative upper
	     bound set the minimum precision to zero and the maximum
	     to the greater of the maximum precision (i.e., with
	     trailing zeros present) and the specified upper bound.  */
	  prec[0] = 0;
	  prec[1] = dir.prec[1] < maxprec ? maxprec : dir.prec[1];
	}
    }
  else if (dir.prec[0] < 0)
    {
      if (dir.prec[1] < 0)
	{
	  /* A precision in a strictly negative range is ignored and
	     the default of 6 is used instead.  */
	  prec[0] = prec[1] = 6;
	}
      else
	{
	  /* For a precision in a partly negative range, the lower bound
	     must be assumed to be zero and the new upper bound is the
	     greater of 6 (the default precision used when the specified
	     precision is negative) and the upper bound of the specified
	     range.  */
	  prec[0] = 0;
	  prec[1] = dir.prec[1] < 6 ? 6 : dir.prec[1];
	}
    }

  if (!arg
      || TREE_CODE (arg) != REAL_CST
      || !useless_type_conversion_p (type, TREE_TYPE (arg)))
    return format_floating (dir, prec);

  /* The minimum and maximum number of bytes produced by the directive.  */
  fmtresult res;

  /* Get the real type format description for the target.  */
  const REAL_VALUE_TYPE *rvp = TREE_REAL_CST_PTR (arg);
  const real_format *rfmt = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)));

  if (!real_isfinite (rvp))
    {
      /* The format for Infinity and NaN is "[-]inf"/"[-]infinity"
	 and "[-]nan" with the choice being implementation-defined
	 but not locale dependent.  */
      bool sign = dir.get_flag ('+') || real_isneg (rvp);
      res.range.min = 3 + sign;

      res.range.likely = res.range.min;
      res.range.max = res.range.min;
      /* The unlikely maximum is "[-/+]infinity" or "[-/+][qs]nan".
	 For NaN, the C/POSIX standards specify two formats:
	   "[-/+]nan"
	 and
	   "[-/+]nan(n-char-sequence)"
	 No known printf implementation outputs the latter format but AIX
	 outputs QNaN and SNaN for quiet and signalling NaN, respectively,
	 so the unlikely maximum reflects that.  */
      res.range.unlikely = sign + (real_isinf (rvp) ? 8 : 4);

      /* The range for infinity and NaN is known unless either width
	 or precision is unknown.  Width has the same effect regardless
	 of whether the argument is finite.  Precision is either ignored
	 (e.g., Glibc) or can have an effect on the short vs long format
	 such as inf/infinity (e.g., Solaris).  */
      res.knownrange = dir.known_width_and_precision ();

      /* Adjust the range for width but ignore precision.  */
      res.adjust_for_width_or_precision (dir.width);

      return res;
    }

  char fmtstr [40];
  char *pfmt = fmtstr;

  /* Append flags.  */
  for (const char *pf = "-+ #0"; *pf; ++pf)
    if (dir.get_flag (*pf))
      *pfmt++ = *pf;

  *pfmt = '\0';

  {
    /* Set up an array to easily iterate over.  */
    unsigned HOST_WIDE_INT* const minmax[] = {
      &res.range.min, &res.range.max
    };

    for (int i = 0; i != sizeof minmax / sizeof *minmax; ++i)
      {
	/* Convert the GCC real value representation with the precision
	   of the real type to the mpfr_t format rounding down in the
	   first iteration that computes the minimum and up in the second
	   that computes the maximum.  This order is arbitrary because
	   rounding in either direction can result in longer output.  */
	mpfr_t mpfrval;
	mpfr_init2 (mpfrval, rfmt->p);
	mpfr_from_real (mpfrval, rvp, i ? MPFR_RNDU : MPFR_RNDD);

	/* Use the MPFR rounding specifier to round down in the first
	   iteration and then up.  In most but not all cases this will
	   result in the same number of bytes.  */
	char rndspec = "DU"[i];

	/* Format it and store the result in the corresponding member
	   of the result struct.  */
	*minmax[i] = get_mpfr_format_length (mpfrval, fmtstr, prec[i],
					     dir.specifier, rndspec);
	mpfr_clear (mpfrval);
      }
  }

  /* Make sure the minimum is less than the maximum (MPFR rounding
     in the call to mpfr_snprintf can result in the reverse.  */
  if (res.range.max < res.range.min)
    {
      unsigned HOST_WIDE_INT tmp = res.range.min;
      res.range.min = res.range.max;
      res.range.max = tmp;
    }

  /* The range is known unless either width or precision is unknown.  */
  res.knownrange = dir.known_width_and_precision ();

  /* For the same floating point constant, unless width or precision
     is unknown, use the longer output as the likely maximum since
     with round to nearest either is equally likely.  Otherwise, when
     precision is unknown, use the greater of the minimum and 3 as
     the likely output (for "0.0" since zero precision is unlikely).  */
  if (res.knownrange)
    res.range.likely = res.range.max;
  else if (res.range.min < 3
	   && dir.prec[0] < 0
	   && (unsigned HOST_WIDE_INT)dir.prec[1] == target_int_max ())
    res.range.likely = 3;
  else
    res.range.likely = res.range.min;

  res.range.unlikely = res.range.max;

  if (res.range.max > 2 && (prec[0] != 0 || prec[1] != 0))
    {
      /* Unless the precision is zero output longer than 2 bytes may
	 include the decimal point which must be a single character
	 up to MB_LEN_MAX in length.  This is overly conservative
	 since in some conversions some constants result in no decimal
	 point (e.g., in %g).  */
      res.range.unlikely += target_mb_len_max () - 1;
    }

  res.adjust_for_width_or_precision (dir.width);
  return res;
}

/* Return a FMTRESULT struct set to the lengths of the shortest and longest
   strings referenced by the expression STR, or (-1, -1) when not known.
   Used by the format_string function below.  */

static fmtresult
get_string_length (tree str, gimple *stmt, unsigned HOST_WIDE_INT max_size,
		   unsigned eltsize, range_query *query)
{
  if (!str)
    return fmtresult ();

  /* Try to determine the dynamic string length first.
     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.  */
  c_strlen_data lendata = { };
  lendata.maxbound = str;
  if (eltsize == 1)
    get_range_strlen_dynamic (str, stmt, &lendata, query);
  else
    {
      /* Determine the length of the shortest and longest string referenced
	 by STR.  Strings of unknown lengths are bounded by the sizes of
	 arrays that subexpressions of STR may refer to.  Pointers that
	 aren't known to point any such arrays result in LENDATA.MAXLEN
	 set to SIZE_MAX.  */
      get_range_strlen (str, &lendata, eltsize);
    }

  /* If LENDATA.MAXBOUND is not equal to .MINLEN it corresponds to the bound
     of the largest array STR refers to, if known, or it's set to SIZE_MAX
     otherwise.  */

  /* Return the default result when nothing is known about the string.  */
  if ((lendata.maxbound && !tree_fits_uhwi_p (lendata.maxbound))
      || !tree_fits_uhwi_p (lendata.maxlen))
    {
      fmtresult res;
      res.nonstr = lendata.decl;
      return res;
    }

  unsigned HOST_WIDE_INT lenmax = tree_to_uhwi (max_object_size ()) - 2;
  if (integer_zerop (lendata.minlen)
      && (!lendata.maxbound || lenmax <= tree_to_uhwi (lendata.maxbound))
      && lenmax <= tree_to_uhwi (lendata.maxlen))
    {
      if (max_size > 0 && max_size < HOST_WIDE_INT_MAX)
	{
	  /* Adjust the conservative unknown/unbounded result if MAX_SIZE
	     is valid.  Set UNLIKELY to maximum in case MAX_SIZE refers
	     to a subobject.
	     TODO: This is overly conservative.  Set UNLIKELY to the size
	     of the outermost enclosing declared object.  */
	  fmtresult res (0, max_size - 1);
	  res.nonstr = lendata.decl;
	  res.range.likely = res.range.max;
	  res.range.unlikely = HOST_WIDE_INT_MAX;
	  return res;
	}

      fmtresult res;
      res.nonstr = lendata.decl;
      return res;
    }

  HOST_WIDE_INT min
    = (tree_fits_uhwi_p (lendata.minlen)
       ? tree_to_uhwi (lendata.minlen)
       : 0);

  HOST_WIDE_INT max
    = (lendata.maxbound && tree_fits_uhwi_p (lendata.maxbound)
       ? tree_to_uhwi (lendata.maxbound)
       : HOST_WIDE_INT_M1U);

  const bool unbounded = integer_all_onesp (lendata.maxlen);

  /* Set the max/likely counters to unbounded when a minimum is known
     but the maximum length isn't bounded.  This implies that STR is
     a conditional expression involving a string of known length and
     an expression of unknown/unbounded length.  */
  if (min
      && (unsigned HOST_WIDE_INT)min < HOST_WIDE_INT_M1U
      && unbounded)
    max = HOST_WIDE_INT_M1U;

  /* get_range_strlen() returns the target value of SIZE_MAX for
     strings of unknown length.  Bump it up to HOST_WIDE_INT_M1U
     which may be bigger.  */
  if ((unsigned HOST_WIDE_INT)min == target_size_max ())
    min = HOST_WIDE_INT_M1U;
  if ((unsigned HOST_WIDE_INT)max == target_size_max ())
    max = HOST_WIDE_INT_M1U;

  fmtresult res (min, max);
  res.nonstr = lendata.decl;

  /* Set RES.KNOWNRANGE to true if and only if all strings referenced
     by STR are known to be bounded (though not necessarily by their
     actual length but perhaps by their maximum possible length).  */
  if (res.range.max < target_int_max ())
    {
      res.knownrange = true;
      /* When the length of the longest string is known and not
	 excessive use it as the likely length of the string(s).  */
      res.range.likely = res.range.max;
    }
  else
    {
      /* When the upper bound is unknown (it can be zero or excessive)
	 set the likely length to the greater of 1.  If MAXBOUND is
	 known, also reset the length of the lower bound to zero.  */
      res.range.likely = res.range.min ? res.range.min : warn_level > 1;
      if (lendata.maxbound && !integer_all_onesp (lendata.maxbound))
	res.range.min = 0;
    }

  res.range.unlikely = unbounded ? HOST_WIDE_INT_MAX : res.range.max;

  return res;
}

/* Return the minimum and maximum number of characters formatted
   by the '%c' format directives and its wide character form for
   the argument ARG.  ARG can be null (for functions such as
   vsprinf).  */

static fmtresult
format_character (const directive &dir, tree arg, range_query *query)
{
  fmtresult res;

  res.knownrange = true;

  if (dir.specifier == 'C'
      || dir.modifier == FMT_LEN_l)
    {
      /* A wide character can result in as few as zero bytes.  */
      res.range.min = 0;

      HOST_WIDE_INT min, max;
      if (get_int_range (arg, dir.info->callstmt, &min, &max, false, 0, query))
	{
	  if (min == 0 && max == 0)
	    {
	      /* The NUL wide character results in no bytes.  */
	      res.range.max = 0;
	      res.range.likely = 0;
	      res.range.unlikely = 0;
	    }
	  else if (min >= 0 && min < 128)
	    {
	      /* Be conservative if the target execution character set
		 is not a 1-to-1 mapping to the source character set or
		 if the source set is not ASCII.  */
	      bool one_2_one_ascii
		= (target_to_host_charmap[0] == 1 && target_to_host ('a') == 97);

	      /* A wide character in the ASCII range most likely results
		 in a single byte, and only unlikely in up to MB_LEN_MAX.  */
	      res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();;
	      res.range.likely = 1;
	      res.range.unlikely = target_mb_len_max ();
	      res.mayfail = !one_2_one_ascii;
	    }
	  else
	    {
	      /* A wide character outside the ASCII range likely results
		 in up to two bytes, and only unlikely in up to MB_LEN_MAX.  */
	      res.range.max = target_mb_len_max ();
	      res.range.likely = 2;
	      res.range.unlikely = res.range.max;
	      /* Converting such a character may fail.  */
	      res.mayfail = true;
	    }
	}
      else
	{
	  /* An unknown wide character is treated the same as a wide
	     character outside the ASCII range.  */
	  res.range.max = target_mb_len_max ();
	  res.range.likely = 2;
	  res.range.unlikely = res.range.max;
	  res.mayfail = true;
	}
    }
  else
    {
      /* A plain '%c' directive.  Its output is exactly 1.  */
      res.range.min = res.range.max = 1;
      res.range.likely = res.range.unlikely = 1;
      res.knownrange = true;
    }

  /* Bump up the byte counters if WIDTH is greater.  */
  return res.adjust_for_width_or_precision (dir.width);
}

/* If TYPE is an array or struct or union, increment *FLDOFF by the starting
   offset of the member that *OFF point into and set *FLDSIZE to its size
   in bytes and decrement *OFF by the same.  Otherwise do nothing.  */

static void
set_aggregate_size_and_offset (tree type, HOST_WIDE_INT *fldoff,
			       HOST_WIDE_INT *fldsize, HOST_WIDE_INT *off)
{
  /* The byte offset of the most basic struct member the byte
     offset *OFF corresponds to, or for a (multidimensional)
     array member, the byte offset of the array element.  */
  if (TREE_CODE (type) == ARRAY_TYPE
      && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
    {
      HOST_WIDE_INT index = 0, arrsize = 0;
      if (array_elt_at_offset (type, *off, &index, &arrsize))
	{
	  *fldoff += index;
	  *off -= index;
	  *fldsize = arrsize;
	}
    }
  else if (RECORD_OR_UNION_TYPE_P (type))
    {
      HOST_WIDE_INT index = 0;
      tree sub = field_at_offset (type, NULL_TREE, *off, &index);
      if (sub)
	{
	  tree subsize = DECL_SIZE_UNIT (sub);
	  if (*fldsize < HOST_WIDE_INT_MAX
	      && subsize
	      && tree_fits_uhwi_p (subsize))
	    *fldsize = tree_to_uhwi (subsize);
	  else
	    *fldsize = HOST_WIDE_INT_MAX;
	  *fldoff += index;
	  *off -= index;
	}
    }
}

/* For an expression X of pointer type, recursively try to find the same
   origin (object or pointer) as Y it references and return such a Y.
   When X refers to an array element or struct member, set *FLDOFF to
   the offset of the element or member from the beginning of the "most
   derived" object and *FLDSIZE to its size.  When nonnull, set *OFF to
   the overall offset from the beginning of the object so that
   *FLDOFF <= *OFF.  */

static tree
get_origin_and_offset_r (tree x, HOST_WIDE_INT *fldoff, HOST_WIDE_INT *fldsize,
			 HOST_WIDE_INT *off)
{
  if (!x)
    return NULL_TREE;

  HOST_WIDE_INT sizebuf = -1;
  if (!fldsize)
    fldsize = &sizebuf;

  if (DECL_P (x))
    {
      /* Set the size if it hasn't been set yet.  */
      if (tree size = DECL_SIZE_UNIT (x))
	if (*fldsize < 0 && tree_fits_shwi_p (size))
	  *fldsize = tree_to_shwi (size);
      return x;
    }

  switch (TREE_CODE (x))
    {
    case ADDR_EXPR:
      x = TREE_OPERAND (x, 0);
      return get_origin_and_offset_r (x, fldoff, fldsize, off);

    case ARRAY_REF:
      {
	tree offset = TREE_OPERAND (x, 1);
	HOST_WIDE_INT idx = (tree_fits_uhwi_p (offset)
			     ? tree_to_uhwi (offset) : HOST_WIDE_INT_MAX);

	tree eltype = TREE_TYPE (x);
	if (TREE_CODE (eltype) == INTEGER_TYPE)
	  {
	    if (off)
	      *off = idx;
	  }
	else if (idx < HOST_WIDE_INT_MAX)
	  *fldoff += idx * int_size_in_bytes (eltype);
	else
	  *fldoff = idx;

	x = TREE_OPERAND (x, 0);
	return get_origin_and_offset_r (x, fldoff, fldsize, nullptr);
      }

    case MEM_REF:
      if (off)
	{
	  tree offset = TREE_OPERAND (x, 1);
	  *off = (tree_fits_uhwi_p (offset)
		  ? tree_to_uhwi (offset) : HOST_WIDE_INT_MAX);
	}

      x = TREE_OPERAND (x, 0);

      if (off)
	{
	  tree xtype
	    = (TREE_CODE (x) == ADDR_EXPR
	       ? TREE_TYPE (TREE_OPERAND (x, 0)) : TREE_TYPE (TREE_TYPE (x)));

	  set_aggregate_size_and_offset (xtype, fldoff, fldsize, off);
	}

      return get_origin_and_offset_r (x, fldoff, fldsize, nullptr);

    case COMPONENT_REF:
      {
	tree fld = TREE_OPERAND (x, 1);
	*fldoff += int_byte_position (fld);

	get_origin_and_offset_r (fld, fldoff, fldsize, off);
	x = TREE_OPERAND (x, 0);
	return get_origin_and_offset_r (x, fldoff, nullptr, off);
      }

    case SSA_NAME:
      {
	gimple *def = SSA_NAME_DEF_STMT (x);
	if (is_gimple_assign (def))
	  {
	    tree_code code = gimple_assign_rhs_code (def);
	    if (code == ADDR_EXPR)
	      {
		x = gimple_assign_rhs1 (def);
		return get_origin_and_offset_r (x, fldoff, fldsize, off);
	      }

	    if (code == POINTER_PLUS_EXPR)
	      {
		tree offset = gimple_assign_rhs2 (def);
		if (off && tree_fits_uhwi_p (offset))
		  *off = tree_to_uhwi (offset);

		x = gimple_assign_rhs1 (def);
		x = get_origin_and_offset_r (x, fldoff, fldsize, off);
		if (off && !tree_fits_uhwi_p (offset))
		  *off = HOST_WIDE_INT_MAX;
		if (off)
		  {
		    tree xtype = TREE_TYPE (x);
		    set_aggregate_size_and_offset (xtype, fldoff, fldsize, off);
		  }
		return x;
	      }
	    else if (code == VAR_DECL)
	      {
		x = gimple_assign_rhs1 (def);
		return get_origin_and_offset_r (x, fldoff, fldsize, off);
	      }
	  }
	else if (gimple_nop_p (def) && SSA_NAME_VAR (x))
	  x = SSA_NAME_VAR (x);

	tree xtype = TREE_TYPE (x);
	if (POINTER_TYPE_P (xtype))
	  xtype = TREE_TYPE (xtype);

	if (off)
	  set_aggregate_size_and_offset (xtype, fldoff, fldsize, off);
      }

    default:
      break;
    }

  return x;
}

/* Nonrecursive version of the above.  */

static tree
get_origin_and_offset (tree x, HOST_WIDE_INT *fldoff, HOST_WIDE_INT *off,
		       HOST_WIDE_INT *fldsize = nullptr)
{
  HOST_WIDE_INT sizebuf;
  if (!fldsize)
    fldsize = &sizebuf;

  *fldsize = -1;

  *fldoff = *off = *fldsize = 0;
  tree orig = get_origin_and_offset_r (x, fldoff, fldsize, off);
  if (!orig)
    return NULL_TREE;

  if (!*fldoff && *off == *fldsize)
    {
      *fldoff = *off;
      *off = 0;
    }

  return orig;
}

/* If ARG refers to the same (sub)object or array element as described
   by DST and DST_FLD, return the byte offset into the struct member or
   array element referenced by ARG and set *ARG_SIZE to the size of
   the (sub)object.  Otherwise return HOST_WIDE_INT_MIN to indicate
   that ARG and DST do not refer to the same object.  */

static HOST_WIDE_INT
alias_offset (tree arg, HOST_WIDE_INT *arg_size,
	      tree dst, HOST_WIDE_INT dst_fld)
{
  /* See if the argument refers to the same base object as the destination
     of the formatted function call, and if so, try to determine if they
     can alias.  */
  if (!arg || !dst || !ptr_derefs_may_alias_p (arg, dst))
    return HOST_WIDE_INT_MIN;

  /* The two arguments may refer to the same object.  If they both refer
     to a struct member, see if the members are one and the same.  */
  HOST_WIDE_INT arg_off = 0, arg_fld = 0;

  tree arg_orig = get_origin_and_offset (arg, &arg_fld, &arg_off, arg_size);

  if (arg_orig == dst && arg_fld == dst_fld)
    return arg_off;

  return HOST_WIDE_INT_MIN;
}

/* Return the minimum and maximum number of characters formatted
   by the '%s' format directive and its wide character form for
   the argument ARG.  ARG can be null (for functions such as
   vsprinf).  */

static fmtresult
format_string (const directive &dir, tree arg, range_query *query)
{
  fmtresult res;

  /* The size of the (sub)object ARG refers to.  Used to adjust
     the conservative get_string_length() result.  */
  HOST_WIDE_INT arg_size = 0;

  if (warn_restrict)
    {
      /* See if ARG might alias the destination of the call with
	 DST_ORIGIN and DST_FIELD.  If so, store the starting offset
	 so that the overlap can be determined for certain later,
	 when the amount of output of the call (including subsequent
	 directives) has been computed.  Otherwise, store HWI_MIN.  */
      res.dst_offset = alias_offset (arg, &arg_size, dir.info->dst_origin,
				     dir.info->dst_field);
      if (res.dst_offset >= 0 && res.dst_offset <= arg_size)
	arg_size -= res.dst_offset;
      else
	arg_size = 0;
    }

  /* Compute the range the argument's length can be in.  */
  int count_by = 1;
  if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
    {
      /* Get a node for a C type that will be the same size
	 as a wchar_t on the target.  */
      tree node = get_typenode_from_name (MODIFIED_WCHAR_TYPE);

      /* Now that we have a suitable node, get the number of
	 bytes it occupies.  */
      count_by = int_size_in_bytes (node);
      gcc_checking_assert (count_by == 2 || count_by == 4);
    }

  fmtresult slen =
    get_string_length (arg, dir.info->callstmt, arg_size, count_by, query);
  if (slen.range.min == slen.range.max
      && slen.range.min < HOST_WIDE_INT_MAX)
    {
      /* The argument is either a string constant or it refers
	 to one of a number of strings of the same length.  */

      /* A '%s' directive with a string argument with constant length.  */
      res.range = slen.range;

      if (dir.specifier == 'S'
	  || dir.modifier == FMT_LEN_l)
	{
	  /* In the worst case the length of output of a wide string S
	     is bounded by MB_LEN_MAX * wcslen (S).  */
	  res.range.max *= target_mb_len_max ();
	  res.range.unlikely = res.range.max;
	  /* It's likely that the total length is not more that
	     2 * wcslen (S).*/
	  res.range.likely = res.range.min * 2;

	  if (dir.prec[1] >= 0
	      && (unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
	    {
	      res.range.max = dir.prec[1];
	      res.range.likely = dir.prec[1];
	      res.range.unlikely = dir.prec[1];
	    }

	  if (dir.prec[0] < 0 && dir.prec[1] > -1)
	    res.range.min = 0;
	  else if (dir.prec[0] >= 0)
	    res.range.likely = dir.prec[0];

	  /* Even a non-empty wide character string need not convert into
	     any bytes.  */
	  res.range.min = 0;

	  /* A non-empty wide character conversion may fail.  */
	  if (slen.range.max > 0)
	    res.mayfail = true;
	}
      else
	{
	  res.knownrange = true;

	  if (dir.prec[0] < 0 && dir.prec[1] > -1)
	    res.range.min = 0;
	  else if ((unsigned HOST_WIDE_INT)dir.prec[0] < res.range.min)
	    res.range.min = dir.prec[0];

	  if ((unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
	    {
	      res.range.max = dir.prec[1];
	      res.range.likely = dir.prec[1];
	      res.range.unlikely = dir.prec[1];
	    }
	}
    }
  else if (arg && integer_zerop (arg))
    {
      /* Handle null pointer argument.  */

      fmtresult res (0);
      res.nullp = true;
      return res;
    }
  else
    {
      /* For a '%s' and '%ls' directive with a non-constant string (either
	 one of a number of strings of known length or an unknown string)
	 the minimum number of characters is lesser of PRECISION[0] and
	 the length of the shortest known string or zero, and the maximum
	 is the lesser of the length of the longest known string or
	 PTRDIFF_MAX and PRECISION[1].  The likely length is either
	 the minimum at level 1 and the greater of the minimum and 1
	 at level 2.  This result is adjust upward for width (if it's
	 specified).  */

      if (dir.specifier == 'S'
	  || dir.modifier == FMT_LEN_l)
	{
	  /* A wide character converts to as few as zero bytes.  */
	  slen.range.min = 0;
	  if (slen.range.max < target_int_max ())
	    slen.range.max *= target_mb_len_max ();

	  if (slen.range.likely < target_int_max ())
	    slen.range.likely *= 2;

	  if (slen.range.likely < target_int_max ())
	    slen.range.unlikely *= target_mb_len_max ();

	  /* A non-empty wide character conversion may fail.  */
	  if (slen.range.max > 0)
	    res.mayfail = true;
	}

      res.range = slen.range;

      if (dir.prec[0] >= 0)
	{
	  /* Adjust the minimum to zero if the string length is unknown,
	     or at most the lower bound of the precision otherwise.  */
	  if (slen.range.min >= target_int_max ())
	    res.range.min = 0;
	  else if ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.min)
	    res.range.min = dir.prec[0];

	  /* Make both maxima no greater than the upper bound of precision.  */
	  if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max
	      || slen.range.max >= target_int_max ())
	    {
	      res.range.max = dir.prec[1];
	      res.range.unlikely = dir.prec[1];
	    }

	  /* If precision is constant, set the likely counter to the lesser
	     of it and the maximum string length.  Otherwise, if the lower
	     bound of precision is greater than zero, set the likely counter
	     to the minimum.  Otherwise set it to zero or one based on
	     the warning level.  */
	  if (dir.prec[0] == dir.prec[1])
	    res.range.likely
	      = ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.max
		 ? dir.prec[0] : slen.range.max);
	  else if (dir.prec[0] > 0)
	    res.range.likely = res.range.min;
	  else
	    res.range.likely = warn_level > 1;
	}
      else if (dir.prec[1] >= 0)
	{
	  res.range.min = 0;
	  if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max)
	    res.range.max = dir.prec[1];
	  res.range.likely = dir.prec[1] ? warn_level > 1 : 0;
	  if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.unlikely)
	    res.range.unlikely = dir.prec[1];
	}
      else if (slen.range.min >= target_int_max ())
	{
	  res.range.min = 0;
	  res.range.max = HOST_WIDE_INT_MAX;
	  /* At level 1 strings of unknown length are assumed to be
	     empty, while at level 1 they are assumed to be one byte
	     long.  */
	  res.range.likely = warn_level > 1;
	  res.range.unlikely = HOST_WIDE_INT_MAX;
	}
      else
	{
	  /* A string of unknown length unconstrained by precision is
	     assumed to be empty at level 1 and just one character long
	     at higher levels.  */
	  if (res.range.likely >= target_int_max ())
	    res.range.likely = warn_level > 1;
	}
    }

  /* If the argument isn't a nul-terminated string and the number
     of bytes on output isn't bounded by precision, set NONSTR.  */
  if (slen.nonstr && slen.range.min < (unsigned HOST_WIDE_INT)dir.prec[0])
    res.nonstr = slen.nonstr;

  /* Bump up the byte counters if WIDTH is greater.  */
  return res.adjust_for_width_or_precision (dir.width);
}

/* Format plain string (part of the format string itself).  */

static fmtresult
format_plain (const directive &dir, tree, range_query *)
{
  fmtresult res (dir.len);
  return res;
}

/* Return true if the RESULT of a directive in a call describe by INFO
   should be diagnosed given the AVAILable space in the destination.  */

static bool
should_warn_p (const call_info &info,
	       const result_range &avail, const result_range &result)
{
  if (result.max <= avail.min)
    {
      /* The least amount of space remaining in the destination is big
	 enough for the longest output.  */
      return false;
    }

  if (info.bounded)
    {
      if (warn_format_trunc == 1 && result.min <= avail.max
	  && info.retval_used ())
	{
	  /* The likely amount of space remaining in the destination is big
	     enough for the least output and the return value is used.  */
	  return false;
	}

      if (warn_format_trunc == 1 && result.likely <= avail.likely
	  && !info.retval_used ())
	{
	  /* The likely amount of space remaining in the destination is big
	     enough for the likely output and the return value is unused.  */
	  return false;
	}

      if (warn_format_trunc == 2
	  && result.likely <= avail.min
	  && (result.max <= avail.min
	      || result.max > HOST_WIDE_INT_MAX))
	{
	  /* The minimum amount of space remaining in the destination is big
	     enough for the longest output.  */
	  return false;
	}
    }
  else
    {
      if (warn_level == 1 && result.likely <= avail.likely)
	{
	  /* The likely amount of space remaining in the destination is big
	     enough for the likely output.  */
	  return false;
	}

      if (warn_level == 2
	  && result.likely <= avail.min
	  && (result.max <= avail.min
	      || result.max > HOST_WIDE_INT_MAX))
	{
	  /* The minimum amount of space remaining in the destination is big
	     enough for the longest output.  */
	  return false;
	}
    }

  return true;
}

/* At format string location describe by DIRLOC in a call described
   by INFO, issue a warning for a directive DIR whose output may be
   in excess of the available space AVAIL_RANGE in the destination
   given the formatting result FMTRES.  This function does nothing
   except decide whether to issue a warning for a possible write
   past the end or truncation and, if so, format the warning.
   Return true if a warning has been issued.  */

static bool
maybe_warn (substring_loc &dirloc, location_t argloc,
	    const call_info &info,
	    const result_range &avail_range, const result_range &res,
	    const directive &dir)
{
  if (!should_warn_p (info, avail_range, res))
    return false;

  /* A warning will definitely be issued below.  */

  /* The maximum byte count to reference in the warning.  Larger counts
     imply that the upper bound is unknown (and could be anywhere between
     RES.MIN + 1 and SIZE_MAX / 2) are printed as "N or more bytes" rather
     than "between N and X" where X is some huge number.  */
  unsigned HOST_WIDE_INT maxbytes = target_dir_max ();

  /* True when there is enough room in the destination for the least
     amount of a directive's output but not enough for its likely or
     maximum output.  */
  bool maybe = (res.min <= avail_range.max
		&& (avail_range.min < res.likely
		    || (res.max < HOST_WIDE_INT_MAX
			&& avail_range.min < res.max)));

  /* Buffer for the directive in the host character set (used when
     the source character set is different).  */
  char hostdir[32];

  if (avail_range.min == avail_range.max)
    {
      /* The size of the destination region is exact.  */
      unsigned HOST_WIDE_INT navail = avail_range.max;

      if (target_to_host (*dir.beg) != '%')
	{
	  /* For plain character directives (i.e., the format string itself)
	     but not others, point the caret at the first character that's
	     past the end of the destination.  */
	  if (navail < dir.len)
	    dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
	}

      if (*dir.beg == '\0')
	{
	  /* This is the terminating nul.  */
	  gcc_assert (res.min == 1 && res.min == res.max);

	  return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
			  info.bounded
			  ? (maybe
			     ? G_("%qE output may be truncated before the "
				  "last format character")
			     : G_("%qE output truncated before the last "
				  "format character"))
			  : (maybe
			     ? G_("%qE may write a terminating nul past the "
				  "end of the destination")
			     : G_("%qE writing a terminating nul past the "
				  "end of the destination")),
			  info.func);
	}

      if (res.min == res.max)
	{
	  const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
	  if (!info.bounded)
	    return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
			      "%<%.*s%> directive writing %wu byte into a "
			      "region of size %wu",
			      "%<%.*s%> directive writing %wu bytes into a "
			      "region of size %wu",
			      (int) dir.len, d, res.min, navail);
	  else if (maybe)
	    return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
			      "%<%.*s%> directive output may be truncated "
			      "writing %wu byte into a region of size %wu",
			      "%<%.*s%> directive output may be truncated "
			      "writing %wu bytes into a region of size %wu",
			      (int) dir.len, d, res.min, navail);
	  else
	    return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
			      "%<%.*s%> directive output truncated writing "
			      "%wu byte into a region of size %wu",
			      "%<%.*s%> directive output truncated writing "
			      "%wu bytes into a region of size %wu",
			      (int) dir.len, d, res.min, navail);
	}
      if (res.min == 0 && res.max < maxbytes)
	return fmtwarn (dirloc, argloc, NULL,
			info.warnopt (),
			info.bounded
			? (maybe
			   ? G_("%<%.*s%> directive output may be truncated "
				"writing up to %wu bytes into a region of "
				"size %wu")
			   : G_("%<%.*s%> directive output truncated writing "
				"up to %wu bytes into a region of size %wu"))
			: G_("%<%.*s%> directive writing up to %wu bytes "
			     "into a region of size %wu"), (int) dir.len,
			target_to_host (hostdir, sizeof hostdir, dir.beg),
			res.max, navail);

      if (res.min == 0 && maxbytes <= res.max)
	/* This is a special case to avoid issuing the potentially
	   confusing warning:
	     writing 0 or more bytes into a region of size 0.  */
	return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			info.bounded
			? (maybe
			   ? G_("%<%.*s%> directive output may be truncated "
				"writing likely %wu or more bytes into a "
				"region of size %wu")
			   : G_("%<%.*s%> directive output truncated writing "
				"likely %wu or more bytes into a region of "
				"size %wu"))
			: G_("%<%.*s%> directive writing likely %wu or more "
			     "bytes into a region of size %wu"), (int) dir.len,
			target_to_host (hostdir, sizeof hostdir, dir.beg),
			res.likely, navail);

      if (res.max < maxbytes)
	return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			info.bounded
			? (maybe
			   ? G_("%<%.*s%> directive output may be truncated "
				"writing between %wu and %wu bytes into a "
				"region of size %wu")
			   : G_("%<%.*s%> directive output truncated "
				"writing between %wu and %wu bytes into a "
				"region of size %wu"))
			: G_("%<%.*s%> directive writing between %wu and "
			     "%wu bytes into a region of size %wu"),
			(int) dir.len,
			target_to_host (hostdir, sizeof hostdir, dir.beg),
			res.min, res.max, navail);

      return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
		      info.bounded
		      ? (maybe
			 ? G_("%<%.*s%> directive output may be truncated "
			      "writing %wu or more bytes into a region of "
			      "size %wu")
			 : G_("%<%.*s%> directive output truncated writing "
			      "%wu or more bytes into a region of size %wu"))
		      : G_("%<%.*s%> directive writing %wu or more bytes "
			   "into a region of size %wu"), (int) dir.len,
		      target_to_host (hostdir, sizeof hostdir, dir.beg),
		      res.min, navail);
    }

  /* The size of the destination region is a range.  */

  if (target_to_host (*dir.beg) != '%')
    {
      unsigned HOST_WIDE_INT navail = avail_range.max;

      /* For plain character directives (i.e., the format string itself)
	 but not others, point the caret at the first character that's
	 past the end of the destination.  */
      if (navail < dir.len)
	dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
    }

  if (*dir.beg == '\0')
    {
      gcc_assert (res.min == 1 && res.min == res.max);

      return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
		      info.bounded
		      ? (maybe
			 ? G_("%qE output may be truncated before the last "
			      "format character")
			 : G_("%qE output truncated before the last format "
			      "character"))
		      : (maybe
			 ? G_("%qE may write a terminating nul past the end "
			      "of the destination")
			 : G_("%qE writing a terminating nul past the end "
			      "of the destination")), info.func);
    }

  if (res.min == res.max)
    {
      const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
      if (!info.bounded)
	return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
			  "%<%.*s%> directive writing %wu byte into a region "
			  "of size between %wu and %wu",
			  "%<%.*s%> directive writing %wu bytes into a region "
			  "of size between %wu and %wu", (int) dir.len, d,
			  res.min, avail_range.min, avail_range.max);
      else if (maybe)
	return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
			  "%<%.*s%> directive output may be truncated writing "
			  "%wu byte into a region of size between %wu and %wu",
			  "%<%.*s%> directive output may be truncated writing "
			  "%wu bytes into a region of size between %wu and "
			  "%wu", (int) dir.len, d, res.min, avail_range.min,
			  avail_range.max);
      else
	return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
			  "%<%.*s%> directive output truncated writing %wu "
			  "byte into a region of size between %wu and %wu",
			  "%<%.*s%> directive output truncated writing %wu "
			  "bytes into a region of size between %wu and %wu",
			  (int) dir.len, d, res.min, avail_range.min,
			  avail_range.max);
    }

  if (res.min == 0 && res.max < maxbytes)
    return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
		    info.bounded
		    ? (maybe
		       ? G_("%<%.*s%> directive output may be truncated "
			    "writing up to %wu bytes into a region of size "
			    "between %wu and %wu")
		       : G_("%<%.*s%> directive output truncated writing "
			    "up to %wu bytes into a region of size between "
			    "%wu and %wu"))
		    : G_("%<%.*s%> directive writing up to %wu bytes "
			 "into a region of size between %wu and %wu"),
		    (int) dir.len,
		    target_to_host (hostdir, sizeof hostdir, dir.beg),
		    res.max, avail_range.min, avail_range.max);

  if (res.min == 0 && maxbytes <= res.max)
    /* This is a special case to avoid issuing the potentially confusing
       warning:
	 writing 0 or more bytes into a region of size between 0 and N.  */
    return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
		    info.bounded
		    ? (maybe
		       ? G_("%<%.*s%> directive output may be truncated "
			    "writing likely %wu or more bytes into a region "
			    "of size between %wu and %wu")
		       : G_("%<%.*s%> directive output truncated writing "
			    "likely %wu or more bytes into a region of size "
			    "between %wu and %wu"))
		    : G_("%<%.*s%> directive writing likely %wu or more bytes "
			 "into a region of size between %wu and %wu"),
		    (int) dir.len,
		    target_to_host (hostdir, sizeof hostdir, dir.beg),
		    res.likely, avail_range.min, avail_range.max);

  if (res.max < maxbytes)
    return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
		    info.bounded
		    ? (maybe
		       ? G_("%<%.*s%> directive output may be truncated "
			    "writing between %wu and %wu bytes into a region "
			    "of size between %wu and %wu")
		       : G_("%<%.*s%> directive output truncated writing "
			    "between %wu and %wu bytes into a region of size "
			    "between %wu and %wu"))
		    : G_("%<%.*s%> directive writing between %wu and "
			 "%wu bytes into a region of size between %wu and "
			 "%wu"), (int) dir.len,
		    target_to_host (hostdir, sizeof hostdir, dir.beg),
		    res.min, res.max, avail_range.min, avail_range.max);

  return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
		  info.bounded
		  ? (maybe
		     ? G_("%<%.*s%> directive output may be truncated writing "
			  "%wu or more bytes into a region of size between "
			  "%wu and %wu")
		     : G_("%<%.*s%> directive output truncated writing "
			  "%wu or more bytes into a region of size between "
			  "%wu and %wu"))
		  : G_("%<%.*s%> directive writing %wu or more bytes "
		       "into a region of size between %wu and %wu"),
		  (int) dir.len,
		  target_to_host (hostdir, sizeof hostdir, dir.beg),
		  res.min, avail_range.min, avail_range.max);
}

/* Given the formatting result described by RES and NAVAIL, the number
   of available bytes in the destination, return the range of bytes
   remaining in the destination.  */

static inline result_range
bytes_remaining (unsigned HOST_WIDE_INT navail, const format_result &res)
{
  result_range range;

  if (HOST_WIDE_INT_MAX <= navail)
    {
      range.min = range.max = range.likely = range.unlikely = navail;
      return range;
    }

  /* The lower bound of the available range is the available size
     minus the maximum output size, and the upper bound is the size
     minus the minimum.  */
  range.max = res.range.min < navail ? navail - res.range.min : 0;

  range.likely = res.range.likely < navail ? navail - res.range.likely : 0;

  if (res.range.max < HOST_WIDE_INT_MAX)
    range.min = res.range.max < navail ? navail - res.range.max : 0;
  else
    range.min = range.likely;

  range.unlikely = (res.range.unlikely < navail
		    ? navail - res.range.unlikely : 0);

  return range;
}

/* Compute the length of the output resulting from the directive DIR
   in a call described by INFO and update the overall result of the call
   in *RES.  Return true if the directive has been handled.  */

static bool
format_directive (const call_info &info,
		  format_result *res, const directive &dir,
		  range_query *query)
{
  /* Offset of the beginning of the directive from the beginning
     of the format string.  */
  size_t offset = dir.beg - info.fmtstr;
  size_t start = offset;
  size_t length = offset + dir.len - !!dir.len;

  /* Create a location for the whole directive from the % to the format
     specifier.  */
  substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
			offset, start, length);

  /* Also get the location of the argument if possible.
     This doesn't work for integer literals or function calls.  */
  location_t argloc = UNKNOWN_LOCATION;
  if (dir.arg)
    argloc = EXPR_LOCATION (dir.arg);

  /* Bail when there is no function to compute the output length,
     or when minimum length checking has been disabled.   */
  if (!dir.fmtfunc || res->range.min >= HOST_WIDE_INT_MAX)
    return false;

  /* Compute the range of lengths of the formatted output.  */
  fmtresult fmtres = dir.fmtfunc (dir, dir.arg, query);

  /* Record whether the output of all directives is known to be
     bounded by some maximum, implying that their arguments are
     either known exactly or determined to be in a known range
     or, for strings, limited by the upper bounds of the arrays
     they refer to.  */
  res->knownrange &= fmtres.knownrange;

  if (!fmtres.knownrange)
    {
      /* Only when the range is known, check it against the host value
	 of INT_MAX + (the number of bytes of the "%.*Lf" directive with
	 INT_MAX precision, which is the longest possible output of any
	 single directive).  That's the largest valid byte count (though
	 not valid call to a printf-like function because it can never
	 return such a count).  Otherwise, the range doesn't correspond
	 to known values of the argument.  */
      if (fmtres.range.max > target_dir_max ())
	{
	  /* Normalize the MAX counter to avoid having to deal with it
	     later.  The counter can be less than HOST_WIDE_INT_M1U
	     when compiling for an ILP32 target on an LP64 host.  */
	  fmtres.range.max = HOST_WIDE_INT_M1U;
	  /* Disable exact and maximum length checking after a failure
	     to determine the maximum number of characters (for example
	     for wide characters or wide character strings) but continue
	     tracking the minimum number of characters.  */
	  res->range.max = HOST_WIDE_INT_M1U;
	}

      if (fmtres.range.min > target_dir_max ())
	{
	  /* Disable exact length checking after a failure to determine
	     even the minimum number of characters (it shouldn't happen
	     except in an error) but keep tracking the minimum and maximum
	     number of characters.  */
	  return true;
	}
    }

  /* Buffer for the directive in the host character set (used when
     the source character set is different).  */
  char hostdir[32];

  int dirlen = dir.len;

  if (fmtres.nullp)
    {
      fmtwarn (dirloc, argloc, NULL, info.warnopt (),
	       "%<%.*s%> directive argument is null",
	       dirlen, target_to_host (hostdir, sizeof hostdir, dir.beg));

      /* Don't bother processing the rest of the format string.  */
      res->warned = true;
      res->range.min = HOST_WIDE_INT_M1U;
      res->range.max = HOST_WIDE_INT_M1U;
      return false;
    }

  /* Compute the number of available bytes in the destination.  There
     must always be at least one byte of space for the terminating
     NUL that's appended after the format string has been processed.  */
  result_range avail_range = bytes_remaining (info.objsize, *res);

  /* If the argument aliases a part of the destination of the formatted
     call at offset FMTRES.DST_OFFSET append the directive and its result
     to the set of aliases for later processing.  */
  if (fmtres.dst_offset != HOST_WIDE_INT_MIN)
    res->append_alias (dir, fmtres.dst_offset, fmtres.range);

  bool warned = res->warned;

  if (!warned)
    warned = maybe_warn (dirloc, argloc, info, avail_range,
			 fmtres.range, dir);

  /* Bump up the total maximum if it isn't too big.  */
  if (res->range.max < HOST_WIDE_INT_MAX
      && fmtres.range.max < HOST_WIDE_INT_MAX)
    res->range.max += fmtres.range.max;

  /* Raise the total unlikely maximum by the larger of the maximum
     and the unlikely maximum.  */
  unsigned HOST_WIDE_INT save = res->range.unlikely;
  if (fmtres.range.max < fmtres.range.unlikely)
    res->range.unlikely += fmtres.range.unlikely;
  else
    res->range.unlikely += fmtres.range.max;

  if (res->range.unlikely < save)
    res->range.unlikely = HOST_WIDE_INT_M1U;

  res->range.min += fmtres.range.min;
  res->range.likely += fmtres.range.likely;

  /* Has the minimum directive output length exceeded the maximum
     of 4095 bytes required to be supported?  */
  bool minunder4k = fmtres.range.min < 4096;
  bool maxunder4k = fmtres.range.max < 4096;
  /* Clear POSUNDER4K in the overall result if the maximum has exceeded
     the 4k (this is necessary to avoid the return value optimization
     that may not be safe in the maximum case).  */
  if (!maxunder4k)
    res->posunder4k = false;
  /* Also clear POSUNDER4K if the directive may fail.  */
  if (fmtres.mayfail)
    res->posunder4k = false;

  if (!warned
      /* Only warn at level 2.  */
      && warn_level > 1
      /* Only warn for string functions.  */
      && info.is_string_func ()
      && (!minunder4k
	  || (!maxunder4k && fmtres.range.max < HOST_WIDE_INT_MAX)))
    {
      /* The directive output may be longer than the maximum required
	 to be handled by an implementation according to 7.21.6.1, p15
	 of C11.  Warn on this only at level 2 but remember this and
	 prevent folding the return value when done.  This allows for
	 the possibility of the actual libc call failing due to ENOMEM
	 (like Glibc does with very large precision or width).
	 Issue the "may exceed" warning only for string functions and
	 not for fprintf or printf.  */

      if (fmtres.range.min == fmtres.range.max)
	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			  "%<%.*s%> directive output of %wu bytes exceeds "
			  "minimum required size of 4095", dirlen,
			  target_to_host (hostdir, sizeof hostdir, dir.beg),
			  fmtres.range.min);
      else if (!minunder4k)
	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			  "%<%.*s%> directive output between %wu and %wu "
			  "bytes exceeds minimum required size of 4095",
			  dirlen,
			  target_to_host (hostdir, sizeof hostdir, dir.beg),
			  fmtres.range.min, fmtres.range.max);
      else if (!info.retval_used () && info.is_string_func ())
	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			  "%<%.*s%> directive output between %wu and %wu "
			  "bytes may exceed minimum required size of "
			  "4095",
			  dirlen,
			  target_to_host (hostdir, sizeof hostdir, dir.beg),
			  fmtres.range.min, fmtres.range.max);
    }

  /* Has the likely and maximum directive output exceeded INT_MAX?  */
  bool likelyximax = *dir.beg && res->range.likely > target_int_max ();
  /* Don't consider the maximum to be in excess when it's the result
     of a string of unknown length (i.e., whose maximum has been set
     to be greater than or equal to HOST_WIDE_INT_MAX.  */
  bool maxximax = (*dir.beg
		   && res->range.max > target_int_max ()
		   && res->range.max < HOST_WIDE_INT_MAX);

  if (!warned
      /* Warn for the likely output size at level 1.  */
      && (likelyximax
	  /* But only warn for the maximum at level 2.  */
	  || (warn_level > 1
	      && maxximax
	      && fmtres.range.max < HOST_WIDE_INT_MAX)))
    {
      if (fmtres.range.min > target_int_max ())
	{
	  /* The directive output exceeds INT_MAX bytes.  */
	  if (fmtres.range.min == fmtres.range.max)
	    warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			      "%<%.*s%> directive output of %wu bytes exceeds "
			      "%<INT_MAX%>", dirlen,
			      target_to_host (hostdir, sizeof hostdir, dir.beg),
			      fmtres.range.min);
	  else
	    warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			      "%<%.*s%> directive output between %wu and "
			      "%wu bytes exceeds %<INT_MAX%>", dirlen,
			      target_to_host (hostdir, sizeof hostdir, dir.beg),
			      fmtres.range.min, fmtres.range.max);
	}
      else if (res->range.min > target_int_max ())
	{
	  /* The directive output is under INT_MAX but causes the result
	     to exceed INT_MAX bytes.  */
	  if (fmtres.range.min == fmtres.range.max)
	    warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			      "%<%.*s%> directive output of %wu bytes causes "
			      "result to exceed %<INT_MAX%>", dirlen,
			      target_to_host (hostdir, sizeof hostdir, dir.beg),
			      fmtres.range.min);
	  else
	    warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			      "%<%.*s%> directive output between %wu and "
			      "%wu bytes causes result to exceed %<INT_MAX%>",
			      dirlen,
			      target_to_host (hostdir, sizeof hostdir, dir.beg),
			      fmtres.range.min, fmtres.range.max);
	}
      else if ((!info.retval_used () || !info.bounded)
	       && (info.is_string_func ()))
	/* Warn for calls to string functions that either aren't bounded
	   (sprintf) or whose return value isn't used.  */
	warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			  "%<%.*s%> directive output between %wu and "
			  "%wu bytes may cause result to exceed "
			  "%<INT_MAX%>", dirlen,
			  target_to_host (hostdir, sizeof hostdir, dir.beg),
			  fmtres.range.min, fmtres.range.max);
    }

  if (!warned && fmtres.nonstr)
    {
      warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
			"%<%.*s%> directive argument is not a nul-terminated "
			"string",
			dirlen,
			target_to_host (hostdir, sizeof hostdir, dir.beg));
      if (warned && DECL_P (fmtres.nonstr))
	inform (DECL_SOURCE_LOCATION (fmtres.nonstr),
		"referenced argument declared here");
      return false;
    }

  if (warned && fmtres.range.min < fmtres.range.likely
      && fmtres.range.likely < fmtres.range.max)
    inform_n (info.fmtloc, fmtres.range.likely,
	      "assuming directive output of %wu byte",
	      "assuming directive output of %wu bytes",
	      fmtres.range.likely);

  if (warned && fmtres.argmin)
    {
      if (fmtres.argmin == fmtres.argmax)
	inform (info.fmtloc, "directive argument %qE", fmtres.argmin);
      else if (fmtres.knownrange)
	inform (info.fmtloc, "directive argument in the range [%E, %E]",
		fmtres.argmin, fmtres.argmax);
      else
	inform (info.fmtloc,
		"using the range [%E, %E] for directive argument",
		fmtres.argmin, fmtres.argmax);
    }

  res->warned |= warned;

  if (!dir.beg[0] && res->warned)
    {
      location_t callloc = gimple_location (info.callstmt);

      unsigned HOST_WIDE_INT min = res->range.min;
      unsigned HOST_WIDE_INT max = res->range.max;

      if (info.objsize < HOST_WIDE_INT_MAX)
	{
	  /* If a warning has been issued for buffer overflow or truncation
	     help the user figure out how big a buffer they need.  */

	  if (min == max)
	    inform_n (callloc, min,
		      "%qE output %wu byte into a destination of size %wu",
		      "%qE output %wu bytes into a destination of size %wu",
		      info.func, min, info.objsize);
	  else if (max < HOST_WIDE_INT_MAX)
	    inform (callloc,
		    "%qE output between %wu and %wu bytes into "
		    "a destination of size %wu",
		    info.func, min, max, info.objsize);
	  else if (min < res->range.likely && res->range.likely < max)
	    inform (callloc,
		    "%qE output %wu or more bytes (assuming %wu) into "
		    "a destination of size %wu",
		    info.func, min, res->range.likely, info.objsize);
	  else
	    inform (callloc,
		    "%qE output %wu or more bytes into a destination of size "
		    "%wu",
		    info.func, min, info.objsize);
	}
      else if (!info.is_string_func ())
	{
	  /* If the warning is for a file function like fprintf
	     of printf with no destination size just print the computed
	     result.  */
	  if (min == max)
	    inform_n (callloc, min,
		      "%qE output %wu byte", "%qE output %wu bytes",
		      info.func, min);
	  else if (max < HOST_WIDE_INT_MAX)
	    inform (callloc,
		    "%qE output between %wu and %wu bytes",
		    info.func, min, max);
	  else if (min < res->range.likely && res->range.likely < max)
	    inform (callloc,
		    "%qE output %wu or more bytes (assuming %wu)",
		    info.func, min, res->range.likely);
	  else
	    inform (callloc,
		    "%qE output %wu or more bytes",
		    info.func, min);
	}
    }

  if (dump_file && *dir.beg)
    {
      fprintf (dump_file,
	       "    Result: "
	       HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", "
	       HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC " ("
	       HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", "
	       HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ")\n",
	       fmtres.range.min, fmtres.range.likely,
	       fmtres.range.max, fmtres.range.unlikely,
	       res->range.min, res->range.likely,
	       res->range.max, res->range.unlikely);
    }

  return true;
}

/* Parse a format directive in function call described by INFO starting
   at STR and populate DIR structure.  Bump up *ARGNO by the number of
   arguments extracted for the directive.  Return the length of
   the directive.  */

static size_t
parse_directive (call_info &info,
		 directive &dir, format_result *res,
		 const char *str, unsigned *argno,
		 range_query *query)
{
  const char *pcnt = strchr (str, target_percent);
  dir.beg = str;

  if (size_t len = pcnt ? pcnt - str : *str ? strlen (str) : 1)
    {
      /* This directive is either a plain string or the terminating nul
	 (which isn't really a directive but it simplifies things to
	 handle it as if it were).  */
      dir.len = len;
      dir.fmtfunc = format_plain;

      if (dump_file)
	{
	  fprintf (dump_file, "  Directive %u at offset "
		   HOST_WIDE_INT_PRINT_UNSIGNED ": \"%.*s\", "
		   "length = " HOST_WIDE_INT_PRINT_UNSIGNED "\n",
		   dir.dirno,
		   (unsigned HOST_WIDE_INT)(size_t)(dir.beg - info.fmtstr),
		   (int)dir.len, dir.beg, (unsigned HOST_WIDE_INT) dir.len);
	}

      return len - !*str;
    }

  /* Set the directive argument's number to correspond to its position
     in the formatted function call's argument list.  */
  dir.argno = *argno;

  const char *pf = pcnt + 1;

    /* POSIX numbered argument index or zero when none.  */
  HOST_WIDE_INT dollar = 0;

  /* With and precision.  -1 when not specified, HOST_WIDE_INT_MIN
     when given by a va_list argument, and a non-negative value
     when specified in the format string itself.  */
  HOST_WIDE_INT width = -1;
  HOST_WIDE_INT precision = -1;

  /* Pointers to the beginning of the width and precision decimal
     string (if any) within the directive.  */
  const char *pwidth = 0;
  const char *pprec = 0;

  /* When the value of the decimal string that specifies width or
     precision is out of range, points to the digit that causes
     the value to exceed the limit.  */
  const char *werange = NULL;
  const char *perange = NULL;

  /* Width specified via the asterisk.  Need not be INTEGER_CST.
     For vararg functions set to void_node.  */
  tree star_width = NULL_TREE;

  /* Width specified via the asterisk.  Need not be INTEGER_CST.
     For vararg functions set to void_node.  */
  tree star_precision = NULL_TREE;

  if (ISDIGIT (target_to_host (*pf)))
    {
      /* This could be either a POSIX positional argument, the '0'
	 flag, or a width, depending on what follows.  Store it as
	 width and sort it out later after the next character has
	 been seen.  */
      pwidth = pf;
      width = target_strtowi (&pf, &werange);
    }
  else if (target_to_host (*pf) == '*')
    {
      /* Similarly to the block above, this could be either a POSIX
	 positional argument or a width, depending on what follows.  */
      if (*argno < gimple_call_num_args (info.callstmt))
	star_width = gimple_call_arg (info.callstmt, (*argno)++);
      else
	star_width = void_node;
      ++pf;
    }

  if (target_to_host (*pf) == '$')
    {
      /* Handle the POSIX dollar sign which references the 1-based
	 positional argument number.  */
      if (width != -1)
	dollar = width + info.argidx;
      else if (star_width
	       && TREE_CODE (star_width) == INTEGER_CST
	       && (TYPE_PRECISION (TREE_TYPE (star_width))
		   <= TYPE_PRECISION (integer_type_node)))
	dollar = width + tree_to_shwi (star_width);

      /* Bail when the numbered argument is out of range (it will
	 have already been diagnosed by -Wformat).  */
      if (dollar == 0
	  || dollar == (int)info.argidx
	  || dollar > gimple_call_num_args (info.callstmt))
	return false;

      --dollar;

      star_width = NULL_TREE;
      width = -1;
      ++pf;
    }

  if (dollar || !star_width)
    {
      if (width != -1)
	{
	  if (width == 0)
	    {
	      /* The '0' that has been interpreted as a width above is
		 actually a flag.  Reset HAVE_WIDTH, set the '0' flag,
		 and continue processing other flags.  */
	      width = -1;
	      dir.set_flag ('0');
	    }
	  else if (!dollar)
	    {
	      /* (Non-zero) width has been seen.  The next character
		 is either a period or a digit.  */
	      goto start_precision;
	    }
	}
      /* When either '$' has been seen, or width has not been seen,
	 the next field is the optional flags followed by an optional
	 width.  */
      for ( ; ; ) {
	switch (target_to_host (*pf))
	  {
	  case ' ':
	  case '0':
	  case '+':
	  case '-':
	  case '#':
	    dir.set_flag (target_to_host (*pf++));
	    break;

	  default:
	    goto start_width;
	  }
      }

    start_width:
      if (ISDIGIT (target_to_host (*pf)))
	{
	  werange = 0;
	  pwidth = pf;
	  width = target_strtowi (&pf, &werange);
	}
      else if (target_to_host (*pf) == '*')
	{
	  if (*argno < gimple_call_num_args (info.callstmt))
	    star_width = gimple_call_arg (info.callstmt, (*argno)++);
	  else
	    {
	      /* This is (likely) a va_list.  It could also be an invalid
		 call with insufficient arguments.  */
	      star_width = void_node;
	    }
	  ++pf;
	}
      else if (target_to_host (*pf) == '\'')
	{
	  /* The POSIX apostrophe indicating a numeric grouping
	     in the current locale.  Even though it's possible to
	     estimate the upper bound on the size of the output
	     based on the number of digits it probably isn't worth
	     continuing.  */
	  return 0;
	}
    }

 start_precision:
  if (target_to_host (*pf) == '.')
    {
      ++pf;

      if (ISDIGIT (target_to_host (*pf)))
	{
	  pprec = pf;
	  precision = target_strtowi (&pf, &perange);
	}
      else if (target_to_host (*pf) == '*')
	{
	  if (*argno < gimple_call_num_args (info.callstmt))
	    star_precision = gimple_call_arg (info.callstmt, (*argno)++);
	  else
	    {
	      /* This is (likely) a va_list.  It could also be an invalid
		 call with insufficient arguments.  */
	      star_precision = void_node;
	    }
	  ++pf;
	}
      else
	{
	  /* The decimal precision or the asterisk are optional.
	     When neither is specified it's taken to be zero.  */
	  precision = 0;
	}
    }

  switch (target_to_host (*pf))
    {
    case 'h':
      if (target_to_host (pf[1]) == 'h')
	{
	  ++pf;
	  dir.modifier = FMT_LEN_hh;
	}
      else
	dir.modifier = FMT_LEN_h;
      ++pf;
      break;

    case 'j':
      dir.modifier = FMT_LEN_j;
      ++pf;
      break;

    case 'L':
      dir.modifier = FMT_LEN_L;
      ++pf;
      break;

    case 'l':
      if (target_to_host (pf[1]) == 'l')
	{
	  ++pf;
	  dir.modifier = FMT_LEN_ll;
	}
      else
	dir.modifier = FMT_LEN_l;
      ++pf;
      break;

    case 't':
      dir.modifier = FMT_LEN_t;
      ++pf;
      break;

    case 'z':
      dir.modifier = FMT_LEN_z;
      ++pf;
      break;
    }

  switch (target_to_host (*pf))
    {
      /* Handle a sole '%' character the same as "%%" but since it's
	 undefined prevent the result from being folded.  */
    case '\0':
      --pf;
      res->range.min = res->range.max = HOST_WIDE_INT_M1U;
      /* FALLTHRU */
    case '%':
      dir.fmtfunc = format_percent;
      break;

    case 'a':
    case 'A':
    case 'e':
    case 'E':
    case 'f':
    case 'F':
    case 'g':
    case 'G':
      res->floating = true;
      dir.fmtfunc = format_floating;
      break;

    case 'd':
    case 'i':
    case 'o':
    case 'u':
    case 'x':
    case 'X':
      dir.fmtfunc = format_integer;
      break;

    case 'p':
      /* The %p output is implementation-defined.  It's possible
	 to determine this format but due to extensions (especially
	 those of the Linux kernel -- see bug 78512) the first %p
	 in the format string disables any further processing.  */
      return false;

    case 'n':
      /* %n has side-effects even when nothing is actually printed to
	 any buffer.  */
      info.nowrite = false;
      dir.fmtfunc = format_none;
      break;

    case 'C':
    case 'c':
      /* POSIX wide character and C/POSIX narrow character.  */
      dir.fmtfunc = format_character;
      break;

    case 'S':
    case 's':
      /* POSIX wide string and C/POSIX narrow character string.  */
      dir.fmtfunc = format_string;
      break;

    default:
      /* Unknown conversion specification.  */
      return 0;
    }

  dir.specifier = target_to_host (*pf++);

  /* Store the length of the format directive.  */
  dir.len = pf - pcnt;

  /* Buffer for the directive in the host character set (used when
     the source character set is different).  */
  char hostdir[32];

  if (star_width)
    {
      if (INTEGRAL_TYPE_P (TREE_TYPE (star_width)))
	dir.set_width (star_width, query);
      else
	{
	  /* Width specified by a va_list takes on the range [0, -INT_MIN]
	     (width is the absolute value of that specified).  */
	  dir.width[0] = 0;
	  dir.width[1] = target_int_max () + 1;
	}
    }
  else
    {
      if (width == HOST_WIDE_INT_MAX && werange)
	{
	  size_t begin = dir.beg - info.fmtstr + (pwidth - pcnt);
	  size_t caret = begin + (werange - pcnt);
	  size_t end = pf - info.fmtstr - 1;

	  /* Create a location for the width part of the directive,
	     pointing the caret at the first out-of-range digit.  */
	  substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
				caret, begin, end);

	  fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
		   "%<%.*s%> directive width out of range", (int) dir.len,
		   target_to_host (hostdir, sizeof hostdir, dir.beg));
	}

      dir.set_width (width);
    }

  if (star_precision)
    {
      if (INTEGRAL_TYPE_P (TREE_TYPE (star_precision)))
	dir.set_precision (star_precision, query);
      else
	{
	  /* Precision specified by a va_list takes on the range [-1, INT_MAX]
	     (unlike width, negative precision is ignored).  */
	  dir.prec[0] = -1;
	  dir.prec[1] = target_int_max ();
	}
    }
  else
    {
      if (precision == HOST_WIDE_INT_MAX && perange)
	{
	  size_t begin = dir.beg - info.fmtstr + (pprec - pcnt) - 1;
	  size_t caret = dir.beg - info.fmtstr + (perange - pcnt) - 1;
	  size_t end = pf - info.fmtstr - 2;

	  /* Create a location for the precision part of the directive,
	     including the leading period, pointing the caret at the first
	     out-of-range digit .  */
	  substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
				caret, begin, end);

	  fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
		   "%<%.*s%> directive precision out of range", (int) dir.len,
		   target_to_host (hostdir, sizeof hostdir, dir.beg));
	}

      dir.set_precision (precision);
    }

  /* Extract the argument if the directive takes one and if it's
     available (e.g., the function doesn't take a va_list).  Treat
     missing arguments the same as va_list, even though they will
     have likely already been diagnosed by -Wformat.  */
  if (dir.specifier != '%'
      && *argno < gimple_call_num_args (info.callstmt))
    dir.arg = gimple_call_arg (info.callstmt, dollar ? dollar : (*argno)++);

  if (dump_file)
    {
      fprintf (dump_file,
	       "  Directive %u at offset " HOST_WIDE_INT_PRINT_UNSIGNED
	       ": \"%.*s\"",
	       dir.dirno,
	       (unsigned HOST_WIDE_INT)(size_t)(dir.beg - info.fmtstr),
	       (int)dir.len, dir.beg);
      if (star_width)
	{
	  if (dir.width[0] == dir.width[1])
	    fprintf (dump_file, ", width = " HOST_WIDE_INT_PRINT_DEC,
		     dir.width[0]);
	  else
	    fprintf (dump_file,
		     ", width in range [" HOST_WIDE_INT_PRINT_DEC
		     ", " HOST_WIDE_INT_PRINT_DEC "]",
		     dir.width[0], dir.width[1]);
	}

      if (star_precision)
	{
	  if (dir.prec[0] == dir.prec[1])
	    fprintf (dump_file, ", precision = " HOST_WIDE_INT_PRINT_DEC,
		     dir.prec[0]);
	  else
	    fprintf (dump_file,
		     ", precision in range [" HOST_WIDE_INT_PRINT_DEC
		     HOST_WIDE_INT_PRINT_DEC "]",
		     dir.prec[0], dir.prec[1]);
	}
      fputc ('\n', dump_file);
    }

  return dir.len;
}

/* Diagnose overlap between destination and %s directive arguments.  */

static void
maybe_warn_overlap (call_info &info, format_result *res)
{
  /* Two vectors of 1-based indices corresponding to either certainly
     or possibly aliasing arguments.  */
  auto_vec<int, 16> aliasarg[2];

  /* Go through the array of potentially aliasing directives and collect
     argument numbers of those that do or may overlap the destination
     object given the full result.  */
  for (unsigned i = 0; i != res->alias_count; ++i)
    {
      const format_result::alias_info &alias = res->aliases[i];

      enum { possible = -1, none = 0, certain = 1 } overlap = none;

      /* If the precision is zero there is no overlap.  (This only
	 considers %s directives and ignores %n.)  */
      if (alias.dir.prec[0] == 0 && alias.dir.prec[1] == 0)
	continue;

      if (alias.offset == HOST_WIDE_INT_MAX
	  || info.dst_offset == HOST_WIDE_INT_MAX)
	overlap = possible;
      else if (alias.offset == info.dst_offset)
	overlap = alias.dir.prec[0] == 0 ? possible : certain;
      else
	{
	  /* Determine overlap from the range of output and offsets
	     into the same destination as the source, and rule out
	     impossible overlap.  */
	  unsigned HOST_WIDE_INT albeg = alias.offset;
	  unsigned HOST_WIDE_INT dstbeg = info.dst_offset;

	  unsigned HOST_WIDE_INT alend = albeg + alias.range.min;
	  unsigned HOST_WIDE_INT dstend = dstbeg + res->range.min - 1;

	  if ((albeg <= dstbeg && alend > dstbeg)
	      || (albeg >= dstbeg && albeg < dstend))
	    overlap = certain;
	  else
	    {
	      alend = albeg + alias.range.max;
	      if (alend < albeg)
		alend = HOST_WIDE_INT_M1U;

	      dstend = dstbeg + res->range.max - 1;
	      if (dstend < dstbeg)
		dstend = HOST_WIDE_INT_M1U;

	      if ((albeg >= dstbeg && albeg <= dstend)
		  || (alend >= dstbeg && alend <= dstend))
		overlap = possible;
	    }
	}

      if (overlap == none)
	continue;

      /* Append the 1-based argument number.  */
      aliasarg[overlap != certain].safe_push (alias.dir.argno + 1);

      /* Disable any kind of optimization.  */
      res->range.unlikely = HOST_WIDE_INT_M1U;
    }

  tree arg0 = gimple_call_arg (info.callstmt, 0);
  location_t loc = gimple_location (info.callstmt);

  bool aliaswarn = false;

  unsigned ncertain = aliasarg[0].length ();
  unsigned npossible = aliasarg[1].length ();
  if (ncertain && npossible)
    {
      /* If there are multiple arguments that overlap, some certainly
	 and some possibly, handle both sets in a single diagnostic.  */
      aliaswarn
	= warning_at (loc, OPT_Wrestrict,
		      "%qE arguments %Z and maybe %Z overlap destination "
		      "object %qE",
		      info.func, aliasarg[0].address (), ncertain,
		      aliasarg[1].address (), npossible,
		      info.dst_origin);
    }
  else if (ncertain)
    {
      /* There is only one set of two or more arguments and they all
	 certainly overlap the destination.  */
      aliaswarn
	= warning_n (loc, OPT_Wrestrict, ncertain,
		     "%qE argument %Z overlaps destination object %qE",
		     "%qE arguments %Z overlap destination object %qE",
		     info.func, aliasarg[0].address (), ncertain,
		     info.dst_origin);
    }
  else if (npossible)
    {
      /* There is only one set of two or more arguments and they all
	 may overlap (but need not).  */
      aliaswarn
	= warning_n (loc, OPT_Wrestrict, npossible,
		     "%qE argument %Z may overlap destination object %qE",
		     "%qE arguments %Z may overlap destination object %qE",
		     info.func, aliasarg[1].address (), npossible,
		     info.dst_origin);
    }

  if (aliaswarn)
    {
      res->warned = true;

      if (info.dst_origin != arg0)
	{
	  /* If its location is different from the first argument of the call
	     point either at the destination object itself or at the expression
	     that was used to determine the overlap.  */
	  loc = (DECL_P (info.dst_origin)
		 ? DECL_SOURCE_LOCATION (info.dst_origin)
		 : EXPR_LOCATION (info.dst_origin));
	  if (loc != UNKNOWN_LOCATION)
	    inform (loc,
		    "destination object referenced by %<restrict%>-qualified "
		    "argument 1 was declared here");
	}
    }
}

/* Compute the length of the output resulting from the call to a formatted
   output function described by INFO and store the result of the call in
   *RES.  Issue warnings for detected past the end writes.  Return true
   if the complete format string has been processed and *RES can be relied
   on, false otherwise (e.g., when a unknown or unhandled directive was seen
   that caused the processing to be terminated early).  */

static bool
compute_format_length (call_info &info, format_result *res, range_query *query)
{
  if (dump_file)
    {
      location_t callloc = gimple_location (info.callstmt);
      fprintf (dump_file, "%s:%i: ",
	       LOCATION_FILE (callloc), LOCATION_LINE (callloc));
      print_generic_expr (dump_file, info.func, dump_flags);

      fprintf (dump_file,
	       ": objsize = " HOST_WIDE_INT_PRINT_UNSIGNED
	       ", fmtstr = \"%s\"\n",
	       info.objsize, info.fmtstr);
    }

  /* Reset the minimum and maximum byte counters.  */
  res->range.min = res->range.max = 0;

  /* No directive has been seen yet so the length of output is bounded
     by the known range [0, 0] (with no conversion resulting in a failure
     or producing more than 4K bytes) until determined otherwise.  */
  res->knownrange = true;
  res->floating = false;
  res->warned = false;

  /* 1-based directive counter.  */
  unsigned dirno = 1;

  /* The variadic argument counter.  */
  unsigned argno = info.argidx;

  bool success = true;

  for (const char *pf = info.fmtstr; ; ++dirno)
    {
      directive dir (&info, dirno);

      size_t n = parse_directive (info, dir, res, pf, &argno, query);

      /* Return failure if the format function fails.  */
      if (!format_directive (info, res, dir, query))
	return false;

      /* Return success when the directive is zero bytes long and it's
	 the last thing in the format string (i.e., it's the terminating
	 nul, which isn't really a directive but handling it as one makes
	 things simpler).  */
      if (!n)
	{
	  success = *pf == '\0';
	  break;
	}

      pf += n;
    }

  maybe_warn_overlap (info, res);

  /* The complete format string was processed (with or without warnings).  */
  return success;
}

/* Return the size of the object referenced by the expression DEST in
   statement STMT, if available, or the maximum possible size otherwise.  */

static unsigned HOST_WIDE_INT
get_destination_size (tree dest, gimple *stmt, pointer_query &ptr_qry)
{
  /* When there is no destination return the maximum.  */
  if (!dest)
    return HOST_WIDE_INT_MAX;

  /* Use compute_objsize to determine the size of the destination object.  */
  access_ref aref;
  if (!ptr_qry.get_ref (dest, stmt, &aref))
    return HOST_WIDE_INT_MAX;

  offset_int remsize = aref.size_remaining ();
  if (!wi::fits_uhwi_p (remsize))
    return HOST_WIDE_INT_MAX;

  return remsize.to_uhwi ();
}

/* Return true if the call described by INFO with result RES safe to
   optimize (i.e., no undefined behavior), and set RETVAL to the range
   of its return values.  */

static bool
is_call_safe (const call_info &info,
	      const format_result &res, bool under4k,
	      unsigned HOST_WIDE_INT retval[2])
{
  if (under4k && !res.posunder4k)
    return false;

  /* The minimum return value.  */
  retval[0] = res.range.min;

  /* The maximum return value is in most cases bounded by RES.RANGE.MAX
     but in cases involving multibyte characters could be as large as
     RES.RANGE.UNLIKELY.  */
  retval[1]
    = res.range.unlikely < res.range.max ? res.range.max : res.range.unlikely;

  /* Adjust the number of bytes which includes the terminating nul
     to reflect the return value of the function which does not.
     Because the valid range of the function is [INT_MIN, INT_MAX],
     a valid range before the adjustment below is [0, INT_MAX + 1]
     (the functions only return negative values on error or undefined
     behavior).  */
  if (retval[0] <= target_int_max () + 1)
    --retval[0];
  if (retval[1] <= target_int_max () + 1)
    --retval[1];

  /* Avoid the return value optimization when the behavior of the call
     is undefined either because any directive may have produced 4K or
     more of output, or the return value exceeds INT_MAX, or because
     the output overflows the destination object (but leave it enabled
     when the function is bounded because then the behavior is well-
     defined).  */
  if (retval[0] == retval[1]
      && (info.bounded || retval[0] < info.objsize)
      && retval[0] <= target_int_max ())
    return true;

  if ((info.bounded || retval[1] < info.objsize)
      && (retval[0] < target_int_max ()
	  && retval[1] < target_int_max ()))
    return true;

  if (!under4k && (info.bounded || retval[0] < info.objsize))
    return true;

  return false;
}

/* Given a suitable result RES of a call to a formatted output function
   described by INFO, substitute the result for the return value of
   the call.  The result is suitable if the number of bytes it represents
   is known and exact.  A result that isn't suitable for substitution may
   have its range set to the range of return values, if that is known.
   Return true if the call is removed and gsi_next should not be performed
   in the caller.  */

static bool
try_substitute_return_value (gimple_stmt_iterator *gsi,
			     const call_info &info,
			     const format_result &res)
{
  tree lhs = gimple_get_lhs (info.callstmt);

  /* Set to true when the entire call has been removed.  */
  bool removed = false;

  /* The minimum and maximum return value.  */
  unsigned HOST_WIDE_INT retval[2] = {0};
  bool safe = is_call_safe (info, res, true, retval);

  if (safe
      && retval[0] == retval[1]
      /* Not prepared to handle possibly throwing calls here; they shouldn't
	 appear in non-artificial testcases, except when the __*_chk routines
	 are badly declared.  */
      && !stmt_ends_bb_p (info.callstmt))
    {
      tree cst = build_int_cst (lhs ? TREE_TYPE (lhs) : integer_type_node,
				retval[0]);

      if (lhs == NULL_TREE && info.nowrite)
	{
	  /* Remove the call to the bounded function with a zero size
	     (e.g., snprintf(0, 0, "%i", 123)) if there is no lhs.  */
	  unlink_stmt_vdef (info.callstmt);
	  gsi_remove (gsi, true);
	  removed = true;
	}
      else if (info.nowrite)
	{
	  /* Replace the call to the bounded function with a zero size
	     (e.g., snprintf(0, 0, "%i", 123) with the constant result
	     of the function.  */
	  gimplify_and_update_call_from_tree (gsi, cst);
	  gimple *callstmt = gsi_stmt (*gsi);
	  update_stmt (callstmt);
	}
      else if (lhs)
	{
	  /* Replace the left-hand side of the call with the constant
	     result of the formatted function.  */
	  gimple_call_set_lhs (info.callstmt, NULL_TREE);
	  gimple *g = gimple_build_assign (lhs, cst);
	  gsi_insert_after (gsi, g, GSI_NEW_STMT);
	  update_stmt (info.callstmt);
	}

      if (dump_file)
	{
	  if (removed)
	    fprintf (dump_file, "  Removing call statement.");
	  else
	    {
	      fprintf (dump_file, "  Substituting ");
	      print_generic_expr (dump_file, cst, dump_flags);
	      fprintf (dump_file, " for %s.\n",
		       info.nowrite ? "statement" : "return value");
	    }
	}
    }
  else if (lhs && types_compatible_p (TREE_TYPE (lhs), integer_type_node))
    {
      bool setrange = false;

      if (safe
	  && (info.bounded || retval[1] < info.objsize)
	  && (retval[0] < target_int_max ()
	      && retval[1] < target_int_max ()))
	{
	  /* If the result is in a valid range bounded by the size of
	     the destination set it so that it can be used for subsequent
	     optimizations.  */
	  int prec = TYPE_PRECISION (integer_type_node);

	  wide_int min = wi::shwi (retval[0], prec);
	  wide_int max = wi::shwi (retval[1], prec);
	  set_range_info (lhs, VR_RANGE, min, max);

	  setrange = true;
	}

      if (dump_file)
	{
	  const char *inbounds
	    = (retval[0] < info.objsize
	       ? (retval[1] < info.objsize
		  ? "in" : "potentially out-of")
	       : "out-of");

	  const char *what = setrange ? "Setting" : "Discarding";
	  if (retval[0] != retval[1])
	    fprintf (dump_file,
		     "  %s %s-bounds return value range ["
		     HOST_WIDE_INT_PRINT_UNSIGNED ", "
		     HOST_WIDE_INT_PRINT_UNSIGNED "].\n",
		     what, inbounds, retval[0], retval[1]);
	  else
	    fprintf (dump_file, "  %s %s-bounds return value "
		     HOST_WIDE_INT_PRINT_UNSIGNED ".\n",
		     what, inbounds, retval[0]);
	}
    }

  if (dump_file)
    fputc ('\n', dump_file);

  return removed;
}

/* Try to simplify a s{,n}printf call described by INFO with result
   RES by replacing it with a simpler and presumably more efficient
   call (such as strcpy).  */

static bool
try_simplify_call (gimple_stmt_iterator *gsi,
		   const call_info &info,
		   const format_result &res)
{
  unsigned HOST_WIDE_INT dummy[2];
  if (!is_call_safe (info, res, info.retval_used (), dummy))
    return false;

  switch (info.fncode)
    {
    case BUILT_IN_SNPRINTF:
      return gimple_fold_builtin_snprintf (gsi);

    case BUILT_IN_SPRINTF:
      return gimple_fold_builtin_sprintf (gsi);

    default:
      ;
    }

  return false;
}

/* Return the zero-based index of the format string argument of a printf
   like function and set *IDX_ARGS to the first format argument.  When
   no such index exists return UINT_MAX.  */

static unsigned
get_user_idx_format (tree fndecl, unsigned *idx_args)
{
  tree attrs = lookup_attribute ("format", DECL_ATTRIBUTES (fndecl));
  if (!attrs)
    attrs = lookup_attribute ("format", TYPE_ATTRIBUTES (TREE_TYPE (fndecl)));

  if (!attrs)
    return UINT_MAX;

  attrs = TREE_VALUE (attrs);

  tree archetype = TREE_VALUE (attrs);
  if (strcmp ("printf", IDENTIFIER_POINTER (archetype)))
    return UINT_MAX;

  attrs = TREE_CHAIN (attrs);
  tree fmtarg = TREE_VALUE (attrs);

  attrs = TREE_CHAIN (attrs);
  tree elliparg = TREE_VALUE (attrs);

  /* Attribute argument indices are 1-based but we use zero-based.  */
  *idx_args = tree_to_uhwi (elliparg) - 1;
  return tree_to_uhwi (fmtarg) - 1;
}

}   /* Unnamed namespace.  */

/* Determine if a GIMPLE call at *GSI is to one of the sprintf-like built-in
   functions and if so, handle it.  Return true if the call is removed and
   gsi_next should not be performed in the caller.  */

bool
handle_printf_call (gimple_stmt_iterator *gsi, pointer_query &ptr_qry)
{
  init_target_to_host_charmap ();

  call_info info = call_info ();

  info.callstmt = gsi_stmt (*gsi);
  info.func = gimple_call_fndecl (info.callstmt);
  if (!info.func)
    return false;

  /* Format string argument number (valid for all functions).  */
  unsigned idx_format = UINT_MAX;
  if (gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL))
    info.fncode = DECL_FUNCTION_CODE (info.func);
  else
    {
      unsigned idx_args;
      idx_format = get_user_idx_format (info.func, &idx_args);
      if (idx_format == UINT_MAX
	  || idx_format >= gimple_call_num_args (info.callstmt)
	  || idx_args > gimple_call_num_args (info.callstmt)
	  || !POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (info.callstmt,
							  idx_format))))
	return false;
      info.fncode = BUILT_IN_NONE;
      info.argidx = idx_args;
    }

  /* The size of the destination as in snprintf(dest, size, ...).  */
  unsigned HOST_WIDE_INT dstsize = HOST_WIDE_INT_M1U;

  /* The size of the destination determined by __builtin_object_size.  */
  unsigned HOST_WIDE_INT objsize = HOST_WIDE_INT_M1U;

  /* Zero-based buffer size argument number (snprintf and vsnprintf).  */
  unsigned idx_dstsize = UINT_MAX;

  /* Object size argument number (snprintf_chk and vsnprintf_chk).  */
  unsigned idx_objsize = UINT_MAX;

  /* Destinaton argument number (valid for sprintf functions only).  */
  unsigned idx_dstptr = 0;

  switch (info.fncode)
    {
    case BUILT_IN_NONE:
      // User-defined function with attribute format (printf).
      idx_dstptr = -1;
      break;

    case BUILT_IN_FPRINTF:
      // Signature:
      //   __builtin_fprintf (FILE*, format, ...)
      idx_format = 1;
      info.argidx = 2;
      idx_dstptr = -1;
      break;

    case BUILT_IN_FPRINTF_CHK:
      // Signature:
      //   __builtin_fprintf_chk (FILE*, ost, format, ...)
      idx_format = 2;
      info.argidx = 3;
      idx_dstptr = -1;
      break;

    case BUILT_IN_FPRINTF_UNLOCKED:
      // Signature:
      //   __builtin_fprintf_unnlocked (FILE*, format, ...)
      idx_format = 1;
      info.argidx = 2;
      idx_dstptr = -1;
      break;

    case BUILT_IN_PRINTF:
      // Signature:
      //   __builtin_printf (format, ...)
      idx_format = 0;
      info.argidx = 1;
      idx_dstptr = -1;
      break;

    case BUILT_IN_PRINTF_CHK:
      // Signature:
      //   __builtin_printf_chk (ost, format, ...)
      idx_format = 1;
      info.argidx = 2;
      idx_dstptr = -1;
      break;

    case BUILT_IN_PRINTF_UNLOCKED:
      // Signature:
      //   __builtin_printf (format, ...)
      idx_format = 0;
      info.argidx = 1;
      idx_dstptr = -1;
      break;

    case BUILT_IN_SPRINTF:
      // Signature:
      //   __builtin_sprintf (dst, format, ...)
      idx_format = 1;
      info.argidx = 2;
      break;

    case BUILT_IN_SPRINTF_CHK:
      // Signature:
      //   __builtin___sprintf_chk (dst, ost, objsize, format, ...)
      idx_objsize = 2;
      idx_format = 3;
      info.argidx = 4;
      break;

    case BUILT_IN_SNPRINTF:
      // Signature:
      //   __builtin_snprintf (dst, size, format, ...)
      idx_dstsize = 1;
      idx_format = 2;
      info.argidx = 3;
      info.bounded = true;
      break;

    case BUILT_IN_SNPRINTF_CHK:
      // Signature:
      //   __builtin___snprintf_chk (dst, size, ost, objsize, format, ...)
      idx_dstsize = 1;
      idx_objsize = 3;
      idx_format = 4;
      info.argidx = 5;
      info.bounded = true;
      break;

    case BUILT_IN_VFPRINTF:
      // Signature:
      //   __builtin_vprintf (FILE*, format, va_list)
      idx_format = 1;
      info.argidx = -1;
      idx_dstptr = -1;
      break;

    case BUILT_IN_VFPRINTF_CHK:
      // Signature:
      //   __builtin___vfprintf_chk (FILE*, ost, format, va_list)
      idx_format = 2;
      info.argidx = -1;
      idx_dstptr = -1;
      break;

    case BUILT_IN_VPRINTF:
      // Signature:
      //   __builtin_vprintf (format, va_list)
      idx_format = 0;
      info.argidx = -1;
      idx_dstptr = -1;
      break;

    case BUILT_IN_VPRINTF_CHK:
      // Signature:
      //   __builtin___vprintf_chk (ost, format, va_list)
      idx_format = 1;
      info.argidx = -1;
      idx_dstptr = -1;
      break;

    case BUILT_IN_VSNPRINTF:
      // Signature:
      //   __builtin_vsprintf (dst, size, format, va)
      idx_dstsize = 1;
      idx_format = 2;
      info.argidx = -1;
      info.bounded = true;
      break;

    case BUILT_IN_VSNPRINTF_CHK:
      // Signature:
      //   __builtin___vsnprintf_chk (dst, size, ost, objsize, format, va)
      idx_dstsize = 1;
      idx_objsize = 3;
      idx_format = 4;
      info.argidx = -1;
      info.bounded = true;
      break;

    case BUILT_IN_VSPRINTF:
      // Signature:
      //   __builtin_vsprintf (dst, format, va)
      idx_format = 1;
      info.argidx = -1;
      break;

    case BUILT_IN_VSPRINTF_CHK:
      // Signature:
      //   __builtin___vsprintf_chk (dst, ost, objsize, format, va)
      idx_format = 3;
      idx_objsize = 2;
      info.argidx = -1;
      break;

    default:
      return false;
    }

  /* Set the global warning level for this function.  */
  warn_level = info.bounded ? warn_format_trunc : warn_format_overflow;

  /* For all string functions the first argument is a pointer to
     the destination.  */
  tree dstptr = (idx_dstptr < gimple_call_num_args (info.callstmt)
		 ? gimple_call_arg (info.callstmt, 0) : NULL_TREE);

  info.format = gimple_call_arg (info.callstmt, idx_format);

  /* True when the destination size is constant as opposed to the lower
     or upper bound of a range.  */
  bool dstsize_cst_p = true;
  bool posunder4k = true;

  if (idx_dstsize == UINT_MAX)
    {
      /* For non-bounded functions like sprintf, determine the size
	 of the destination from the object or pointer passed to it
	 as the first argument.  */
      dstsize = get_destination_size (dstptr, info.callstmt, ptr_qry);
    }
  else if (tree size = gimple_call_arg (info.callstmt, idx_dstsize))
    {
      /* For bounded functions try to get the size argument.  */

      if (TREE_CODE (size) == INTEGER_CST)
	{
	  dstsize = tree_to_uhwi (size);
	  /* No object can be larger than SIZE_MAX bytes (half the address
	     space) on the target.
	     The functions are defined only for output of at most INT_MAX
	     bytes.  Specifying a bound in excess of that limit effectively
	     defeats the bounds checking (and on some implementations such
	     as Solaris cause the function to fail with EINVAL).  */
	  if (dstsize > target_size_max () / 2)
	    {
	      /* Avoid warning if -Wstringop-overflow is specified since
		 it also warns for the same thing though only for the
		 checking built-ins.  */
	      if ((idx_objsize == UINT_MAX
		   || !warn_stringop_overflow))
		warning_at (gimple_location (info.callstmt), info.warnopt (),
			    "specified bound %wu exceeds maximum object size "
			    "%wu",
			    dstsize, target_size_max () / 2);
	      /* POSIX requires snprintf to fail if DSTSIZE is greater
		 than INT_MAX.  Even though not all POSIX implementations
		 conform to the requirement, avoid folding in this case.  */
	      posunder4k = false;
	    }
	  else if (dstsize > target_int_max ())
	    {
	      warning_at (gimple_location (info.callstmt), info.warnopt (),
			  "specified bound %wu exceeds %<INT_MAX%>",
			  dstsize);
	      /* POSIX requires snprintf to fail if DSTSIZE is greater
		 than INT_MAX.  Avoid folding in that case.  */
	      posunder4k = false;
	    }
	}
      else if (TREE_CODE (size) == SSA_NAME)
	{
	  /* Try to determine the range of values of the argument
	     and use the greater of the two at level 1 and the smaller
	     of them at level 2.  */
	  value_range vr;
	  ptr_qry.rvals->range_of_expr (vr, size, info.callstmt);

	  if (!vr.undefined_p ())
	    {
	      tree type = TREE_TYPE (size);
	      tree tmin = wide_int_to_tree (type, vr.lower_bound ());
	      tree tmax = wide_int_to_tree (type, vr.upper_bound ());
	      unsigned HOST_WIDE_INT minsize = TREE_INT_CST_LOW (tmin);
	      unsigned HOST_WIDE_INT maxsize = TREE_INT_CST_LOW (tmax);
	      dstsize = warn_level < 2 ? maxsize : minsize;

	      if (minsize > target_int_max ())
		warning_at (gimple_location (info.callstmt), info.warnopt (),
			    "specified bound range [%wu, %wu] exceeds "
			    "%<INT_MAX%>",
			    minsize, maxsize);

	      /* POSIX requires snprintf to fail if DSTSIZE is greater
		 than INT_MAX.  Avoid folding if that's possible.  */
	      if (maxsize > target_int_max ())
		posunder4k = false;
	    }

	  /* The destination size is not constant.  If the function is
	     bounded (e.g., snprintf) a lower bound of zero doesn't
	     necessarily imply it can be eliminated.  */
	  dstsize_cst_p = false;
	}
    }

  if (idx_objsize != UINT_MAX)
    if (tree size = gimple_call_arg (info.callstmt, idx_objsize))
      if (tree_fits_uhwi_p (size))
	objsize = tree_to_uhwi (size);

  if (info.bounded && !dstsize)
    {
      /* As a special case, when the explicitly specified destination
	 size argument (to a bounded function like snprintf) is zero
	 it is a request to determine the number of bytes on output
	 without actually producing any.  Pretend the size is
	 unlimited in this case.  */
      info.objsize = HOST_WIDE_INT_MAX;
      info.nowrite = dstsize_cst_p;
    }
  else
    {
      /* For calls to non-bounded functions or to those of bounded
	 functions with a non-zero size, warn if the destination
	 pointer is null.  */
      if (dstptr && integer_zerop (dstptr))
	{
	  /* This is diagnosed with -Wformat only when the null is a constant
	     pointer.  The warning here diagnoses instances where the pointer
	     is not constant.  */
	  location_t loc = gimple_location (info.callstmt);
	  warning_at (EXPR_LOC_OR_LOC (dstptr, loc),
		      info.warnopt (), "null destination pointer");
	  return false;
	}

      /* Set the object size to the smaller of the two arguments
	 of both have been specified and they're not equal.  */
      info.objsize = dstsize < objsize ? dstsize : objsize;

      if (info.bounded
	  && dstsize < target_size_max () / 2 && objsize < dstsize
	  /* Avoid warning if -Wstringop-overflow is specified since
	     it also warns for the same thing though only for the
	     checking built-ins.  */
	  && (idx_objsize == UINT_MAX
	      || !warn_stringop_overflow))
	{
	  warning_at (gimple_location (info.callstmt), info.warnopt (),
		      "specified bound %wu exceeds the size %wu "
		      "of the destination object", dstsize, objsize);
	}
    }

  /* Determine if the format argument may be null and warn if not
     and if the argument is null.  */
  if (integer_zerop (info.format)
      && gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL))
    {
      location_t loc = gimple_location (info.callstmt);
      warning_at (EXPR_LOC_OR_LOC (info.format, loc),
		  info.warnopt (), "null format string");
      return false;
    }

  info.fmtstr = get_format_string (info.format, &info.fmtloc);
  if (!info.fmtstr)
    return false;

  if (warn_restrict)
    {
      /* Compute the origin of the destination pointer and its offset
	 from the base object/pointer if possible.  */
      info.dst_offset = 0;
      info.dst_origin = get_origin_and_offset (dstptr, &info.dst_field,
					       &info.dst_offset);
    }

  /* The result is the number of bytes output by the formatted function,
     including the terminating NUL.  */
  format_result res;

  /* I/O functions with no destination argument (i.e., all forms of fprintf
     and printf) may fail under any conditions.  Others (i.e., all forms of
     sprintf) may only fail under specific conditions determined for each
     directive.  Clear POSUNDER4K for the former set of functions and set
     it to true for the latter (it can only be cleared later, but it is
     never set to true again).  */
  res.posunder4k = posunder4k && dstptr;

  bool success = compute_format_length (info, &res, ptr_qry.rvals);
  if (res.warned)
    suppress_warning (info.callstmt, info.warnopt ());

  /* When optimizing and the printf return value optimization is enabled,
     attempt to substitute the computed result for the return value of
     the call.  Avoid this optimization when -frounding-math is in effect
     and the format string contains a floating point directive.  */
  bool call_removed = false;
  if (success && optimize > 0)
    {
      /* Save a copy of the iterator pointing at the call.  The iterator
	 may change to point past the call in try_substitute_return_value
	 but the original value is needed in try_simplify_call.  */
      gimple_stmt_iterator gsi_call = *gsi;

      if (flag_printf_return_value
	  && (!flag_rounding_math || !res.floating))
	call_removed = try_substitute_return_value (gsi, info, res);

      if (!call_removed)
	try_simplify_call (&gsi_call, info, res);
    }

  return call_removed;
}
