LCOV - code coverage report
Current view: top level - gcc - gimple-ssa-sprintf.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.1 % 1799 1693
Test Date: 2024-12-14 13:15:07 Functions: 96.1 % 51 49
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-beta

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,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.