/* 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 "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, int 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, int 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.  */
  int 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 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))
    {
      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);
}

/* Determine the offset *INDEX of the first byte of an array element of
   TYPE (possibly recursively) into which the byte offset OFF points.
   On success set *INDEX to the offset of the first byte and return type.
   Otherwise, if no such element can be found, return null.  */

static tree
array_elt_at_offset (tree type, HOST_WIDE_INT off, HOST_WIDE_INT *index)
{
  gcc_assert (TREE_CODE (type) == ARRAY_TYPE);

  tree eltype = type;
  while (TREE_CODE (TREE_TYPE (eltype)) == ARRAY_TYPE)
    eltype = TREE_TYPE (eltype);

  if (TYPE_MODE (TREE_TYPE (eltype)) != TYPE_MODE (char_type_node))
    eltype = TREE_TYPE (eltype);

  if (eltype == type)
    {
      *index = 0;
      return type;
    }

  HOST_WIDE_INT typsz = int_size_in_bytes (type);
  HOST_WIDE_INT eltsz = int_size_in_bytes (eltype);
  if (off < typsz * eltsz)
    {
      *index = (off / eltsz) * eltsz;
      return TREE_CODE (eltype) == ARRAY_TYPE ? TREE_TYPE (eltype) : eltype;
    }

  return NULL_TREE;
}

/* Determine the offset *INDEX of the first byte of a struct member of TYPE
   (possibly recursively) into which the byte offset OFF points.  On success
   set *INDEX to the offset of the first byte and return true.  Otherwise,
   if no such member can be found, return false.  */

static bool
field_at_offset (tree type, HOST_WIDE_INT off, HOST_WIDE_INT *index)
{
  gcc_assert (RECORD_OR_UNION_TYPE_P (type));

  for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
    {
      if (TREE_CODE (fld) != FIELD_DECL || DECL_ARTIFICIAL (fld))
	continue;

      tree fldtype = TREE_TYPE (fld);
      HOST_WIDE_INT fldoff = int_byte_position (fld);

      /* If the size is not available the field is a flexible array
	 member.  Treat this case as success.  */
      tree typesize = TYPE_SIZE_UNIT (fldtype);
      HOST_WIDE_INT fldsize = (tree_fits_uhwi_p (typesize)
			       ? tree_to_uhwi (typesize)
			       : off);

      if (fldoff + fldsize < off)
	continue;

      if (TREE_CODE (fldtype) == ARRAY_TYPE)
	{
	  HOST_WIDE_INT idx = 0;
	  if (tree ft = array_elt_at_offset (fldtype, off, &idx))
	    fldtype = ft;
	  else
	    break;

	  *index += idx;
	  fldoff -= idx;
	  off -= idx;
	}

      if (RECORD_OR_UNION_TYPE_P (fldtype))
	{
	  *index += fldoff;
	  return field_at_offset (fldtype, off - fldoff, index);
	}

      *index += fldoff;
      return true;
    }

  return false;
}

/* For an expression X of pointer type, recursively try to find the same
   origin (object or pointer) as Y it references and return such an X.
   When X refers to a struct member, set *FLDOFF to the offset of the
   member from the beginning of the "most derived" object.  */

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

  switch (TREE_CODE (x))
    {
    case ADDR_EXPR:
      x = TREE_OPERAND (x, 0);
      return get_origin_and_offset (x, fldoff, 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 (x, fldoff, NULL);
      }

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

	  /* 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.  */
	  HOST_WIDE_INT index = 0;

	  if ((RECORD_OR_UNION_TYPE_P (xtype)
	       && field_at_offset (xtype, *off, &index))
	      || (TREE_CODE (xtype) == ARRAY_TYPE
		  && TREE_CODE (TREE_TYPE (xtype)) == ARRAY_TYPE
		  && array_elt_at_offset (xtype, *off, &index)))
	    {
	      *fldoff += index;
	      *off -= index;
	    }
	}

      return get_origin_and_offset (x, fldoff, NULL);

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

	get_origin_and_offset (fld, fldoff, off);
	x = TREE_OPERAND (x, 0);
	return get_origin_and_offset (x, fldoff, 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 (x, fldoff, off);
	      }

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

		x = gimple_assign_rhs1 (def);
		return get_origin_and_offset (x, fldoff, NULL);
	      }
	    else if (code == VAR_DECL)
	      {
		x = gimple_assign_rhs1 (def);
		return get_origin_and_offset (x, fldoff, off);
	      }
	  }
	else if (gimple_nop_p (def) && SSA_NAME_VAR (x))
	  x = SSA_NAME_VAR (x);
      }

    default:
      break;
    }

  return x;
}

/* 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.  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, 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);

  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;

  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, dir.info->dst_origin,
				     dir.info->dst_field);
    }

  /* 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, 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 (),
	       "%G%<%.*s%> directive argument is null",
	       info.callstmt, 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 if
   available, or the maximum possible size otherwise.  */

static unsigned HOST_WIDE_INT
get_destination_size (tree dest, 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, &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.  */
	  if (!update_call_from_tree (gsi, cst))
	    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, 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 (), "%Gnull destination pointer",
		      info.callstmt);
	  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 (), "%Gnull format string",
		  info.callstmt);
      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)
    gimple_set_no_warning (info.callstmt, true);

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