LCOV - code coverage report
Current view: top level - gcc - gimple-ssa-sprintf.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 1641 1753 93.6 %
Date: 2020-04-04 11:58:09 Functions: 45 47 95.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Copyright (C) 2016-2020 Free Software Foundation, Inc.
       2                 :            :    Contributed by Martin Sebor <msebor@redhat.com>.
       3                 :            : 
       4                 :            : This file is part of GCC.
       5                 :            : 
       6                 :            : GCC is free software; you can redistribute it and/or modify it under
       7                 :            : the terms of the GNU General Public License as published by the Free
       8                 :            : Software Foundation; either version 3, or (at your option) any later
       9                 :            : version.
      10                 :            : 
      11                 :            : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :            : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :            : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :            : for more details.
      15                 :            : 
      16                 :            : You should have received a copy of the GNU General Public License
      17                 :            : along with GCC; see the file COPYING3.  If not see
      18                 :            : <http://www.gnu.org/licenses/>.  */
      19                 :            : 
      20                 :            : /* This file implements the printf-return-value pass.  The pass does
      21                 :            :    two things: 1) it analyzes calls to formatted output functions like
      22                 :            :    sprintf looking for possible buffer overflows and calls to bounded
      23                 :            :    functions like snprintf for early truncation (and under the control
      24                 :            :    of the -Wformat-length option issues warnings), and 2) under the
      25                 :            :    control of the -fprintf-return-value option it folds the return
      26                 :            :    value of safe calls into constants, making it possible to eliminate
      27                 :            :    code that depends on the value of those constants.
      28                 :            : 
      29                 :            :    For all functions (bounded or not) the pass uses the size of the
      30                 :            :    destination object.  That means that it will diagnose calls to
      31                 :            :    snprintf not on the basis of the size specified by the function's
      32                 :            :    second argument but rathger on the basis of the size the first
      33                 :            :    argument points to (if possible).  For bound-checking built-ins
      34                 :            :    like __builtin___snprintf_chk the pass uses the size typically
      35                 :            :    determined by __builtin_object_size and passed to the built-in
      36                 :            :    by the Glibc inline wrapper.
      37                 :            : 
      38                 :            :    The pass handles all forms standard sprintf format directives,
      39                 :            :    including character, integer, floating point, pointer, and strings,
      40                 :            :    with the standard C flags, widths, and precisions.  For integers
      41                 :            :    and strings it computes the length of output itself.  For floating
      42                 :            :    point it uses MPFR to fornmat known constants with up and down
      43                 :            :    rounding and uses the resulting range of output lengths.  For
      44                 :            :    strings it uses the length of string literals and the sizes of
      45                 :            :    character arrays that a character pointer may point to as a bound
      46                 :            :    on the longest string.  */
      47                 :            : 
      48                 :            : #include "config.h"
      49                 :            : #include "system.h"
      50                 :            : #include "coretypes.h"
      51                 :            : #include "backend.h"
      52                 :            : #include "tree.h"
      53                 :            : #include "gimple.h"
      54                 :            : #include "tree-pass.h"
      55                 :            : #include "ssa.h"
      56                 :            : #include "gimple-fold.h"
      57                 :            : #include "gimple-pretty-print.h"
      58                 :            : #include "diagnostic-core.h"
      59                 :            : #include "fold-const.h"
      60                 :            : #include "gimple-iterator.h"
      61                 :            : #include "tree-ssa.h"
      62                 :            : #include "tree-object-size.h"
      63                 :            : #include "tree-cfg.h"
      64                 :            : #include "tree-ssa-propagate.h"
      65                 :            : #include "calls.h"
      66                 :            : #include "cfgloop.h"
      67                 :            : #include "tree-scalar-evolution.h"
      68                 :            : #include "tree-ssa-loop.h"
      69                 :            : #include "intl.h"
      70                 :            : #include "langhooks.h"
      71                 :            : 
      72                 :            : #include "attribs.h"
      73                 :            : #include "builtins.h"
      74                 :            : #include "stor-layout.h"
      75                 :            : 
      76                 :            : #include "realmpfr.h"
      77                 :            : #include "target.h"
      78                 :            : 
      79                 :            : #include "cpplib.h"
      80                 :            : #include "input.h"
      81                 :            : #include "toplev.h"
      82                 :            : #include "substring-locations.h"
      83                 :            : #include "diagnostic.h"
      84                 :            : #include "domwalk.h"
      85                 :            : #include "alloc-pool.h"
      86                 :            : #include "vr-values.h"
      87                 :            : #include "tree-ssa-strlen.h"
      88                 :            : #include "tree-dfa.h"
      89                 :            : 
      90                 :            : /* The likely worst case value of MB_LEN_MAX for the target, large enough
      91                 :            :    for UTF-8.  Ideally, this would be obtained by a target hook if it were
      92                 :            :    to be used for optimization but it's good enough as is for warnings.  */
      93                 :            : #define target_mb_len_max()   6
      94                 :            : 
      95                 :            : /* The maximum number of bytes a single non-string directive can result
      96                 :            :    in.  This is the result of printf("%.*Lf", INT_MAX, -LDBL_MAX) for
      97                 :            :    LDBL_MAX_10_EXP of 4932.  */
      98                 :            : #define IEEE_MAX_10_EXP    4932
      99                 :            : #define target_dir_max()   (target_int_max () + IEEE_MAX_10_EXP + 2)
     100                 :            : 
     101                 :            : namespace {
     102                 :            : 
     103                 :            : /* Set to the warning level for the current function which is equal
     104                 :            :    either to warn_format_trunc for bounded functions or to
     105                 :            :    warn_format_overflow otherwise.  */
     106                 :            : 
     107                 :            : static int warn_level;
     108                 :            : 
     109                 :            : /* The minimum, maximum, likely, and unlikely maximum number of bytes
     110                 :            :    of output either a formatting function or an individual directive
     111                 :            :    can result in.  */
     112                 :            : 
     113                 :            : struct result_range
     114                 :            : {
     115                 :            :   /* The absolute minimum number of bytes.  The result of a successful
     116                 :            :      conversion is guaranteed to be no less than this.  (An erroneous
     117                 :            :      conversion can be indicated by MIN > HOST_WIDE_INT_MAX.)  */
     118                 :            :   unsigned HOST_WIDE_INT min;
     119                 :            :   /* The likely maximum result that is used in diagnostics.  In most
     120                 :            :      cases MAX is the same as the worst case UNLIKELY result.  */
     121                 :            :   unsigned HOST_WIDE_INT max;
     122                 :            :   /* The likely result used to trigger diagnostics.  For conversions
     123                 :            :      that result in a range of bytes [MIN, MAX], LIKELY is somewhere
     124                 :            :      in that range.  */
     125                 :            :   unsigned HOST_WIDE_INT likely;
     126                 :            :   /* In rare cases (e.g., for nultibyte characters) UNLIKELY gives
     127                 :            :      the worst cases maximum result of a directive.  In most cases
     128                 :            :      UNLIKELY == MAX.  UNLIKELY is used to control the return value
     129                 :            :      optimization but not in diagnostics.  */
     130                 :            :   unsigned HOST_WIDE_INT unlikely;
     131                 :            : };
     132                 :            : 
     133                 :            : /* Return the value of INT_MIN for the target.  */
     134                 :            : 
     135                 :            : static inline HOST_WIDE_INT
     136                 :     521338 : target_int_min ()
     137                 :            : {
     138                 :     521338 :   return tree_to_shwi (TYPE_MIN_VALUE (integer_type_node));
     139                 :            : }
     140                 :            : 
     141                 :            : /* Return the value of INT_MAX for the target.  */
     142                 :            : 
     143                 :            : static inline unsigned HOST_WIDE_INT
     144                 :    1384530 : target_int_max ()
     145                 :            : {
     146                 :    1384530 :   return tree_to_uhwi (TYPE_MAX_VALUE (integer_type_node));
     147                 :            : }
     148                 :            : 
     149                 :            : /* Return the value of SIZE_MAX for the target.  */
     150                 :            : 
     151                 :            : static inline unsigned HOST_WIDE_INT
     152                 :     136400 : target_size_max ()
     153                 :            : {
     154                 :     136400 :   return tree_to_uhwi (TYPE_MAX_VALUE (size_type_node));
     155                 :            : }
     156                 :            : 
     157                 :            : /* A straightforward mapping from the execution character set to the host
     158                 :            :    character set indexed by execution character.  */
     159                 :            : 
     160                 :            : static char target_to_host_charmap[256];
     161                 :            : 
     162                 :            : /* Initialize a mapping from the execution character set to the host
     163                 :            :    character set.  */
     164                 :            : 
     165                 :            : static bool
     166                 :    3474700 : init_target_to_host_charmap ()
     167                 :            : {
     168                 :            :   /* If the percent sign is non-zero the mapping has already been
     169                 :            :      initialized.  */
     170                 :    3474700 :   if (target_to_host_charmap['%'])
     171                 :            :     return true;
     172                 :            : 
     173                 :            :   /* Initialize the target_percent character (done elsewhere).  */
     174                 :      84722 :   if (!init_target_chars ())
     175                 :            :     return false;
     176                 :            : 
     177                 :            :   /* The subset of the source character set used by printf conversion
     178                 :            :      specifications (strictly speaking, not all letters are used but
     179                 :            :      they are included here for the sake of simplicity).  The dollar
     180                 :            :      sign must be included even though it's not in the basic source
     181                 :            :      character set.  */
     182                 :      84722 :   const char srcset[] = " 0123456789!\"#%&'()*+,-./:;<=>?[\\]^_{|}~$"
     183                 :            :     "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
     184                 :            : 
     185                 :            :   /* Set the mapping for all characters to some ordinary value (i,e.,
     186                 :            :      not none used in printf conversion specifications) and overwrite
     187                 :            :      those that are used by conversion specifications with their
     188                 :            :      corresponding values.  */
     189                 :      84722 :   memset (target_to_host_charmap + 1, '?', sizeof target_to_host_charmap - 1);
     190                 :            : 
     191                 :            :   /* Are the two sets of characters the same?  */
     192                 :      84722 :   bool all_same_p = true;
     193                 :            : 
     194                 :    7963870 :   for (const char *pc = srcset; *pc; ++pc)
     195                 :            :     {
     196                 :            :       /* Slice off the high end bits in case target characters are
     197                 :            :          signed.  All values are expected to be non-nul, otherwise
     198                 :            :          there's a problem.  */
     199                 :    7879150 :       if (unsigned char tc = lang_hooks.to_target_charset (*pc))
     200                 :            :         {
     201                 :    7879150 :           target_to_host_charmap[tc] = *pc;
     202                 :    7879150 :           if (tc != *pc)
     203                 :        372 :             all_same_p = false;
     204                 :            :         }
     205                 :            :       else
     206                 :            :         return false;
     207                 :            : 
     208                 :            :     }
     209                 :            : 
     210                 :            :   /* Set the first element to a non-zero value if the mapping
     211                 :            :      is 1-to-1, otherwise leave it clear (NUL is assumed to be
     212                 :            :      the same in both character sets).  */
     213                 :      84722 :   target_to_host_charmap[0] = all_same_p;
     214                 :            : 
     215                 :      84722 :   return true;
     216                 :            : }
     217                 :            : 
     218                 :            : /* Return the host source character corresponding to the character
     219                 :            :    CH in the execution character set if one exists, or some innocuous
     220                 :            :    (non-special, non-nul) source character otherwise.  */
     221                 :            : 
     222                 :            : static inline unsigned char
     223                 :    2614880 : target_to_host (unsigned char ch)
     224                 :            : {
     225                 :    2614880 :   return target_to_host_charmap[ch];
     226                 :            : }
     227                 :            : 
     228                 :            : /* Convert an initial substring of the string TARGSTR consisting of
     229                 :            :    characters in the execution character set into a string in the
     230                 :            :    source character set on the host and store up to HOSTSZ characters
     231                 :            :    in the buffer pointed to by HOSTR.  Return HOSTR.  */
     232                 :            : 
     233                 :            : static const char*
     234                 :       5198 : target_to_host (char *hostr, size_t hostsz, const char *targstr)
     235                 :            : {
     236                 :            :   /* Make sure the buffer is reasonably big.  */
     237                 :       5198 :   gcc_assert (hostsz > 4);
     238                 :            : 
     239                 :            :   /* The interesting subset of source and execution characters are
     240                 :            :      the same so no conversion is necessary.  However, truncate
     241                 :            :      overlong strings just like the translated strings are.  */
     242                 :       5198 :   if (target_to_host_charmap['\0'] == 1)
     243                 :            :     {
     244                 :       5135 :       size_t len = strlen (targstr);
     245                 :       5135 :       if (len >= hostsz)
     246                 :            :         {
     247                 :        323 :           memcpy (hostr, targstr, hostsz - 4);
     248                 :        323 :           strcpy (hostr + hostsz - 4, "...");
     249                 :            :         }
     250                 :            :       else
     251                 :       4812 :         memcpy (hostr, targstr, len + 1);
     252                 :       5135 :       return hostr;
     253                 :            :     }
     254                 :            : 
     255                 :            :   /* Convert the initial substring of TARGSTR to the corresponding
     256                 :            :      characters in the host set, appending "..." if TARGSTR is too
     257                 :            :      long to fit.  Using the static buffer assumes the function is
     258                 :            :      not called in between sequence points (which it isn't).  */
     259                 :        330 :   for (char *ph = hostr; ; ++targstr)
     260                 :            :     {
     261                 :        393 :       *ph++ = target_to_host (*targstr);
     262                 :        393 :       if (!*targstr)
     263                 :            :         break;
     264                 :            : 
     265                 :        331 :       if (size_t (ph - hostr) == hostsz)
     266                 :            :         {
     267                 :          1 :           strcpy (ph - 4, "...");
     268                 :          1 :           break;
     269                 :            :         }
     270                 :            :     }
     271                 :            : 
     272                 :            :   return hostr;
     273                 :            : }
     274                 :            : 
     275                 :            : /* Convert the sequence of decimal digits in the execution character
     276                 :            :    starting at *PS to a HOST_WIDE_INT, analogously to strtol.  Return
     277                 :            :    the result and set *PS to one past the last converted character.
     278                 :            :    On range error set ERANGE to the digit that caused it.  */
     279                 :            : 
     280                 :            : static inline HOST_WIDE_INT
     281                 :       2610 : target_strtowi (const char **ps, const char **erange)
     282                 :            : {
     283                 :       2610 :   unsigned HOST_WIDE_INT val = 0;
     284                 :      10684 :   for ( ; ; ++*ps)
     285                 :            :     {
     286                 :       6647 :       unsigned char c = target_to_host (**ps);
     287                 :       6647 :       if (ISDIGIT (c))
     288                 :            :         {
     289                 :       4039 :           c -= '0';
     290                 :            : 
     291                 :            :           /* Check for overflow.  */
     292                 :       4039 :           if (val > ((unsigned HOST_WIDE_INT) HOST_WIDE_INT_MAX - c) / 10LU)
     293                 :            :             {
     294                 :          2 :               val = HOST_WIDE_INT_MAX;
     295                 :          2 :               *erange = *ps;
     296                 :            : 
     297                 :            :               /* Skip the remaining digits.  */
     298                 :          2 :               do
     299                 :          2 :                 c = target_to_host (*++*ps);
     300                 :          2 :               while (ISDIGIT (c));
     301                 :            :               break;
     302                 :            :             }
     303                 :            :           else
     304                 :       4037 :             val = val * 10 + c;
     305                 :            :         }
     306                 :            :       else
     307                 :            :         break;
     308                 :       4037 :     }
     309                 :            : 
     310                 :       2610 :   return val;
     311                 :            : }
     312                 :            : 
     313                 :            : /* Given FORMAT, set *PLOC to the source location of the format string
     314                 :            :    and return the format string if it is known or null otherwise.  */
     315                 :            : 
     316                 :            : static const char*
     317                 :      78393 : get_format_string (tree format, location_t *ploc)
     318                 :            : {
     319                 :      78393 :   *ploc = EXPR_LOC_OR_LOC (format, input_location);
     320                 :            : 
     321                 :      78393 :   return c_getstr (format);
     322                 :            : }
     323                 :            : 
     324                 :            : /* For convenience and brevity, shorter named entrypoints of
     325                 :            :    format_string_diagnostic_t::emit_warning_va and
     326                 :            :    format_string_diagnostic_t::emit_warning_n_va.
     327                 :            :    These have to be functions with the attribute so that exgettext
     328                 :            :    works properly.  */
     329                 :            : 
     330                 :            : static bool
     331                 :            : ATTRIBUTE_GCC_DIAG (5, 6)
     332                 :       5711 : fmtwarn (const substring_loc &fmt_loc, location_t param_loc,
     333                 :            :          const char *corrected_substring, int opt, const char *gmsgid, ...)
     334                 :            : {
     335                 :       5711 :   format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
     336                 :       5711 :                                    corrected_substring);
     337                 :       5711 :   va_list ap;
     338                 :       5711 :   va_start (ap, gmsgid);
     339                 :       5711 :   bool warned = diag.emit_warning_va (opt, gmsgid, &ap);
     340                 :       5711 :   va_end (ap);
     341                 :            : 
     342                 :       5711 :   return warned;
     343                 :            : }
     344                 :            : 
     345                 :            : static bool
     346                 :            : ATTRIBUTE_GCC_DIAG (6, 8) ATTRIBUTE_GCC_DIAG (7, 8)
     347                 :        539 : fmtwarn_n (const substring_loc &fmt_loc, location_t param_loc,
     348                 :            :            const char *corrected_substring, int opt, unsigned HOST_WIDE_INT n,
     349                 :            :            const char *singular_gmsgid, const char *plural_gmsgid, ...)
     350                 :            : {
     351                 :        539 :   format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
     352                 :        539 :                                    corrected_substring);
     353                 :        539 :   va_list ap;
     354                 :        539 :   va_start (ap, plural_gmsgid);
     355                 :        539 :   bool warned = diag.emit_warning_n_va (opt, n, singular_gmsgid, plural_gmsgid,
     356                 :            :                                         &ap);
     357                 :        539 :   va_end (ap);
     358                 :            : 
     359                 :        539 :   return warned;
     360                 :            : }
     361                 :            : 
     362                 :            : /* Format length modifiers.  */
     363                 :            : 
     364                 :            : enum format_lengths
     365                 :            : {
     366                 :            :   FMT_LEN_none,
     367                 :            :   FMT_LEN_hh,    // char argument
     368                 :            :   FMT_LEN_h,     // short
     369                 :            :   FMT_LEN_l,     // long
     370                 :            :   FMT_LEN_ll,    // long long
     371                 :            :   FMT_LEN_L,     // long double (and GNU long long)
     372                 :            :   FMT_LEN_z,     // size_t
     373                 :            :   FMT_LEN_t,     // ptrdiff_t
     374                 :            :   FMT_LEN_j      // intmax_t
     375                 :            : };
     376                 :            : 
     377                 :            : 
     378                 :            : /* Description of the result of conversion either of a single directive
     379                 :            :    or the whole format string.  */
     380                 :            : 
     381                 :            : class fmtresult
     382                 :            : {
     383                 :            : public:
     384                 :            :   /* Construct a FMTRESULT object with all counters initialized
     385                 :            :      to MIN.  KNOWNRANGE is set when MIN is valid.  */
     386                 :     656574 :   fmtresult (unsigned HOST_WIDE_INT min = HOST_WIDE_INT_MAX)
     387                 :     650593 :   : argmin (), argmax (), dst_offset (HOST_WIDE_INT_MIN), nonstr (),
     388                 :     314075 :     knownrange (min < HOST_WIDE_INT_MAX),
     389                 :     656574 :     mayfail (), nullp ()
     390                 :            :   {
     391                 :     656574 :     range.min = min;
     392                 :     656574 :     range.max = min;
     393                 :     656574 :     range.likely = min;
     394                 :     656574 :     range.unlikely = min;
     395                 :        697 :   }
     396                 :            : 
     397                 :            :   /* Construct a FMTRESULT object with MIN, MAX, and LIKELY counters.
     398                 :            :      KNOWNRANGE is set when both MIN and MAX are valid.   */
     399                 :     132229 :   fmtresult (unsigned HOST_WIDE_INT min, unsigned HOST_WIDE_INT max,
     400                 :            :              unsigned HOST_WIDE_INT likely = HOST_WIDE_INT_MAX)
     401                 :            :   : argmin (), argmax (), dst_offset (HOST_WIDE_INT_MIN), nonstr (),
     402                 :     132229 :     knownrange (min < HOST_WIDE_INT_MAX && max < HOST_WIDE_INT_MAX),
     403                 :     132229 :     mayfail (), nullp ()
     404                 :            :   {
     405                 :     132229 :     range.min = min;
     406                 :     132229 :     range.max = max;
     407                 :     132229 :     range.likely = max < likely ? min : likely;
     408                 :     132229 :     range.unlikely = max;
     409                 :            :   }
     410                 :            : 
     411                 :            :   /* Adjust result upward to reflect the RANGE of values the specified
     412                 :            :      width or precision is known to be in.  */
     413                 :            :   fmtresult& adjust_for_width_or_precision (const HOST_WIDE_INT[2],
     414                 :            :                                             tree = NULL_TREE,
     415                 :            :                                             unsigned = 0, unsigned = 0);
     416                 :            : 
     417                 :            :   /* Return the maximum number of decimal digits a value of TYPE
     418                 :            :      formats as on output.  */
     419                 :            :   static unsigned type_max_digits (tree, int);
     420                 :            : 
     421                 :            :   /* The range a directive's argument is in.  */
     422                 :            :   tree argmin, argmax;
     423                 :            : 
     424                 :            :   /* The starting offset into the destination of the formatted function
     425                 :            :      call of the %s argument that points into (aliases with) the same
     426                 :            :      destination array.  */
     427                 :            :   HOST_WIDE_INT dst_offset;
     428                 :            : 
     429                 :            :   /* The minimum and maximum number of bytes that a directive
     430                 :            :      results in on output for an argument in the range above.  */
     431                 :            :   result_range range;
     432                 :            : 
     433                 :            :   /* Non-nul when the argument of a string directive is not a nul
     434                 :            :      terminated string.  */
     435                 :            :   tree nonstr;
     436                 :            : 
     437                 :            :   /* True when the range above is obtained from a known value of
     438                 :            :      a directive's argument or its bounds and not the result of
     439                 :            :      heuristics that depend on warning levels.  */
     440                 :            :   bool knownrange;
     441                 :            : 
     442                 :            :   /* True for a directive that may fail (such as wide character
     443                 :            :      directives).  */
     444                 :            :   bool mayfail;
     445                 :            : 
     446                 :            :   /* True when the argument is a null pointer.  */
     447                 :            :   bool nullp;
     448                 :            : };
     449                 :            : 
     450                 :            : /* Adjust result upward to reflect the range ADJUST of values the
     451                 :            :    specified width or precision is known to be in.  When non-null,
     452                 :            :    TYPE denotes the type of the directive whose result is being
     453                 :            :    adjusted, BASE gives the base of the directive (octal, decimal,
     454                 :            :    or hex), and ADJ denotes the additional adjustment to the LIKELY
     455                 :            :    counter that may need to be added when ADJUST is a range.  */
     456                 :            : 
     457                 :            : fmtresult&
     458                 :     525478 : fmtresult::adjust_for_width_or_precision (const HOST_WIDE_INT adjust[2],
     459                 :            :                                           tree type /* = NULL_TREE */,
     460                 :            :                                           unsigned base /* = 0 */,
     461                 :            :                                           unsigned adj /* = 0 */)
     462                 :            : {
     463                 :     525478 :   bool minadjusted = false;
     464                 :            : 
     465                 :            :   /* Adjust the minimum and likely counters.  */
     466                 :     525478 :   if (adjust[0] >= 0)
     467                 :            :     {
     468                 :       4140 :       if (range.min < (unsigned HOST_WIDE_INT)adjust[0])
     469                 :            :         {
     470                 :       1337 :           range.min = adjust[0];
     471                 :       1337 :           minadjusted = true;
     472                 :            :         }
     473                 :            : 
     474                 :            :       /* Adjust the likely counter.  */
     475                 :       4140 :       if (range.likely < range.min)
     476                 :       1180 :         range.likely = range.min;
     477                 :            :     }
     478                 :     521338 :   else if (adjust[0] == target_int_min ()
     479                 :     521338 :            && (unsigned HOST_WIDE_INT)adjust[1] == target_int_max ())
     480                 :          0 :     knownrange = false;
     481                 :            : 
     482                 :            :   /* Adjust the maximum counter.  */
     483                 :     525478 :   if (adjust[1] > 0)
     484                 :            :     {
     485                 :       4203 :       if (range.max < (unsigned HOST_WIDE_INT)adjust[1])
     486                 :            :         {
     487                 :       1462 :           range.max = adjust[1];
     488                 :            : 
     489                 :            :           /* Set KNOWNRANGE if both the minimum and maximum have been
     490                 :            :              adjusted.  Otherwise leave it at what it was before.  */
     491                 :       1462 :           knownrange = minadjusted;
     492                 :            :         }
     493                 :            :     }
     494                 :            : 
     495                 :     525478 :   if (warn_level > 1 && type)
     496                 :            :     {
     497                 :            :       /* For large non-constant width or precision whose range spans
     498                 :            :          the maximum number of digits produced by the directive for
     499                 :            :          any argument, set the likely number of bytes to be at most
     500                 :            :          the number digits plus other adjustment determined by the
     501                 :            :          caller (one for sign or two for the hexadecimal "0x"
     502                 :            :          prefix).  */
     503                 :        894 :       unsigned dirdigs = type_max_digits (type, base);
     504                 :        894 :       if (adjust[0] < dirdigs && dirdigs < adjust[1]
     505                 :         28 :           && range.likely < dirdigs)
     506                 :         16 :         range.likely = dirdigs + adj;
     507                 :            :     }
     508                 :     524584 :   else if (range.likely < (range.min ? range.min : 1))
     509                 :            :     {
     510                 :            :       /* Conservatively, set LIKELY to at least MIN but no less than
     511                 :            :          1 unless MAX is zero.  */
     512                 :       6801 :       range.likely = (range.min
     513                 :       6801 :                       ? range.min
     514                 :       6319 :                       : range.max && (range.max < HOST_WIDE_INT_MAX
     515                 :      12916 :                                       || warn_level > 1) ? 1 : 0);
     516                 :            :     }
     517                 :            : 
     518                 :            :   /* Finally adjust the unlikely counter to be at least as large as
     519                 :            :      the maximum.  */
     520                 :     525478 :   if (range.unlikely < range.max)
     521                 :       1565 :     range.unlikely = range.max;
     522                 :            : 
     523                 :     525478 :   return *this;
     524                 :            : }
     525                 :            : 
     526                 :            : /* Return the maximum number of digits a value of TYPE formats in
     527                 :            :    BASE on output, not counting base prefix .  */
     528                 :            : 
     529                 :            : unsigned
     530                 :        894 : fmtresult::type_max_digits (tree type, int base)
     531                 :            : {
     532                 :        894 :   unsigned prec = TYPE_PRECISION (type);
     533                 :        894 :   switch (base)
     534                 :            :     {
     535                 :          0 :     case 8:
     536                 :          0 :       return (prec + 2) / 3;
     537                 :        894 :     case 10:
     538                 :            :       /* Decimal approximation: yields 3, 5, 10, and 20 for precision
     539                 :            :          of 8, 16, 32, and 64 bits.  */
     540                 :        894 :       return prec * 301 / 1000 + 1;
     541                 :          0 :     case 16:
     542                 :          0 :       return prec / 4;
     543                 :            :     }
     544                 :            : 
     545                 :          0 :   gcc_unreachable ();
     546                 :            : }
     547                 :            : 
     548                 :            : static bool
     549                 :            : get_int_range (tree, HOST_WIDE_INT *, HOST_WIDE_INT *, bool, HOST_WIDE_INT,
     550                 :            :                const vr_values *);
     551                 :            : 
     552                 :            : struct call_info;
     553                 :            : 
     554                 :            : /* Description of a format directive.  A directive is either a plain
     555                 :            :    string or a conversion specification that starts with '%'.  */
     556                 :            : 
     557                 :            : struct directive
     558                 :            : {
     559                 :     549584 :   directive (const call_info *inf, unsigned dno)
     560                 :     549584 :     : info (inf), dirno (dno), argno (), beg (), len (), flags (),
     561                 :   37921300 :     width (), prec (),  modifier (), specifier (), arg (), fmtfunc ()
     562                 :     549584 :   { }
     563                 :            : 
     564                 :            :   /* Reference to the info structure describing the call that this
     565                 :            :      directive is a part of.  */
     566                 :            :   const call_info *info;
     567                 :            : 
     568                 :            :   /* The 1-based directive number (for debugging).  */
     569                 :            :   unsigned dirno;
     570                 :            : 
     571                 :            :   /* The zero-based argument number of the directive's argument ARG in
     572                 :            :      the function's argument list.  */
     573                 :            :   unsigned argno;
     574                 :            : 
     575                 :            :   /* The first character of the directive and its length.  */
     576                 :            :   const char *beg;
     577                 :            :   size_t len;
     578                 :            : 
     579                 :            :   /* A bitmap of flags, one for each character.  */
     580                 :            :   unsigned flags[256 / sizeof (int)];
     581                 :            : 
     582                 :            :   /* The range of values of the specified width, or -1 if not specified.  */
     583                 :            :   HOST_WIDE_INT width[2];
     584                 :            :   /* The range of values of the specified precision, or -1 if not
     585                 :            :      specified.  */
     586                 :            :   HOST_WIDE_INT prec[2];
     587                 :            : 
     588                 :            :   /* Length modifier.  */
     589                 :            :   format_lengths modifier;
     590                 :            : 
     591                 :            :   /* Format specifier character.  */
     592                 :            :   char specifier;
     593                 :            : 
     594                 :            :   /* The argument of the directive or null when the directive doesn't
     595                 :            :      take one or when none is available (such as for vararg functions).  */
     596                 :            :   tree arg;
     597                 :            : 
     598                 :            :   /* Format conversion function that given a directive and an argument
     599                 :            :      returns the formatting result.  */
     600                 :            :   fmtresult (*fmtfunc) (const directive &, tree, const vr_values *);
     601                 :            : 
     602                 :            :   /* Return True when a the format flag CHR has been used.  */
     603                 :     373079 :   bool get_flag (char chr) const
     604                 :            :   {
     605                 :     373079 :     unsigned char c = chr & 0xff;
     606                 :     373079 :     return (flags[c / (CHAR_BIT * sizeof *flags)]
     607                 :     373079 :             & (1U << (c % (CHAR_BIT * sizeof *flags))));
     608                 :            :   }
     609                 :            : 
     610                 :            :   /* Make a record of the format flag CHR having been used.  */
     611                 :       1787 :   void set_flag (char chr)
     612                 :            :   {
     613                 :       1787 :     unsigned char c = chr & 0xff;
     614                 :       1787 :     flags[c / (CHAR_BIT * sizeof *flags)]
     615                 :       1787 :       |= (1U << (c % (CHAR_BIT * sizeof *flags)));
     616                 :       1787 :   }
     617                 :            : 
     618                 :            :   /* Reset the format flag CHR.  */
     619                 :            :   void clear_flag (char chr)
     620                 :            :   {
     621                 :            :     unsigned char c = chr & 0xff;
     622                 :            :     flags[c / (CHAR_BIT * sizeof *flags)]
     623                 :            :       &= ~(1U << (c % (CHAR_BIT * sizeof *flags)));
     624                 :            :   }
     625                 :            : 
     626                 :            :   /* Set both bounds of the width range to VAL.  */
     627                 :     233588 :   void set_width (HOST_WIDE_INT val)
     628                 :            :   {
     629                 :     233588 :     width[0] = width[1] = val;
     630                 :     233588 :   }
     631                 :            : 
     632                 :            :   /* Set the width range according to ARG, with both bounds being
     633                 :            :      no less than 0.  For a constant ARG set both bounds to its value
     634                 :            :      or 0, whichever is greater.  For a non-constant ARG in some range
     635                 :            :      set width to its range adjusting each bound to -1 if it's less.
     636                 :            :      For an indeterminate ARG set width to [0, INT_MAX].  */
     637                 :        772 :   void set_width (tree arg, const vr_values *vr)
     638                 :            :   {
     639                 :        772 :     get_int_range (arg, width, width + 1, true, 0, vr);
     640                 :        772 :   }
     641                 :            : 
     642                 :            :   /* Set both bounds of the precision range to VAL.  */
     643                 :     233547 :   void set_precision (HOST_WIDE_INT val)
     644                 :            :   {
     645                 :     233547 :     prec[0] = prec[1] = val;
     646                 :     233547 :   }
     647                 :            : 
     648                 :            :   /* Set the precision range according to ARG, with both bounds being
     649                 :            :      no less than -1.  For a constant ARG set both bounds to its value
     650                 :            :      or -1 whichever is greater.  For a non-constant ARG in some range
     651                 :            :      set precision to its range adjusting each bound to -1 if it's less.
     652                 :            :      For an indeterminate ARG set precision to [-1, INT_MAX].  */
     653                 :        804 :   void set_precision (tree arg, const vr_values *vr)
     654                 :            :   {
     655                 :        804 :     get_int_range (arg, prec, prec + 1, false, -1, vr);
     656                 :        804 :   }
     657                 :            : 
     658                 :            :   /* Return true if both width and precision are known to be
     659                 :            :      either constant or in some range, false otherwise.  */
     660                 :            :   bool known_width_and_precision () const
     661                 :            :   {
     662                 :            :     return ((width[1] < 0
     663                 :            :              || (unsigned HOST_WIDE_INT)width[1] <= target_int_max ())
     664                 :            :             && (prec[1] < 0
     665                 :            :                 || (unsigned HOST_WIDE_INT)prec[1] < target_int_max ()));
     666                 :            :   }
     667                 :            : };
     668                 :            : 
     669                 :            : /* The result of a call to a formatted function.  */
     670                 :            : 
     671                 :            : struct format_result
     672                 :            : {
     673                 :      76154 :   format_result ()
     674                 :      76154 :     : range (), aliases (), alias_count (), knownrange (), posunder4k (),
     675                 :      76154 :     floating (), warned () { /* No-op.  */ }
     676                 :            : 
     677                 :      76154 :   ~format_result ()
     678                 :            :   {
     679                 :      76154 :     XDELETEVEC (aliases);
     680                 :      76154 :   }
     681                 :            : 
     682                 :            :   /* Range of characters written by the formatted function.
     683                 :            :      Setting the minimum to HOST_WIDE_INT_MAX disables all
     684                 :            :      length tracking for the remainder of the format string.  */
     685                 :            :   result_range range;
     686                 :            : 
     687                 :            :   struct alias_info
     688                 :            :   {
     689                 :            :     directive dir;          /* The directive that aliases the destination.  */
     690                 :            :     HOST_WIDE_INT offset;   /* The offset at which it aliases it.  */
     691                 :            :     result_range range;     /* The raw result of the directive.  */
     692                 :            :   };
     693                 :            : 
     694                 :            :   /* An array of directives whose pointer argument aliases a part
     695                 :            :      of the destination object of the formatted function.  */
     696                 :            :   alias_info *aliases;
     697                 :            :   unsigned alias_count;
     698                 :            : 
     699                 :            :   /* True when the range above is obtained from known values of
     700                 :            :      directive arguments, or bounds on the amount of output such
     701                 :            :      as width and precision, and not the result of  heuristics that
     702                 :            :      depend on warning levels.  It's used to issue stricter diagnostics
     703                 :            :      in cases where strings of unknown lengths are bounded by the arrays
     704                 :            :      they are determined to refer to.  KNOWNRANGE must not be used for
     705                 :            :      the return value optimization.  */
     706                 :            :   bool knownrange;
     707                 :            : 
     708                 :            :   /* True if no individual directive could fail or result in more than
     709                 :            :      4095 bytes of output (the total NUMBER_CHARS_{MIN,MAX} might be
     710                 :            :      greater).  Implementations are not required to handle directives
     711                 :            :      that produce more than 4K bytes (leading to undefined behavior)
     712                 :            :      and so when one is found it disables the return value optimization.
     713                 :            :      Similarly, directives that can fail (such as wide character
     714                 :            :      directives) disable the optimization.  */
     715                 :            :   bool posunder4k;
     716                 :            : 
     717                 :            :   /* True when a floating point directive has been seen in the format
     718                 :            :      string.  */
     719                 :            :   bool floating;
     720                 :            : 
     721                 :            :   /* True when an intermediate result has caused a warning.  Used to
     722                 :            :      avoid issuing duplicate warnings while finishing the processing
     723                 :            :      of a call.  WARNED also disables the return value optimization.  */
     724                 :            :   bool warned;
     725                 :            : 
     726                 :            :   /* Preincrement the number of output characters by 1.  */
     727                 :            :   format_result& operator++ ()
     728                 :            :   {
     729                 :            :     return *this += 1;
     730                 :            :   }
     731                 :            : 
     732                 :            :   /* Postincrement the number of output characters by 1.  */
     733                 :            :   format_result operator++ (int)
     734                 :            :   {
     735                 :            :     format_result prev (*this);
     736                 :            :     *this += 1;
     737                 :            :     return prev;
     738                 :            :   }
     739                 :            : 
     740                 :            :   /* Increment the number of output characters by N.  */
     741                 :            :   format_result& operator+= (unsigned HOST_WIDE_INT);
     742                 :            : 
     743                 :            :   /* Add a directive to the sequence of those with potentially aliasing
     744                 :            :      arguments.  */
     745                 :            :   void append_alias (const directive &, HOST_WIDE_INT, const result_range &);
     746                 :            : 
     747                 :            : private:
     748                 :            :   /* Not copyable or assignable.  */
     749                 :            :   format_result (format_result&);
     750                 :            :   void operator= (format_result&);
     751                 :            : };
     752                 :            : 
     753                 :            : format_result&
     754                 :          0 : format_result::operator+= (unsigned HOST_WIDE_INT n)
     755                 :            : {
     756                 :          0 :   gcc_assert (n < HOST_WIDE_INT_MAX);
     757                 :            : 
     758                 :          0 :   if (range.min < HOST_WIDE_INT_MAX)
     759                 :          0 :     range.min += n;
     760                 :            : 
     761                 :          0 :   if (range.max < HOST_WIDE_INT_MAX)
     762                 :          0 :     range.max += n;
     763                 :            : 
     764                 :          0 :   if (range.likely < HOST_WIDE_INT_MAX)
     765                 :          0 :     range.likely += n;
     766                 :            : 
     767                 :          0 :   if (range.unlikely < HOST_WIDE_INT_MAX)
     768                 :          0 :     range.unlikely += n;
     769                 :            : 
     770                 :          0 :   return *this;
     771                 :            : }
     772                 :            : 
     773                 :            : void
     774                 :        212 : format_result::append_alias (const directive &d, HOST_WIDE_INT off,
     775                 :            :                              const result_range &resrng)
     776                 :            : {
     777                 :        212 :   unsigned cnt = alias_count + 1;
     778                 :        212 :   alias_info *ar = XNEWVEC (alias_info, cnt);
     779                 :            : 
     780                 :        216 :   for (unsigned i = 0; i != alias_count; ++i)
     781                 :          4 :     ar[i] = aliases[i];
     782                 :            : 
     783                 :        212 :   ar[alias_count].dir = d;
     784                 :        212 :   ar[alias_count].offset = off;
     785                 :        212 :   ar[alias_count].range = resrng;
     786                 :            : 
     787                 :        212 :   XDELETEVEC (aliases);
     788                 :            : 
     789                 :        212 :   alias_count = cnt;
     790                 :        212 :   aliases = ar;
     791                 :        212 : }
     792                 :            : 
     793                 :            : /* Return the logarithm of X in BASE.  */
     794                 :            : 
     795                 :            : static int
     796                 :     152115 : ilog (unsigned HOST_WIDE_INT x, int base)
     797                 :            : {
     798                 :          0 :   int res = 0;
     799                 :     755968 :   do
     800                 :            :     {
     801                 :     755968 :       ++res;
     802                 :     755968 :       x /= base;
     803                 :     755968 :     } while (x);
     804                 :     152115 :   return res;
     805                 :            : }
     806                 :            : 
     807                 :            : /* Return the number of bytes resulting from converting into a string
     808                 :            :    the INTEGER_CST tree node X in BASE with a minimum of PREC digits.
     809                 :            :    PLUS indicates whether 1 for a plus sign should be added for positive
     810                 :            :    numbers, and PREFIX whether the length of an octal ('O') or hexadecimal
     811                 :            :    ('0x') prefix should be added for nonzero numbers.  Return -1 if X cannot
     812                 :            :    be represented.  */
     813                 :            : 
     814                 :            : static HOST_WIDE_INT
     815                 :     152115 : tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
     816                 :            : {
     817                 :     152115 :   unsigned HOST_WIDE_INT absval;
     818                 :            : 
     819                 :     152115 :   HOST_WIDE_INT res;
     820                 :            : 
     821                 :     152115 :   if (TYPE_UNSIGNED (TREE_TYPE (x)))
     822                 :            :     {
     823                 :      10789 :       if (tree_fits_uhwi_p (x))
     824                 :            :         {
     825                 :      10789 :           absval = tree_to_uhwi (x);
     826                 :      10789 :           res = plus;
     827                 :            :         }
     828                 :            :       else
     829                 :            :         return -1;
     830                 :            :     }
     831                 :            :   else
     832                 :            :     {
     833                 :     141326 :       if (tree_fits_shwi_p (x))
     834                 :            :         {
     835                 :     141326 :           HOST_WIDE_INT i = tree_to_shwi (x);
     836                 :     141326 :          if (HOST_WIDE_INT_MIN == i)
     837                 :            :            {
     838                 :            :              /* Avoid undefined behavior due to negating a minimum.  */
     839                 :            :              absval = HOST_WIDE_INT_MAX;
     840                 :            :              res = 1;
     841                 :            :            }
     842                 :     137434 :          else if (i < 0)
     843                 :            :            {
     844                 :      22535 :              absval = -i;
     845                 :      22535 :              res = 1;
     846                 :            :            }
     847                 :            :          else
     848                 :            :            {
     849                 :     114899 :              absval = i;
     850                 :     114899 :              res = plus;
     851                 :            :            }
     852                 :            :         }
     853                 :            :       else
     854                 :            :         return -1;
     855                 :            :     }
     856                 :            : 
     857                 :     152115 :   int ndigs = ilog (absval, base);
     858                 :            : 
     859                 :     152115 :   res += prec < ndigs ? ndigs : prec;
     860                 :            : 
     861                 :            :   /* Adjust a non-zero value for the base prefix, either hexadecimal,
     862                 :            :      or, unless precision has resulted in a leading zero, also octal.  */
     863                 :     152115 :   if (prefix && absval && (base == 16 || prec <= ndigs))
     864                 :            :     {
     865                 :        451 :       if (base == 8)
     866                 :        141 :         res += 1;
     867                 :        310 :       else if (base == 16)
     868                 :        283 :         res += 2;
     869                 :            :     }
     870                 :            : 
     871                 :            :   return res;
     872                 :            : }
     873                 :            : 
     874                 :            : /* Description of a call to a formatted function.  */
     875                 :            : 
     876                 :            : struct call_info
     877                 :            : {
     878                 :            :   /* Function call statement.  */
     879                 :            :   gimple *callstmt;
     880                 :            : 
     881                 :            :   /* Function called.  */
     882                 :            :   tree func;
     883                 :            : 
     884                 :            :   /* Called built-in function code.  */
     885                 :            :   built_in_function fncode;
     886                 :            : 
     887                 :            :   /* The "origin" of the destination pointer argument, which is either
     888                 :            :      the DECL of the destination buffer being written into or a pointer
     889                 :            :      that points to it, plus some offset.  */
     890                 :            :   tree dst_origin;
     891                 :            : 
     892                 :            :   /* For a destination pointing to a struct array member, the offset of
     893                 :            :      the member.  */
     894                 :            :   HOST_WIDE_INT dst_field;
     895                 :            : 
     896                 :            :   /* The offset into the destination buffer.  */
     897                 :            :   HOST_WIDE_INT dst_offset;
     898                 :            : 
     899                 :            :   /* Format argument and format string extracted from it.  */
     900                 :            :   tree format;
     901                 :            :   const char *fmtstr;
     902                 :            : 
     903                 :            :   /* The location of the format argument.  */
     904                 :            :   location_t fmtloc;
     905                 :            : 
     906                 :            :   /* The destination object size for __builtin___xxx_chk functions
     907                 :            :      typically determined by __builtin_object_size, or -1 if unknown.  */
     908                 :            :   unsigned HOST_WIDE_INT objsize;
     909                 :            : 
     910                 :            :   /* Number of the first variable argument.  */
     911                 :            :   unsigned HOST_WIDE_INT argidx;
     912                 :            : 
     913                 :            :   /* True for functions like snprintf that specify the size of
     914                 :            :      the destination, false for others like sprintf that don't.  */
     915                 :            :   bool bounded;
     916                 :            : 
     917                 :            :   /* True for bounded functions like snprintf that specify a zero-size
     918                 :            :      buffer as a request to compute the size of output without actually
     919                 :            :      writing any.  NOWRITE is cleared in response to the %n directive
     920                 :            :      which has side-effects similar to writing output.  */
     921                 :            :   bool nowrite;
     922                 :            : 
     923                 :            :   /* Return true if the called function's return value is used.  */
     924                 :      71890 :   bool retval_used () const
     925                 :            :   {
     926                 :     142300 :     return gimple_get_lhs (callstmt);
     927                 :            :   }
     928                 :            : 
     929                 :            :   /* Return the warning option corresponding to the called function.  */
     930                 :       6361 :   int warnopt () const
     931                 :            :   {
     932                 :       6361 :     return bounded ? OPT_Wformat_truncation_ : OPT_Wformat_overflow_;
     933                 :            :   }
     934                 :            : 
     935                 :            :   /* Return true for calls to file formatted functions.  */
     936                 :            :   bool is_file_func () const
     937                 :            :   {
     938                 :            :     return (fncode == BUILT_IN_FPRINTF
     939                 :            :             || fncode == BUILT_IN_FPRINTF_CHK
     940                 :            :             || fncode == BUILT_IN_FPRINTF_UNLOCKED
     941                 :            :             || fncode == BUILT_IN_VFPRINTF
     942                 :            :             || fncode == BUILT_IN_VFPRINTF_CHK);
     943                 :            :   }
     944                 :            : 
     945                 :            :   /* Return true for calls to string formatted functions.  */
     946                 :       1374 :   bool is_string_func () const
     947                 :            :   {
     948                 :       1374 :     return (fncode == BUILT_IN_SPRINTF
     949                 :       1374 :             || fncode == BUILT_IN_SPRINTF_CHK
     950                 :       1221 :             || fncode == BUILT_IN_SNPRINTF
     951                 :        985 :             || fncode == BUILT_IN_SNPRINTF_CHK
     952                 :        985 :             || fncode == BUILT_IN_VSPRINTF
     953                 :        985 :             || fncode == BUILT_IN_VSPRINTF_CHK
     954                 :        985 :             || fncode == BUILT_IN_VSNPRINTF
     955                 :        985 :             || fncode == BUILT_IN_VSNPRINTF_CHK);
     956                 :            :   }
     957                 :            : };
     958                 :            : 
     959                 :            : /* Return the result of formatting a no-op directive (such as '%n').  */
     960                 :            : 
     961                 :            : static fmtresult
     962                 :         77 : format_none (const directive &, tree, const vr_values *)
     963                 :            : {
     964                 :         77 :   fmtresult res (0);
     965                 :         77 :   return res;
     966                 :            : }
     967                 :            : 
     968                 :            : /* Return the result of formatting the '%%' directive.  */
     969                 :            : 
     970                 :            : static fmtresult
     971                 :         63 : format_percent (const directive &, tree, const vr_values *)
     972                 :            : {
     973                 :         63 :   fmtresult res (1);
     974                 :         63 :   return res;
     975                 :            : }
     976                 :            : 
     977                 :            : 
     978                 :            : /* Compute intmax_type_node and uintmax_type_node similarly to how
     979                 :            :    tree.c builds size_type_node.  */
     980                 :            : 
     981                 :            : static void
     982                 :        110 : build_intmax_type_nodes (tree *pintmax, tree *puintmax)
     983                 :            : {
     984                 :        110 :   if (strcmp (UINTMAX_TYPE, "unsigned int") == 0)
     985                 :            :     {
     986                 :          0 :       *pintmax = integer_type_node;
     987                 :          0 :       *puintmax = unsigned_type_node;
     988                 :            :     }
     989                 :        220 :   else if (strcmp (UINTMAX_TYPE, "long unsigned int") == 0)
     990                 :            :     {
     991                 :        110 :       *pintmax = long_integer_type_node;
     992                 :        110 :       *puintmax = long_unsigned_type_node;
     993                 :            :     }
     994                 :          0 :   else if (strcmp (UINTMAX_TYPE, "long long unsigned int") == 0)
     995                 :            :     {
     996                 :          0 :       *pintmax = long_long_integer_type_node;
     997                 :          0 :       *puintmax = long_long_unsigned_type_node;
     998                 :            :     }
     999                 :            :   else
    1000                 :            :     {
    1001                 :          0 :       for (int i = 0; i < NUM_INT_N_ENTS; i++)
    1002                 :          0 :         if (int_n_enabled_p[i])
    1003                 :            :           {
    1004                 :          0 :             char name[50], altname[50];
    1005                 :          0 :             sprintf (name, "__int%d unsigned", int_n_data[i].bitsize);
    1006                 :          0 :             sprintf (altname, "__int%d__ unsigned", int_n_data[i].bitsize);
    1007                 :            : 
    1008                 :          0 :             if (strcmp (name, UINTMAX_TYPE) == 0
    1009                 :          0 :                 || strcmp (altname, UINTMAX_TYPE) == 0)
    1010                 :            :               {
    1011                 :          0 :                 *pintmax = int_n_trees[i].signed_type;
    1012                 :          0 :                 *puintmax = int_n_trees[i].unsigned_type;
    1013                 :          0 :                 return;
    1014                 :            :               }
    1015                 :            :           }
    1016                 :          0 :       gcc_unreachable ();
    1017                 :            :     }
    1018                 :            : }
    1019                 :            : 
    1020                 :            : /* Determine the range [*PMIN, *PMAX] that the expression ARG is
    1021                 :            :    in and that is representable in type int.
    1022                 :            :    Return true when the range is a subrange of that of int.
    1023                 :            :    When ARG is null it is as if it had the full range of int.
    1024                 :            :    When ABSOLUTE is true the range reflects the absolute value of
    1025                 :            :    the argument.  When ABSOLUTE is false, negative bounds of
    1026                 :            :    the determined range are replaced with NEGBOUND.  */
    1027                 :            : 
    1028                 :            : static bool
    1029                 :       2141 : get_int_range (tree arg, HOST_WIDE_INT *pmin, HOST_WIDE_INT *pmax,
    1030                 :            :                bool absolute, HOST_WIDE_INT negbound,
    1031                 :            :                const class vr_values *vr_values)
    1032                 :            : {
    1033                 :            :   /* The type of the result.  */
    1034                 :       2141 :   const_tree type = integer_type_node;
    1035                 :            : 
    1036                 :       2141 :   bool knownrange = false;
    1037                 :            : 
    1038                 :       2141 :   if (!arg)
    1039                 :            :     {
    1040                 :        454 :       *pmin = tree_to_shwi (TYPE_MIN_VALUE (type));
    1041                 :        454 :       *pmax = tree_to_shwi (TYPE_MAX_VALUE (type));
    1042                 :            :     }
    1043                 :       1687 :   else if (TREE_CODE (arg) == INTEGER_CST
    1044                 :       2367 :            && TYPE_PRECISION (TREE_TYPE (arg)) <= TYPE_PRECISION (type))
    1045                 :            :     {
    1046                 :            :       /* For a constant argument return its value adjusted as specified
    1047                 :            :          by NEGATIVE and NEGBOUND and return true to indicate that the
    1048                 :            :          result is known.  */
    1049                 :        676 :       *pmin = tree_fits_shwi_p (arg) ? tree_to_shwi (arg) : tree_to_uhwi (arg);
    1050                 :        676 :       *pmax = *pmin;
    1051                 :        676 :       knownrange = true;
    1052                 :            :     }
    1053                 :            :   else
    1054                 :            :     {
    1055                 :            :       /* True if the argument's range cannot be determined.  */
    1056                 :       1011 :       bool unknown = true;
    1057                 :            : 
    1058                 :       1011 :       tree argtype = TREE_TYPE (arg);
    1059                 :            : 
    1060                 :            :       /* Ignore invalid arguments with greater precision that that
    1061                 :            :          of the expected type (e.g., in sprintf("%*i", 12LL, i)).
    1062                 :            :          They will have been detected and diagnosed by -Wformat and
    1063                 :            :          so it's not important to complicate this code to try to deal
    1064                 :            :          with them again.  */
    1065                 :       1011 :       if (TREE_CODE (arg) == SSA_NAME
    1066                 :        843 :           && INTEGRAL_TYPE_P (argtype)
    1067                 :       1854 :           && TYPE_PRECISION (argtype) <= TYPE_PRECISION (type))
    1068                 :            :         {
    1069                 :            :           /* Try to determine the range of values of the integer argument.  */
    1070                 :        807 :           const value_range_equiv *vr
    1071                 :        807 :             = CONST_CAST (class vr_values *, vr_values)->get_value_range (arg);
    1072                 :            : 
    1073                 :        807 :           if (range_int_cst_p (vr))
    1074                 :            :             {
    1075                 :        568 :               HOST_WIDE_INT type_min
    1076                 :        568 :                 = (TYPE_UNSIGNED (argtype)
    1077                 :          2 :                    ? tree_to_uhwi (TYPE_MIN_VALUE (argtype))
    1078                 :        568 :                    : tree_to_shwi (TYPE_MIN_VALUE (argtype)));
    1079                 :            : 
    1080                 :        568 :               HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype));
    1081                 :            : 
    1082                 :        568 :               *pmin = TREE_INT_CST_LOW (vr->min ());
    1083                 :        568 :               *pmax = TREE_INT_CST_LOW (vr->max ());
    1084                 :            : 
    1085                 :        568 :               if (*pmin < *pmax)
    1086                 :            :                 {
    1087                 :            :                   /* Return true if the adjusted range is a subrange of
    1088                 :            :                      the full range of the argument's type.  *PMAX may
    1089                 :            :                      be less than *PMIN when the argument is unsigned
    1090                 :            :                      and its upper bound is in excess of TYPE_MAX.  In
    1091                 :            :                      that (invalid) case disregard the range and use that
    1092                 :            :                      of the expected type instead.  */
    1093                 :        568 :                   knownrange = type_min < *pmin || *pmax < type_max;
    1094                 :            : 
    1095                 :            :                   unknown = false;
    1096                 :            :                 }
    1097                 :            :             }
    1098                 :            :         }
    1099                 :            : 
    1100                 :            :       /* Handle an argument with an unknown range as if none had been
    1101                 :            :          provided.  */
    1102                 :            :       if (unknown)
    1103                 :        443 :         return get_int_range (NULL_TREE, pmin, pmax, absolute,
    1104                 :        443 :                               negbound, vr_values);
    1105                 :            :     }
    1106                 :            : 
    1107                 :            :   /* Adjust each bound as specified by ABSOLUTE and NEGBOUND.  */
    1108                 :       1698 :   if (absolute)
    1109                 :            :     {
    1110                 :        772 :       if (*pmin < 0)
    1111                 :            :         {
    1112                 :        309 :           if (*pmin == *pmax)
    1113                 :         24 :             *pmin = *pmax = -*pmin;
    1114                 :            :           else
    1115                 :            :             {
    1116                 :            :               /* Make sure signed overlow is avoided.  */
    1117                 :        285 :               gcc_assert (*pmin != HOST_WIDE_INT_MIN);
    1118                 :            : 
    1119                 :        285 :               HOST_WIDE_INT tmp = -*pmin;
    1120                 :        285 :               *pmin = 0;
    1121                 :        285 :               if (*pmax < tmp)
    1122                 :        275 :                 *pmax = tmp;
    1123                 :            :             }
    1124                 :            :         }
    1125                 :            :     }
    1126                 :        926 :   else if (*pmin < negbound)
    1127                 :        369 :     *pmin = negbound;
    1128                 :            : 
    1129                 :            :   return knownrange;
    1130                 :            : }
    1131                 :            : 
    1132                 :            : /* With the range [*ARGMIN, *ARGMAX] of an integer directive's actual
    1133                 :            :    argument, due to the conversion from either *ARGMIN or *ARGMAX to
    1134                 :            :    the type of the directive's formal argument it's possible for both
    1135                 :            :    to result in the same number of bytes or a range of bytes that's
    1136                 :            :    less than the number of bytes that would result from formatting
    1137                 :            :    some other value in the range [*ARGMIN, *ARGMAX].  This can be
    1138                 :            :    determined by checking for the actual argument being in the range
    1139                 :            :    of the type of the directive.  If it isn't it must be assumed to
    1140                 :            :    take on the full range of the directive's type.
    1141                 :            :    Return true when the range has been adjusted to the full range
    1142                 :            :    of DIRTYPE, and false otherwise.  */
    1143                 :            : 
    1144                 :            : static bool
    1145                 :      37681 : adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax)
    1146                 :            : {
    1147                 :      37681 :   tree argtype = TREE_TYPE (*argmin);
    1148                 :      37681 :   unsigned argprec = TYPE_PRECISION (argtype);
    1149                 :      37681 :   unsigned dirprec = TYPE_PRECISION (dirtype);
    1150                 :            : 
    1151                 :            :   /* If the actual argument and the directive's argument have the same
    1152                 :            :      precision and sign there can be no overflow and so there is nothing
    1153                 :            :      to adjust.  */
    1154                 :      37681 :   if (argprec == dirprec && TYPE_SIGN (argtype) == TYPE_SIGN (dirtype))
    1155                 :            :     return false;
    1156                 :            : 
    1157                 :            :   /* The logic below was inspired/lifted from the CONVERT_EXPR_CODE_P
    1158                 :            :      branch in the extract_range_from_unary_expr function in tree-vrp.c.  */
    1159                 :            : 
    1160                 :       4339 :   if (TREE_CODE (*argmin) == INTEGER_CST
    1161                 :       4339 :       && TREE_CODE (*argmax) == INTEGER_CST
    1162                 :       8678 :       && (dirprec >= argprec
    1163                 :       1989 :           || integer_zerop (int_const_binop (RSHIFT_EXPR,
    1164                 :       1989 :                                              int_const_binop (MINUS_EXPR,
    1165                 :            :                                                               *argmax,
    1166                 :            :                                                               *argmin),
    1167                 :       3591 :                                              size_int (dirprec)))))
    1168                 :            :     {
    1169                 :       2737 :       *argmin = force_fit_type (dirtype, wi::to_widest (*argmin), 0, false);
    1170                 :       2737 :       *argmax = force_fit_type (dirtype, wi::to_widest (*argmax), 0, false);
    1171                 :            : 
    1172                 :            :       /* If *ARGMIN is still less than *ARGMAX the conversion above
    1173                 :            :          is safe.  Otherwise, it has overflowed and would be unsafe.  */
    1174                 :       2737 :       if (tree_int_cst_le (*argmin, *argmax))
    1175                 :            :         return false;
    1176                 :            :     }
    1177                 :            : 
    1178                 :       2369 :   *argmin = TYPE_MIN_VALUE (dirtype);
    1179                 :       2369 :   *argmax = TYPE_MAX_VALUE (dirtype);
    1180                 :       2369 :   return true;
    1181                 :            : }
    1182                 :            : 
    1183                 :            : /* Return a range representing the minimum and maximum number of bytes
    1184                 :            :    that the format directive DIR will output for any argument given
    1185                 :            :    the WIDTH and PRECISION (extracted from DIR).  This function is
    1186                 :            :    used when the directive argument or its value isn't known.  */
    1187                 :            : 
    1188                 :            : static fmtresult
    1189                 :     189865 : format_integer (const directive &dir, tree arg, const vr_values *vr_values)
    1190                 :            : {
    1191                 :     189865 :   tree intmax_type_node;
    1192                 :     189865 :   tree uintmax_type_node;
    1193                 :            : 
    1194                 :            :   /* Base to format the number in.  */
    1195                 :     189865 :   int base;
    1196                 :            : 
    1197                 :            :   /* True when a conversion is preceded by a prefix indicating the base
    1198                 :            :      of the argument (octal or hexadecimal).  */
    1199                 :     189865 :   bool maybebase = dir.get_flag ('#');
    1200                 :            : 
    1201                 :            :   /* True when a signed conversion is preceded by a sign or space.  */
    1202                 :     189865 :   bool maybesign = false;
    1203                 :            : 
    1204                 :            :   /* True for signed conversions (i.e., 'd' and 'i').  */
    1205                 :     189865 :   bool sign = false;
    1206                 :            : 
    1207                 :     189865 :   switch (dir.specifier)
    1208                 :            :     {
    1209                 :     175293 :     case 'd':
    1210                 :     175293 :     case 'i':
    1211                 :            :       /* Space and '+' are  only meaningful for signed conversions.  */
    1212                 :     175293 :       maybesign = dir.get_flag (' ') | dir.get_flag ('+');
    1213                 :     175293 :       sign = true;
    1214                 :     175293 :       base = 10;
    1215                 :     175293 :       break;
    1216                 :            :     case 'u':
    1217                 :            :       base = 10;
    1218                 :            :       break;
    1219                 :        808 :     case 'o':
    1220                 :        808 :       base = 8;
    1221                 :        808 :       break;
    1222                 :       3495 :     case 'X':
    1223                 :       3495 :     case 'x':
    1224                 :       3495 :       base = 16;
    1225                 :       3495 :       break;
    1226                 :          0 :     default:
    1227                 :          0 :       gcc_unreachable ();
    1228                 :            :     }
    1229                 :            : 
    1230                 :            :   /* The type of the "formal" argument expected by the directive.  */
    1231                 :     189865 :   tree dirtype = NULL_TREE;
    1232                 :            : 
    1233                 :            :   /* Determine the expected type of the argument from the length
    1234                 :            :      modifier.  */
    1235                 :     189865 :   switch (dir.modifier)
    1236                 :            :     {
    1237                 :     137989 :     case FMT_LEN_none:
    1238                 :     137989 :       if (dir.specifier == 'p')
    1239                 :          0 :         dirtype = ptr_type_node;
    1240                 :            :       else
    1241                 :     137989 :         dirtype = sign ? integer_type_node : unsigned_type_node;
    1242                 :            :       break;
    1243                 :            : 
    1244                 :       1150 :     case FMT_LEN_h:
    1245                 :       1150 :       dirtype = sign ? short_integer_type_node : short_unsigned_type_node;
    1246                 :            :       break;
    1247                 :            : 
    1248                 :       1603 :     case FMT_LEN_hh:
    1249                 :       1603 :       dirtype = sign ? signed_char_type_node : unsigned_char_type_node;
    1250                 :            :       break;
    1251                 :            : 
    1252                 :      46311 :     case FMT_LEN_l:
    1253                 :      46311 :       dirtype = sign ? long_integer_type_node : long_unsigned_type_node;
    1254                 :            :       break;
    1255                 :            : 
    1256                 :       1877 :     case FMT_LEN_L:
    1257                 :       1877 :     case FMT_LEN_ll:
    1258                 :       1877 :       dirtype = (sign
    1259                 :       1877 :                  ? long_long_integer_type_node
    1260                 :            :                  : long_long_unsigned_type_node);
    1261                 :            :       break;
    1262                 :            : 
    1263                 :        776 :     case FMT_LEN_z:
    1264                 :        776 :       dirtype = signed_or_unsigned_type_for (!sign, size_type_node);
    1265                 :        776 :       break;
    1266                 :            : 
    1267                 :         49 :     case FMT_LEN_t:
    1268                 :         49 :       dirtype = signed_or_unsigned_type_for (!sign, ptrdiff_type_node);
    1269                 :         49 :       break;
    1270                 :            : 
    1271                 :        110 :     case FMT_LEN_j:
    1272                 :        110 :       build_intmax_type_nodes (&intmax_type_node, &uintmax_type_node);
    1273                 :        110 :       dirtype = sign ? intmax_type_node : uintmax_type_node;
    1274                 :            :       break;
    1275                 :            : 
    1276                 :          0 :     default:
    1277                 :          0 :       return fmtresult ();
    1278                 :            :     }
    1279                 :            : 
    1280                 :            :   /* The type of the argument to the directive, either deduced from
    1281                 :            :      the actual non-constant argument if one is known, or from
    1282                 :            :      the directive itself when none has been provided because it's
    1283                 :            :      a va_list.  */
    1284                 :     189865 :   tree argtype = NULL_TREE;
    1285                 :            : 
    1286                 :     189865 :   if (!arg)
    1287                 :            :     {
    1288                 :            :       /* When the argument has not been provided, use the type of
    1289                 :            :          the directive's argument as an approximation.  This will
    1290                 :            :          result in false positives for directives like %i with
    1291                 :            :          arguments with smaller precision (such as short or char).  */
    1292                 :            :       argtype = dirtype;
    1293                 :            :     }
    1294                 :     189544 :   else if (TREE_CODE (arg) == INTEGER_CST)
    1295                 :            :     {
    1296                 :            :       /* When a constant argument has been provided use its value
    1297                 :            :          rather than type to determine the length of the output.  */
    1298                 :     152153 :       fmtresult res;
    1299                 :            : 
    1300                 :     152153 :       if ((dir.prec[0] <= 0 && dir.prec[1] >= 0) && integer_zerop (arg))
    1301                 :            :         {
    1302                 :            :           /* As a special case, a precision of zero with a zero argument
    1303                 :            :              results in zero bytes except in base 8 when the '#' flag is
    1304                 :            :              specified, and for signed conversions in base 8 and 10 when
    1305                 :            :              either the space or '+' flag has been specified and it results
    1306                 :            :              in just one byte (with width having the normal effect).  This
    1307                 :            :              must extend to the case of a specified precision with
    1308                 :            :              an unknown value because it can be zero.  */
    1309                 :        222 :           res.range.min = ((base == 8 && dir.get_flag ('#')) || maybesign);
    1310                 :        222 :           if (res.range.min == 0 && dir.prec[0] != dir.prec[1])
    1311                 :            :             {
    1312                 :         99 :               res.range.max = 1;
    1313                 :         99 :               res.range.likely = 1;
    1314                 :            :             }
    1315                 :            :           else
    1316                 :            :             {
    1317                 :        123 :               res.range.max = res.range.min;
    1318                 :        123 :               res.range.likely = res.range.min;
    1319                 :            :             }
    1320                 :            :         }
    1321                 :            :       else
    1322                 :            :         {
    1323                 :            :           /* Convert the argument to the type of the directive.  */
    1324                 :     151931 :           arg = fold_convert (dirtype, arg);
    1325                 :            : 
    1326                 :     151931 :           res.range.min = tree_digits (arg, base, dir.prec[0],
    1327                 :            :                                        maybesign, maybebase);
    1328                 :     151931 :           if (dir.prec[0] == dir.prec[1])
    1329                 :     151747 :             res.range.max = res.range.min;
    1330                 :            :           else
    1331                 :        184 :             res.range.max = tree_digits (arg, base, dir.prec[1],
    1332                 :            :                                          maybesign, maybebase);
    1333                 :     151931 :           res.range.likely = res.range.min;
    1334                 :     151931 :           res.knownrange = true;
    1335                 :            :         }
    1336                 :            : 
    1337                 :     152153 :       res.range.unlikely = res.range.max;
    1338                 :            : 
    1339                 :            :       /* Bump up the counters if WIDTH is greater than LEN.  */
    1340                 :     152153 :       res.adjust_for_width_or_precision (dir.width, dirtype, base,
    1341                 :     152153 :                                          (sign | maybebase) + (base == 16));
    1342                 :            :       /* Bump up the counters again if PRECision is greater still.  */
    1343                 :     152153 :       res.adjust_for_width_or_precision (dir.prec, dirtype, base,
    1344                 :     152153 :                                          (sign | maybebase) + (base == 16));
    1345                 :            : 
    1346                 :     152153 :       return res;
    1347                 :            :     }
    1348                 :      74772 :   else if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
    1349                 :      37654 :            || TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE)
    1350                 :            :     /* Determine the type of the provided non-constant argument.  */
    1351                 :      37685 :     argtype = TREE_TYPE (arg);
    1352                 :            :   else
    1353                 :            :     /* Don't bother with invalid arguments since they likely would
    1354                 :            :        have already been diagnosed, and disable any further checking
    1355                 :            :        of the format string by returning [-1, -1].  */
    1356                 :         27 :     return fmtresult ();
    1357                 :            : 
    1358                 :      37685 :   fmtresult res;
    1359                 :            : 
    1360                 :            :   /* Using either the range the non-constant argument is in, or its
    1361                 :            :      type (either "formal" or actual), create a range of values that
    1362                 :            :      constrain the length of output given the warning level.  */
    1363                 :      37685 :   tree argmin = NULL_TREE;
    1364                 :      37685 :   tree argmax = NULL_TREE;
    1365                 :            : 
    1366                 :      37685 :   if (arg
    1367                 :      37364 :       && TREE_CODE (arg) == SSA_NAME
    1368                 :      36152 :       && INTEGRAL_TYPE_P (argtype))
    1369                 :            :     {
    1370                 :            :       /* Try to determine the range of values of the integer argument
    1371                 :            :          (range information is not available for pointers).  */
    1372                 :      36006 :       const value_range_equiv *vr
    1373                 :      36006 :         = CONST_CAST (class vr_values *, vr_values)->get_value_range (arg);
    1374                 :            : 
    1375                 :      36006 :       if (range_int_cst_p (vr))
    1376                 :            :         {
    1377                 :      14409 :           argmin = vr->min ();
    1378                 :      14409 :           argmax = vr->max ();
    1379                 :            : 
    1380                 :            :           /* Set KNOWNRANGE if the argument is in a known subrange
    1381                 :            :              of the directive's type and neither width nor precision
    1382                 :            :              is unknown.  (KNOWNRANGE may be reset below).  */
    1383                 :      14409 :           res.knownrange
    1384                 :      14409 :             = ((!tree_int_cst_equal (TYPE_MIN_VALUE (dirtype), argmin)
    1385                 :       1386 :                 || !tree_int_cst_equal (TYPE_MAX_VALUE (dirtype), argmax))
    1386                 :      15651 :                && dir.known_width_and_precision ());
    1387                 :            : 
    1388                 :      14409 :           res.argmin = argmin;
    1389                 :      14409 :           res.argmax = argmax;
    1390                 :            :         }
    1391                 :      21597 :       else if (vr->kind () == VR_ANTI_RANGE)
    1392                 :            :         {
    1393                 :            :           /* Handle anti-ranges if/when bug 71690 is resolved.  */
    1394                 :            :         }
    1395                 :      15020 :       else if (vr->varying_p () || vr->undefined_p ())
    1396                 :            :         {
    1397                 :            :           /* The argument here may be the result of promoting the actual
    1398                 :            :              argument to int.  Try to determine the type of the actual
    1399                 :            :              argument before promotion and narrow down its range that
    1400                 :            :              way.  */
    1401                 :      14923 :           gimple *def = SSA_NAME_DEF_STMT (arg);
    1402                 :      14923 :           if (is_gimple_assign (def))
    1403                 :            :             {
    1404                 :       7876 :               tree_code code = gimple_assign_rhs_code (def);
    1405                 :       7876 :               if (code == INTEGER_CST)
    1406                 :            :                 {
    1407                 :          4 :                   arg = gimple_assign_rhs1 (def);
    1408                 :          4 :                   return format_integer (dir, arg, vr_values);
    1409                 :            :                 }
    1410                 :            : 
    1411                 :       7872 :               if (code == NOP_EXPR)
    1412                 :            :                 {
    1413                 :       1847 :                   tree type = TREE_TYPE (gimple_assign_rhs1 (def));
    1414                 :       1847 :                   if (INTEGRAL_TYPE_P (type)
    1415                 :       1847 :                       || TREE_CODE (type) == POINTER_TYPE)
    1416                 :       1847 :                     argtype = type;
    1417                 :            :                 }
    1418                 :            :             }
    1419                 :            :         }
    1420                 :            :     }
    1421                 :            : 
    1422                 :      37681 :   if (!argmin)
    1423                 :            :     {
    1424                 :      23272 :       if (TREE_CODE (argtype) == POINTER_TYPE)
    1425                 :            :         {
    1426                 :        335 :           argmin = build_int_cst (pointer_sized_int_node, 0);
    1427                 :        335 :           argmax = build_all_ones_cst (pointer_sized_int_node);
    1428                 :            :         }
    1429                 :            :       else
    1430                 :            :         {
    1431                 :      22937 :           argmin = TYPE_MIN_VALUE (argtype);
    1432                 :      22937 :           argmax = TYPE_MAX_VALUE (argtype);
    1433                 :            :         }
    1434                 :            :     }
    1435                 :            : 
    1436                 :            :   /* Clear KNOWNRANGE if the range has been adjusted to the maximum
    1437                 :            :      of the directive.  If it has been cleared then since ARGMIN and/or
    1438                 :            :      ARGMAX have been adjusted also adjust the corresponding ARGMIN and
    1439                 :            :      ARGMAX in the result to include in diagnostics.  */
    1440                 :      37681 :   if (adjust_range_for_overflow (dirtype, &argmin, &argmax))
    1441                 :            :     {
    1442                 :       2369 :       res.knownrange = false;
    1443                 :       2369 :       res.argmin = argmin;
    1444                 :       2369 :       res.argmax = argmax;
    1445                 :            :     }
    1446                 :            : 
    1447                 :            :   /* Recursively compute the minimum and maximum from the known range.  */
    1448                 :      37681 :   if (TYPE_UNSIGNED (dirtype) || tree_int_cst_sgn (argmin) >= 0)
    1449                 :            :     {
    1450                 :            :       /* For unsigned conversions/directives or signed when
    1451                 :            :          the minimum is positive, use the minimum and maximum to compute
    1452                 :            :          the shortest and longest output, respectively.  */
    1453                 :      11469 :       res.range.min = format_integer (dir, argmin, vr_values).range.min;
    1454                 :      11469 :       res.range.max = format_integer (dir, argmax, vr_values).range.max;
    1455                 :            :     }
    1456                 :      26212 :   else if (tree_int_cst_sgn (argmax) < 0)
    1457                 :            :     {
    1458                 :            :       /* For signed conversions/directives if maximum is negative,
    1459                 :            :          use the minimum as the longest output and maximum as the
    1460                 :            :          shortest output.  */
    1461                 :         17 :       res.range.min = format_integer (dir, argmax, vr_values).range.min;
    1462                 :         17 :       res.range.max = format_integer (dir, argmin, vr_values).range.max;
    1463                 :            :     }
    1464                 :            :   else
    1465                 :            :     {
    1466                 :            :       /* Otherwise, 0 is inside of the range and minimum negative.  Use 0
    1467                 :            :          as the shortest output and for the longest output compute the
    1468                 :            :          length of the output of both minimum and maximum and pick the
    1469                 :            :          longer.  */
    1470                 :      26195 :       unsigned HOST_WIDE_INT max1
    1471                 :      26195 :         = format_integer (dir, argmin, vr_values).range.max;
    1472                 :      26195 :       unsigned HOST_WIDE_INT max2
    1473                 :      26195 :         = format_integer (dir, argmax, vr_values).range.max;
    1474                 :      26195 :       res.range.min
    1475                 :      26195 :         = format_integer (dir, integer_zero_node, vr_values).range.min;
    1476                 :      26195 :       res.range.max = MAX (max1, max2);
    1477                 :            :     }
    1478                 :            : 
    1479                 :            :   /* If the range is known, use the maximum as the likely length.  */
    1480                 :      37681 :   if (res.knownrange)
    1481                 :      14081 :     res.range.likely = res.range.max;
    1482                 :            :   else
    1483                 :            :     {
    1484                 :            :       /* Otherwise, use the minimum.  Except for the case where for %#x or
    1485                 :            :          %#o the minimum is just for a single value in the range (0) and
    1486                 :            :          for all other values it is something longer, like 0x1 or 01.
    1487                 :            :           Use the length for value 1 in that case instead as the likely
    1488                 :            :           length.  */
    1489                 :      23600 :       res.range.likely = res.range.min;
    1490                 :      23600 :       if (maybebase
    1491                 :      23600 :           && base != 10
    1492                 :      23600 :           && (tree_int_cst_sgn (argmin) < 0 || tree_int_cst_sgn (argmax) > 0))
    1493                 :            :         {
    1494                 :        270 :           if (res.range.min == 1)
    1495                 :        404 :             res.range.likely += base == 8 ? 1 : 2;
    1496                 :         36 :           else if (res.range.min == 2
    1497                 :         12 :                    && base == 16
    1498                 :          5 :                    && (dir.width[0] == 2 || dir.prec[0] == 2))
    1499                 :          5 :             ++res.range.likely;
    1500                 :            :         }
    1501                 :            :     }
    1502                 :            : 
    1503                 :      37681 :   res.range.unlikely = res.range.max;
    1504                 :      37681 :   res.adjust_for_width_or_precision (dir.width, dirtype, base,
    1505                 :      37681 :                                      (sign | maybebase) + (base == 16));
    1506                 :      37681 :   res.adjust_for_width_or_precision (dir.prec, dirtype, base,
    1507                 :      37681 :                                      (sign | maybebase) + (base == 16));
    1508                 :            : 
    1509                 :      37681 :   return res;
    1510                 :            : }
    1511                 :            : 
    1512                 :            : /* Return the number of bytes that a format directive consisting of FLAGS,
    1513                 :            :    PRECision, format SPECification, and MPFR rounding specifier RNDSPEC,
    1514                 :            :    would result for argument X under ideal conditions (i.e., if PREC
    1515                 :            :    weren't excessive).  MPFR 3.1 allocates large amounts of memory for
    1516                 :            :    values of PREC with large magnitude and can fail (see MPFR bug #21056).
    1517                 :            :    This function works around those problems.  */
    1518                 :            : 
    1519                 :            : static unsigned HOST_WIDE_INT
    1520                 :       6506 : get_mpfr_format_length (mpfr_ptr x, const char *flags, HOST_WIDE_INT prec,
    1521                 :            :                         char spec, char rndspec)
    1522                 :            : {
    1523                 :       6506 :   char fmtstr[40];
    1524                 :            : 
    1525                 :       6506 :   HOST_WIDE_INT len = strlen (flags);
    1526                 :            : 
    1527                 :       6506 :   fmtstr[0] = '%';
    1528                 :       6506 :   memcpy (fmtstr + 1, flags, len);
    1529                 :       6506 :   memcpy (fmtstr + 1 + len, ".*R", 3);
    1530                 :       6506 :   fmtstr[len + 4] = rndspec;
    1531                 :       6506 :   fmtstr[len + 5] = spec;
    1532                 :       6506 :   fmtstr[len + 6] = '\0';
    1533                 :            : 
    1534                 :       6506 :   spec = TOUPPER (spec);
    1535                 :       6506 :   if (spec == 'E' || spec == 'F')
    1536                 :            :     {
    1537                 :            :       /* For %e, specify the precision explicitly since mpfr_sprintf
    1538                 :            :          does its own thing just to be different (see MPFR bug 21088).  */
    1539                 :       3266 :       if (prec < 0)
    1540                 :          0 :         prec = 6;
    1541                 :            :     }
    1542                 :            :   else
    1543                 :            :     {
    1544                 :            :       /* Avoid passing negative precisions with larger magnitude to MPFR
    1545                 :            :          to avoid exposing its bugs.  (A negative precision is supposed
    1546                 :            :          to be ignored.)  */
    1547                 :       3240 :       if (prec < 0)
    1548                 :            :         prec = -1;
    1549                 :            :     }
    1550                 :            : 
    1551                 :       6506 :   HOST_WIDE_INT p = prec;
    1552                 :            : 
    1553                 :       6506 :   if (spec == 'G' && !strchr (flags, '#'))
    1554                 :            :     {
    1555                 :            :       /* For G/g without the pound flag, precision gives the maximum number
    1556                 :            :          of significant digits which is bounded by LDBL_MAX_10_EXP, or, for
    1557                 :            :          a 128 bit IEEE extended precision, 4932.  Using twice as much here
    1558                 :            :          should be more than sufficient for any real format.  */
    1559                 :       3002 :       if ((IEEE_MAX_10_EXP * 2) < prec)
    1560                 :         18 :         prec = IEEE_MAX_10_EXP * 2;
    1561                 :            :       p = prec;
    1562                 :            :     }
    1563                 :            :   else
    1564                 :            :     {
    1565                 :            :       /* Cap precision arbitrarily at 1KB and add the difference
    1566                 :            :          (if any) to the MPFR result.  */
    1567                 :       3504 :       if (prec > 1024)
    1568                 :            :         p = 1024;
    1569                 :            :     }
    1570                 :            : 
    1571                 :       6506 :   len = mpfr_snprintf (NULL, 0, fmtstr, (int)p, x);
    1572                 :            : 
    1573                 :            :   /* Handle the unlikely (impossible?) error by returning more than
    1574                 :            :      the maximum dictated by the function's return type.  */
    1575                 :       6506 :   if (len < 0)
    1576                 :          0 :     return target_dir_max () + 1;
    1577                 :            : 
    1578                 :            :   /* Adjust the return value by the difference.  */
    1579                 :       6506 :   if (p < prec)
    1580                 :        158 :     len += prec - p;
    1581                 :            : 
    1582                 :       6506 :   return len;
    1583                 :            : }
    1584                 :            : 
    1585                 :            : /* Return the number of bytes to format using the format specifier
    1586                 :            :    SPEC and the precision PREC the largest value in the real floating
    1587                 :            :    TYPE.  */
    1588                 :            : 
    1589                 :            : static unsigned HOST_WIDE_INT
    1590                 :       5588 : format_floating_max (tree type, char spec, HOST_WIDE_INT prec)
    1591                 :            : {
    1592                 :       5588 :   machine_mode mode = TYPE_MODE (type);
    1593                 :            : 
    1594                 :            :   /* IBM Extended mode.  */
    1595                 :      39116 :   if (MODE_COMPOSITE_P (mode))
    1596                 :            :     mode = DFmode;
    1597                 :            : 
    1598                 :            :   /* Get the real type format desription for the target.  */
    1599                 :       5588 :   const real_format *rfmt = REAL_MODE_FORMAT (mode);
    1600                 :       5588 :   REAL_VALUE_TYPE rv;
    1601                 :            : 
    1602                 :       5588 :   real_maxval (&rv, 0, mode);
    1603                 :            : 
    1604                 :            :   /* Convert the GCC real value representation with the precision
    1605                 :            :      of the real type to the mpfr_t format with the GCC default
    1606                 :            :      round-to-nearest mode.  */
    1607                 :       5588 :   mpfr_t x;
    1608                 :       5588 :   mpfr_init2 (x, rfmt->p);
    1609                 :       5588 :   mpfr_from_real (x, &rv, MPFR_RNDN);
    1610                 :            : 
    1611                 :            :   /* Return a value one greater to account for the leading minus sign.  */
    1612                 :       5588 :   unsigned HOST_WIDE_INT r
    1613                 :       5588 :     = 1 + get_mpfr_format_length (x, "", prec, spec, 'D');
    1614                 :       5588 :   mpfr_clear (x);
    1615                 :       5588 :   return r;
    1616                 :            : }
    1617                 :            : 
    1618                 :            : /* Return a range representing the minimum and maximum number of bytes
    1619                 :            :    that the directive DIR will output for any argument.  PREC gives
    1620                 :            :    the adjusted precision range to account for negative precisions
    1621                 :            :    meaning the default 6.  This function is used when the directive
    1622                 :            :    argument or its value isn't known.  */
    1623                 :            : 
    1624                 :            : static fmtresult
    1625                 :       5680 : format_floating (const directive &dir, const HOST_WIDE_INT prec[2])
    1626                 :            : {
    1627                 :       5680 :   tree type;
    1628                 :            : 
    1629                 :       5680 :   switch (dir.modifier)
    1630                 :            :     {
    1631                 :       4786 :     case FMT_LEN_l:
    1632                 :       4786 :     case FMT_LEN_none:
    1633                 :       4786 :       type = double_type_node;
    1634                 :       4786 :       break;
    1635                 :            : 
    1636                 :        784 :     case FMT_LEN_L:
    1637                 :        784 :       type = long_double_type_node;
    1638                 :        784 :       break;
    1639                 :            : 
    1640                 :         18 :     case FMT_LEN_ll:
    1641                 :         18 :       type = long_double_type_node;
    1642                 :         18 :       break;
    1643                 :            : 
    1644                 :         92 :     default:
    1645                 :         92 :       return fmtresult ();
    1646                 :            :     }
    1647                 :            : 
    1648                 :            :   /* The minimum and maximum number of bytes produced by the directive.  */
    1649                 :       5588 :   fmtresult res;
    1650                 :            : 
    1651                 :            :   /* The minimum output as determined by flags.  It's always at least 1.
    1652                 :            :      When plus or space are set the output is preceded by either a sign
    1653                 :            :      or a space.  */
    1654                 :       5588 :   unsigned flagmin = (1 /* for the first digit */
    1655                 :       5588 :                       + (dir.get_flag ('+') | dir.get_flag (' ')));
    1656                 :            : 
    1657                 :            :   /* The minimum is 3 for "inf" and "nan" for all specifiers, plus 1
    1658                 :            :      for the plus sign/space with the '+' and ' ' flags, respectively,
    1659                 :            :      unless reduced below.  */
    1660                 :       5588 :   res.range.min = 2 + flagmin;
    1661                 :            : 
    1662                 :            :   /* When the pound flag is set the decimal point is included in output
    1663                 :            :      regardless of precision.  Whether or not a decimal point is included
    1664                 :            :      otherwise depends on the specification and precision.  */
    1665                 :       5588 :   bool radix = dir.get_flag ('#');
    1666                 :            : 
    1667                 :       5588 :   switch (dir.specifier)
    1668                 :            :     {
    1669                 :        112 :     case 'A':
    1670                 :        112 :     case 'a':
    1671                 :        112 :       {
    1672                 :        112 :         HOST_WIDE_INT minprec = 6 + !radix /* decimal point */;
    1673                 :        112 :         if (dir.prec[0] <= 0)
    1674                 :            :           minprec = 0;
    1675                 :         24 :         else if (dir.prec[0] > 0)
    1676                 :         24 :           minprec = dir.prec[0] + !radix /* decimal point */;
    1677                 :            : 
    1678                 :        112 :         res.range.likely = (2 /* 0x */
    1679                 :            :                             + flagmin
    1680                 :        112 :                             + radix
    1681                 :        112 :                             + minprec
    1682                 :        112 :                             + 3 /* p+0 */);
    1683                 :            : 
    1684                 :        112 :         res.range.max = format_floating_max (type, 'a', prec[1]);
    1685                 :            : 
    1686                 :            :         /* The unlikely maximum accounts for the longest multibyte
    1687                 :            :            decimal point character.  */
    1688                 :        112 :         res.range.unlikely = res.range.max;
    1689                 :        112 :         if (dir.prec[1] > 0)
    1690                 :         37 :           res.range.unlikely += target_mb_len_max () - 1;
    1691                 :            : 
    1692                 :            :         break;
    1693                 :            :       }
    1694                 :            : 
    1695                 :        303 :     case 'E':
    1696                 :        303 :     case 'e':
    1697                 :        303 :       {
    1698                 :            :         /* Minimum output attributable to precision and, when it's
    1699                 :            :            non-zero, decimal point.  */
    1700                 :        303 :         HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0;
    1701                 :            : 
    1702                 :            :         /* The likely minimum output is "[-+]1.234567e+00" regardless
    1703                 :            :            of the value of the actual argument.  */
    1704                 :        303 :         res.range.likely = (flagmin
    1705                 :        303 :                             + radix
    1706                 :        303 :                             + minprec
    1707                 :        303 :                             + 2 /* e+ */ + 2);
    1708                 :            : 
    1709                 :        303 :         res.range.max = format_floating_max (type, 'e', prec[1]);
    1710                 :            : 
    1711                 :            :         /* The unlikely maximum accounts for the longest multibyte
    1712                 :            :            decimal point character.  */
    1713                 :        303 :         if (dir.prec[0] != dir.prec[1]
    1714                 :        253 :             || dir.prec[0] == -1 || dir.prec[0] > 0)
    1715                 :        262 :           res.range.unlikely = res.range.max + target_mb_len_max () -1;
    1716                 :            :         else
    1717                 :         41 :           res.range.unlikely = res.range.max;
    1718                 :            :         break;
    1719                 :            :       }
    1720                 :            : 
    1721                 :       2316 :     case 'F':
    1722                 :       2316 :     case 'f':
    1723                 :       2316 :       {
    1724                 :            :         /* Minimum output attributable to precision and, when it's non-zero,
    1725                 :            :            decimal point.  */
    1726                 :       2316 :         HOST_WIDE_INT minprec = prec[0] ? prec[0] + !radix : 0;
    1727                 :            : 
    1728                 :            :         /* For finite numbers (i.e., not infinity or NaN) the lower bound
    1729                 :            :            when precision isn't specified is 8 bytes ("1.23456" since
    1730                 :            :            precision is taken to be 6).  When precision is zero, the lower
    1731                 :            :            bound is 1 byte (e.g., "1").  Otherwise, when precision is greater
    1732                 :            :            than zero, then the lower bound is 2 plus precision (plus flags).
    1733                 :            :            But in all cases, the lower bound is no greater than 3.  */
    1734                 :       2316 :         unsigned HOST_WIDE_INT min = flagmin + radix + minprec;
    1735                 :       2316 :         if (min < res.range.min)
    1736                 :        326 :           res.range.min = min;
    1737                 :            : 
    1738                 :            :         /* Compute the upper bound for -TYPE_MAX.  */
    1739                 :       2316 :         res.range.max = format_floating_max (type, 'f', prec[1]);
    1740                 :            : 
    1741                 :            :         /* The minimum output with unknown precision is a single byte
    1742                 :            :            (e.g., "0") but the more likely output is 3 bytes ("0.0").  */
    1743                 :       2316 :         if (dir.prec[0] < 0 && dir.prec[1] > 0)
    1744                 :         44 :           res.range.likely = 3;
    1745                 :            :         else
    1746                 :       2272 :           res.range.likely = min;
    1747                 :            : 
    1748                 :            :         /* The unlikely maximum accounts for the longest multibyte
    1749                 :            :            decimal point character.  */
    1750                 :       2316 :         if (dir.prec[0] != dir.prec[1]
    1751                 :       2269 :             || dir.prec[0] == -1 || dir.prec[0] > 0)
    1752                 :       2035 :           res.range.unlikely = res.range.max + target_mb_len_max () - 1;
    1753                 :            :         break;
    1754                 :            :       }
    1755                 :            : 
    1756                 :       2857 :     case 'G':
    1757                 :       2857 :     case 'g':
    1758                 :       2857 :       {
    1759                 :            :         /* The %g output depends on precision and the exponent of
    1760                 :            :            the argument.  Since the value of the argument isn't known
    1761                 :            :            the lower bound on the range of bytes (not counting flags
    1762                 :            :            or width) is 1 plus radix (i.e., either "0" or "0." for
    1763                 :            :            "%g" and "%#g", respectively, with a zero argument).  */
    1764                 :       2857 :         unsigned HOST_WIDE_INT min = flagmin + radix;
    1765                 :       2857 :         if (min < res.range.min)
    1766                 :       2857 :           res.range.min = min;
    1767                 :            : 
    1768                 :       2857 :         char spec = 'g';
    1769                 :       2857 :         HOST_WIDE_INT maxprec = dir.prec[1];
    1770                 :       2857 :         if (radix && maxprec)
    1771                 :            :           {
    1772                 :            :             /* When the pound flag (radix) is set, trailing zeros aren't
    1773                 :            :                trimmed and so the longest output is the same as for %e,
    1774                 :            :                except with precision minus 1 (as specified in C11).  */
    1775                 :         19 :             spec = 'e';
    1776                 :         19 :             if (maxprec > 0)
    1777                 :          8 :               --maxprec;
    1778                 :            :             else if (maxprec < 0)
    1779                 :            :               maxprec = 5;
    1780                 :            :           }
    1781                 :            :         else
    1782                 :       2838 :           maxprec = prec[1];
    1783                 :            : 
    1784                 :       2857 :         res.range.max = format_floating_max (type, spec, maxprec);
    1785                 :            : 
    1786                 :            :         /* The likely output is either the maximum computed above
    1787                 :            :            minus 1 (assuming the maximum is positive) when precision
    1788                 :            :            is known (or unspecified), or the same minimum as for %e
    1789                 :            :            (which is computed for a non-negative argument).  Unlike
    1790                 :            :            for the other specifiers above the likely output isn't
    1791                 :            :            the minimum because for %g that's 1 which is unlikely.  */
    1792                 :       2857 :         if (dir.prec[1] < 0
    1793                 :       2857 :             || (unsigned HOST_WIDE_INT)dir.prec[1] < target_int_max ())
    1794                 :       2843 :           res.range.likely = res.range.max - 1;
    1795                 :            :         else
    1796                 :            :           {
    1797                 :         14 :             HOST_WIDE_INT minprec = 6 + !radix /* decimal point */;
    1798                 :         14 :             res.range.likely = (flagmin
    1799                 :         14 :                                 + radix
    1800                 :         14 :                                 + minprec
    1801                 :         14 :                                 + 2 /* e+ */ + 2);
    1802                 :            :           }
    1803                 :            : 
    1804                 :            :         /* The unlikely maximum accounts for the longest multibyte
    1805                 :            :            decimal point character.  */
    1806                 :       2857 :         res.range.unlikely = res.range.max + target_mb_len_max () - 1;
    1807                 :       2857 :         break;
    1808                 :            :       }
    1809                 :            : 
    1810                 :          0 :     default:
    1811                 :          0 :       return fmtresult ();
    1812                 :            :     }
    1813                 :            : 
    1814                 :            :   /* Bump up the byte counters if WIDTH is greater.  */
    1815                 :       5588 :   res.adjust_for_width_or_precision (dir.width);
    1816                 :       5588 :   return res;
    1817                 :            : }
    1818                 :            : 
    1819                 :            : /* Return a range representing the minimum and maximum number of bytes
    1820                 :            :    that the directive DIR will write on output for the floating argument
    1821                 :            :    ARG.  */
    1822                 :            : 
    1823                 :            : static fmtresult
    1824                 :       6159 : format_floating (const directive &dir, tree arg, const vr_values *)
    1825                 :            : {
    1826                 :       6159 :   HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] };
    1827                 :      12318 :   tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll
    1828                 :       6159 :                ? long_double_type_node : double_type_node);
    1829                 :            : 
    1830                 :            :   /* For an indeterminate precision the lower bound must be assumed
    1831                 :            :      to be zero.  */
    1832                 :       6159 :   if (TOUPPER (dir.specifier) == 'A')
    1833                 :            :     {
    1834                 :            :       /* Get the number of fractional decimal digits needed to represent
    1835                 :            :          the argument without a loss of accuracy.  */
    1836                 :        192 :       unsigned fmtprec
    1837                 :        576 :         = REAL_MODE_FORMAT (TYPE_MODE (type))->p;
    1838                 :            : 
    1839                 :            :       /* The precision of the IEEE 754 double format is 53.
    1840                 :            :          The precision of all other GCC binary double formats
    1841                 :            :          is 56 or less.  */
    1842                 :        192 :       unsigned maxprec = fmtprec <= 56 ? 13 : 15;
    1843                 :            : 
    1844                 :            :       /* For %a, leave the minimum precision unspecified to let
    1845                 :            :          MFPR trim trailing zeros (as it and many other systems
    1846                 :            :          including Glibc happen to do) and set the maximum
    1847                 :            :          precision to reflect what it would be with trailing zeros
    1848                 :            :          present (as Solaris and derived systems do).  */
    1849                 :        192 :       if (dir.prec[1] < 0)
    1850                 :            :         {
    1851                 :            :           /* Both bounds are negative implies that precision has
    1852                 :            :              not been specified.  */
    1853                 :         96 :           prec[0] = maxprec;
    1854                 :         96 :           prec[1] = -1;
    1855                 :            :         }
    1856                 :         96 :       else if (dir.prec[0] < 0)
    1857                 :            :         {
    1858                 :            :           /* With a negative lower bound and a non-negative upper
    1859                 :            :              bound set the minimum precision to zero and the maximum
    1860                 :            :              to the greater of the maximum precision (i.e., with
    1861                 :            :              trailing zeros present) and the specified upper bound.  */
    1862                 :         20 :           prec[0] = 0;
    1863                 :         20 :           prec[1] = dir.prec[1] < maxprec ? maxprec : dir.prec[1];
    1864                 :            :         }
    1865                 :            :     }
    1866                 :       5967 :   else if (dir.prec[0] < 0)
    1867                 :            :     {
    1868                 :       5122 :       if (dir.prec[1] < 0)
    1869                 :            :         {
    1870                 :            :           /* A precision in a strictly negative range is ignored and
    1871                 :            :              the default of 6 is used instead.  */
    1872                 :       4989 :           prec[0] = prec[1] = 6;
    1873                 :            :         }
    1874                 :            :       else
    1875                 :            :         {
    1876                 :            :           /* For a precision in a partly negative range, the lower bound
    1877                 :            :              must be assumed to be zero and the new upper bound is the
    1878                 :            :              greater of 6 (the default precision used when the specified
    1879                 :            :              precision is negative) and the upper bound of the specified
    1880                 :            :              range.  */
    1881                 :        133 :           prec[0] = 0;
    1882                 :        133 :           prec[1] = dir.prec[1] < 6 ? 6 : dir.prec[1];
    1883                 :            :         }
    1884                 :            :     }
    1885                 :            : 
    1886                 :       6159 :   if (!arg
    1887                 :       6060 :       || TREE_CODE (arg) != REAL_CST
    1888                 :       6639 :       || !useless_type_conversion_p (type, TREE_TYPE (arg)))
    1889                 :       5680 :     return format_floating (dir, prec);
    1890                 :            : 
    1891                 :            :   /* The minimum and maximum number of bytes produced by the directive.  */
    1892                 :        479 :   fmtresult res;
    1893                 :            : 
    1894                 :            :   /* Get the real type format desription for the target.  */
    1895                 :        479 :   const REAL_VALUE_TYPE *rvp = TREE_REAL_CST_PTR (arg);
    1896                 :       1437 :   const real_format *rfmt = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)));
    1897                 :            : 
    1898                 :        479 :   if (!real_isfinite (rvp))
    1899                 :            :     {
    1900                 :            :       /* The format for Infinity and NaN is "[-]inf"/"[-]infinity"
    1901                 :            :          and "[-]nan" with the choice being implementation-defined
    1902                 :            :          but not locale dependent.  */
    1903                 :         20 :       bool sign = dir.get_flag ('+') || real_isneg (rvp);
    1904                 :         20 :       res.range.min = 3 + sign;
    1905                 :            : 
    1906                 :         20 :       res.range.likely = res.range.min;
    1907                 :         20 :       res.range.max = res.range.min;
    1908                 :            :       /* The unlikely maximum is "[-/+]infinity" or "[-/+][qs]nan".
    1909                 :            :          For NaN, the C/POSIX standards specify two formats:
    1910                 :            :            "[-/+]nan"
    1911                 :            :          and
    1912                 :            :            "[-/+]nan(n-char-sequence)"
    1913                 :            :          No known printf implementation outputs the latter format but AIX
    1914                 :            :          outputs QNaN and SNaN for quiet and signalling NaN, respectively,
    1915                 :            :          so the unlikely maximum reflects that.  */
    1916                 :         20 :       res.range.unlikely = sign + (real_isinf (rvp) ? 8 : 4);
    1917                 :            : 
    1918                 :            :       /* The range for infinity and NaN is known unless either width
    1919                 :            :          or precision is unknown.  Width has the same effect regardless
    1920                 :            :          of whether the argument is finite.  Precision is either ignored
    1921                 :            :          (e.g., Glibc) or can have an effect on the short vs long format
    1922                 :            :          such as inf/infinity (e.g., Solaris).  */
    1923                 :         20 :       res.knownrange = dir.known_width_and_precision ();
    1924                 :            : 
    1925                 :            :       /* Adjust the range for width but ignore precision.  */
    1926                 :         20 :       res.adjust_for_width_or_precision (dir.width);
    1927                 :            : 
    1928                 :         20 :       return res;
    1929                 :            :     }
    1930                 :            : 
    1931                 :            :   char fmtstr [40];
    1932                 :            :   char *pfmt = fmtstr;
    1933                 :            : 
    1934                 :            :   /* Append flags.  */
    1935                 :       2754 :   for (const char *pf = "-+ #0"; *pf; ++pf)
    1936                 :       2295 :     if (dir.get_flag (*pf))
    1937                 :         12 :       *pfmt++ = *pf;
    1938                 :            : 
    1939                 :        459 :   *pfmt = '\0';
    1940                 :            : 
    1941                 :        459 :   {
    1942                 :            :     /* Set up an array to easily iterate over.  */
    1943                 :        459 :     unsigned HOST_WIDE_INT* const minmax[] = {
    1944                 :            :       &res.range.min, &res.range.max
    1945                 :        459 :     };
    1946                 :            : 
    1947                 :       1377 :     for (int i = 0; i != sizeof minmax / sizeof *minmax; ++i)
    1948                 :            :       {
    1949                 :            :         /* Convert the GCC real value representation with the precision
    1950                 :            :            of the real type to the mpfr_t format rounding down in the
    1951                 :            :            first iteration that computes the minimm and up in the second
    1952                 :            :            that computes the maximum.  This order is arbibtrary because
    1953                 :            :            rounding in either direction can result in longer output.  */
    1954                 :        918 :         mpfr_t mpfrval;
    1955                 :        918 :         mpfr_init2 (mpfrval, rfmt->p);
    1956                 :       1377 :         mpfr_from_real (mpfrval, rvp, i ? MPFR_RNDU : MPFR_RNDD);
    1957                 :            : 
    1958                 :            :         /* Use the MPFR rounding specifier to round down in the first
    1959                 :            :            iteration and then up.  In most but not all cases this will
    1960                 :            :            result in the same number of bytes.  */
    1961                 :        918 :         char rndspec = "DU"[i];
    1962                 :            : 
    1963                 :            :         /* Format it and store the result in the corresponding member
    1964                 :            :            of the result struct.  */
    1965                 :       1836 :         *minmax[i] = get_mpfr_format_length (mpfrval, fmtstr, prec[i],
    1966                 :        918 :                                              dir.specifier, rndspec);
    1967                 :        918 :         mpfr_clear (mpfrval);
    1968                 :            :       }
    1969                 :            :   }
    1970                 :            : 
    1971                 :            :   /* Make sure the minimum is less than the maximum (MPFR rounding
    1972                 :            :      in the call to mpfr_snprintf can result in the reverse.  */
    1973                 :        459 :   if (res.range.max < res.range.min)
    1974                 :            :     {
    1975                 :         32 :       unsigned HOST_WIDE_INT tmp = res.range.min;
    1976                 :         32 :       res.range.min = res.range.max;
    1977                 :         32 :       res.range.max = tmp;
    1978                 :            :     }
    1979                 :            : 
    1980                 :            :   /* The range is known unless either width or precision is unknown.  */
    1981                 :        459 :   res.knownrange = dir.known_width_and_precision ();
    1982                 :            : 
    1983                 :            :   /* For the same floating point constant, unless width or precision
    1984                 :            :      is unknown, use the longer output as the likely maximum since
    1985                 :            :      with round to nearest either is equally likely.  Otheriwse, when
    1986                 :            :      precision is unknown, use the greater of the minimum and 3 as
    1987                 :            :      the likely output (for "0.0" since zero precision is unlikely).  */
    1988                 :        459 :   if (res.knownrange)
    1989                 :        417 :     res.range.likely = res.range.max;
    1990                 :         42 :   else if (res.range.min < 3
    1991                 :         17 :            && dir.prec[0] < 0
    1992                 :         57 :            && (unsigned HOST_WIDE_INT)dir.prec[1] == target_int_max ())
    1993                 :         13 :     res.range.likely = 3;
    1994                 :            :   else
    1995                 :         29 :     res.range.likely = res.range.min;
    1996                 :            : 
    1997                 :        459 :   res.range.unlikely = res.range.max;
    1998                 :            : 
    1999                 :        459 :   if (res.range.max > 2 && (prec[0] != 0 || prec[1] != 0))
    2000                 :            :     {
    2001                 :            :       /* Unless the precision is zero output longer than 2 bytes may
    2002                 :            :          include the decimal point which must be a single character
    2003                 :            :          up to MB_LEN_MAX in length.  This is overly conservative
    2004                 :            :          since in some conversions some constants result in no decimal
    2005                 :            :          point (e.g., in %g).  */
    2006                 :        410 :       res.range.unlikely += target_mb_len_max () - 1;
    2007                 :            :     }
    2008                 :            : 
    2009                 :        459 :   res.adjust_for_width_or_precision (dir.width);
    2010                 :        459 :   return res;
    2011                 :            : }
    2012                 :            : 
    2013                 :            : /* Return a FMTRESULT struct set to the lengths of the shortest and longest
    2014                 :            :    strings referenced by the expression STR, or (-1, -1) when not known.
    2015                 :            :    Used by the format_string function below.  */
    2016                 :            : 
    2017                 :            : static fmtresult
    2018                 :     138755 : get_string_length (tree str, unsigned eltsize, const vr_values *vr)
    2019                 :            : {
    2020                 :     138755 :   if (!str)
    2021                 :        578 :     return fmtresult ();
    2022                 :            : 
    2023                 :            :   /* Try to determine the dynamic string length first.
    2024                 :            :      Set MAXBOUND to an arbitrary non-null non-integer node as a request
    2025                 :            :      to have it set to the length of the longest string in a PHI.  */
    2026                 :     138177 :   c_strlen_data lendata = { };
    2027                 :     138177 :   lendata.maxbound = str;
    2028                 :     138177 :   if (eltsize == 1)
    2029                 :     137876 :     get_range_strlen_dynamic (str, &lendata, vr);
    2030                 :            :   else
    2031                 :            :     {
    2032                 :            :       /* Determine the length of the shortest and longest string referenced
    2033                 :            :          by STR.  Strings of unknown lengths are bounded by the sizes of
    2034                 :            :          arrays that subexpressions of STR may refer to.  Pointers that
    2035                 :            :          aren't known to point any such arrays result in LENDATA.MAXLEN
    2036                 :            :          set to SIZE_MAX.  */
    2037                 :        301 :       get_range_strlen (str, &lendata, eltsize);
    2038                 :            :     }
    2039                 :            : 
    2040                 :            :   /* If LENDATA.MAXBOUND is not equal to .MINLEN it corresponds to the bound
    2041                 :            :      of the largest array STR refers to, if known, or it's set to SIZE_MAX
    2042                 :            :      otherwise.  */
    2043                 :            : 
    2044                 :            :   /* Return the default result when nothing is known about the string.  */
    2045                 :     138177 :   if ((lendata.maxbound && !tree_fits_uhwi_p (lendata.maxbound))
    2046                 :     138177 :       || !tree_fits_uhwi_p (lendata.maxlen))
    2047                 :            :     {
    2048                 :          0 :       fmtresult res;
    2049                 :          0 :       res.nonstr = lendata.decl;
    2050                 :          0 :       return res;
    2051                 :            :     }
    2052                 :            : 
    2053                 :     138177 :   unsigned HOST_WIDE_INT lenmax = tree_to_uhwi (max_object_size ()) - 2;
    2054                 :     138177 :   if (integer_zerop (lendata.minlen)
    2055                 :       8268 :       && (!lendata.maxbound || lenmax <= tree_to_uhwi (lendata.maxbound))
    2056                 :     144125 :       && lenmax <= tree_to_uhwi (lendata.maxlen))
    2057                 :            :     {
    2058                 :       5948 :       fmtresult res;
    2059                 :       5948 :       res.nonstr = lendata.decl;
    2060                 :       5948 :       return res;
    2061                 :            :     }
    2062                 :            : 
    2063                 :     264458 :   HOST_WIDE_INT min
    2064                 :     132229 :     = (tree_fits_uhwi_p (lendata.minlen)
    2065                 :     132229 :        ? tree_to_uhwi (lendata.minlen)
    2066                 :            :        : 0);
    2067                 :            : 
    2068                 :     264458 :   HOST_WIDE_INT max
    2069                 :     132225 :     = (lendata.maxbound && tree_fits_uhwi_p (lendata.maxbound)
    2070                 :     264454 :        ? tree_to_uhwi (lendata.maxbound)
    2071                 :            :        : HOST_WIDE_INT_M1U);
    2072                 :            : 
    2073                 :     132229 :   const bool unbounded = integer_all_onesp (lendata.maxlen);
    2074                 :            : 
    2075                 :            :   /* Set the max/likely counters to unbounded when a minimum is known
    2076                 :            :      but the maximum length isn't bounded.  This implies that STR is
    2077                 :            :      a conditional expression involving a string of known length and
    2078                 :            :      and an expression of unknown/unbounded length.  */
    2079                 :     132229 :   if (min
    2080                 :     132229 :       && (unsigned HOST_WIDE_INT)min < HOST_WIDE_INT_M1U
    2081                 :     129909 :       && unbounded)
    2082                 :        134 :     max = HOST_WIDE_INT_M1U;
    2083                 :            : 
    2084                 :            :   /* get_range_strlen() returns the target value of SIZE_MAX for
    2085                 :            :      strings of unknown length.  Bump it up to HOST_WIDE_INT_M1U
    2086                 :            :      which may be bigger.  */
    2087                 :     132229 :   if ((unsigned HOST_WIDE_INT)min == target_size_max ())
    2088                 :          0 :     min = HOST_WIDE_INT_M1U;
    2089                 :     132229 :   if ((unsigned HOST_WIDE_INT)max == target_size_max ())
    2090                 :        132 :     max = HOST_WIDE_INT_M1U;
    2091                 :            : 
    2092                 :     132229 :   fmtresult res (min, max);
    2093                 :     132229 :   res.nonstr = lendata.decl;
    2094                 :            : 
    2095                 :            :   /* Set RES.KNOWNRANGE to true if and only if all strings referenced
    2096                 :            :      by STR are known to be bounded (though not necessarily by their
    2097                 :            :      actual length but perhaps by their maximum possible length).  */
    2098                 :     132229 :   if (res.range.max < target_int_max ())
    2099                 :            :     {
    2100                 :            :       res.knownrange = true;
    2101                 :            :       /* When the length of the longest string is known and not
    2102                 :            :          excessive use it as the likely length of the string(s).  */
    2103                 :            :       res.range.likely = res.range.max;
    2104                 :            :     }
    2105                 :            :   else
    2106                 :            :     {
    2107                 :            :       /* When the upper bound is unknown (it can be zero or excessive)
    2108                 :            :          set the likely length to the greater of 1.  If MAXBOUND is
    2109                 :            :          known, also reset the length of the lower bound to zero.  */
    2110                 :        138 :       res.range.likely = res.range.min ? res.range.min : warn_level > 1;
    2111                 :        138 :       if (lendata.maxbound && !integer_all_onesp (lendata.maxbound))
    2112                 :            :         res.range.min = 0;
    2113                 :            :     }
    2114                 :            : 
    2115                 :     132229 :   res.range.unlikely = unbounded ? HOST_WIDE_INT_MAX : res.range.max;
    2116                 :            : 
    2117                 :     132229 :   return res;
    2118                 :            : }
    2119                 :            : 
    2120                 :            : /* Return the minimum and maximum number of characters formatted
    2121                 :            :    by the '%c' format directives and its wide character form for
    2122                 :            :    the argument ARG.  ARG can be null (for functions such as
    2123                 :            :    vsprinf).  */
    2124                 :            : 
    2125                 :            : static fmtresult
    2126                 :       1021 : format_character (const directive &dir, tree arg, const vr_values *vr_values)
    2127                 :            : {
    2128                 :       1021 :   fmtresult res;
    2129                 :            : 
    2130                 :       1021 :   res.knownrange = true;
    2131                 :            : 
    2132                 :       1021 :   if (dir.specifier == 'C'
    2133                 :        971 :       || dir.modifier == FMT_LEN_l)
    2134                 :            :     {
    2135                 :            :       /* A wide character can result in as few as zero bytes.  */
    2136                 :        122 :       res.range.min = 0;
    2137                 :            : 
    2138                 :        122 :       HOST_WIDE_INT min, max;
    2139                 :        122 :       if (get_int_range (arg, &min, &max, false, 0, vr_values))
    2140                 :            :         {
    2141                 :         58 :           if (min == 0 && max == 0)
    2142                 :            :             {
    2143                 :            :               /* The NUL wide character results in no bytes.  */
    2144                 :         17 :               res.range.max = 0;
    2145                 :         17 :               res.range.likely = 0;
    2146                 :         17 :               res.range.unlikely = 0;
    2147                 :            :             }
    2148                 :         41 :           else if (min >= 0 && min < 128)
    2149                 :            :             {
    2150                 :            :               /* Be conservative if the target execution character set
    2151                 :            :                  is not a 1-to-1 mapping to the source character set or
    2152                 :            :                  if the source set is not ASCII.  */
    2153                 :         34 :               bool one_2_one_ascii
    2154                 :         34 :                 = (target_to_host_charmap[0] == 1 && target_to_host ('a') == 97);
    2155                 :            : 
    2156                 :            :               /* A wide character in the ASCII range most likely results
    2157                 :            :                  in a single byte, and only unlikely in up to MB_LEN_MAX.  */
    2158                 :         34 :               res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();;
    2159                 :         34 :               res.range.likely = 1;
    2160                 :         34 :               res.range.unlikely = target_mb_len_max ();
    2161                 :         34 :               res.mayfail = !one_2_one_ascii;
    2162                 :            :             }
    2163                 :            :           else
    2164                 :            :             {
    2165                 :            :               /* A wide character outside the ASCII range likely results
    2166                 :            :                  in up to two bytes, and only unlikely in up to MB_LEN_MAX.  */
    2167                 :          7 :               res.range.max = target_mb_len_max ();
    2168                 :          7 :               res.range.likely = 2;
    2169                 :          7 :               res.range.unlikely = res.range.max;
    2170                 :            :               /* Converting such a character may fail.  */
    2171                 :          7 :               res.mayfail = true;
    2172                 :            :             }
    2173                 :            :         }
    2174                 :            :       else
    2175                 :            :         {
    2176                 :            :           /* An unknown wide character is treated the same as a wide
    2177                 :            :              character outside the ASCII range.  */
    2178                 :         64 :           res.range.max = target_mb_len_max ();
    2179                 :         64 :           res.range.likely = 2;
    2180                 :         64 :           res.range.unlikely = res.range.max;
    2181                 :         64 :           res.mayfail = true;
    2182                 :        122 :         }
    2183                 :            :     }
    2184                 :            :   else
    2185                 :            :     {
    2186                 :            :       /* A plain '%c' directive.  Its ouput is exactly 1.  */
    2187                 :        899 :       res.range.min = res.range.max = 1;
    2188                 :        899 :       res.range.likely = res.range.unlikely = 1;
    2189                 :        899 :       res.knownrange = true;
    2190                 :            :     }
    2191                 :            : 
    2192                 :            :   /* Bump up the byte counters if WIDTH is greater.  */
    2193                 :       1021 :   return res.adjust_for_width_or_precision (dir.width);
    2194                 :            : }
    2195                 :            : 
    2196                 :            : /* Determine the offset *INDEX of the first byte of an array element of
    2197                 :            :    TYPE (possibly recursively) into which the byte offset OFF points.
    2198                 :            :    On success set *INDEX to the offset of the first byte and return type.
    2199                 :            :    Otherwise, if no such element can be found, return null.  */
    2200                 :            : 
    2201                 :            : static tree
    2202                 :        335 : array_elt_at_offset (tree type, HOST_WIDE_INT off, HOST_WIDE_INT *index)
    2203                 :            : {
    2204                 :        335 :   gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    2205                 :            : 
    2206                 :            :   tree eltype = type;
    2207                 :        351 :   while (TREE_CODE (TREE_TYPE (eltype)) == ARRAY_TYPE)
    2208                 :        351 :     eltype = TREE_TYPE (eltype);
    2209                 :            : 
    2210                 :        335 :   if (TYPE_MODE (TREE_TYPE (eltype)) != TYPE_MODE (char_type_node))
    2211                 :         16 :     eltype = TREE_TYPE (eltype);
    2212                 :            : 
    2213                 :        335 :   if (eltype == type)
    2214                 :            :     {
    2215                 :        303 :       *index = 0;
    2216                 :        303 :       return type;
    2217                 :            :     }
    2218                 :            : 
    2219                 :         32 :   HOST_WIDE_INT typsz = int_size_in_bytes (type);
    2220                 :         32 :   HOST_WIDE_INT eltsz = int_size_in_bytes (eltype);
    2221                 :         32 :   if (off < typsz * eltsz)
    2222                 :            :     {
    2223                 :         32 :       *index = (off / eltsz) * eltsz;
    2224                 :         48 :       return TREE_CODE (eltype) == ARRAY_TYPE ? TREE_TYPE (eltype) : eltype;
    2225                 :            :     }
    2226                 :            : 
    2227                 :            :   return NULL_TREE;
    2228                 :            : }
    2229                 :            : 
    2230                 :            : /* Determine the offset *INDEX of the first byte of a struct member of TYPE
    2231                 :            :    (possibly recursively) into which the byte offset OFF points.  On success
    2232                 :            :    set *INDEX to the offset of the first byte and return true.  Otherwise,
    2233                 :            :    if no such member can be found, return false.  */
    2234                 :            : 
    2235                 :            : static bool
    2236                 :        899 : field_at_offset (tree type, HOST_WIDE_INT off, HOST_WIDE_INT *index)
    2237                 :            : {
    2238                 :        899 :   gcc_assert (RECORD_OR_UNION_TYPE_P (type));
    2239                 :            : 
    2240                 :       1085 :   for (tree fld = TYPE_FIELDS (type); fld; fld = TREE_CHAIN (fld))
    2241                 :            :     {
    2242                 :       2142 :       if (TREE_CODE (fld) != FIELD_DECL || DECL_ARTIFICIAL (fld))
    2243                 :          0 :         continue;
    2244                 :            : 
    2245                 :       1071 :       tree fldtype = TREE_TYPE (fld);
    2246                 :       1071 :       HOST_WIDE_INT fldoff = int_byte_position (fld);
    2247                 :            : 
    2248                 :            :       /* If the size is not available the field is a flexible array
    2249                 :            :          member.  Treat this case as success.  */
    2250                 :       1071 :       tree typesize = TYPE_SIZE_UNIT (fldtype);
    2251                 :       2142 :       HOST_WIDE_INT fldsize = (tree_fits_uhwi_p (typesize)
    2252                 :       1071 :                                ? tree_to_uhwi (typesize)
    2253                 :            :                                : off);
    2254                 :            : 
    2255                 :       1071 :       if (fldoff + fldsize < off)
    2256                 :        186 :         continue;
    2257                 :            : 
    2258                 :        885 :       if (TREE_CODE (fldtype) == ARRAY_TYPE)
    2259                 :            :         {
    2260                 :        319 :           HOST_WIDE_INT idx = 0;
    2261                 :        319 :           if (tree ft = array_elt_at_offset (fldtype, off, &idx))
    2262                 :        319 :             fldtype = ft;
    2263                 :            :           else
    2264                 :            :             break;
    2265                 :            : 
    2266                 :        319 :           *index += idx;
    2267                 :        319 :           fldoff -= idx;
    2268                 :        319 :           off -= idx;
    2269                 :            :         }
    2270                 :            : 
    2271                 :        885 :       if (RECORD_OR_UNION_TYPE_P (fldtype))
    2272                 :            :         {
    2273                 :        574 :           *index += fldoff;
    2274                 :        574 :           return field_at_offset (fldtype, off - fldoff, index);
    2275                 :            :         }
    2276                 :            : 
    2277                 :        311 :       *index += fldoff;
    2278                 :        311 :       return true;
    2279                 :            :     }
    2280                 :            : 
    2281                 :            :   return false;
    2282                 :            : }
    2283                 :            : 
    2284                 :            : /* For an expression X of pointer type, recursively try to find the same
    2285                 :            :    origin (object or pointer) as Y it references and return such an X.
    2286                 :            :    When X refers to a struct member, set *FLDOFF to the offset of the
    2287                 :            :    member from the beginning of the "most derived" object.  */
    2288                 :            : 
    2289                 :            : static tree
    2290                 :      27316 : get_origin_and_offset (tree x, HOST_WIDE_INT *fldoff, HOST_WIDE_INT *off)
    2291                 :            : {
    2292                 :      27316 :   if (!x)
    2293                 :            :     return NULL_TREE;
    2294                 :            : 
    2295                 :      12837 :   switch (TREE_CODE (x))
    2296                 :            :     {
    2297                 :       4038 :     case ADDR_EXPR:
    2298                 :       4038 :       x = TREE_OPERAND (x, 0);
    2299                 :       4038 :       return get_origin_and_offset (x, fldoff, off);
    2300                 :            : 
    2301                 :        206 :     case ARRAY_REF:
    2302                 :        206 :       {
    2303                 :        206 :         tree offset = TREE_OPERAND (x, 1);
    2304                 :        412 :         HOST_WIDE_INT idx = (tree_fits_uhwi_p (offset)
    2305                 :        206 :                              ? tree_to_uhwi (offset) : HOST_WIDE_INT_MAX);
    2306                 :            : 
    2307                 :        206 :         tree eltype = TREE_TYPE (x);
    2308                 :        206 :         if (TREE_CODE (eltype) == INTEGER_TYPE)
    2309                 :            :           {
    2310                 :         42 :             if (off)
    2311                 :         42 :               *off = idx;
    2312                 :            :           }
    2313                 :        164 :         else if (idx < HOST_WIDE_INT_MAX)
    2314                 :        164 :           *fldoff += idx * int_size_in_bytes (eltype);
    2315                 :            :         else
    2316                 :          0 :           *fldoff = idx;
    2317                 :            : 
    2318                 :        206 :         x = TREE_OPERAND (x, 0);
    2319                 :        206 :         return get_origin_and_offset (x, fldoff, NULL);
    2320                 :            :       }
    2321                 :            : 
    2322                 :       1517 :     case MEM_REF:
    2323                 :       1517 :       if (off)
    2324                 :            :         {
    2325                 :       1389 :           tree offset = TREE_OPERAND (x, 1);
    2326                 :       1389 :           *off = (tree_fits_uhwi_p (offset)
    2327                 :       1389 :                   ? tree_to_uhwi (offset) : HOST_WIDE_INT_MAX);
    2328                 :            :         }
    2329                 :            : 
    2330                 :       1517 :       x = TREE_OPERAND (x, 0);
    2331                 :            : 
    2332                 :       1517 :       if (off)
    2333                 :            :         {
    2334                 :       1389 :           tree xtype
    2335                 :       1389 :             = (TREE_CODE (x) == ADDR_EXPR
    2336                 :       1714 :                ? TREE_TYPE (TREE_OPERAND (x, 0)) : TREE_TYPE (TREE_TYPE (x)));
    2337                 :            : 
    2338                 :            :           /* The byte offset of the most basic struct member the byte
    2339                 :            :              offset *OFF corresponds to, or for a (multidimensional)
    2340                 :            :              array member, the byte offset of the array element.  */
    2341                 :       1389 :           HOST_WIDE_INT index = 0;
    2342                 :            : 
    2343                 :       1389 :           if ((RECORD_OR_UNION_TYPE_P (xtype)
    2344                 :        325 :                && field_at_offset (xtype, *off, &index))
    2345                 :       1403 :               || (TREE_CODE (xtype) == ARRAY_TYPE
    2346                 :       1062 :                   && TREE_CODE (TREE_TYPE (xtype)) == ARRAY_TYPE
    2347                 :         16 :                   && array_elt_at_offset (xtype, *off, &index)))
    2348                 :            :             {
    2349                 :        327 :               *fldoff += index;
    2350                 :        327 :               *off -= index;
    2351                 :            :             }
    2352                 :            :         }
    2353                 :            : 
    2354                 :       1517 :       return get_origin_and_offset (x, fldoff, NULL);
    2355                 :            : 
    2356                 :        895 :     case COMPONENT_REF:
    2357                 :        895 :       {
    2358                 :        895 :         tree fld = TREE_OPERAND (x, 1);
    2359                 :        895 :         *fldoff += int_byte_position (fld);
    2360                 :            : 
    2361                 :        895 :         get_origin_and_offset (fld, fldoff, off);
    2362                 :        895 :         x = TREE_OPERAND (x, 0);
    2363                 :        895 :         return get_origin_and_offset (x, fldoff, off);
    2364                 :            :       }
    2365                 :            : 
    2366                 :       2411 :     case SSA_NAME:
    2367                 :       2411 :       {
    2368                 :       2411 :         gimple *def = SSA_NAME_DEF_STMT (x);
    2369                 :       2411 :         if (is_gimple_assign (def))
    2370                 :            :           {
    2371                 :       1171 :             tree_code code = gimple_assign_rhs_code (def);
    2372                 :       1171 :             if (code == ADDR_EXPR)
    2373                 :            :               {
    2374                 :        453 :                 x = gimple_assign_rhs1 (def);
    2375                 :        453 :                 return get_origin_and_offset (x, fldoff, off);
    2376                 :            :               }
    2377                 :            : 
    2378                 :        718 :             if (code == POINTER_PLUS_EXPR)
    2379                 :            :               {
    2380                 :        176 :                 tree offset = gimple_assign_rhs2 (def);
    2381                 :        176 :                 if (off)
    2382                 :        161 :                   *off = (tree_fits_uhwi_p (offset)
    2383                 :        161 :                           ? tree_to_uhwi (offset) : HOST_WIDE_INT_MAX);
    2384                 :            : 
    2385                 :        176 :                 x = gimple_assign_rhs1 (def);
    2386                 :        176 :                 return get_origin_and_offset (x, fldoff, NULL);
    2387                 :            :               }
    2388                 :        542 :             else if (code == VAR_DECL)
    2389                 :            :               {
    2390                 :         86 :                 x = gimple_assign_rhs1 (def);
    2391                 :         86 :                 return get_origin_and_offset (x, fldoff, off);
    2392                 :            :               }
    2393                 :            :           }
    2394                 :       1240 :         else if (gimple_nop_p (def) && SSA_NAME_VAR (x))
    2395                 :      27316 :           x = SSA_NAME_VAR (x);
    2396                 :            :       }
    2397                 :            : 
    2398                 :            :     default:
    2399                 :            :       break;
    2400                 :            :     }
    2401                 :            : 
    2402                 :            :   return x;
    2403                 :            : }
    2404                 :            : 
    2405                 :            : /* If ARG refers to the same (sub)object or array element as described
    2406                 :            :    by DST and DST_FLD, return the byte offset into the struct member or
    2407                 :            :    array element referenced by ARG.  Otherwise return HOST_WIDE_INT_MIN
    2408                 :            :    to indicate that ARG and DST do not refer to the same object.  */
    2409                 :            : 
    2410                 :            : static HOST_WIDE_INT
    2411                 :       5353 : alias_offset (tree arg, tree dst, HOST_WIDE_INT dst_fld)
    2412                 :            : {
    2413                 :            :   /* See if the argument refers to the same base object as the destination
    2414                 :            :      of the formatted function call, and if so, try to determine if they
    2415                 :            :      can alias.  */
    2416                 :       5353 :   if (!arg || !dst || !ptr_derefs_may_alias_p (arg, dst))
    2417                 :       3541 :     return HOST_WIDE_INT_MIN;
    2418                 :            : 
    2419                 :            :   /* The two arguments may refer to the same object.  If they both refer
    2420                 :            :      to a struct member, see if the members are one and the same.  */
    2421                 :       1812 :   HOST_WIDE_INT arg_off = 0, arg_fld = 0;
    2422                 :            : 
    2423                 :       1812 :   tree arg_orig = get_origin_and_offset (arg, &arg_fld, &arg_off);
    2424                 :            : 
    2425                 :       1812 :   if (arg_orig == dst && arg_fld == dst_fld)
    2426                 :        212 :     return arg_off;
    2427                 :            : 
    2428                 :            :   return HOST_WIDE_INT_MIN;
    2429                 :            : }
    2430                 :            : 
    2431                 :            : /* Return the minimum and maximum number of characters formatted
    2432                 :            :    by the '%s' format directive and its wide character form for
    2433                 :            :    the argument ARG.  ARG can be null (for functions such as
    2434                 :            :    vsprinf).  */
    2435                 :            : 
    2436                 :            : static fmtresult
    2437                 :     138755 : format_string (const directive &dir, tree arg, const vr_values *vr_values)
    2438                 :            : {
    2439                 :     138755 :   fmtresult res;
    2440                 :            : 
    2441                 :     138755 :   if (warn_restrict)
    2442                 :            :     {
    2443                 :            :       /* See if ARG might alias the destination of the call with
    2444                 :            :          DST_ORIGIN and DST_FIELD.  If so, store the starting offset
    2445                 :            :          so that the overlap can be determined for certain later,
    2446                 :            :          when the amount of output of the call (including subsequent
    2447                 :            :          directives) has been computed.  Otherwise, store HWI_MIN.  */
    2448                 :       5353 :       res.dst_offset = alias_offset (arg, dir.info->dst_origin,
    2449                 :       5353 :                                      dir.info->dst_field);
    2450                 :            :     }
    2451                 :            : 
    2452                 :            :   /* Compute the range the argument's length can be in.  */
    2453                 :     138755 :   int count_by = 1;
    2454                 :     138755 :   if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
    2455                 :            :     {
    2456                 :            :       /* Get a node for a C type that will be the same size
    2457                 :            :          as a wchar_t on the target.  */
    2458                 :        301 :       tree node = get_typenode_from_name (MODIFIED_WCHAR_TYPE);
    2459                 :            : 
    2460                 :            :       /* Now that we have a suitable node, get the number of
    2461                 :            :          bytes it occupies.  */
    2462                 :        301 :       count_by = int_size_in_bytes (node);
    2463                 :        301 :       gcc_checking_assert (count_by == 2 || count_by == 4);
    2464                 :            :     }
    2465                 :            : 
    2466                 :     138755 :   fmtresult slen = get_string_length (arg, count_by, vr_values);
    2467                 :     138755 :   if (slen.range.min == slen.range.max
    2468                 :     136491 :       && slen.range.min < HOST_WIDE_INT_MAX)
    2469                 :            :     {
    2470                 :            :       /* The argument is either a string constant or it refers
    2471                 :            :          to one of a number of strings of the same length.  */
    2472                 :            : 
    2473                 :            :       /* A '%s' directive with a string argument with constant length.  */
    2474                 :     129965 :       res.range = slen.range;
    2475                 :            : 
    2476                 :     129965 :       if (dir.specifier == 'S'
    2477                 :     129961 :           || dir.modifier == FMT_LEN_l)
    2478                 :            :         {
    2479                 :            :           /* In the worst case the length of output of a wide string S
    2480                 :            :              is bounded by MB_LEN_MAX * wcslen (S).  */
    2481                 :        116 :           res.range.max *= target_mb_len_max ();
    2482                 :        116 :           res.range.unlikely = res.range.max;
    2483                 :            :           /* It's likely that the total length is not more that
    2484                 :            :              2 * wcslen (S).*/
    2485                 :        116 :           res.range.likely = res.range.min * 2;
    2486                 :            : 
    2487                 :        116 :           if (dir.prec[1] >= 0
    2488                 :         57 :               && (unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
    2489                 :            :             {
    2490                 :         51 :               res.range.max = dir.prec[1];
    2491                 :         51 :               res.range.likely = dir.prec[1];
    2492                 :         51 :               res.range.unlikely = dir.prec[1];
    2493                 :            :             }
    2494                 :            : 
    2495                 :        116 :           if (dir.prec[0] < 0 && dir.prec[1] > -1)
    2496                 :            :             res.range.min = 0;
    2497                 :        112 :           else if (dir.prec[0] >= 0)
    2498                 :         53 :             res.range.likely = dir.prec[0];
    2499                 :            : 
    2500                 :            :           /* Even a non-empty wide character string need not convert into
    2501                 :            :              any bytes.  */
    2502                 :        116 :           res.range.min = 0;
    2503                 :            : 
    2504                 :            :           /* A non-empty wide character conversion may fail.  */
    2505                 :        116 :           if (slen.range.max > 0)
    2506                 :         80 :             res.mayfail = true;
    2507                 :            :         }
    2508                 :            :       else
    2509                 :            :         {
    2510                 :     129849 :           res.knownrange = true;
    2511                 :            : 
    2512                 :     129849 :           if (dir.prec[0] < 0 && dir.prec[1] > -1)
    2513                 :         16 :             res.range.min = 0;
    2514                 :     129833 :           else if ((unsigned HOST_WIDE_INT)dir.prec[0] < res.range.min)
    2515                 :         87 :             res.range.min = dir.prec[0];
    2516                 :            : 
    2517                 :     129849 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
    2518                 :            :             {
    2519                 :         69 :               res.range.max = dir.prec[1];
    2520                 :         69 :               res.range.likely = dir.prec[1];
    2521                 :         69 :               res.range.unlikely = dir.prec[1];
    2522                 :            :             }
    2523                 :            :         }
    2524                 :            :     }
    2525                 :       8790 :   else if (arg && integer_zerop (arg))
    2526                 :            :     {
    2527                 :            :       /* Handle null pointer argument.  */
    2528                 :            : 
    2529                 :         33 :       fmtresult res (0);
    2530                 :         33 :       res.nullp = true;
    2531                 :         33 :       return res;
    2532                 :            :     }
    2533                 :            :   else
    2534                 :            :     {
    2535                 :            :       /* For a '%s' and '%ls' directive with a non-constant string (either
    2536                 :            :          one of a number of strings of known length or an unknown string)
    2537                 :            :          the minimum number of characters is lesser of PRECISION[0] and
    2538                 :            :          the length of the shortest known string or zero, and the maximum
    2539                 :            :          is the lessser of the length of the longest known string or
    2540                 :            :          PTRDIFF_MAX and PRECISION[1].  The likely length is either
    2541                 :            :          the minimum at level 1 and the greater of the minimum and 1
    2542                 :            :          at level 2.  This result is adjust upward for width (if it's
    2543                 :            :          specified).  */
    2544                 :            : 
    2545                 :       8757 :       if (dir.specifier == 'S'
    2546                 :       8722 :           || dir.modifier == FMT_LEN_l)
    2547                 :            :         {
    2548                 :            :           /* A wide character converts to as few as zero bytes.  */
    2549                 :        179 :           slen.range.min = 0;
    2550                 :        179 :           if (slen.range.max < target_int_max ())
    2551                 :         43 :             slen.range.max *= target_mb_len_max ();
    2552                 :            : 
    2553                 :        179 :           if (slen.range.likely < target_int_max ())
    2554                 :         50 :             slen.range.likely *= 2;
    2555                 :            : 
    2556                 :        179 :           if (slen.range.likely < target_int_max ())
    2557                 :         50 :             slen.range.unlikely *= target_mb_len_max ();
    2558                 :            : 
    2559                 :            :           /* A non-empty wide character conversion may fail.  */
    2560                 :        179 :           if (slen.range.max > 0)
    2561                 :        179 :             res.mayfail = true;
    2562                 :            :         }
    2563                 :            : 
    2564                 :       8757 :       res.range = slen.range;
    2565                 :            : 
    2566                 :       8757 :       if (dir.prec[0] >= 0)
    2567                 :            :         {
    2568                 :            :           /* Adjust the minimum to zero if the string length is unknown,
    2569                 :            :              or at most the lower bound of the precision otherwise.  */
    2570                 :        290 :           if (slen.range.min >= target_int_max ())
    2571                 :        133 :             res.range.min = 0;
    2572                 :        157 :           else if ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.min)
    2573                 :         21 :             res.range.min = dir.prec[0];
    2574                 :            : 
    2575                 :            :           /* Make both maxima no greater than the upper bound of precision.  */
    2576                 :        290 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max
    2577                 :        290 :               || slen.range.max >= target_int_max ())
    2578                 :            :             {
    2579                 :        218 :               res.range.max = dir.prec[1];
    2580                 :        218 :               res.range.unlikely = dir.prec[1];
    2581                 :            :             }
    2582                 :            : 
    2583                 :            :           /* If precision is constant, set the likely counter to the lesser
    2584                 :            :              of it and the maximum string length.  Otherwise, if the lower
    2585                 :            :              bound of precision is greater than zero, set the likely counter
    2586                 :            :              to the minimum.  Otherwise set it to zero or one based on
    2587                 :            :              the warning level.  */
    2588                 :        290 :           if (dir.prec[0] == dir.prec[1])
    2589                 :        156 :             res.range.likely
    2590                 :        156 :               = ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.max
    2591                 :            :                  ? dir.prec[0] : slen.range.max);
    2592                 :        134 :           else if (dir.prec[0] > 0)
    2593                 :         37 :             res.range.likely = res.range.min;
    2594                 :            :           else
    2595                 :         97 :             res.range.likely = warn_level > 1;
    2596                 :            :         }
    2597                 :       8467 :       else if (dir.prec[1] >= 0)
    2598                 :            :         {
    2599                 :         29 :           res.range.min = 0;
    2600                 :         29 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max)
    2601                 :         29 :             res.range.max = dir.prec[1];
    2602                 :         29 :           res.range.likely = dir.prec[1] ? warn_level > 1 : 0;
    2603                 :         29 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.unlikely)
    2604                 :         29 :             res.range.unlikely = dir.prec[1];
    2605                 :            :         }
    2606                 :       8438 :       else if (slen.range.min >= target_int_max ())
    2607                 :            :         {
    2608                 :       6216 :           res.range.min = 0;
    2609                 :       6216 :           res.range.max = HOST_WIDE_INT_MAX;
    2610                 :            :           /* At level 1 strings of unknown length are assumed to be
    2611                 :            :              empty, while at level 1 they are assumed to be one byte
    2612                 :            :              long.  */
    2613                 :       6216 :           res.range.likely = warn_level > 1;
    2614                 :       6216 :           res.range.unlikely = HOST_WIDE_INT_MAX;
    2615                 :            :         }
    2616                 :            :       else
    2617                 :            :         {
    2618                 :            :           /* A string of unknown length unconstrained by precision is
    2619                 :            :              assumed to be empty at level 1 and just one character long
    2620                 :            :              at higher levels.  */
    2621                 :       2222 :           if (res.range.likely >= target_int_max ())
    2622                 :        112 :             res.range.likely = warn_level > 1;
    2623                 :            :         }
    2624                 :            :     }
    2625                 :            : 
    2626                 :            :   /* If the argument isn't a nul-terminated string and the number
    2627                 :            :      of bytes on output isn't bounded by precision, set NONSTR.  */
    2628                 :     138722 :   if (slen.nonstr && slen.range.min < (unsigned HOST_WIDE_INT)dir.prec[0])
    2629                 :        135 :     res.nonstr = slen.nonstr;
    2630                 :            : 
    2631                 :            :   /* Bump up the byte counters if WIDTH is greater.  */
    2632                 :     138722 :   return res.adjust_for_width_or_precision (dir.width);
    2633                 :            : }
    2634                 :            : 
    2635                 :            : /* Format plain string (part of the format string itself).  */
    2636                 :            : 
    2637                 :            : static fmtresult
    2638                 :     314075 : format_plain (const directive &dir, tree, const vr_values *)
    2639                 :            : {
    2640                 :     314075 :   fmtresult res (dir.len);
    2641                 :     314075 :   return res;
    2642                 :            : }
    2643                 :            : 
    2644                 :            : /* Return true if the RESULT of a directive in a call describe by INFO
    2645                 :            :    should be diagnosed given the AVAILable space in the destination.  */
    2646                 :            : 
    2647                 :            : static bool
    2648                 :     546928 : should_warn_p (const call_info &info,
    2649                 :            :                const result_range &avail, const result_range &result)
    2650                 :            : {
    2651                 :     546928 :   if (result.max <= avail.min)
    2652                 :            :     {
    2653                 :            :       /* The least amount of space remaining in the destination is big
    2654                 :            :          enough for the longest output.  */
    2655                 :            :       return false;
    2656                 :            :     }
    2657                 :            : 
    2658                 :       9770 :   if (info.bounded)
    2659                 :            :     {
    2660                 :        769 :       if (warn_format_trunc == 1 && result.min <= avail.max
    2661                 :       2041 :           && info.retval_used ())
    2662                 :            :         {
    2663                 :            :           /* The likely amount of space remaining in the destination is big
    2664                 :            :              enough for the least output and the return value is used.  */
    2665                 :            :           return false;
    2666                 :            :         }
    2667                 :            : 
    2668                 :        714 :       if (warn_format_trunc == 1 && result.likely <= avail.likely
    2669                 :       1906 :           && !info.retval_used ())
    2670                 :            :         {
    2671                 :            :           /* The likely amount of space remaining in the destination is big
    2672                 :            :              enough for the likely output and the return value is unused.  */
    2673                 :            :           return false;
    2674                 :            :         }
    2675                 :            : 
    2676                 :        596 :       if (warn_format_trunc == 2
    2677                 :         22 :           && result.likely <= avail.min
    2678                 :          7 :           && (result.max <= avail.min
    2679                 :          7 :               || result.max > HOST_WIDE_INT_MAX))
    2680                 :            :         {
    2681                 :            :           /* The minimum amount of space remaining in the destination is big
    2682                 :            :              enough for the longest output.  */
    2683                 :          7 :           return false;
    2684                 :            :         }
    2685                 :            :     }
    2686                 :            :   else
    2687                 :            :     {
    2688                 :       8464 :       if (warn_level == 1 && result.likely <= avail.likely)
    2689                 :            :         {
    2690                 :            :           /* The likely amount of space remaining in the destination is big
    2691                 :            :              enough for the likely output.  */
    2692                 :            :           return false;
    2693                 :            :         }
    2694                 :            : 
    2695                 :       5481 :       if (warn_level == 2
    2696                 :        301 :           && result.likely <= avail.min
    2697                 :            :           && (result.max <= avail.min
    2698                 :        195 :               || result.max > HOST_WIDE_INT_MAX))
    2699                 :            :         {
    2700                 :            :           /* The minimum amount of space remaining in the destination is big
    2701                 :            :              enough for the longest output.  */
    2702                 :        130 :           return false;
    2703                 :            :         }
    2704                 :            :     }
    2705                 :            : 
    2706                 :            :   return true;
    2707                 :            : }
    2708                 :            : 
    2709                 :            : /* At format string location describe by DIRLOC in a call described
    2710                 :            :    by INFO, issue a warning for a directive DIR whose output may be
    2711                 :            :    in excess of the available space AVAIL_RANGE in the destination
    2712                 :            :    given the formatting result FMTRES.  This function does nothing
    2713                 :            :    except decide whether to issue a warning for a possible write
    2714                 :            :    past the end or truncation and, if so, format the warning.
    2715                 :            :    Return true if a warning has been issued.  */
    2716                 :            : 
    2717                 :            : static bool
    2718                 :     546928 : maybe_warn (substring_loc &dirloc, location_t argloc,
    2719                 :            :             const call_info &info,
    2720                 :            :             const result_range &avail_range, const result_range &res,
    2721                 :            :             const directive &dir)
    2722                 :            : {
    2723                 :     546928 :   if (!should_warn_p (info, avail_range, res))
    2724                 :            :     return false;
    2725                 :            : 
    2726                 :            :   /* A warning will definitely be issued below.  */
    2727                 :            : 
    2728                 :            :   /* The maximum byte count to reference in the warning.  Larger counts
    2729                 :            :      imply that the upper bound is unknown (and could be anywhere between
    2730                 :            :      RES.MIN + 1 and SIZE_MAX / 2) are printed as "N or more bytes" rather
    2731                 :            :      than "between N and X" where X is some huge number.  */
    2732                 :       5940 :   unsigned HOST_WIDE_INT maxbytes = target_dir_max ();
    2733                 :            : 
    2734                 :            :   /* True when there is enough room in the destination for the least
    2735                 :            :      amount of a directive's output but not enough for its likely or
    2736                 :            :      maximum output.  */
    2737                 :      11880 :   bool maybe = (res.min <= avail_range.max
    2738                 :       5940 :                 && (avail_range.min < res.likely
    2739                 :       3359 :                     || (res.max < HOST_WIDE_INT_MAX
    2740                 :        275 :                         && avail_range.min < res.max)));
    2741                 :            : 
    2742                 :            :   /* Buffer for the directive in the host character set (used when
    2743                 :            :      the source character set is different).  */
    2744                 :       5940 :   char hostdir[32];
    2745                 :            : 
    2746                 :       5940 :   if (avail_range.min == avail_range.max)
    2747                 :            :     {
    2748                 :            :       /* The size of the destination region is exact.  */
    2749                 :       5130 :       unsigned HOST_WIDE_INT navail = avail_range.max;
    2750                 :            : 
    2751                 :       5130 :       if (target_to_host (*dir.beg) != '%')
    2752                 :            :         {
    2753                 :            :           /* For plain character directives (i.e., the format string itself)
    2754                 :            :              but not others, point the caret at the first character that's
    2755                 :            :              past the end of the destination.  */
    2756                 :        634 :           if (navail < dir.len)
    2757                 :        634 :             dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
    2758                 :            :         }
    2759                 :            : 
    2760                 :       5130 :       if (*dir.beg == '\0')
    2761                 :            :         {
    2762                 :            :           /* This is the terminating nul.  */
    2763                 :        578 :           gcc_assert (res.min == 1 && res.min == res.max);
    2764                 :            : 
    2765                 :       1019 :           return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    2766                 :        578 :                           info.bounded
    2767                 :            :                           ? (maybe
    2768                 :        137 :                              ? G_("%qE output may be truncated before the "
    2769                 :            :                                   "last format character")
    2770                 :            :                              : G_("%qE output truncated before the last "
    2771                 :            :                                   "format character"))
    2772                 :            :                           : (maybe
    2773                 :        441 :                              ? G_("%qE may write a terminating nul past the "
    2774                 :            :                                   "end of the destination")
    2775                 :            :                              : G_("%qE writing a terminating nul past the "
    2776                 :            :                                   "end of the destination")),
    2777                 :       1156 :                           info.func);
    2778                 :            :         }
    2779                 :            : 
    2780                 :       4552 :       if (res.min == res.max)
    2781                 :            :         {
    2782                 :        394 :           const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
    2783                 :        394 :           if (!info.bounded)
    2784                 :        344 :             return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2785                 :            :                               "%<%.*s%> directive writing %wu byte into a "
    2786                 :            :                               "region of size %wu",
    2787                 :            :                               "%<%.*s%> directive writing %wu bytes into a "
    2788                 :            :                               "region of size %wu",
    2789                 :        344 :                               (int) dir.len, d, res.min, navail);
    2790                 :         50 :           else if (maybe)
    2791                 :          0 :             return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2792                 :            :                               "%<%.*s%> directive output may be truncated "
    2793                 :            :                               "writing %wu byte into a region of size %wu",
    2794                 :            :                               "%<%.*s%> directive output may be truncated "
    2795                 :            :                               "writing %wu bytes into a region of size %wu",
    2796                 :          0 :                               (int) dir.len, d, res.min, navail);
    2797                 :            :           else
    2798                 :         50 :             return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2799                 :            :                               "%<%.*s%> directive output truncated writing "
    2800                 :            :                               "%wu byte into a region of size %wu",
    2801                 :            :                               "%<%.*s%> directive output truncated writing "
    2802                 :            :                               "%wu bytes into a region of size %wu",
    2803                 :         50 :                               (int) dir.len, d, res.min, navail);
    2804                 :            :         }
    2805                 :       4158 :       if (res.min == 0 && res.max < maxbytes)
    2806                 :        612 :         return fmtwarn (dirloc, argloc, NULL,
    2807                 :            :                         info.warnopt (),
    2808                 :        207 :                         info.bounded
    2809                 :            :                         ? (maybe
    2810                 :          9 :                            ? G_("%<%.*s%> directive output may be truncated "
    2811                 :            :                                 "writing up to %wu bytes into a region of "
    2812                 :            :                                 "size %wu")
    2813                 :            :                            : G_("%<%.*s%> directive output truncated writing "
    2814                 :            :                                 "up to %wu bytes into a region of size %wu"))
    2815                 :            :                         : G_("%<%.*s%> directive writing up to %wu bytes "
    2816                 :        207 :                              "into a region of size %wu"), (int) dir.len,
    2817                 :            :                         target_to_host (hostdir, sizeof hostdir, dir.beg),
    2818                 :        207 :                         res.max, navail);
    2819                 :            : 
    2820                 :       3951 :       if (res.min == 0 && maxbytes <= res.max)
    2821                 :            :         /* This is a special case to avoid issuing the potentially
    2822                 :            :            confusing warning:
    2823                 :            :              writing 0 or more bytes into a region of size 0.  */
    2824                 :       6017 :         return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2825                 :       3091 :                         info.bounded
    2826                 :            :                         ? (maybe
    2827                 :        165 :                            ? G_("%<%.*s%> directive output may be truncated "
    2828                 :            :                                 "writing likely %wu or more bytes into a "
    2829                 :            :                                 "region of size %wu")
    2830                 :            :                            : G_("%<%.*s%> directive output truncated writing "
    2831                 :            :                                 "likely %wu or more bytes into a region of "
    2832                 :            :                                 "size %wu"))
    2833                 :            :                         : G_("%<%.*s%> directive writing likely %wu or more "
    2834                 :       3091 :                              "bytes into a region of size %wu"), (int) dir.len,
    2835                 :            :                         target_to_host (hostdir, sizeof hostdir, dir.beg),
    2836                 :       6182 :                         res.likely, navail);
    2837                 :            : 
    2838                 :        860 :       if (res.max < maxbytes)
    2839                 :       2493 :         return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2840                 :        855 :                         info.bounded
    2841                 :            :                         ? (maybe
    2842                 :         72 :                            ? G_("%<%.*s%> directive output may be truncated "
    2843                 :            :                                 "writing between %wu and %wu bytes into a "
    2844                 :            :                                 "region of size %wu")
    2845                 :            :                            : G_("%<%.*s%> directive output truncated "
    2846                 :            :                                 "writing between %wu and %wu bytes into a "
    2847                 :            :                                 "region of size %wu"))
    2848                 :            :                         : G_("%<%.*s%> directive writing between %wu and "
    2849                 :            :                              "%wu bytes into a region of size %wu"),
    2850                 :        855 :                         (int) dir.len,
    2851                 :            :                         target_to_host (hostdir, sizeof hostdir, dir.beg),
    2852                 :        855 :                         res.min, res.max, navail);
    2853                 :            : 
    2854                 :         15 :       return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2855                 :          5 :                       info.bounded
    2856                 :            :                       ? (maybe
    2857                 :          0 :                          ? G_("%<%.*s%> directive output may be truncated "
    2858                 :            :                               "writing %wu or more bytes into a region of "
    2859                 :            :                               "size %wu")
    2860                 :            :                          : G_("%<%.*s%> directive output truncated writing "
    2861                 :            :                               "%wu or more bytes into a region of size %wu"))
    2862                 :            :                       : G_("%<%.*s%> directive writing %wu or more bytes "
    2863                 :          5 :                            "into a region of size %wu"), (int) dir.len,
    2864                 :            :                       target_to_host (hostdir, sizeof hostdir, dir.beg),
    2865                 :          5 :                       res.min, navail);
    2866                 :            :     }
    2867                 :            : 
    2868                 :            :   /* The size of the destination region is a range.  */
    2869                 :            : 
    2870                 :        810 :   if (target_to_host (*dir.beg) != '%')
    2871                 :            :     {
    2872                 :        617 :       unsigned HOST_WIDE_INT navail = avail_range.max;
    2873                 :            : 
    2874                 :            :       /* For plain character directives (i.e., the format string itself)
    2875                 :            :          but not others, point the caret at the first character that's
    2876                 :            :          past the end of the destination.  */
    2877                 :        617 :       if (navail < dir.len)
    2878                 :          1 :         dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
    2879                 :            :     }
    2880                 :            : 
    2881                 :        810 :   if (*dir.beg == '\0')
    2882                 :            :     {
    2883                 :        474 :       gcc_assert (res.min == 1 && res.min == res.max);
    2884                 :            : 
    2885                 :        867 :       return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    2886                 :        474 :                       info.bounded
    2887                 :            :                       ? (maybe
    2888                 :         81 :                          ? G_("%qE output may be truncated before the last "
    2889                 :            :                               "format character")
    2890                 :            :                          : G_("%qE output truncated before the last format "
    2891                 :            :                               "character"))
    2892                 :            :                       : (maybe
    2893                 :        393 :                          ? G_("%qE may write a terminating nul past the end "
    2894                 :            :                               "of the destination")
    2895                 :            :                          : G_("%qE writing a terminating nul past the end "
    2896                 :        948 :                               "of the destination")), info.func);
    2897                 :            :     }
    2898                 :            : 
    2899                 :        336 :   if (res.min == res.max)
    2900                 :            :     {
    2901                 :        145 :       const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
    2902                 :        145 :       if (!info.bounded)
    2903                 :        129 :         return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2904                 :            :                           "%<%.*s%> directive writing %wu byte into a region "
    2905                 :            :                           "of size between %wu and %wu",
    2906                 :            :                           "%<%.*s%> directive writing %wu bytes into a region "
    2907                 :        129 :                           "of size between %wu and %wu", (int) dir.len, d,
    2908                 :        129 :                           res.min, avail_range.min, avail_range.max);
    2909                 :         16 :       else if (maybe)
    2910                 :         15 :         return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2911                 :            :                           "%<%.*s%> directive output may be truncated writing "
    2912                 :            :                           "%wu byte into a region of size between %wu and %wu",
    2913                 :            :                           "%<%.*s%> directive output may be truncated writing "
    2914                 :            :                           "%wu bytes into a region of size between %wu and "
    2915                 :         15 :                           "%wu", (int) dir.len, d, res.min, avail_range.min,
    2916                 :         15 :                           avail_range.max);
    2917                 :            :       else
    2918                 :          1 :         return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2919                 :            :                           "%<%.*s%> directive output truncated writing %wu "
    2920                 :            :                           "byte into a region of size between %wu and %wu",
    2921                 :            :                           "%<%.*s%> directive output truncated writing %wu "
    2922                 :            :                           "bytes into a region of size between %wu and %wu",
    2923                 :          1 :                           (int) dir.len, d, res.min, avail_range.min,
    2924                 :          1 :                           avail_range.max);
    2925                 :            :     }
    2926                 :            : 
    2927                 :        191 :   if (res.min == 0 && res.max < maxbytes)
    2928                 :          3 :     return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2929                 :          1 :                     info.bounded
    2930                 :            :                     ? (maybe
    2931                 :          0 :                        ? G_("%<%.*s%> directive output may be truncated "
    2932                 :            :                             "writing up to %wu bytes into a region of size "
    2933                 :            :                             "between %wu and %wu")
    2934                 :            :                        : G_("%<%.*s%> directive output truncated writing "
    2935                 :            :                             "up to %wu bytes into a region of size between "
    2936                 :            :                             "%wu and %wu"))
    2937                 :            :                     : G_("%<%.*s%> directive writing up to %wu bytes "
    2938                 :            :                          "into a region of size between %wu and %wu"),
    2939                 :          1 :                     (int) dir.len,
    2940                 :            :                     target_to_host (hostdir, sizeof hostdir, dir.beg),
    2941                 :          1 :                     res.max, avail_range.min, avail_range.max);
    2942                 :            : 
    2943                 :        190 :   if (res.min == 0 && maxbytes <= res.max)
    2944                 :            :     /* This is a special case to avoid issuing the potentially confusing
    2945                 :            :        warning:
    2946                 :            :          writing 0 or more bytes into a region of size between 0 and N.  */
    2947                 :          2 :     return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2948                 :          1 :                     info.bounded
    2949                 :            :                     ? (maybe
    2950                 :          0 :                        ? G_("%<%.*s%> directive output may be truncated "
    2951                 :            :                             "writing likely %wu or more bytes into a region "
    2952                 :            :                             "of size between %wu and %wu")
    2953                 :            :                        : G_("%<%.*s%> directive output truncated writing "
    2954                 :            :                             "likely %wu or more bytes into a region of size "
    2955                 :            :                             "between %wu and %wu"))
    2956                 :            :                     : G_("%<%.*s%> directive writing likely %wu or more bytes "
    2957                 :            :                          "into a region of size between %wu and %wu"),
    2958                 :          1 :                     (int) dir.len,
    2959                 :            :                     target_to_host (hostdir, sizeof hostdir, dir.beg),
    2960                 :          2 :                     res.likely, avail_range.min, avail_range.max);
    2961                 :            : 
    2962                 :        189 :   if (res.max < maxbytes)
    2963                 :        508 :     return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2964                 :        189 :                     info.bounded
    2965                 :            :                     ? (maybe
    2966                 :         59 :                        ? G_("%<%.*s%> directive output may be truncated "
    2967                 :            :                             "writing between %wu and %wu bytes into a region "
    2968                 :            :                             "of size between %wu and %wu")
    2969                 :            :                        : G_("%<%.*s%> directive output truncated writing "
    2970                 :            :                             "between %wu and %wu bytes into a region of size "
    2971                 :            :                             "between %wu and %wu"))
    2972                 :            :                     : G_("%<%.*s%> directive writing between %wu and "
    2973                 :            :                          "%wu bytes into a region of size between %wu and "
    2974                 :        189 :                          "%wu"), (int) dir.len,
    2975                 :            :                     target_to_host (hostdir, sizeof hostdir, dir.beg),
    2976                 :        189 :                     res.min, res.max, avail_range.min, avail_range.max);
    2977                 :            : 
    2978                 :          0 :   return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2979                 :          0 :                   info.bounded
    2980                 :            :                   ? (maybe
    2981                 :          0 :                      ? G_("%<%.*s%> directive output may be truncated writing "
    2982                 :            :                           "%wu or more bytes into a region of size between "
    2983                 :            :                           "%wu and %wu")
    2984                 :            :                      : G_("%<%.*s%> directive output truncated writing "
    2985                 :            :                           "%wu or more bytes into a region of size between "
    2986                 :            :                           "%wu and %wu"))
    2987                 :            :                   : G_("%<%.*s%> directive writing %wu or more bytes "
    2988                 :            :                        "into a region of size between %wu and %wu"),
    2989                 :          0 :                   (int) dir.len,
    2990                 :            :                   target_to_host (hostdir, sizeof hostdir, dir.beg),
    2991                 :          0 :                   res.min, avail_range.min, avail_range.max);
    2992                 :            : }
    2993                 :            : 
    2994                 :            : /* Given the formatting result described by RES and NAVAIL, the number
    2995                 :            :    of available in the destination, return the range of bytes remaining
    2996                 :            :    in the destination.  */
    2997                 :            : 
    2998                 :            : static inline result_range
    2999                 :     548302 : bytes_remaining (unsigned HOST_WIDE_INT navail, const format_result &res)
    3000                 :            : {
    3001                 :     548302 :   result_range range;
    3002                 :            : 
    3003                 :     548302 :   if (HOST_WIDE_INT_MAX <= navail)
    3004                 :            :     {
    3005                 :     534056 :       range.min = range.max = range.likely = range.unlikely = navail;
    3006                 :     534056 :       return range;
    3007                 :            :     }
    3008                 :            : 
    3009                 :            :   /* The lower bound of the available range is the available size
    3010                 :            :      minus the maximum output size, and the upper bound is the size
    3011                 :            :      minus the minimum.  */
    3012                 :      14246 :   range.max = res.range.min < navail ? navail - res.range.min : 0;
    3013                 :            : 
    3014                 :      14246 :   range.likely = res.range.likely < navail ? navail - res.range.likely : 0;
    3015                 :            : 
    3016                 :      14246 :   if (res.range.max < HOST_WIDE_INT_MAX)
    3017                 :      10698 :     range.min = res.range.max < navail ? navail - res.range.max : 0;
    3018                 :            :   else
    3019                 :       3548 :     range.min = range.likely;
    3020                 :            : 
    3021                 :      28492 :   range.unlikely = (res.range.unlikely < navail
    3022                 :      14246 :                     ? navail - res.range.unlikely : 0);
    3023                 :            : 
    3024                 :      14246 :   return range;
    3025                 :            : }
    3026                 :            : 
    3027                 :            : /* Compute the length of the output resulting from the directive DIR
    3028                 :            :    in a call described by INFO and update the overall result of the call
    3029                 :            :    in *RES.  Return true if the directive has been handled.  */
    3030                 :            : 
    3031                 :            : static bool
    3032                 :     549584 : format_directive (const call_info &info,
    3033                 :            :                   format_result *res, const directive &dir,
    3034                 :            :                   const class vr_values *vr_values)
    3035                 :            : {
    3036                 :            :   /* Offset of the beginning of the directive from the beginning
    3037                 :            :      of the format string.  */
    3038                 :     549584 :   size_t offset = dir.beg - info.fmtstr;
    3039                 :     549584 :   size_t start = offset;
    3040                 :     549584 :   size_t length = offset + dir.len - !!dir.len;
    3041                 :            : 
    3042                 :            :   /* Create a location for the whole directive from the % to the format
    3043                 :            :      specifier.  */
    3044                 :    1099170 :   substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
    3045                 :     549584 :                         offset, start, length);
    3046                 :            : 
    3047                 :            :   /* Also get the location of the argument if possible.
    3048                 :            :      This doesn't work for integer literals or function calls.  */
    3049                 :     549584 :   location_t argloc = UNKNOWN_LOCATION;
    3050                 :     549584 :   if (dir.arg)
    3051                 :     233109 :     argloc = EXPR_LOCATION (dir.arg);
    3052                 :            : 
    3053                 :            :   /* Bail when there is no function to compute the output length,
    3054                 :            :      or when minimum length checking has been disabled.   */
    3055                 :     549584 :   if (!dir.fmtfunc || res->range.min >= HOST_WIDE_INT_MAX)
    3056                 :            :     return false;
    3057                 :            : 
    3058                 :            :   /* Compute the range of lengths of the formatted output.  */
    3059                 :     548454 :   fmtresult fmtres = dir.fmtfunc (dir, dir.arg, vr_values);
    3060                 :            : 
    3061                 :            :   /* Record whether the output of all directives is known to be
    3062                 :            :      bounded by some maximum, implying that their arguments are
    3063                 :            :      either known exactly or determined to be in a known range
    3064                 :            :      or, for strings, limited by the upper bounds of the arrays
    3065                 :            :      they refer to.  */
    3066                 :     548454 :   res->knownrange &= fmtres.knownrange;
    3067                 :            : 
    3068                 :     548454 :   if (!fmtres.knownrange)
    3069                 :            :     {
    3070                 :            :       /* Only when the range is known, check it against the host value
    3071                 :            :          of INT_MAX + (the number of bytes of the "%.*Lf" directive with
    3072                 :            :          INT_MAX precision, which is the longest possible output of any
    3073                 :            :          single directive).  That's the largest valid byte count (though
    3074                 :            :          not valid call to a printf-like function because it can never
    3075                 :            :          return such a count).  Otherwise, the range doesn't correspond
    3076                 :            :          to known values of the argument.  */
    3077                 :      38403 :       if (fmtres.range.max > target_dir_max ())
    3078                 :            :         {
    3079                 :            :           /* Normalize the MAX counter to avoid having to deal with it
    3080                 :            :              later.  The counter can be less than HOST_WIDE_INT_M1U
    3081                 :            :              when compiling for an ILP32 target on an LP64 host.  */
    3082                 :       6577 :           fmtres.range.max = HOST_WIDE_INT_M1U;
    3083                 :            :           /* Disable exact and maximum length checking after a failure
    3084                 :            :              to determine the maximum number of characters (for example
    3085                 :            :              for wide characters or wide character strings) but continue
    3086                 :            :              tracking the minimum number of characters.  */
    3087                 :       6577 :           res->range.max = HOST_WIDE_INT_M1U;
    3088                 :            :         }
    3089                 :            : 
    3090                 :      38403 :       if (fmtres.range.min > target_dir_max ())
    3091                 :            :         {
    3092                 :            :           /* Disable exact length checking after a failure to determine
    3093                 :            :              even the minimum number of characters (it shouldn't happen
    3094                 :            :              except in an error) but keep tracking the minimum and maximum
    3095                 :            :              number of characters.  */
    3096                 :            :           return true;
    3097                 :            :         }
    3098                 :            :     }
    3099                 :            : 
    3100                 :            :   /* Buffer for the directive in the host character set (used when
    3101                 :            :      the source character set is different).  */
    3102                 :     548335 :   char hostdir[32];
    3103                 :            : 
    3104                 :     548335 :   int dirlen = dir.len;
    3105                 :            : 
    3106                 :     548335 :   if (fmtres.nullp)
    3107                 :            :     {
    3108                 :         33 :       fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3109                 :            :                "%G%<%.*s%> directive argument is null",
    3110                 :         33 :                info.callstmt, dirlen,
    3111                 :         33 :                target_to_host (hostdir, sizeof hostdir, dir.beg));
    3112                 :            : 
    3113                 :            :       /* Don't bother processing the rest of the format string.  */
    3114                 :         33 :       res->warned = true;
    3115                 :         33 :       res->range.min = HOST_WIDE_INT_M1U;
    3116                 :         33 :       res->range.max = HOST_WIDE_INT_M1U;
    3117                 :         33 :       return false;
    3118                 :            :     }
    3119                 :            : 
    3120                 :            :   /* Compute the number of available bytes in the destination.  There
    3121                 :            :      must always be at least one byte of space for the terminating
    3122                 :            :      NUL that's appended after the format string has been processed.  */
    3123                 :     548302 :   result_range avail_range = bytes_remaining (info.objsize, *res);
    3124                 :            : 
    3125                 :            :   /* If the argument aliases a part of the destination of the formatted
    3126                 :            :      call at offset FMTRES.DST_OFFSET append the directive and its result
    3127                 :            :      to the set of aliases for later processing.  */
    3128                 :     548302 :   if (fmtres.dst_offset != HOST_WIDE_INT_MIN)
    3129                 :        212 :     res->append_alias (dir, fmtres.dst_offset, fmtres.range);
    3130                 :            : 
    3131                 :     548302 :   bool warned = res->warned;
    3132                 :            : 
    3133                 :     548302 :   if (!warned)
    3134                 :     546928 :     warned = maybe_warn (dirloc, argloc, info, avail_range,
    3135                 :            :                          fmtres.range, dir);
    3136                 :            : 
    3137                 :            :   /* Bump up the total maximum if it isn't too big.  */
    3138                 :     548302 :   if (res->range.max < HOST_WIDE_INT_MAX
    3139                 :     525017 :       && fmtres.range.max < HOST_WIDE_INT_MAX)
    3140                 :     525015 :     res->range.max += fmtres.range.max;
    3141                 :            : 
    3142                 :            :   /* Raise the total unlikely maximum by the larger of the maximum
    3143                 :            :      and the unlikely maximum.  */
    3144                 :     548302 :   unsigned HOST_WIDE_INT save = res->range.unlikely;
    3145                 :     548302 :   if (fmtres.range.max < fmtres.range.unlikely)
    3146                 :       6068 :     res->range.unlikely += fmtres.range.unlikely;
    3147                 :            :   else
    3148                 :     542234 :     res->range.unlikely += fmtres.range.max;
    3149                 :            : 
    3150                 :     548302 :   if (res->range.unlikely < save)
    3151                 :      23615 :     res->range.unlikely = HOST_WIDE_INT_M1U;
    3152                 :            : 
    3153                 :     548302 :   res->range.min += fmtres.range.min;
    3154                 :     548302 :   res->range.likely += fmtres.range.likely;
    3155                 :            : 
    3156                 :            :   /* Has the minimum directive output length exceeded the maximum
    3157                 :            :      of 4095 bytes required to be supported?  */
    3158                 :     548302 :   bool minunder4k = fmtres.range.min < 4096;
    3159                 :     548302 :   bool maxunder4k = fmtres.range.max < 4096;
    3160                 :            :   /* Clear POSUNDER4K in the overall result if the maximum has exceeded
    3161                 :            :      the 4k (this is necessary to avoid the return value optimization
    3162                 :            :      that may not be safe in the maximum case).  */
    3163                 :     548302 :   if (!maxunder4k)
    3164                 :       7293 :     res->posunder4k = false;
    3165                 :            :   /* Also clear POSUNDER4K if the directive may fail.  */
    3166                 :     548302 :   if (fmtres.mayfail)
    3167                 :        335 :     res->posunder4k = false;
    3168                 :            : 
    3169                 :     548302 :   if (!warned
    3170                 :            :       /* Only warn at level 2.  */
    3171                 :     545137 :       && warn_level > 1
    3172                 :            :       /* Only warn for string functions.  */
    3173                 :       1148 :       && info.is_string_func ()
    3174                 :     548680 :       && (!minunder4k
    3175                 :        376 :           || (!maxunder4k && fmtres.range.max < HOST_WIDE_INT_MAX)))
    3176                 :            :     {
    3177                 :            :       /* The directive output may be longer than the maximum required
    3178                 :            :          to be handled by an implementation according to 7.21.6.1, p15
    3179                 :            :          of C11.  Warn on this only at level 2 but remember this and
    3180                 :            :          prevent folding the return value when done.  This allows for
    3181                 :            :          the possibility of the actual libc call failing due to ENOMEM
    3182                 :            :          (like Glibc does with very large precision or width).
    3183                 :            :          Issue the "may exceed" warning only for string functions and
    3184                 :            :          not for fprintf or printf.  */
    3185                 :            : 
    3186                 :          6 :       if (fmtres.range.min == fmtres.range.max)
    3187                 :          2 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3188                 :            :                           "%<%.*s%> directive output of %wu bytes exceeds "
    3189                 :            :                           "minimum required size of 4095", dirlen,
    3190                 :          2 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3191                 :            :                           fmtres.range.min);
    3192                 :          4 :       else if (!minunder4k)
    3193                 :          0 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3194                 :            :                           "%<%.*s%> directive output between %wu and %wu "
    3195                 :            :                           "bytes exceeds minimum required size of 4095",
    3196                 :            :                           dirlen,
    3197                 :          0 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3198                 :            :                           fmtres.range.min, fmtres.range.max);
    3199                 :          4 :       else if (!info.retval_used () && info.is_string_func ())
    3200                 :          2 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3201                 :            :                           "%<%.*s%> directive output between %wu and %wu "
    3202                 :            :                           "bytes may exceed minimum required size of "
    3203                 :            :                           "4095",
    3204                 :            :                           dirlen,
    3205                 :          2 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3206                 :            :                           fmtres.range.min, fmtres.range.max);
    3207                 :            :     }
    3208                 :            : 
    3209                 :            :   /* Has the likely and maximum directive output exceeded INT_MAX?  */
    3210                 :     548302 :   bool likelyximax = *dir.beg && res->range.likely > target_int_max ();
    3211                 :            :   /* Don't consider the maximum to be in excess when it's the result
    3212                 :            :      of a string of unknown length (i.e., whose maximum has been set
    3213                 :            :      to be greater than or equal to HOST_WIDE_INT_MAX.  */
    3214                 :     548302 :   bool maxximax = (*dir.beg
    3215                 :     473446 :                    && res->range.max > target_int_max ()
    3216                 :     566105 :                    && res->range.max < HOST_WIDE_INT_MAX);
    3217                 :            : 
    3218                 :     548302 :   if (!warned
    3219                 :            :       /* Warn for the likely output size at level 1.  */
    3220                 :     545133 :       && (likelyximax
    3221                 :            :           /* But only warn for the maximum at level 2.  */
    3222                 :     544995 :           || (warn_level > 1
    3223                 :       1040 :               && maxximax
    3224                 :         84 :               && fmtres.range.max < HOST_WIDE_INT_MAX)))
    3225                 :            :     {
    3226                 :        222 :       if (fmtres.range.min > target_int_max ())
    3227                 :            :         {
    3228                 :            :           /* The directive output exceeds INT_MAX bytes.  */
    3229                 :         32 :           if (fmtres.range.min == fmtres.range.max)
    3230                 :         40 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3231                 :            :                               "%<%.*s%> directive output of %wu bytes exceeds "
    3232                 :            :                               "%<INT_MAX%>", dirlen,
    3233                 :            :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3234                 :            :                               fmtres.range.min);
    3235                 :            :           else
    3236                 :         24 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3237                 :            :                               "%<%.*s%> directive output between %wu and "
    3238                 :            :                               "%wu bytes exceeds %<INT_MAX%>", dirlen,
    3239                 :            :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3240                 :            :                               fmtres.range.min, fmtres.range.max);
    3241                 :            :         }
    3242                 :        190 :       else if (res->range.min > target_int_max ())
    3243                 :            :         {
    3244                 :            :           /* The directive output is under INT_MAX but causes the result
    3245                 :            :              to exceed INT_MAX bytes.  */
    3246                 :        104 :           if (fmtres.range.min == fmtres.range.max)
    3247                 :        182 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3248                 :            :                               "%<%.*s%> directive output of %wu bytes causes "
    3249                 :            :                               "result to exceed %<INT_MAX%>", dirlen,
    3250                 :            :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3251                 :            :                               fmtres.range.min);
    3252                 :            :           else
    3253                 :         26 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3254                 :            :                               "%<%.*s%> directive output between %wu and "
    3255                 :            :                               "%wu bytes causes result to exceed %<INT_MAX%>",
    3256                 :            :                               dirlen,
    3257                 :            :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3258                 :            :                               fmtres.range.min, fmtres.range.max);
    3259                 :            :         }
    3260                 :         86 :       else if ((!info.retval_used () || !info.bounded)
    3261                 :         86 :                && (info.is_string_func ()))
    3262                 :            :         /* Warn for calls to string functions that either aren't bounded
    3263                 :            :            (sprintf) or whose return value isn't used.  */
    3264                 :          0 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3265                 :            :                           "%<%.*s%> directive output between %wu and "
    3266                 :            :                           "%wu bytes may cause result to exceed "
    3267                 :            :                           "%<INT_MAX%>", dirlen,
    3268                 :          0 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3269                 :            :                           fmtres.range.min, fmtres.range.max);
    3270                 :            :     }
    3271                 :            : 
    3272                 :     548302 :   if (!warned && fmtres.nonstr)
    3273                 :            :     {
    3274                 :        268 :       warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3275                 :            :                         "%<%.*s%> directive argument is not a nul-terminated "
    3276                 :            :                         "string",
    3277                 :            :                         dirlen,
    3278                 :        135 :                         target_to_host (hostdir, sizeof hostdir, dir.beg));
    3279                 :        135 :       if (warned && DECL_P (fmtres.nonstr))
    3280                 :         45 :         inform (DECL_SOURCE_LOCATION (fmtres.nonstr),
    3281                 :            :                 "referenced argument declared here");
    3282                 :        135 :       return false;
    3283                 :            :     }
    3284                 :            : 
    3285                 :     548167 :   if (warned && fmtres.range.min < fmtres.range.likely
    3286                 :        557 :       && fmtres.range.likely < fmtres.range.max)
    3287                 :        333 :     inform_n (info.fmtloc, fmtres.range.likely,
    3288                 :            :               "assuming directive output of %wu byte",
    3289                 :            :               "assuming directive output of %wu bytes",
    3290                 :            :               fmtres.range.likely);
    3291                 :            : 
    3292                 :     548167 :   if (warned && fmtres.argmin)
    3293                 :            :     {
    3294                 :        369 :       if (fmtres.argmin == fmtres.argmax)
    3295                 :          0 :         inform (info.fmtloc, "directive argument %qE", fmtres.argmin);
    3296                 :        369 :       else if (fmtres.knownrange)
    3297                 :        163 :         inform (info.fmtloc, "directive argument in the range [%E, %E]",
    3298                 :            :                 fmtres.argmin, fmtres.argmax);
    3299                 :            :       else
    3300                 :        206 :         inform (info.fmtloc,
    3301                 :            :                 "using the range [%E, %E] for directive argument",
    3302                 :            :                 fmtres.argmin, fmtres.argmax);
    3303                 :            :     }
    3304                 :            : 
    3305                 :     548167 :   res->warned |= warned;
    3306                 :            : 
    3307                 :     548167 :   if (!dir.beg[0] && res->warned)
    3308                 :            :     {
    3309                 :       1929 :       location_t callloc = gimple_location (info.callstmt);
    3310                 :            : 
    3311                 :       1929 :       unsigned HOST_WIDE_INT min = res->range.min;
    3312                 :       1929 :       unsigned HOST_WIDE_INT max = res->range.max;
    3313                 :            : 
    3314                 :       1929 :       if (info.objsize < HOST_WIDE_INT_MAX)
    3315                 :            :         {
    3316                 :            :           /* If a warning has been issued for buffer overflow or truncation
    3317                 :            :              help the user figure out how big a buffer they need.  */
    3318                 :            : 
    3319                 :       1791 :           if (min == max)
    3320                 :        661 :             inform_n (callloc, min,
    3321                 :            :                       "%qE output %wu byte into a destination of size %wu",
    3322                 :            :                       "%qE output %wu bytes into a destination of size %wu",
    3323                 :        661 :                       info.func, min, info.objsize);
    3324                 :       1130 :           else if (max < HOST_WIDE_INT_MAX)
    3325                 :       1086 :             inform (callloc,
    3326                 :            :                     "%qE output between %wu and %wu bytes into "
    3327                 :            :                     "a destination of size %wu",
    3328                 :       1086 :                     info.func, min, max, info.objsize);
    3329                 :         44 :           else if (min < res->range.likely && res->range.likely < max)
    3330                 :         25 :             inform (callloc,
    3331                 :            :                     "%qE output %wu or more bytes (assuming %wu) into "
    3332                 :            :                     "a destination of size %wu",
    3333                 :         25 :                     info.func, min, res->range.likely, info.objsize);
    3334                 :            :           else
    3335                 :         19 :             inform (callloc,
    3336                 :            :                     "%qE output %wu or more bytes into a destination of size "
    3337                 :            :                     "%wu",
    3338                 :         19 :                     info.func, min, info.objsize);
    3339                 :            :         }
    3340                 :        138 :       else if (!info.is_string_func ())
    3341                 :            :         {
    3342                 :            :           /* If the warning is for a file function like fprintf
    3343                 :            :              of printf with no destination size just print the computed
    3344                 :            :              result.  */
    3345                 :        129 :           if (min == max)
    3346                 :         77 :             inform_n (callloc, min,
    3347                 :            :                       "%qE output %wu byte", "%qE output %wu bytes",
    3348                 :         77 :                       info.func, min);
    3349                 :         52 :           else if (max < HOST_WIDE_INT_MAX)
    3350                 :         12 :             inform (callloc,
    3351                 :            :                     "%qE output between %wu and %wu bytes",
    3352                 :         12 :                     info.func, min, max);
    3353                 :         40 :           else if (min < res->range.likely && res->range.likely < max)
    3354                 :          0 :             inform (callloc,
    3355                 :            :                     "%qE output %wu or more bytes (assuming %wu)",
    3356                 :          0 :                     info.func, min, res->range.likely);
    3357                 :            :           else
    3358                 :         40 :             inform (callloc,
    3359                 :            :                     "%qE output %wu or more bytes",
    3360                 :         40 :                     info.func, min);
    3361                 :            :         }
    3362                 :            :     }
    3363                 :            : 
    3364                 :     548167 :   if (dump_file && *dir.beg)
    3365                 :            :     {
    3366                 :          0 :       fprintf (dump_file,
    3367                 :            :                "    Result: "
    3368                 :            :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", "
    3369                 :            :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC " ("
    3370                 :            :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", "
    3371                 :            :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ")\n",
    3372                 :            :                fmtres.range.min, fmtres.range.likely,
    3373                 :            :                fmtres.range.max, fmtres.range.unlikely,
    3374                 :            :                res->range.min, res->range.likely,
    3375                 :            :                res->range.max, res->range.unlikely);
    3376                 :            :     }
    3377                 :            : 
    3378                 :            :   return true;
    3379                 :            : }
    3380                 :            : 
    3381                 :            : /* Parse a format directive in function call described by INFO starting
    3382                 :            :    at STR and populate DIR structure.  Bump up *ARGNO by the number of
    3383                 :            :    arguments extracted for the directive.  Return the length of
    3384                 :            :    the directive.  */
    3385                 :            : 
    3386                 :            : static size_t
    3387                 :     549584 : parse_directive (call_info &info,
    3388                 :            :                  directive &dir, format_result *res,
    3389                 :            :                  const char *str, unsigned *argno,
    3390                 :            :                  const vr_values *vr_values)
    3391                 :            : {
    3392                 :     549584 :   const char *pcnt = strchr (str, target_percent);
    3393                 :     549584 :   dir.beg = str;
    3394                 :            : 
    3395                 :     549584 :   if (size_t len = pcnt ? pcnt - str : *str ? strlen (str) : 1)
    3396                 :            :     {
    3397                 :            :       /* This directive is either a plain string or the terminating nul
    3398                 :            :          (which isn't really a directive but it simplifies things to
    3399                 :            :          handle it as if it were).  */
    3400                 :     314077 :       dir.len = len;
    3401                 :     314077 :       dir.fmtfunc = format_plain;
    3402                 :            : 
    3403                 :     314077 :       if (dump_file)
    3404                 :            :         {
    3405                 :          0 :           fprintf (dump_file, "  Directive %u at offset "
    3406                 :            :                    HOST_WIDE_INT_PRINT_UNSIGNED ": \"%.*s\", "
    3407                 :            :                    "length = " HOST_WIDE_INT_PRINT_UNSIGNED "\n",
    3408                 :            :                    dir.dirno,
    3409                 :          0 :                    (unsigned HOST_WIDE_INT)(size_t)(dir.beg - info.fmtstr),
    3410                 :            :                    (int)dir.len, dir.beg, (unsigned HOST_WIDE_INT) dir.len);
    3411                 :            :         }
    3412                 :            : 
    3413                 :     314077 :       return len - !*str;
    3414                 :            :     }
    3415                 :            : 
    3416                 :            :   /* Set the directive argument's number to correspond to its position
    3417                 :            :      in the formatted function call's argument list.  */
    3418                 :     235507 :   dir.argno = *argno;
    3419                 :            : 
    3420                 :     235507 :   const char *pf = pcnt + 1;
    3421                 :            : 
    3422                 :            :     /* POSIX numbered argument index or zero when none.  */
    3423                 :     235507 :   HOST_WIDE_INT dollar = 0;
    3424                 :            : 
    3425                 :            :   /* With and precision.  -1 when not specified, HOST_WIDE_INT_MIN
    3426                 :            :      when given by a va_list argument, and a non-negative value
    3427                 :            :      when specified in the format string itself.  */
    3428                 :     235507 :   HOST_WIDE_INT width = -1;
    3429                 :     235507 :   HOST_WIDE_INT precision = -1;
    3430                 :            : 
    3431                 :            :   /* Pointers to the beginning of the width and precision decimal
    3432                 :            :      string (if any) within the directive.  */
    3433                 :     235507 :   const char *pwidth = 0;
    3434                 :     235507 :   const char *pprec = 0;
    3435                 :            : 
    3436                 :            :   /* When the value of the decimal string that specifies width or
    3437                 :            :      precision is out of range, points to the digit that causes
    3438                 :            :      the value to exceed the limit.  */
    3439                 :     235507 :   const char *werange = NULL;
    3440                 :     235507 :   const char *perange = NULL;
    3441                 :            : 
    3442                 :            :   /* Width specified via the asterisk.  Need not be INTEGER_CST.
    3443                 :            :      For vararg functions set to void_node.  */
    3444                 :     235507 :   tree star_width = NULL_TREE;
    3445                 :            : 
    3446                 :            :   /* Width specified via the asterisk.  Need not be INTEGER_CST.
    3447                 :            :      For vararg functions set to void_node.  */
    3448                 :     235507 :   tree star_precision = NULL_TREE;
    3449                 :            : 
    3450                 :     235507 :   if (ISDIGIT (target_to_host (*pf)))
    3451                 :            :     {
    3452                 :            :       /* This could be either a POSIX positional argument, the '0'
    3453                 :            :          flag, or a width, depending on what follows.  Store it as
    3454                 :            :          width and sort it out later after the next character has
    3455                 :            :          been seen.  */
    3456                 :       1044 :       pwidth = pf;
    3457                 :       1044 :       width = target_strtowi (&pf, &werange);
    3458                 :            :     }
    3459                 :     234463 :   else if (target_to_host (*pf) == '*')
    3460                 :            :     {
    3461                 :            :       /* Similarly to the block above, this could be either a POSIX
    3462                 :            :          positional argument or a width, depending on what follows.  */
    3463                 :        765 :       if (*argno < gimple_call_num_args (info.callstmt))
    3464                 :        753 :         star_width = gimple_call_arg (info.callstmt, (*argno)++);
    3465                 :            :       else
    3466                 :         12 :         star_width = void_node;
    3467                 :        765 :       ++pf;
    3468                 :            :     }
    3469                 :            : 
    3470                 :     235507 :   if (target_to_host (*pf) == '$')
    3471                 :            :     {
    3472                 :            :       /* Handle the POSIX dollar sign which references the 1-based
    3473                 :            :          positional argument number.  */
    3474                 :        110 :       if (width != -1)
    3475                 :        110 :         dollar = width + info.argidx;
    3476                 :          0 :       else if (star_width
    3477                 :          0 :                && TREE_CODE (star_width) == INTEGER_CST
    3478                 :          0 :                && (TYPE_PRECISION (TREE_TYPE (star_width))
    3479                 :          0 :                    <= TYPE_PRECISION (integer_type_node)))
    3480                 :          0 :         dollar = width + tree_to_shwi (star_width);
    3481                 :            : 
    3482                 :            :       /* Bail when the numbered argument is out of range (it will
    3483                 :            :          have already been diagnosed by -Wformat).  */
    3484                 :        110 :       if (dollar == 0
    3485                 :        106 :           || dollar == (int)info.argidx
    3486                 :        214 :           || dollar > gimple_call_num_args (info.callstmt))
    3487                 :            :         return false;
    3488                 :            : 
    3489                 :         96 :       --dollar;
    3490                 :            : 
    3491                 :         96 :       star_width = NULL_TREE;
    3492                 :         96 :       width = -1;
    3493                 :         96 :       ++pf;
    3494                 :            :     }
    3495                 :            : 
    3496                 :     235493 :   if (dollar || !star_width)
    3497                 :            :     {
    3498                 :     234728 :       if (width != -1)
    3499                 :            :         {
    3500                 :        934 :           if (width == 0)
    3501                 :            :             {
    3502                 :            :               /* The '0' that has been interpreted as a width above is
    3503                 :            :                  actually a flag.  Reset HAVE_WIDTH, set the '0' flag,
    3504                 :            :                  and continue processing other flags.  */
    3505                 :        142 :               width = -1;
    3506                 :     233936 :               dir.set_flag ('0');
    3507                 :            :             }
    3508                 :        792 :           else if (!dollar)
    3509                 :            :             {
    3510                 :            :               /* (Non-zero) width has been seen.  The next character
    3511                 :            :                  is either a period or a digit.  */
    3512                 :        792 :               goto start_precision;
    3513                 :            :             }
    3514                 :            :         }
    3515                 :            :       /* When either '$' has been seen, or width has not been seen,
    3516                 :            :          the next field is the optional flags followed by an optional
    3517                 :            :          width.  */
    3518                 :     235581 :       for ( ; ; ) {
    3519                 :     235581 :         switch (target_to_host (*pf))
    3520                 :            :           {
    3521                 :       1645 :           case ' ':
    3522                 :       1645 :           case '0':
    3523                 :       1645 :           case '+':
    3524                 :       1645 :           case '-':
    3525                 :       1645 :           case '#':
    3526                 :     235581 :             dir.set_flag (target_to_host (*pf++));
    3527                 :            :             break;
    3528                 :            : 
    3529                 :     233936 :           default:
    3530                 :     233936 :             goto start_width;
    3531                 :            :           }
    3532                 :            :       }
    3533                 :            : 
    3534                 :     233936 :     start_width:
    3535                 :     233936 :       if (ISDIGIT (target_to_host (*pf)))
    3536                 :            :         {
    3537                 :        315 :           werange = 0;
    3538                 :        315 :           pwidth = pf;
    3539                 :        315 :           width = target_strtowi (&pf, &werange);
    3540                 :            :         }
    3541                 :     233621 :       else if (target_to_host (*pf) == '*')
    3542                 :            :         {
    3543                 :         48 :           if (*argno < gimple_call_num_args (info.callstmt))
    3544                 :         48 :             star_width = gimple_call_arg (info.callstmt, (*argno)++);
    3545                 :            :           else
    3546                 :            :             {
    3547                 :            :               /* This is (likely) a va_list.  It could also be an invalid
    3548                 :            :                  call with insufficient arguments.  */
    3549                 :          0 :               star_width = void_node;
    3550                 :            :             }
    3551                 :         48 :           ++pf;
    3552                 :            :         }
    3553                 :     233573 :       else if (target_to_host (*pf) == '\'')
    3554                 :            :         {
    3555                 :            :           /* The POSIX apostrophe indicating a numeric grouping
    3556                 :            :              in the current locale.  Even though it's possible to
    3557                 :            :              estimate the upper bound on the size of the output
    3558                 :            :              based on the number of digits it probably isn't worth
    3559                 :            :              continuing.  */
    3560                 :            :           return 0;
    3561                 :            :         }
    3562                 :            :     }
    3563                 :            : 
    3564                 :        765 :  start_precision:
    3565                 :     235459 :   if (target_to_host (*pf) == '.')
    3566                 :            :     {
    3567                 :       2162 :       ++pf;
    3568                 :            : 
    3569                 :       2162 :       if (ISDIGIT (target_to_host (*pf)))
    3570                 :            :         {
    3571                 :       1251 :           pprec = pf;
    3572                 :       1251 :           precision = target_strtowi (&pf, &perange);
    3573                 :            :         }
    3574                 :        911 :       else if (target_to_host (*pf) == '*')
    3575                 :            :         {
    3576                 :        843 :           if (*argno < gimple_call_num_args (info.callstmt))
    3577                 :        820 :             star_precision = gimple_call_arg (info.callstmt, (*argno)++);
    3578                 :            :           else
    3579                 :            :             {
    3580                 :            :               /* This is (likely) a va_list.  It could also be an invalid
    3581                 :            :                  call with insufficient arguments.  */
    3582                 :         23 :               star_precision = void_node;
    3583                 :            :             }
    3584                 :        843 :           ++pf;
    3585                 :            :         }
    3586                 :            :       else
    3587                 :            :         {
    3588                 :            :           /* The decimal precision or the asterisk are optional.
    3589                 :            :              When neither is dirified it's taken to be zero.  */
    3590                 :            :           precision = 0;
    3591                 :            :         }
    3592                 :            :     }
    3593                 :            : 
    3594                 :     235459 :   switch (target_to_host (*pf))
    3595                 :            :     {
    3596                 :       1112 :     case 'h':
    3597                 :       1112 :       if (target_to_host (pf[1]) == 'h')
    3598                 :            :         {
    3599                 :        645 :           ++pf;
    3600                 :        645 :           dir.modifier = FMT_LEN_hh;
    3601                 :            :         }
    3602                 :            :       else
    3603                 :        467 :         dir.modifier = FMT_LEN_h;
    3604                 :       1112 :       ++pf;
    3605                 :       1112 :       break;
    3606                 :            : 
    3607                 :        104 :     case 'j':
    3608                 :        104 :       dir.modifier = FMT_LEN_j;
    3609                 :        104 :       ++pf;
    3610                 :        104 :       break;
    3611                 :            : 
    3612                 :        937 :     case 'L':
    3613                 :        937 :       dir.modifier = FMT_LEN_L;
    3614                 :        937 :       ++pf;
    3615                 :        937 :       break;
    3616                 :            : 
    3617                 :      13094 :     case 'l':
    3618                 :      13094 :       if (target_to_host (pf[1]) == 'l')
    3619                 :            :         {
    3620                 :        529 :           ++pf;
    3621                 :        529 :           dir.modifier = FMT_LEN_ll;
    3622                 :            :         }
    3623                 :            :       else
    3624                 :      12565 :         dir.modifier = FMT_LEN_l;
    3625                 :      13094 :       ++pf;
    3626                 :      13094 :       break;
    3627                 :            : 
    3628                 :         45 :     case 't':
    3629                 :         45 :       dir.modifier = FMT_LEN_t;
    3630                 :         45 :       ++pf;
    3631                 :         45 :       break;
    3632                 :            : 
    3633                 :        415 :     case 'z':
    3634                 :        415 :       dir.modifier = FMT_LEN_z;
    3635                 :        415 :       ++pf;
    3636                 :        415 :       break;
    3637                 :            :     }
    3638                 :            : 
    3639                 :     235459 :   switch (target_to_host (*pf))
    3640                 :            :     {
    3641                 :            :       /* Handle a sole '%' character the same as "%%" but since it's
    3642                 :            :          undefined prevent the result from being folded.  */
    3643                 :          0 :     case '\0':
    3644                 :          0 :       --pf;
    3645                 :          0 :       res->range.min = res->range.max = HOST_WIDE_INT_M1U;
    3646                 :            :       /* FALLTHRU */
    3647                 :         63 :     case '%':
    3648                 :         63 :       dir.fmtfunc = format_percent;
    3649                 :         63 :       break;
    3650                 :            : 
    3651                 :       6159 :     case 'a':
    3652                 :       6159 :     case 'A':
    3653                 :       6159 :     case 'e':
    3654                 :       6159 :     case 'E':
    3655                 :       6159 :     case 'f':
    3656                 :       6159 :     case 'F':
    3657                 :       6159 :     case 'g':
    3658                 :       6159 :     case 'G':
    3659                 :       6159 :       res->floating = true;
    3660                 :       6159 :       dir.fmtfunc = format_floating;
    3661                 :       6159 :       break;
    3662                 :            : 
    3663                 :      88304 :     case 'd':
    3664                 :      88304 :     case 'i':
    3665                 :      88304 :     case 'o':
    3666                 :      88304 :     case 'u':
    3667                 :      88304 :     case 'x':
    3668                 :      88304 :     case 'X':
    3669                 :      88304 :       dir.fmtfunc = format_integer;
    3670                 :      88304 :       break;
    3671                 :            : 
    3672                 :            :     case 'p':
    3673                 :            :       /* The %p output is implementation-defined.  It's possible
    3674                 :            :          to determine this format but due to extensions (edirially
    3675                 :            :          those of the Linux kernel -- see bug 78512) the first %p
    3676                 :            :          in the format string disables any further processing.  */
    3677                 :            :       return false;
    3678                 :            : 
    3679                 :         77 :     case 'n':
    3680                 :            :       /* %n has side-effects even when nothing is actually printed to
    3681                 :            :          any buffer.  */
    3682                 :         77 :       info.nowrite = false;
    3683                 :         77 :       dir.fmtfunc = format_none;
    3684                 :         77 :       break;
    3685                 :            : 
    3686                 :       1021 :     case 'C':
    3687                 :       1021 :     case 'c':
    3688                 :            :       /* POSIX wide character and C/POSIX narrow character.  */
    3689                 :       1021 :       dir.fmtfunc = format_character;
    3690                 :       1021 :       break;
    3691                 :            : 
    3692                 :     138755 :     case 'S':
    3693                 :     138755 :     case 's':
    3694                 :            :       /* POSIX wide string and C/POSIX narrow character string.  */
    3695                 :     138755 :       dir.fmtfunc = format_string;
    3696                 :     138755 :       break;
    3697                 :            : 
    3698                 :            :     default:
    3699                 :            :       /* Unknown conversion specification.  */
    3700                 :            :       return 0;
    3701                 :            :     }
    3702                 :            : 
    3703                 :     234379 :   dir.specifier = target_to_host (*pf++);
    3704                 :            : 
    3705                 :            :   /* Store the length of the format directive.  */
    3706                 :     234379 :   dir.len = pf - pcnt;
    3707                 :            : 
    3708                 :            :   /* Buffer for the directive in the host character set (used when
    3709                 :            :      the source character set is different).  */
    3710                 :     234379 :   char hostdir[32];
    3711                 :            : 
    3712                 :     234379 :   if (star_width)
    3713                 :            :     {
    3714                 :        791 :       if (INTEGRAL_TYPE_P (TREE_TYPE (star_width)))
    3715                 :        772 :         dir.set_width (star_width, vr_values);
    3716                 :            :       else
    3717                 :            :         {
    3718                 :            :           /* Width specified by a va_list takes on the range [0, -INT_MIN]
    3719                 :            :              (width is the absolute value of that specified).  */
    3720                 :         19 :           dir.width[0] = 0;
    3721                 :         19 :           dir.width[1] = target_int_max () + 1;
    3722                 :            :         }
    3723                 :            :     }
    3724                 :            :   else
    3725                 :            :     {
    3726                 :     233588 :       if (width == HOST_WIDE_INT_MAX && werange)
    3727                 :            :         {
    3728                 :          1 :           size_t begin = dir.beg - info.fmtstr + (pwidth - pcnt);
    3729                 :          1 :           size_t caret = begin + (werange - pcnt);
    3730                 :          1 :           size_t end = pf - info.fmtstr - 1;
    3731                 :            : 
    3732                 :            :           /* Create a location for the width part of the directive,
    3733                 :            :              pointing the caret at the first out-of-range digit.  */
    3734                 :          2 :           substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
    3735                 :          1 :                                 caret, begin, end);
    3736                 :            : 
    3737                 :          2 :           fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    3738                 :          1 :                    "%<%.*s%> directive width out of range", (int) dir.len,
    3739                 :            :                    target_to_host (hostdir, sizeof hostdir, dir.beg));
    3740                 :            :         }
    3741                 :            : 
    3742                 :     233588 :       dir.set_width (width);
    3743                 :            :     }
    3744                 :            : 
    3745                 :     234379 :   if (star_precision)
    3746                 :            :     {
    3747                 :        832 :       if (INTEGRAL_TYPE_P (TREE_TYPE (star_precision)))
    3748                 :        804 :         dir.set_precision (star_precision, vr_values);
    3749                 :            :       else
    3750                 :            :         {
    3751                 :            :           /* Precision specified by a va_list takes on the range [-1, INT_MAX]
    3752                 :            :              (unlike width, negative precision is ignored).  */
    3753                 :         28 :           dir.prec[0] = -1;
    3754                 :         28 :           dir.prec[1] = target_int_max ();
    3755                 :            :         }
    3756                 :            :     }
    3757                 :            :   else
    3758                 :            :     {
    3759                 :     233547 :       if (precision == HOST_WIDE_INT_MAX && perange)
    3760                 :            :         {
    3761                 :          1 :           size_t begin = dir.beg - info.fmtstr + (pprec - pcnt) - 1;
    3762                 :          1 :           size_t caret = dir.beg - info.fmtstr + (perange - pcnt) - 1;
    3763                 :          1 :           size_t end = pf - info.fmtstr - 2;
    3764                 :            : 
    3765                 :            :           /* Create a location for the precision part of the directive,
    3766                 :            :              including the leading period, pointing the caret at the first
    3767                 :            :              out-of-range digit .  */
    3768                 :          2 :           substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
    3769                 :          1 :                                 caret, begin, end);
    3770                 :            : 
    3771                 :          2 :           fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    3772                 :          1 :                    "%<%.*s%> directive precision out of range", (int) dir.len,
    3773                 :            :                    target_to_host (hostdir, sizeof hostdir, dir.beg));
    3774                 :            :         }
    3775                 :            : 
    3776                 :     233547 :       dir.set_precision (precision);
    3777                 :            :     }
    3778                 :            : 
    3779                 :            :   /* Extract the argument if the directive takes one and if it's
    3780                 :            :      available (e.g., the function doesn't take a va_list).  Treat
    3781                 :            :      missing arguments the same as va_list, even though they will
    3782                 :            :      have likely already been diagnosed by -Wformat.  */
    3783                 :     234379 :   if (dir.specifier != '%'
    3784                 :     234379 :       && *argno < gimple_call_num_args (info.callstmt))
    3785                 :     233109 :     dir.arg = gimple_call_arg (info.callstmt, dollar ? dollar : (*argno)++);
    3786                 :            : 
    3787                 :     234379 :   if (dump_file)
    3788                 :            :     {
    3789                 :          0 :       fprintf (dump_file,
    3790                 :            :                "  Directive %u at offset " HOST_WIDE_INT_PRINT_UNSIGNED
    3791                 :            :                ": \"%.*s\"",
    3792                 :            :                dir.dirno,
    3793                 :          0 :                (unsigned HOST_WIDE_INT)(size_t)(dir.beg - info.fmtstr),
    3794                 :          0 :                (int)dir.len, dir.beg);
    3795                 :          0 :       if (star_width)
    3796                 :            :         {
    3797                 :          0 :           if (dir.width[0] == dir.width[1])
    3798                 :          0 :             fprintf (dump_file, ", width = " HOST_WIDE_INT_PRINT_DEC,
    3799                 :            :                      dir.width[0]);
    3800                 :            :           else
    3801                 :          0 :             fprintf (dump_file,
    3802                 :            :                      ", width in range [" HOST_WIDE_INT_PRINT_DEC
    3803                 :            :                      ", " HOST_WIDE_INT_PRINT_DEC "]",
    3804                 :            :                      dir.width[0], dir.width[1]);
    3805                 :            :         }
    3806                 :            : 
    3807                 :          0 :       if (star_precision)
    3808                 :            :         {
    3809                 :          0 :           if (dir.prec[0] == dir.prec[1])
    3810                 :          0 :             fprintf (dump_file, ", precision = " HOST_WIDE_INT_PRINT_DEC,
    3811                 :            :                      dir.prec[0]);
    3812                 :            :           else
    3813                 :          0 :             fprintf (dump_file,
    3814                 :            :                      ", precision in range [" HOST_WIDE_INT_PRINT_DEC
    3815                 :            :                      HOST_WIDE_INT_PRINT_DEC "]",
    3816                 :            :                      dir.prec[0], dir.prec[1]);
    3817                 :            :         }
    3818                 :          0 :       fputc ('\n', dump_file);
    3819                 :            :     }
    3820                 :            : 
    3821                 :     234379 :   return dir.len;
    3822                 :            : }
    3823                 :            : 
    3824                 :            : /* Diagnose overlap between destination and %s directive arguments.  */
    3825                 :            : 
    3826                 :            : static void
    3827                 :      74856 : maybe_warn_overlap (call_info &info, format_result *res)
    3828                 :            : {
    3829                 :            :   /* Two vectors of 1-based indices corresponding to either certainly
    3830                 :            :      or possibly aliasing arguments.  */
    3831                 :     374280 :   auto_vec<int, 16> aliasarg[2];
    3832                 :            : 
    3833                 :            :   /* Go through the array of potentially aliasing directives and collect
    3834                 :            :      argument numbers of those that do or may overlap the destination
    3835                 :            :      object given the full result.  */
    3836                 :      75068 :   for (unsigned i = 0; i != res->alias_count; ++i)
    3837                 :            :     {
    3838                 :        212 :       const format_result::alias_info &alias = res->aliases[i];
    3839                 :            : 
    3840                 :        212 :       enum { possible = -1, none = 0, certain = 1 } overlap = none;
    3841                 :            : 
    3842                 :            :       /* If the precision is zero there is no overlap.  (This only
    3843                 :            :          considers %s directives and ignores %n.)  */
    3844                 :        212 :       if (alias.dir.prec[0] == 0 && alias.dir.prec[1] == 0)
    3845                 :          6 :         continue;
    3846                 :            : 
    3847                 :        206 :       if (alias.offset == HOST_WIDE_INT_MAX
    3848                 :        165 :           || info.dst_offset == HOST_WIDE_INT_MAX)
    3849                 :            :         overlap = possible;
    3850                 :        145 :       else if (alias.offset == info.dst_offset)
    3851                 :         54 :         overlap = alias.dir.prec[0] == 0 ? possible : certain;
    3852                 :            :       else
    3853                 :            :         {
    3854                 :            :           /* Determine overlap from the range of output and offsets
    3855                 :            :              into the same destination as the source, and rule out
    3856                 :            :              impossible overlap.  */
    3857                 :         91 :           unsigned HOST_WIDE_INT albeg = alias.offset;
    3858                 :         91 :           unsigned HOST_WIDE_INT dstbeg = info.dst_offset;
    3859                 :            : 
    3860                 :         91 :           unsigned HOST_WIDE_INT alend = albeg + alias.range.min;
    3861                 :         91 :           unsigned HOST_WIDE_INT dstend = dstbeg + res->range.min - 1;
    3862                 :            : 
    3863                 :         91 :           if ((albeg <= dstbeg && alend > dstbeg)
    3864                 :         87 :               || (albeg >= dstbeg && albeg < dstend))
    3865                 :            :             overlap = certain;
    3866                 :            :           else
    3867                 :            :             {
    3868                 :         83 :               alend = albeg + alias.range.max;
    3869                 :         83 :               if (alend < albeg)
    3870                 :         35 :                 alend = HOST_WIDE_INT_M1U;
    3871                 :            : 
    3872                 :         83 :               dstend = dstbeg + res->range.max - 1;
    3873                 :         83 :               if (dstend < dstbeg)
    3874                 :          4 :                 dstend = HOST_WIDE_INT_M1U;
    3875                 :            : 
    3876                 :         83 :               if ((albeg >= dstbeg && albeg <= dstend)
    3877                 :         35 :                   || (alend >= dstbeg && alend <= dstend))
    3878                 :            :                 overlap = possible;
    3879                 :            :             }
    3880                 :            :         }
    3881                 :            : 
    3882                 :          1 :       if (overlap == none)
    3883                 :          5 :         continue;
    3884                 :            : 
    3885                 :            :       /* Append the 1-based argument number.  */
    3886                 :        201 :       aliasarg[overlap != certain].safe_push (alias.dir.argno + 1);
    3887                 :            : 
    3888                 :            :       /* Disable any kind of optimization.  */
    3889                 :        201 :       res->range.unlikely = HOST_WIDE_INT_M1U;
    3890                 :            :     }
    3891                 :            : 
    3892                 :      74856 :   tree arg0 = gimple_call_arg (info.callstmt, 0);
    3893                 :      74856 :   location_t loc = gimple_location (info.callstmt);
    3894                 :            : 
    3895                 :      74856 :   bool aliaswarn = false;
    3896                 :            : 
    3897                 :      74856 :   unsigned ncertain = aliasarg[0].length ();
    3898                 :      74856 :   unsigned npossible = aliasarg[1].length ();
    3899                 :      74856 :   if (ncertain && npossible)
    3900                 :            :     {
    3901                 :            :       /* If there are multiple arguments that overlap, some certainly
    3902                 :            :          and some possibly, handle both sets in a single diagnostic.  */
    3903                 :          1 :       aliaswarn
    3904                 :          3 :         = warning_at (loc, OPT_Wrestrict,
    3905                 :            :                       "%qE arguments %Z and maybe %Z overlap destination "
    3906                 :            :                       "object %qE",
    3907                 :            :                       info.func, aliasarg[0].address (), ncertain,
    3908                 :            :                       aliasarg[1].address (), npossible,
    3909                 :            :                       info.dst_origin);
    3910                 :            :     }
    3911                 :      74855 :   else if (ncertain)
    3912                 :            :     {
    3913                 :            :       /* There is only one set of two or more arguments and they all
    3914                 :            :          certainly overlap the destination.  */
    3915                 :         59 :       aliaswarn
    3916                 :        118 :         = warning_n (loc, OPT_Wrestrict, ncertain,
    3917                 :            :                      "%qE argument %Z overlaps destination object %qE",
    3918                 :            :                      "%qE arguments %Z overlap destination object %qE",
    3919                 :            :                      info.func, aliasarg[0].address (), ncertain,
    3920                 :            :                      info.dst_origin);
    3921                 :            :     }
    3922                 :      74796 :   else if (npossible)
    3923                 :            :     {
    3924                 :            :       /* There is only one set of two or more arguments and they all
    3925                 :            :          may overlap (but need not).  */
    3926                 :        138 :       aliaswarn
    3927                 :        276 :         = warning_n (loc, OPT_Wrestrict, npossible,
    3928                 :            :                      "%qE argument %Z may overlap destination object %qE",
    3929                 :            :                      "%qE arguments %Z may overlap destination object %qE",
    3930                 :            :                      info.func, aliasarg[1].address (), npossible,
    3931                 :            :                      info.dst_origin);
    3932                 :            :     }
    3933                 :            : 
    3934                 :        198 :   if (aliaswarn)
    3935                 :            :     {
    3936                 :        198 :       res->warned = true;
    3937                 :            : 
    3938                 :        198 :       if (info.dst_origin != arg0)
    3939                 :            :         {
    3940                 :            :           /* If its location is different from the first argument of the call
    3941                 :            :              point either at the destination object itself or at the expression
    3942                 :            :              that was used to determine the overlap.  */
    3943                 :     224568 :           loc = (DECL_P (info.dst_origin)
    3944                 :        198 :                  ? DECL_SOURCE_LOCATION (info.dst_origin)
    3945                 :          0 :                  : EXPR_LOCATION (info.dst_origin));
    3946                 :        198 :           if (loc != UNKNOWN_LOCATION)
    3947                 :        198 :             inform (loc,
    3948                 :            :                     "destination object referenced by %<restrict%>-qualified "
    3949                 :            :                     "argument 1 was declared here");
    3950                 :            :         }
    3951                 :            :     }
    3952                 :      74856 : }
    3953                 :            : 
    3954                 :            : /* Compute the length of the output resulting from the call to a formatted
    3955                 :            :    output function described by INFO and store the result of the call in
    3956                 :            :    *RES.  Issue warnings for detected past the end writes.  Return true
    3957                 :            :    if the complete format string has been processed and *RES can be relied
    3958                 :            :    on, false otherwise (e.g., when a unknown or unhandled directive was seen
    3959                 :            :    that caused the processing to be terminated early).  */
    3960                 :            : 
    3961                 :            : static bool
    3962                 :      76154 : compute_format_length (call_info &info, format_result *res, const vr_values *vr)
    3963                 :            : {
    3964                 :      76154 :   if (dump_file)
    3965                 :            :     {
    3966                 :          0 :       location_t callloc = gimple_location (info.callstmt);
    3967                 :          0 :       fprintf (dump_file, "%s:%i: ",
    3968                 :          0 :                LOCATION_FILE (callloc), LOCATION_LINE (callloc));
    3969                 :          0 :       print_generic_expr (dump_file, info.func, dump_flags);
    3970                 :            : 
    3971                 :          0 :       fprintf (dump_file,
    3972                 :            :                ": objsize = " HOST_WIDE_INT_PRINT_UNSIGNED
    3973                 :            :                ", fmtstr = \"%s\"\n",
    3974                 :            :                info.objsize, info.fmtstr);
    3975                 :            :     }
    3976                 :            : 
    3977                 :            :   /* Reset the minimum and maximum byte counters.  */
    3978                 :      76154 :   res->range.min = res->range.max = 0;
    3979                 :            : 
    3980                 :            :   /* No directive has been seen yet so the length of output is bounded
    3981                 :            :      by the known range [0, 0] (with no conversion resulting in a failure
    3982                 :            :      or producing more than 4K bytes) until determined otherwise.  */
    3983                 :      76154 :   res->knownrange = true;
    3984                 :      76154 :   res->floating = false;
    3985                 :      76154 :   res->warned = false;
    3986                 :            : 
    3987                 :            :   /* 1-based directive counter.  */
    3988                 :      76154 :   unsigned dirno = 1;
    3989                 :            : 
    3990                 :            :   /* The variadic argument counter.  */
    3991                 :      76154 :   unsigned argno = info.argidx;
    3992                 :            : 
    3993                 :      76154 :   bool success = true;
    3994                 :            : 
    3995                 :      76154 :   for (const char *pf = info.fmtstr; ; ++dirno)
    3996                 :            :     {
    3997                 :     549584 :       directive dir (&info, dirno);
    3998                 :            : 
    3999                 :     549584 :       size_t n = parse_directive (info, dir, res, pf, &argno, vr);
    4000                 :            : 
    4001                 :            :       /* Return failure if the format function fails.  */
    4002                 :     549584 :       if (!format_directive (info, res, dir, vr))
    4003                 :       1298 :         return false;
    4004                 :            : 
    4005                 :            :       /* Return success when the directive is zero bytes long and it's
    4006                 :            :          the last thing in the format string (i.e., it's the terminating
    4007                 :            :          nul, which isn't really a directive but handling it as one makes
    4008                 :            :          things simpler).  */
    4009                 :     548286 :       if (!n)
    4010                 :            :         {
    4011                 :      74856 :           success = *pf == '\0';
    4012                 :      74856 :           break;
    4013                 :            :         }
    4014                 :            : 
    4015                 :     473430 :       pf += n;
    4016                 :     473430 :     }
    4017                 :            : 
    4018                 :      74856 :   maybe_warn_overlap (info, res);
    4019                 :            : 
    4020                 :            :   /* The complete format string was processed (with or without warnings).  */
    4021                 :      74856 :   return success;
    4022                 :            : }
    4023                 :            : 
    4024                 :            : /* Return the size of the object referenced by the expression DEST if
    4025                 :            :    available, or the maximum possible size otherwise.  */
    4026                 :            : 
    4027                 :            : static unsigned HOST_WIDE_INT
    4028                 :      75916 : get_destination_size (tree dest)
    4029                 :            : {
    4030                 :            :   /* When there is no destination return the maximum.  */
    4031                 :      75916 :   if (!dest)
    4032                 :            :     return HOST_WIDE_INT_MAX;
    4033                 :            : 
    4034                 :            :   /* Initialize object size info before trying to compute it.  */
    4035                 :       5807 :   init_object_sizes ();
    4036                 :            : 
    4037                 :            :   /* Use __builtin_object_size to determine the size of the destination
    4038                 :            :      object.  When optimizing, determine the smallest object (such as
    4039                 :            :      a member array as opposed to the whole enclosing object), otherwise
    4040                 :            :      use type-zero object size to determine the size of the enclosing
    4041                 :            :      object (the function fails without optimization in this type).  */
    4042                 :       5807 :   int ost = optimize > 0;
    4043                 :       5807 :   unsigned HOST_WIDE_INT size;
    4044                 :       5807 :   if (compute_builtin_object_size (dest, ost, &size))
    4045                 :       4989 :     return size;
    4046                 :            : 
    4047                 :            :   return HOST_WIDE_INT_MAX;
    4048                 :            : }
    4049                 :            : 
    4050                 :            : /* Return true if the call described by INFO with result RES safe to
    4051                 :            :    optimize (i.e., no undefined behavior), and set RETVAL to the range
    4052                 :            :    of its return values.  */
    4053                 :            : 
    4054                 :            : static bool
    4055                 :     140809 : is_call_safe (const call_info &info,
    4056                 :            :               const format_result &res, bool under4k,
    4057                 :            :               unsigned HOST_WIDE_INT retval[2])
    4058                 :            : {
    4059                 :     140809 :   if (under4k && !res.posunder4k)
    4060                 :            :     return false;
    4061                 :            : 
    4062                 :            :   /* The minimum return value.  */
    4063                 :      72344 :   retval[0] = res.range.min;
    4064                 :            : 
    4065                 :            :   /* The maximum return value is in most cases bounded by RES.RANGE.MAX
    4066                 :            :      but in cases involving multibyte characters could be as large as
    4067                 :            :      RES.RANGE.UNLIKELY.  */
    4068                 :      72344 :   retval[1]
    4069                 :      72344 :     = res.range.unlikely < res.range.max ? res.range.max : res.range.unlikely;
    4070                 :            : 
    4071                 :            :   /* Adjust the number of bytes which includes the terminating nul
    4072                 :            :      to reflect the return value of the function which does not.
    4073                 :            :      Because the valid range of the function is [INT_MIN, INT_MAX],
    4074                 :            :      a valid range before the adjustment below is [0, INT_MAX + 1]
    4075                 :            :      (the functions only return negative values on error or undefined
    4076                 :            :      behavior).  */
    4077                 :      72344 :   if (retval[0] <= target_int_max () + 1)
    4078                 :      72214 :     --retval[0];
    4079                 :      72344 :   if (retval[1] <= target_int_max () + 1)
    4080                 :      66768 :     --retval[1];
    4081                 :            : 
    4082                 :            :   /* Avoid the return value optimization when the behavior of the call
    4083                 :            :      is undefined either because any directive may have produced 4K or
    4084                 :            :      more of output, or the return value exceeds INT_MAX, or because
    4085                 :            :      the output overflows the destination object (but leave it enabled
    4086                 :            :      when the function is bounded because then the behavior is well-
    4087                 :            :      defined).  */
    4088                 :      72344 :   if (retval[0] == retval[1]
    4089                 :      50110 :       && (info.bounded || retval[0] < info.objsize)
    4090                 :     121978 :       && retval[0] <= target_int_max ())
    4091                 :            :     return true;
    4092                 :            : 
    4093                 :      21461 :   if ((info.bounded || retval[1] < info.objsize)
    4094                 :      37422 :       && (retval[0] < target_int_max ()
    4095                 :      15861 :           && retval[1] < target_int_max ()))
    4096                 :            :     return true;
    4097                 :            : 
    4098                 :       7656 :   if (!under4k && (info.bounded || retval[0] < info.objsize))
    4099                 :       5398 :     return true;
    4100                 :            : 
    4101                 :            :   return false;
    4102                 :            : }
    4103                 :            : 
    4104                 :            : /* Given a suitable result RES of a call to a formatted output function
    4105                 :            :    described by INFO, substitute the result for the return value of
    4106                 :            :    the call.  The result is suitable if the number of bytes it represents
    4107                 :            :    is known and exact.  A result that isn't suitable for substitution may
    4108                 :            :    have its range set to the range of return values, if that is known.
    4109                 :            :    Return true if the call is removed and gsi_next should not be performed
    4110                 :            :    in the caller.  */
    4111                 :            : 
    4112                 :            : static bool
    4113                 :      70399 : try_substitute_return_value (gimple_stmt_iterator *gsi,
    4114                 :            :                              const call_info &info,
    4115                 :            :                              const format_result &res)
    4116                 :            : {
    4117                 :      70399 :   tree lhs = gimple_get_lhs (info.callstmt);
    4118                 :            : 
    4119                 :            :   /* Set to true when the entire call has been removed.  */
    4120                 :      70399 :   bool removed = false;
    4121                 :            : 
    4122                 :            :   /* The minimum and maximum return value.  */
    4123                 :      70399 :   unsigned HOST_WIDE_INT retval[2];
    4124                 :      70399 :   bool safe = is_call_safe (info, res, true, retval);
    4125                 :            : 
    4126                 :      70399 :   if (safe
    4127                 :       2091 :       && retval[0] == retval[1]
    4128                 :            :       /* Not prepared to handle possibly throwing calls here; they shouldn't
    4129                 :            :          appear in non-artificial testcases, except when the __*_chk routines
    4130                 :            :          are badly declared.  */
    4131                 :      71449 :       && !stmt_ends_bb_p (info.callstmt))
    4132                 :            :     {
    4133                 :       1557 :       tree cst = build_int_cst (lhs ? TREE_TYPE (lhs) : integer_type_node,
    4134                 :            :                                 retval[0]);
    4135                 :            : 
    4136                 :       1019 :       if (lhs == NULL_TREE && info.nowrite)
    4137                 :            :         {
    4138                 :            :           /* Remove the call to the bounded function with a zero size
    4139                 :            :              (e.g., snprintf(0, 0, "%i", 123)) if there is no lhs.  */
    4140                 :         11 :           unlink_stmt_vdef (info.callstmt);
    4141                 :         11 :           gsi_remove (gsi, true);
    4142                 :         11 :           removed = true;
    4143                 :            :         }
    4144                 :       1008 :       else if (info.nowrite)
    4145                 :            :         {
    4146                 :            :           /* Replace the call to the bounded function with a zero size
    4147                 :            :              (e.g., snprintf(0, 0, "%i", 123) with the constant result
    4148                 :            :              of the function.  */
    4149                 :        170 :           if (!update_call_from_tree (gsi, cst))
    4150                 :          0 :             gimplify_and_update_call_from_tree (gsi, cst);
    4151                 :        170 :           gimple *callstmt = gsi_stmt (*gsi);
    4152                 :        170 :           update_stmt (callstmt);
    4153                 :            :         }
    4154                 :        838 :       else if (lhs)
    4155                 :            :         {
    4156                 :            :           /* Replace the left-hand side of the call with the constant
    4157                 :            :              result of the formatted function.  */
    4158                 :        368 :           gimple_call_set_lhs (info.callstmt, NULL_TREE);
    4159                 :        368 :           gimple *g = gimple_build_assign (lhs, cst);
    4160                 :        368 :           gsi_insert_after (gsi, g, GSI_NEW_STMT);
    4161                 :        368 :           update_stmt (info.callstmt);
    4162                 :            :         }
    4163                 :            : 
    4164                 :       1019 :       if (dump_file)
    4165                 :            :         {
    4166                 :          0 :           if (removed)
    4167                 :          0 :             fprintf (dump_file, "  Removing call statement.");
    4168                 :            :           else
    4169                 :            :             {
    4170                 :          0 :               fprintf (dump_file, "  Substituting ");
    4171                 :          0 :               print_generic_expr (dump_file, cst, dump_flags);
    4172                 :          0 :               fprintf (dump_file, " for %s.\n",
    4173                 :          0 :                        info.nowrite ? "statement" : "return value");
    4174                 :            :             }
    4175                 :            :         }
    4176                 :            :     }
    4177                 :      69380 :   else if (lhs && types_compatible_p (TREE_TYPE (lhs), integer_type_node))
    4178                 :            :     {
    4179                 :       2266 :       bool setrange = false;
    4180                 :            : 
    4181                 :       2266 :       if (safe
    4182                 :        493 :           && (info.bounded || retval[1] < info.objsize)
    4183                 :       2759 :           && (retval[0] < target_int_max ()
    4184                 :        493 :               && retval[1] < target_int_max ()))
    4185                 :            :         {
    4186                 :            :           /* If the result is in a valid range bounded by the size of
    4187                 :            :              the destination set it so that it can be used for subsequent
    4188                 :            :              optimizations.  */
    4189                 :        493 :           int prec = TYPE_PRECISION (integer_type_node);
    4190                 :            : 
    4191                 :        986 :           wide_int min = wi::shwi (retval[0], prec);
    4192                 :        986 :           wide_int max = wi::shwi (retval[1], prec);
    4193                 :        493 :           set_range_info (lhs, VR_RANGE, min, max);
    4194                 :            : 
    4195                 :        493 :           setrange = true;
    4196                 :            :         }
    4197                 :            : 
    4198                 :       2266 :       if (dump_file)
    4199                 :            :         {
    4200                 :          0 :           const char *inbounds
    4201                 :          0 :             = (retval[0] < info.objsize
    4202                 :          0 :                ? (retval[1] < info.objsize
    4203                 :          0 :                   ? "in" : "potentially out-of")
    4204                 :            :                : "out-of");
    4205                 :            : 
    4206                 :          0 :           const char *what = setrange ? "Setting" : "Discarding";
    4207                 :          0 :           if (retval[0] != retval[1])
    4208                 :          0 :             fprintf (dump_file,
    4209                 :            :                      "  %s %s-bounds return value range ["
    4210                 :            :                      HOST_WIDE_INT_PRINT_UNSIGNED ", "
    4211                 :            :                      HOST_WIDE_INT_PRINT_UNSIGNED "].\n",
    4212                 :            :                      what, inbounds, retval[0], retval[1]);
    4213                 :            :           else
    4214                 :          0 :             fprintf (dump_file, "  %s %s-bounds return value "
    4215                 :            :                      HOST_WIDE_INT_PRINT_UNSIGNED ".\n",
    4216                 :            :                      what, inbounds, retval[0]);
    4217                 :            :         }
    4218                 :            :     }
    4219                 :            : 
    4220                 :      70399 :   if (dump_file)
    4221                 :          0 :     fputc ('\n', dump_file);
    4222                 :            : 
    4223                 :      70399 :   return removed;
    4224                 :            : }
    4225                 :            : 
    4226                 :            : /* Try to simplify a s{,n}printf call described by INFO with result
    4227                 :            :    RES by replacing it with a simpler and presumably more efficient
    4228                 :            :    call (such as strcpy).  */
    4229                 :            : 
    4230                 :            : static bool
    4231                 :      70410 : try_simplify_call (gimple_stmt_iterator *gsi,
    4232                 :            :                    const call_info &info,
    4233                 :            :                    const format_result &res)
    4234                 :            : {
    4235                 :      70410 :   unsigned HOST_WIDE_INT dummy[2];
    4236                 :      70410 :   if (!is_call_safe (info, res, info.retval_used (), dummy))
    4237                 :            :     return false;
    4238                 :            : 
    4239                 :      67995 :   switch (info.fncode)
    4240                 :            :     {
    4241                 :       1184 :     case BUILT_IN_SNPRINTF:
    4242                 :       1184 :       return gimple_fold_builtin_snprintf (gsi);
    4243                 :            : 
    4244                 :       1565 :     case BUILT_IN_SPRINTF:
    4245                 :       1565 :       return gimple_fold_builtin_sprintf (gsi);
    4246                 :            : 
    4247                 :            :     default:
    4248                 :            :       ;
    4249                 :            :     }
    4250                 :            : 
    4251                 :            :   return false;
    4252                 :            : }
    4253                 :            : 
    4254                 :            : /* Return the zero-based index of the format string argument of a printf
    4255                 :            :    like function and set *IDX_ARGS to the first format argument.  When
    4256                 :            :    no such index exists return UINT_MAX.  */
    4257                 :            : 
    4258                 :            : static unsigned
    4259                 :    2631320 : get_user_idx_format (tree fndecl, unsigned *idx_args)
    4260                 :            : {
    4261                 :    2631320 :   tree attrs = lookup_attribute ("format", DECL_ATTRIBUTES (fndecl));
    4262                 :    2631320 :   if (!attrs)
    4263                 :    2631320 :     attrs = lookup_attribute ("format", TYPE_ATTRIBUTES (TREE_TYPE (fndecl)));
    4264                 :            : 
    4265                 :    2631320 :   if (!attrs)
    4266                 :            :     return UINT_MAX;
    4267                 :            : 
    4268                 :      12014 :   attrs = TREE_VALUE (attrs);
    4269                 :            : 
    4270                 :      12014 :   tree archetype = TREE_VALUE (attrs);
    4271                 :      12014 :   if (strcmp ("printf", IDENTIFIER_POINTER (archetype)))
    4272                 :            :     return UINT_MAX;
    4273                 :            : 
    4274                 :       9087 :   attrs = TREE_CHAIN (attrs);
    4275                 :       9087 :   tree fmtarg = TREE_VALUE (attrs);
    4276                 :            : 
    4277                 :       9087 :   attrs = TREE_CHAIN (attrs);
    4278                 :       9087 :   tree elliparg = TREE_VALUE (attrs);
    4279                 :            : 
    4280                 :            :   /* Attribute argument indices are 1-based but we use zero-based.  */
    4281                 :       9087 :   *idx_args = tree_to_uhwi (elliparg) - 1;
    4282                 :       9087 :   return tree_to_uhwi (fmtarg) - 1;
    4283                 :            : }
    4284                 :            : 
    4285                 :            : }   /* Unnamed namespace.  */
    4286                 :            : 
    4287                 :            : /* Determine if a GIMPLE call at *GSI is to one of the sprintf-like built-in
    4288                 :            :    functions and if so, handle it.  Return true if the call is removed and
    4289                 :            :    gsi_next should not be performed in the caller.  */
    4290                 :            : 
    4291                 :            : bool
    4292                 :    3474700 : handle_printf_call (gimple_stmt_iterator *gsi, const vr_values *vr_values)
    4293                 :            : {
    4294                 :    3474700 :   init_target_to_host_charmap ();
    4295                 :            : 
    4296                 :    3474700 :   call_info info = call_info ();
    4297                 :            : 
    4298                 :    3474700 :   info.callstmt = gsi_stmt (*gsi);
    4299                 :    3474700 :   info.func = gimple_call_fndecl (info.callstmt);
    4300                 :    3474700 :   if (!info.func)
    4301                 :            :     return false;
    4302                 :            : 
    4303                 :            :   /* Format string argument number (valid for all functions).  */
    4304                 :    3248590 :   unsigned idx_format = UINT_MAX;
    4305                 :    3248590 :   if (gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL))
    4306                 :     617271 :     info.fncode = DECL_FUNCTION_CODE (info.func);
    4307                 :            :   else
    4308                 :            :     {
    4309                 :    2631320 :       unsigned idx_args;
    4310                 :    2631320 :       idx_format = get_user_idx_format (info.func, &idx_args);
    4311                 :    2631320 :       if (idx_format == UINT_MAX
    4312                 :       9087 :           || idx_format >= gimple_call_num_args (info.callstmt)
    4313                 :       9087 :           || idx_args > gimple_call_num_args (info.callstmt)
    4314                 :    2640380 :           || !POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (info.callstmt,
    4315                 :            :                                                           idx_format))))
    4316                 :    2622260 :         return false;
    4317                 :       9059 :       info.fncode = BUILT_IN_NONE;
    4318                 :       9059 :       info.argidx = idx_args;
    4319                 :            :     }
    4320                 :            : 
    4321                 :            :   /* The size of the destination as in snprintf(dest, size, ...).  */
    4322                 :     626330 :   unsigned HOST_WIDE_INT dstsize = HOST_WIDE_INT_M1U;
    4323                 :            : 
    4324                 :            :   /* The size of the destination determined by __builtin_object_size.  */
    4325                 :     626330 :   unsigned HOST_WIDE_INT objsize = HOST_WIDE_INT_M1U;
    4326                 :            : 
    4327                 :            :   /* Zero-based buffer size argument number (snprintf and vsnprintf).  */
    4328                 :     626330 :   unsigned idx_dstsize = UINT_MAX;
    4329                 :            : 
    4330                 :            :   /* Object size argument number (snprintf_chk and vsnprintf_chk).  */
    4331                 :     626330 :   unsigned idx_objsize = UINT_MAX;
    4332                 :            : 
    4333                 :            :   /* Destinaton argument number (valid for sprintf functions only).  */
    4334                 :     626330 :   unsigned idx_dstptr = 0;
    4335                 :            : 
    4336                 :     626330 :   switch (info.fncode)
    4337                 :            :     {
    4338                 :            :     case BUILT_IN_NONE:
    4339                 :            :       // User-defined function with attribute format (printf).
    4340                 :            :       idx_dstptr = -1;
    4341                 :            :       break;
    4342                 :            : 
    4343                 :      42570 :     case BUILT_IN_FPRINTF:
    4344                 :            :       // Signature:
    4345                 :            :       //   __builtin_fprintf (FILE*, format, ...)
    4346                 :      42570 :       idx_format = 1;
    4347                 :      42570 :       info.argidx = 2;
    4348                 :      42570 :       idx_dstptr = -1;
    4349                 :      42570 :       break;
    4350                 :            : 
    4351                 :        148 :     case BUILT_IN_FPRINTF_CHK:
    4352                 :            :       // Signature:
    4353                 :            :       //   __builtin_fprintf_chk (FILE*, ost, format, ...)
    4354                 :        148 :       idx_format = 2;
    4355                 :        148 :       info.argidx = 3;
    4356                 :        148 :       idx_dstptr = -1;
    4357                 :        148 :       break;
    4358                 :            : 
    4359                 :         64 :     case BUILT_IN_FPRINTF_UNLOCKED:
    4360                 :            :       // Signature:
    4361                 :            :       //   __builtin_fprintf_unnlocked (FILE*, format, ...)
    4362                 :         64 :       idx_format = 1;
    4363                 :         64 :       info.argidx = 2;
    4364                 :         64 :       idx_dstptr = -1;
    4365                 :         64 :       break;
    4366                 :            : 
    4367                 :      17343 :     case BUILT_IN_PRINTF:
    4368                 :            :       // Signature:
    4369                 :            :       //   __builtin_printf (format, ...)
    4370                 :      17343 :       idx_format = 0;
    4371                 :      17343 :       info.argidx = 1;
    4372                 :      17343 :       idx_dstptr = -1;
    4373                 :      17343 :       break;
    4374                 :            : 
    4375                 :        151 :     case BUILT_IN_PRINTF_CHK:
    4376                 :            :       // Signature:
    4377                 :            :       //   __builtin_printf_chk (ost, format, ...)
    4378                 :        151 :       idx_format = 1;
    4379                 :        151 :       info.argidx = 2;
    4380                 :        151 :       idx_dstptr = -1;
    4381                 :        151 :       break;
    4382                 :            : 
    4383                 :         63 :     case BUILT_IN_PRINTF_UNLOCKED:
    4384                 :            :       // Signature:
    4385                 :            :       //   __builtin_printf (format, ...)
    4386                 :         63 :       idx_format = 0;
    4387                 :         63 :       info.argidx = 1;
    4388                 :         63 :       idx_dstptr = -1;
    4389                 :         63 :       break;
    4390                 :            : 
    4391                 :       3398 :     case BUILT_IN_SPRINTF:
    4392                 :            :       // Signature:
    4393                 :            :       //   __builtin_sprintf (dst, format, ...)
    4394                 :       3398 :       idx_format = 1;
    4395                 :       3398 :       info.argidx = 2;
    4396                 :       3398 :       break;
    4397                 :            : 
    4398                 :       1112 :     case BUILT_IN_SPRINTF_CHK:
    4399                 :            :       // Signature:
    4400                 :            :       //   __builtin___sprintf_chk (dst, ost, objsize, format, ...)
    4401                 :       1112 :       idx_objsize = 2;
    4402                 :       1112 :       idx_format = 3;
    4403                 :       1112 :       info.argidx = 4;
    4404                 :       1112 :       break;
    4405                 :            : 
    4406                 :       1645 :     case BUILT_IN_SNPRINTF:
    4407                 :            :       // Signature:
    4408                 :            :       //   __builtin_snprintf (dst, size, format, ...)
    4409                 :       1645 :       idx_dstsize = 1;
    4410                 :       1645 :       idx_format = 2;
    4411                 :       1645 :       info.argidx = 3;
    4412                 :       1645 :       info.bounded = true;
    4413                 :       1645 :       break;
    4414                 :            : 
    4415                 :        136 :     case BUILT_IN_SNPRINTF_CHK:
    4416                 :            :       // Signature:
    4417                 :            :       //   __builtin___snprintf_chk (dst, size, ost, objsize, format, ...)
    4418                 :        136 :       idx_dstsize = 1;
    4419                 :        136 :       idx_objsize = 3;
    4420                 :        136 :       idx_format = 4;
    4421                 :        136 :       info.argidx = 5;
    4422                 :        136 :       info.bounded = true;
    4423                 :        136 :       break;
    4424                 :            : 
    4425                 :        367 :     case BUILT_IN_VFPRINTF:
    4426                 :            :       // Signature:
    4427                 :            :       //   __builtin_vprintf (FILE*, format, va_list)
    4428                 :        367 :       idx_format = 1;
    4429                 :        367 :       info.argidx = -1;
    4430                 :        367 :       idx_dstptr = -1;
    4431                 :        367 :       break;
    4432                 :            : 
    4433                 :        139 :     case BUILT_IN_VFPRINTF_CHK:
    4434                 :            :       // Signature:
    4435                 :            :       //   __builtin___vfprintf_chk (FILE*, ost, format, va_list)
    4436                 :        139 :       idx_format = 2;
    4437                 :        139 :       info.argidx = -1;
    4438                 :        139 :       idx_dstptr = -1;
    4439                 :        139 :       break;
    4440                 :            : 
    4441                 :         58 :     case BUILT_IN_VPRINTF:
    4442                 :            :       // Signature:
    4443                 :            :       //   __builtin_vprintf (format, va_list)
    4444                 :         58 :       idx_format = 0;
    4445                 :         58 :       info.argidx = -1;
    4446                 :         58 :       idx_dstptr = -1;
    4447                 :         58 :       break;
    4448                 :            : 
    4449                 :        147 :     case BUILT_IN_VPRINTF_CHK:
    4450                 :            :       // Signature:
    4451                 :            :       //   __builtin___vprintf_chk (ost, format, va_list)
    4452                 :        147 :       idx_format = 1;
    4453                 :        147 :       info.argidx = -1;
    4454                 :        147 :       idx_dstptr = -1;
    4455                 :        147 :       break;
    4456                 :            : 
    4457                 :        639 :     case BUILT_IN_VSNPRINTF:
    4458                 :            :       // Signature:
    4459                 :            :       //   __builtin_vsprintf (dst, size, format, va)
    4460                 :        639 :       idx_dstsize = 1;
    4461                 :        639 :       idx_format = 2;
    4462                 :        639 :       info.argidx = -1;
    4463                 :        639 :       info.bounded = true;
    4464                 :        639 :       break;
    4465                 :            : 
    4466                 :        131 :     case BUILT_IN_VSNPRINTF_CHK:
    4467                 :            :       // Signature:
    4468                 :            :       //   __builtin___vsnprintf_chk (dst, size, ost, objsize, format, va)
    4469                 :        131 :       idx_dstsize = 1;
    4470                 :        131 :       idx_objsize = 3;
    4471                 :        131 :       idx_format = 4;
    4472                 :        131 :       info.argidx = -1;
    4473                 :        131 :       info.bounded = true;
    4474                 :        131 :       break;
    4475                 :            : 
    4476                 :       1119 :     case BUILT_IN_VSPRINTF:
    4477                 :            :       // Signature:
    4478                 :            :       //   __builtin_vsprintf (dst, format, va)
    4479                 :       1119 :       idx_format = 1;
    4480                 :       1119 :       info.argidx = -1;
    4481                 :       1119 :       break;
    4482                 :            : 
    4483                 :        178 :     case BUILT_IN_VSPRINTF_CHK:
    4484                 :            :       // Signature:
    4485                 :            :       //   __builtin___vsprintf_chk (dst, ost, objsize, format, va)
    4486                 :        178 :       idx_format = 3;
    4487                 :        178 :       idx_objsize = 2;
    4488                 :        178 :       info.argidx = -1;
    4489                 :        178 :       break;
    4490                 :            : 
    4491                 :            :     default:
    4492                 :            :       return false;
    4493                 :            :     }
    4494                 :            : 
    4495                 :            :   /* Set the global warning level for this function.  */
    4496                 :      78467 :   warn_level = info.bounded ? warn_format_trunc : warn_format_overflow;
    4497                 :            : 
    4498                 :            :   /* For all string functions the first argument is a pointer to
    4499                 :            :      the destination.  */
    4500                 :      78467 :   tree dstptr = (idx_dstptr < gimple_call_num_args (info.callstmt)
    4501                 :      78467 :                  ? gimple_call_arg (info.callstmt, 0) : NULL_TREE);
    4502                 :            : 
    4503                 :      78467 :   info.format = gimple_call_arg (info.callstmt, idx_format);
    4504                 :            : 
    4505                 :            :   /* True when the destination size is constant as opposed to the lower
    4506                 :            :      or upper bound of a range.  */
    4507                 :      78467 :   bool dstsize_cst_p = true;
    4508                 :      78467 :   bool posunder4k = true;
    4509                 :            : 
    4510                 :      78467 :   if (idx_dstsize == UINT_MAX)
    4511                 :            :     {
    4512                 :            :       /* For non-bounded functions like sprintf, determine the size
    4513                 :            :          of the destination from the object or pointer passed to it
    4514                 :            :          as the first argument.  */
    4515                 :      75916 :       dstsize = get_destination_size (dstptr);
    4516                 :            :     }
    4517                 :       2551 :   else if (tree size = gimple_call_arg (info.callstmt, idx_dstsize))
    4518                 :            :     {
    4519                 :            :       /* For bounded functions try to get the size argument.  */
    4520                 :            : 
    4521                 :       2551 :       if (TREE_CODE (size) == INTEGER_CST)
    4522                 :            :         {
    4523                 :       2015 :           dstsize = tree_to_uhwi (size);
    4524                 :            :           /* No object can be larger than SIZE_MAX bytes (half the address
    4525                 :            :              space) on the target.
    4526                 :            :              The functions are defined only for output of at most INT_MAX
    4527                 :            :              bytes.  Specifying a bound in excess of that limit effectively
    4528                 :            :              defeats the bounds checking (and on some implementations such
    4529                 :            :              as Solaris cause the function to fail with EINVAL).  */
    4530                 :       2015 :           if (dstsize > target_size_max () / 2)
    4531                 :            :             {
    4532                 :            :               /* Avoid warning if -Wstringop-overflow is specified since
    4533                 :            :                  it also warns for the same thing though only for the
    4534                 :            :                  checking built-ins.  */
    4535                 :         10 :               if ((idx_objsize == UINT_MAX
    4536                 :          1 :                    || !warn_stringop_overflow))
    4537                 :          9 :                 warning_at (gimple_location (info.callstmt), info.warnopt (),
    4538                 :            :                             "specified bound %wu exceeds maximum object size "
    4539                 :            :                             "%wu",
    4540                 :            :                             dstsize, target_size_max () / 2);
    4541                 :            :               /* POSIX requires snprintf to fail if DSTSIZE is greater
    4542                 :            :                  than INT_MAX.  Even though not all POSIX implementations
    4543                 :            :                  conform to the requirement, avoid folding in this case.  */
    4544                 :            :               posunder4k = false;
    4545                 :            :             }
    4546                 :       2005 :           else if (dstsize > target_int_max ())
    4547                 :            :             {
    4548                 :         16 :               warning_at (gimple_location (info.callstmt), info.warnopt (),
    4549                 :            :                           "specified bound %wu exceeds %<INT_MAX%>",
    4550                 :            :                           dstsize);
    4551                 :            :               /* POSIX requires snprintf to fail if DSTSIZE is greater
    4552                 :            :                  than INT_MAX.  Avoid folding in that case.  */
    4553                 :         16 :               posunder4k = false;
    4554                 :            :             }
    4555                 :            :         }
    4556                 :        536 :       else if (TREE_CODE (size) == SSA_NAME)
    4557                 :            :         {
    4558                 :            :           /* Try to determine the range of values of the argument
    4559                 :            :              and use the greater of the two at level 1 and the smaller
    4560                 :            :              of them at level 2.  */
    4561                 :        519 :           const value_range_equiv *vr
    4562                 :        519 :             = CONST_CAST (class vr_values *, vr_values)->get_value_range (size);
    4563                 :            : 
    4564                 :        519 :           if (range_int_cst_p (vr))
    4565                 :            :             {
    4566                 :         79 :               unsigned HOST_WIDE_INT minsize = TREE_INT_CST_LOW (vr->min ());
    4567                 :         79 :               unsigned HOST_WIDE_INT maxsize = TREE_INT_CST_LOW (vr->max ());
    4568                 :         79 :               dstsize = warn_level < 2 ? maxsize : minsize;
    4569                 :            : 
    4570                 :         79 :               if (minsize > target_int_max ())
    4571                 :          8 :                 warning_at (gimple_location (info.callstmt), info.warnopt (),
    4572                 :            :                             "specified bound range [%wu, %wu] exceeds "
    4573                 :            :                             "%<INT_MAX%>",
    4574                 :            :                             minsize, maxsize);
    4575                 :            : 
    4576                 :            :               /* POSIX requires snprintf to fail if DSTSIZE is greater
    4577                 :            :                  than INT_MAX.  Avoid folding if that's possible.  */
    4578                 :         79 :               if (maxsize > target_int_max ())
    4579                 :         46 :                 posunder4k = false;
    4580                 :            :             }
    4581                 :        440 :           else if (vr->varying_p ())
    4582                 :            :             {
    4583                 :            :               /* POSIX requires snprintf to fail if DSTSIZE is greater
    4584                 :            :                  than INT_MAX.  Since SIZE's range is unknown, avoid
    4585                 :            :                  folding.  */
    4586                 :        380 :               posunder4k = false;
    4587                 :            :             }
    4588                 :            : 
    4589                 :            :           /* The destination size is not constant.  If the function is
    4590                 :            :              bounded (e.g., snprintf) a lower bound of zero doesn't
    4591                 :            :              necessarily imply it can be eliminated.  */
    4592                 :            :           dstsize_cst_p = false;
    4593                 :            :         }
    4594                 :            :     }
    4595                 :            : 
    4596                 :      78467 :   if (idx_objsize != UINT_MAX)
    4597                 :       1557 :     if (tree size = gimple_call_arg (info.callstmt, idx_objsize))
    4598                 :       1557 :       if (tree_fits_uhwi_p (size))
    4599                 :       1544 :         objsize = tree_to_uhwi (size);
    4600                 :            : 
    4601                 :      78467 :   if (info.bounded && !dstsize)
    4602                 :            :     {
    4603                 :            :       /* As a special case, when the explicitly specified destination
    4604                 :            :          size argument (to a bounded function like snprintf) is zero
    4605                 :            :          it is a request to determine the number of bytes on output
    4606                 :            :          without actually producing any.  Pretend the size is
    4607                 :            :          unlimited in this case.  */
    4608                 :        386 :       info.objsize = HOST_WIDE_INT_MAX;
    4609                 :        386 :       info.nowrite = dstsize_cst_p;
    4610                 :            :     }
    4611                 :            :   else
    4612                 :            :     {
    4613                 :            :       /* For calls to non-bounded functions or to those of bounded
    4614                 :            :          functions with a non-zero size, warn if the destination
    4615                 :            :          pointer is null.  */
    4616                 :      78081 :       if (dstptr && integer_zerop (dstptr))
    4617                 :            :         {
    4618                 :            :           /* This is diagnosed with -Wformat only when the null is a constant
    4619                 :            :              pointer.  The warning here diagnoses instances where the pointer
    4620                 :            :              is not constant.  */
    4621                 :         19 :           location_t loc = gimple_location (info.callstmt);
    4622                 :         29 :           warning_at (EXPR_LOC_OR_LOC (dstptr, loc),
    4623                 :            :                       info.warnopt (), "%Gnull destination pointer",
    4624                 :            :                       info.callstmt);
    4625                 :         19 :           return false;
    4626                 :            :         }
    4627                 :            : 
    4628                 :            :       /* Set the object size to the smaller of the two arguments
    4629                 :            :          of both have been specified and they're not equal.  */
    4630                 :      78062 :       info.objsize = dstsize < objsize ? dstsize : objsize;
    4631                 :            : 
    4632                 :      78062 :       if (info.bounded
    4633                 :       2156 :           && dstsize < target_size_max () / 2 && objsize < dstsize
    4634                 :            :           /* Avoid warning if -Wstringop-overflow is specified since
    4635                 :            :              it also warns for the same thing though only for the
    4636                 :            :              checking built-ins.  */
    4637                 :      78133 :           && (idx_objsize == UINT_MAX
    4638                 :         71 :               || !warn_stringop_overflow))
    4639                 :            :         {
    4640                 :          4 :           warning_at (gimple_location (info.callstmt), info.warnopt (),
    4641                 :            :                       "specified bound %wu exceeds the size %wu "
    4642                 :            :                       "of the destination object", dstsize, objsize);
    4643                 :            :         }
    4644                 :            :     }
    4645                 :            : 
    4646                 :            :   /* Determine if the format argument may be null and warn if not
    4647                 :            :      and if the argument is null.  */
    4648                 :      78448 :   if (integer_zerop (info.format)
    4649                 :      78448 :       && gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL))
    4650                 :            :     {
    4651                 :         55 :       location_t loc = gimple_location (info.callstmt);
    4652                 :        102 :       warning_at (EXPR_LOC_OR_LOC (info.format, loc),
    4653                 :            :                   info.warnopt (), "%Gnull format string",
    4654                 :            :                   info.callstmt);
    4655                 :         55 :       return false;
    4656                 :            :     }
    4657                 :            : 
    4658                 :      78393 :   info.fmtstr = get_format_string (info.format, &info.fmtloc);
    4659                 :      78393 :   if (!info.fmtstr)
    4660                 :            :     return false;
    4661                 :            : 
    4662                 :      76154 :   if (warn_restrict)
    4663                 :            :     {
    4664                 :            :       /* Compute the origin of the destination pointer and its offset
    4665                 :            :          from the base object/pointer if possible.  */
    4666                 :      17238 :       info.dst_offset = 0;
    4667                 :      17238 :       info.dst_origin = get_origin_and_offset (dstptr, &info.dst_field,
    4668                 :            :                                                &info.dst_offset);
    4669                 :            :     }
    4670                 :            : 
    4671                 :            :   /* The result is the number of bytes output by the formatted function,
    4672                 :            :      including the terminating NUL.  */
    4673                 :    3550860 :   format_result res;
    4674                 :            : 
    4675                 :            :   /* I/O functions with no destination argument (i.e., all forms of fprintf
    4676                 :            :      and printf) may fail under any conditions.  Others (i.e., all forms of
    4677                 :            :      sprintf) may only fail under specific conditions determined for each
    4678                 :            :      directive.  Clear POSUNDER4K for the former set of functions and set
    4679                 :            :      it to true for the latter (it can only be cleared later, but it is
    4680                 :            :      never set to true again).  */
    4681                 :      76154 :   res.posunder4k = posunder4k && dstptr;
    4682                 :            : 
    4683                 :      76154 :   bool success = compute_format_length (info, &res, vr_values);
    4684                 :      76154 :   if (res.warned)
    4685                 :       2162 :     gimple_set_no_warning (info.callstmt, true);
    4686                 :            : 
    4687                 :            :   /* When optimizing and the printf return value optimization is enabled,
    4688                 :            :      attempt to substitute the computed result for the return value of
    4689                 :            :      the call.  Avoid this optimization when -frounding-math is in effect
    4690                 :            :      and the format string contains a floating point directive.  */
    4691                 :      76154 :   bool call_removed = false;
    4692                 :      76154 :   if (success && optimize > 0)
    4693                 :            :     {
    4694                 :            :       /* Save a copy of the iterator pointing at the call.  The iterator
    4695                 :            :          may change to point past the call in try_substitute_return_value
    4696                 :            :          but the original value is needed in try_simplify_call.  */
    4697                 :      70421 :       gimple_stmt_iterator gsi_call = *gsi;
    4698                 :            : 
    4699                 :      70421 :       if (flag_printf_return_value
    4700                 :      70399 :           && (!flag_rounding_math || !res.floating))
    4701                 :      70399 :         call_removed = try_substitute_return_value (gsi, info, res);
    4702                 :            : 
    4703                 :      70399 :       if (!call_removed)
    4704                 :      70410 :         try_simplify_call (&gsi_call, info, res);
    4705                 :            :     }
    4706                 :            : 
    4707                 :      76154 :   return call_removed;
    4708                 :            : }

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.