LCOV - code coverage report
Current view: top level - gcc - gimple-ssa-sprintf.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.1 % 1801 1695
Test Date: 2024-04-20 14:03:02 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                 :      610439 : target_int_min ()
     138                 :             : {
     139                 :      610439 :   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                 :     1801757 : target_int_max ()
     146                 :             : {
     147                 :     1801757 :   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                 :      183352 : target_size_max ()
     154                 :             : {
     155                 :      183352 :   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                 :     4673371 : init_target_to_host_charmap ()
     168                 :             : {
     169                 :             :   /* If the percent sign is non-zero the mapping has already been
     170                 :             :      initialized.  */
     171                 :     4673371 :   if (target_to_host_charmap['%'])
     172                 :             :     return true;
     173                 :             : 
     174                 :             :   /* Initialize the target_percent character (done elsewhere).  */
     175                 :      106251 :   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                 :      106251 :   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                 :      106251 :   memset (target_to_host_charmap + 1, '?', sizeof target_to_host_charmap - 1);
     191                 :             : 
     192                 :             :   /* Are the two sets of characters the same?  */
     193                 :      106251 :   bool all_same_p = true;
     194                 :             : 
     195                 :     9987594 :   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                 :     9881343 :       if (unsigned char tc = lang_hooks.to_target_charset (*pc))
     201                 :             :         {
     202                 :     9881343 :           target_to_host_charmap[tc] = *pc;
     203                 :     9881343 :           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                 :      106251 :   target_to_host_charmap[0] = all_same_p;
     215                 :             : 
     216                 :      106251 :   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                 :     2129942 : target_to_host (unsigned char ch)
     225                 :             : {
     226                 :     2129942 :   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                 :        5389 : target_to_host (char *hostr, size_t hostsz, const char *targstr)
     236                 :             : {
     237                 :             :   /* Make sure the buffer is reasonably big.  */
     238                 :        5389 :   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                 :        5389 :   if (target_to_host_charmap['\0'] == 1)
     244                 :             :     {
     245                 :        5326 :       size_t len = strlen (targstr);
     246                 :        5326 :       if (len >= hostsz)
     247                 :             :         {
     248                 :         326 :           memcpy (hostr, targstr, hostsz - 4);
     249                 :         326 :           strcpy (hostr + hostsz - 4, "...");
     250                 :             :         }
     251                 :             :       else
     252                 :        5000 :         memcpy (hostr, targstr, len + 1);
     253                 :        5326 :       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                 :        2377 : target_strtowi (const char **ps, const char **erange)
     283                 :             : {
     284                 :        2377 :   unsigned HOST_WIDE_INT val = 0;
     285                 :       10263 :   for ( ; ; ++*ps)
     286                 :             :     {
     287                 :        6320 :       unsigned char c = target_to_host (**ps);
     288                 :        6320 :       if (ISDIGIT (c))
     289                 :             :         {
     290                 :        3945 :           c -= '0';
     291                 :             : 
     292                 :             :           /* Check for overflow.  */
     293                 :        3945 :           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                 :        3943 :             val = val * 10 + c;
     306                 :             :         }
     307                 :             :       else
     308                 :             :         break;
     309                 :        3943 :     }
     310                 :             : 
     311                 :        2377 :   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                 :      112079 : get_format_string (tree format, location_t *ploc)
     319                 :             : {
     320                 :      112079 :   *ploc = EXPR_LOC_OR_LOC (format, input_location);
     321                 :             : 
     322                 :      112079 :   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                 :        5886 : fmtwarn (const substring_loc &fmt_loc, location_t param_loc,
     334                 :             :          const char *corrected_substring, opt_code opt,
     335                 :             :          const char *gmsgid, ...)
     336                 :             : {
     337                 :        5886 :   format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
     338                 :        5886 :                                    corrected_substring);
     339                 :        5886 :   va_list ap;
     340                 :        5886 :   va_start (ap, gmsgid);
     341                 :        5886 :   bool warned = diag.emit_warning_va (opt, gmsgid, &ap);
     342                 :        5886 :   va_end (ap);
     343                 :             : 
     344                 :        5886 :   return warned;
     345                 :             : }
     346                 :             : 
     347                 :             : static bool
     348                 :             : ATTRIBUTE_GCC_DIAG (6, 8) ATTRIBUTE_GCC_DIAG (7, 8)
     349                 :         544 : 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                 :         544 :   format_string_diagnostic_t diag (fmt_loc, NULL, param_loc, NULL,
     355                 :         544 :                                    corrected_substring);
     356                 :         544 :   va_list ap;
     357                 :         544 :   va_start (ap, plural_gmsgid);
     358                 :         544 :   bool warned = diag.emit_warning_n_va (opt, n, singular_gmsgid, plural_gmsgid,
     359                 :             :                                         &ap);
     360                 :         544 :   va_end (ap);
     361                 :             : 
     362                 :         544 :   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                 :      833734 :   fmtresult (unsigned HOST_WIDE_INT min = HOST_WIDE_INT_MAX)
     390                 :      833734 :   : argmin (), argmax (), dst_offset (HOST_WIDE_INT_MIN), nonstr (),
     391                 :      832665 :     knownrange (min < HOST_WIDE_INT_MAX),
     392                 :      833734 :     mayfail (), nullp ()
     393                 :             :   {
     394                 :      833734 :     range.min = min;
     395                 :      833734 :     range.max = min;
     396                 :      833734 :     range.likely = min;
     397                 :      833734 :     range.unlikely = min;
     398                 :         697 :   }
     399                 :             : 
     400                 :             :   /* Construct a FMTRESULT object with MIN, MAX, and LIKELY counters.
     401                 :             :      KNOWNRANGE is set when both MIN and MAX are valid.   */
     402                 :      176854 :   fmtresult (unsigned HOST_WIDE_INT min, unsigned HOST_WIDE_INT max,
     403                 :             :              unsigned HOST_WIDE_INT likely = HOST_WIDE_INT_MAX)
     404                 :      176854 :   : argmin (), argmax (), dst_offset (HOST_WIDE_INT_MIN), nonstr (),
     405                 :      176854 :     knownrange (min < HOST_WIDE_INT_MAX && max < HOST_WIDE_INT_MAX),
     406                 :      176854 :     mayfail (), nullp ()
     407                 :             :   {
     408                 :      176854 :     range.min = min;
     409                 :      176854 :     range.max = max;
     410                 :      176854 :     range.likely = max < likely ? min : likely;
     411                 :      176854 :     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                 :      615061 : 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                 :      615061 :   bool minadjusted = false;
     467                 :             : 
     468                 :             :   /* Adjust the minimum and likely counters.  */
     469                 :      615061 :   if (adjust[0] >= 0)
     470                 :             :     {
     471                 :        4622 :       if (range.min < (unsigned HOST_WIDE_INT)adjust[0])
     472                 :             :         {
     473                 :        1479 :           range.min = adjust[0];
     474                 :        1479 :           minadjusted = true;
     475                 :             :         }
     476                 :             : 
     477                 :             :       /* Adjust the likely counter.  */
     478                 :        4622 :       if (range.likely < range.min)
     479                 :        1322 :         range.likely = range.min;
     480                 :             :     }
     481                 :      610439 :   else if (adjust[0] == target_int_min ()
     482                 :      610439 :            && (unsigned HOST_WIDE_INT)adjust[1] == target_int_max ())
     483                 :           0 :     knownrange = false;
     484                 :             : 
     485                 :             :   /* Adjust the maximum counter.  */
     486                 :      615061 :   if (adjust[1] > 0)
     487                 :             :     {
     488                 :        4685 :       if (range.max < (unsigned HOST_WIDE_INT)adjust[1])
     489                 :             :         {
     490                 :        1620 :           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                 :        1620 :           knownrange = minadjusted;
     495                 :             :         }
     496                 :             :     }
     497                 :             : 
     498                 :      615061 :   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                 :      614157 :   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                 :       13044 :       range.likely = (range.min
     516                 :       13044 :                       ? range.min
     517                 :       12399 :                       : range.max && (range.max < HOST_WIDE_INT_MAX
     518                 :       25169 :                                       || warn_level > 1) ? 1 : 0);
     519                 :             :     }
     520                 :             : 
     521                 :             :   /* Finally adjust the unlikely counter to be at least as large as
     522                 :             :      the maximum.  */
     523                 :      615061 :   if (range.unlikely < range.max)
     524                 :        1752 :     range.unlikely = range.max;
     525                 :             : 
     526                 :      615061 :   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                 :      716185 :   directive (const call_info *inf, unsigned dno)
     565                 :    46552025 :     : info (inf), dirno (dno), argno (), beg (), len (), flags (),
     566                 :     3580925 :     width (), prec (),  modifier (), specifier (), arg (), fmtfunc ()
     567                 :      716185 :   { }
     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                 :      410154 :   bool get_flag (char chr) const
     609                 :             :   {
     610                 :      410154 :     unsigned char c = chr & 0xff;
     611                 :      410154 :     return (flags[c / (CHAR_BIT * sizeof *flags)]
     612                 :      410154 :             & (1U << (c % (CHAR_BIT * sizeof *flags))));
     613                 :             :   }
     614                 :             : 
     615                 :             :   /* Make a record of the format flag CHR having been used.  */
     616                 :        1789 :   void set_flag (char chr)
     617                 :             :   {
     618                 :        1789 :     unsigned char c = chr & 0xff;
     619                 :        1789 :     flags[c / (CHAR_BIT * sizeof *flags)]
     620                 :        1789 :       |= (1U << (c % (CHAR_BIT * sizeof *flags)));
     621                 :        1789 :   }
     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                 :      297196 :   void set_width (HOST_WIDE_INT val)
     633                 :             :   {
     634                 :      297196 :     width[0] = width[1] = val;
     635                 :      297196 :   }
     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                 :      297098 :   void set_precision (HOST_WIDE_INT val)
     646                 :             :   {
     647                 :      297098 :     prec[0] = prec[1] = val;
     648                 :      297098 :   }
     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                 :       17344 :   bool known_width_and_precision () const
     660                 :             :   {
     661                 :       17344 :     return ((width[1] < 0
     662                 :         292 :              || (unsigned HOST_WIDE_INT)width[1] <= target_int_max ())
     663                 :       17606 :             && (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                 :      106992 :   format_result ()
     673                 :      106992 :     : range (), aliases (), alias_count (), knownrange (), posunder4k (),
     674                 :      106992 :     floating (), warned () { /* No-op.  */ }
     675                 :             : 
     676                 :      106992 :   ~format_result ()
     677                 :             :   {
     678                 :      106992 :     XDELETEVEC (aliases);
     679                 :      106992 :   }
     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                 :      170706 : ilog (unsigned HOST_WIDE_INT x, int base)
     796                 :             : {
     797                 :           0 :   int res = 0;
     798                 :      849545 :   do
     799                 :             :     {
     800                 :      849545 :       ++res;
     801                 :      849545 :       x /= base;
     802                 :      849545 :     } while (x);
     803                 :      170706 :   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                 :      170706 : tree_digits (tree x, int base, HOST_WIDE_INT prec, bool plus, bool prefix)
     815                 :             : {
     816                 :      170706 :   unsigned HOST_WIDE_INT absval;
     817                 :             : 
     818                 :      170706 :   HOST_WIDE_INT res;
     819                 :             : 
     820                 :      170706 :   if (TYPE_UNSIGNED (TREE_TYPE (x)))
     821                 :             :     {
     822                 :       12209 :       if (tree_fits_uhwi_p (x))
     823                 :             :         {
     824                 :       12209 :           absval = tree_to_uhwi (x);
     825                 :       12209 :           res = plus;
     826                 :             :         }
     827                 :             :       else
     828                 :             :         return -1;
     829                 :             :     }
     830                 :             :   else
     831                 :             :     {
     832                 :      158497 :       if (tree_fits_shwi_p (x))
     833                 :             :         {
     834                 :      158497 :           HOST_WIDE_INT i = tree_to_shwi (x);
     835                 :      158497 :          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                 :      154532 :          else if (i < 0)
     842                 :             :            {
     843                 :       24977 :              absval = -i;
     844                 :       24977 :              res = 1;
     845                 :             :            }
     846                 :             :          else
     847                 :             :            {
     848                 :      129555 :              absval = i;
     849                 :      129555 :              res = plus;
     850                 :             :            }
     851                 :             :         }
     852                 :             :       else
     853                 :             :         return -1;
     854                 :             :     }
     855                 :             : 
     856                 :      170706 :   int ndigs = ilog (absval, base);
     857                 :             : 
     858                 :      170706 :   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                 :      170706 :   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                 :       98954 :   bool retval_used () const
     924                 :             :   {
     925                 :        2045 :     return gimple_get_lhs (callstmt);
     926                 :             :   }
     927                 :             : 
     928                 :             :   /* Return the warning option corresponding to the called function.  */
     929                 :        8211 :   opt_code warnopt () const
     930                 :             :   {
     931                 :        5576 :     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                 :         786 : directive::set_width (tree arg, range_query *query)
     960                 :             : {
     961                 :         786 :   get_int_range (arg, info->callstmt, width, width + 1, true, 0, query);
     962                 :         786 : }
     963                 :             : 
     964                 :             : void
     965                 :         875 : directive::set_precision (tree arg, range_query *query)
     966                 :             : {
     967                 :         875 :   get_int_range (arg, info->callstmt, prec, prec + 1, false, -1, query);
     968                 :         875 : }
     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                 :        2228 : 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                 :        2228 :   const_tree type = integer_type_node;
    1047                 :             : 
    1048                 :        2228 :   bool knownrange = false;
    1049                 :             : 
    1050                 :        2228 :   if (!arg)
    1051                 :             :     {
    1052                 :         456 :       *pmin = tree_to_shwi (TYPE_MIN_VALUE (type));
    1053                 :         456 :       *pmax = tree_to_shwi (TYPE_MAX_VALUE (type));
    1054                 :             :     }
    1055                 :        1772 :   else if (TREE_CODE (arg) == INTEGER_CST
    1056                 :        1772 :            && 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                 :         688 :       *pmin = tree_fits_shwi_p (arg) ? tree_to_shwi (arg) : tree_to_uhwi (arg);
    1062                 :         688 :       *pmax = *pmin;
    1063                 :         688 :       knownrange = true;
    1064                 :             :     }
    1065                 :             :   else
    1066                 :             :     {
    1067                 :             :       /* True if the argument's range cannot be determined.  */
    1068                 :        1084 :       bool unknown = true;
    1069                 :             : 
    1070                 :        1084 :       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                 :        1084 :       if (TREE_CODE (arg) == SSA_NAME
    1078                 :        1080 :           && INTEGRAL_TYPE_P (argtype)
    1079                 :        2162 :           && TYPE_PRECISION (argtype) <= TYPE_PRECISION (type))
    1080                 :             :         {
    1081                 :             :           /* Try to determine the range of values of the integer argument.  */
    1082                 :        1016 :           value_range vr;
    1083                 :        1016 :           query->range_of_expr (vr, arg, stmt);
    1084                 :             : 
    1085                 :        1016 :           if (!vr.undefined_p () && !vr.varying_p ())
    1086                 :             :             {
    1087                 :         639 :               HOST_WIDE_INT type_min
    1088                 :         639 :                 = (TYPE_UNSIGNED (argtype)
    1089                 :         639 :                    ? tree_to_uhwi (TYPE_MIN_VALUE (argtype))
    1090                 :         635 :                    : tree_to_shwi (TYPE_MIN_VALUE (argtype)));
    1091                 :             : 
    1092                 :         639 :               HOST_WIDE_INT type_max = tree_to_uhwi (TYPE_MAX_VALUE (argtype));
    1093                 :             : 
    1094                 :         639 :               tree type = TREE_TYPE (arg);
    1095                 :         639 :               tree tmin = wide_int_to_tree (type, vr.lower_bound ());
    1096                 :         639 :               tree tmax = wide_int_to_tree (type, vr.upper_bound ());
    1097                 :         639 :               *pmin = TREE_INT_CST_LOW (tmin);
    1098                 :         639 :               *pmax = TREE_INT_CST_LOW (tmax);
    1099                 :             : 
    1100                 :         639 :               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                 :         639 :                   knownrange = type_min < *pmin || *pmax < type_max;
    1109                 :             : 
    1110                 :             :                   unknown = false;
    1111                 :             :                 }
    1112                 :             :             }
    1113                 :        1016 :         }
    1114                 :             : 
    1115                 :             :       /* Handle an argument with an unknown range as if none had been
    1116                 :             :          provided.  */
    1117                 :        1016 :       if (unknown)
    1118                 :         445 :         return get_int_range (NULL_TREE, NULL, pmin, pmax, absolute,
    1119                 :         445 :                               negbound, query);
    1120                 :             :     }
    1121                 :             : 
    1122                 :             :   /* Adjust each bound as specified by ABSOLUTE and NEGBOUND.  */
    1123                 :        1783 :   if (absolute)
    1124                 :             :     {
    1125                 :         786 :       if (*pmin < 0)
    1126                 :             :         {
    1127                 :         312 :           if (*pmin == *pmax)
    1128                 :          24 :             *pmin = *pmax = -*pmin;
    1129                 :             :           else
    1130                 :             :             {
    1131                 :             :               /* Make sure signed overlow is avoided.  */
    1132                 :         288 :               gcc_assert (*pmin != HOST_WIDE_INT_MIN);
    1133                 :             : 
    1134                 :         288 :               HOST_WIDE_INT tmp = -*pmin;
    1135                 :         288 :               *pmin = 0;
    1136                 :         288 :               if (*pmax < tmp)
    1137                 :         270 :                 *pmax = tmp;
    1138                 :             :             }
    1139                 :             :         }
    1140                 :             :     }
    1141                 :         997 :   else if (*pmin < negbound)
    1142                 :         406 :     *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                 :       39325 : adjust_range_for_overflow (tree dirtype, tree *argmin, tree *argmax)
    1161                 :             : {
    1162                 :       39325 :   tree argtype = TREE_TYPE (*argmin);
    1163                 :       39325 :   unsigned argprec = TYPE_PRECISION (argtype);
    1164                 :       39325 :   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                 :       39325 :   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                 :        4124 :   if (TREE_CODE (*argmin) == INTEGER_CST
    1176                 :        4124 :       && TREE_CODE (*argmax) == INTEGER_CST
    1177                 :        8248 :       && (dirprec >= argprec
    1178                 :        1791 :           || integer_zerop (int_const_binop (RSHIFT_EXPR,
    1179                 :        1791 :                                              int_const_binop (MINUS_EXPR,
    1180                 :             :                                                               *argmax,
    1181                 :             :                                                               *argmin),
    1182                 :        3244 :                                              size_int (dirprec)))))
    1183                 :             :     {
    1184                 :        2671 :       unsigned int maxprec = MAX (argprec, dirprec);
    1185                 :        2671 :       *argmin = force_fit_type (dirtype,
    1186                 :        2671 :                                 wide_int::from (wi::to_wide (*argmin), maxprec,
    1187                 :        2671 :                                                 TYPE_SIGN (argtype)),
    1188                 :             :                                 0, false);
    1189                 :        2671 :       *argmax = force_fit_type (dirtype,
    1190                 :        2671 :                                 wide_int::from (wi::to_wide (*argmax), maxprec,
    1191                 :        2671 :                                                 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                 :        2671 :       if (tree_int_cst_le (*argmin, *argmax))
    1197                 :             :         return false;
    1198                 :             :     }
    1199                 :             : 
    1200                 :        2642 :   *argmin = TYPE_MIN_VALUE (dirtype);
    1201                 :        2642 :   *argmax = TYPE_MAX_VALUE (dirtype);
    1202                 :        2642 :   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                 :      210097 : format_integer (const directive &dir, tree arg, pointer_query &ptr_qry)
    1212                 :             : {
    1213                 :      210097 :   tree intmax_type_node;
    1214                 :      210097 :   tree uintmax_type_node;
    1215                 :             : 
    1216                 :             :   /* Base to format the number in.  */
    1217                 :      210097 :   int base;
    1218                 :             : 
    1219                 :             :   /* True when a conversion is preceded by a prefix indicating the base
    1220                 :             :      of the argument (octal or hexadecimal).  */
    1221                 :      210097 :   const bool maybebase = dir.get_flag ('#');
    1222                 :             : 
    1223                 :             :   /* True when a signed conversion is preceded by a sign or space.  */
    1224                 :      210097 :   bool maybesign = false;
    1225                 :             : 
    1226                 :             :   /* True for signed conversions (i.e., 'd' and 'i').  */
    1227                 :      210097 :   bool sign = false;
    1228                 :             : 
    1229                 :      210097 :   switch (dir.specifier)
    1230                 :             :     {
    1231                 :      193446 :     case 'd':
    1232                 :      193446 :     case 'i':
    1233                 :             :       /* Space and '+' are  only meaningful for signed conversions.  */
    1234                 :      193446 :       maybesign = dir.get_flag (' ') | dir.get_flag ('+');
    1235                 :      193446 :       sign = true;
    1236                 :      193446 :       base = 10;
    1237                 :      193446 :       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                 :        4887 :     case 'X':
    1249                 :        4887 :     case 'x':
    1250                 :        4887 :       base = 16;
    1251                 :        4887 :       break;
    1252                 :           0 :     default:
    1253                 :           0 :       gcc_unreachable ();
    1254                 :             :     }
    1255                 :             : 
    1256                 :      210097 :   const unsigned adj = (sign | maybebase) + (base == 2 || base == 16);
    1257                 :             : 
    1258                 :             :   /* The type of the "formal" argument expected by the directive.  */
    1259                 :      210097 :   tree dirtype = NULL_TREE;
    1260                 :             : 
    1261                 :             :   /* Determine the expected type of the argument from the length
    1262                 :             :      modifier.  */
    1263                 :      210097 :   switch (dir.modifier)
    1264                 :             :     {
    1265                 :      151072 :     case FMT_LEN_none:
    1266                 :      151072 :       if (dir.specifier == 'p')
    1267                 :             :         dirtype = ptr_type_node;
    1268                 :             :       else
    1269                 :      151072 :         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                 :        1618 :     case FMT_LEN_hh:
    1277                 :        1618 :       dirtype = sign ? signed_char_type_node : unsigned_char_type_node;
    1278                 :             :       break;
    1279                 :             : 
    1280                 :       49772 :     case FMT_LEN_l:
    1281                 :       49772 :       dirtype = sign ? long_integer_type_node : long_unsigned_type_node;
    1282                 :             :       break;
    1283                 :             : 
    1284                 :        2029 :     case FMT_LEN_L:
    1285                 :        2029 :     case FMT_LEN_ll:
    1286                 :        2029 :       dirtype = (sign
    1287                 :        2029 :                  ? long_long_integer_type_node
    1288                 :             :                  : long_long_unsigned_type_node);
    1289                 :             :       break;
    1290                 :             : 
    1291                 :        4653 :     case FMT_LEN_z:
    1292                 :        4653 :       dirtype = signed_or_unsigned_type_for (!sign, size_type_node);
    1293                 :        4653 :       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                 :      210097 :   tree argtype = NULL_TREE;
    1313                 :             : 
    1314                 :      210097 :   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                 :      209780 :   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                 :      170744 :       fmtresult res;
    1327                 :             : 
    1328                 :      170744 :       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                 :         222 :           res.range.min = ((base == 8 && dir.get_flag ('#')) || maybesign);
    1338                 :         222 :           if (res.range.min == 0 && dir.prec[0] != dir.prec[1])
    1339                 :             :             {
    1340                 :          99 :               res.range.max = 1;
    1341                 :          99 :               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                 :      170522 :           arg = fold_convert (dirtype, arg);
    1353                 :             : 
    1354                 :      170522 :           res.range.min = tree_digits (arg, base, dir.prec[0],
    1355                 :             :                                        maybesign, maybebase);
    1356                 :      170522 :           if (dir.prec[0] == dir.prec[1])
    1357                 :      170338 :             res.range.max = res.range.min;
    1358                 :             :           else
    1359                 :         184 :             res.range.max = tree_digits (arg, base, dir.prec[1],
    1360                 :             :                                          maybesign, maybebase);
    1361                 :      170522 :           res.range.likely = res.range.min;
    1362                 :      170522 :           res.knownrange = true;
    1363                 :             :         }
    1364                 :             : 
    1365                 :      170744 :       res.range.unlikely = res.range.max;
    1366                 :             : 
    1367                 :             :       /* Bump up the counters if WIDTH is greater than LEN.  */
    1368                 :      170744 :       res.adjust_for_width_or_precision (dir.width, dirtype, base, adj);
    1369                 :             :       /* Bump up the counters again if PRECision is greater still.  */
    1370                 :      170744 :       res.adjust_for_width_or_precision (dir.prec, dirtype, base, adj);
    1371                 :             : 
    1372                 :      170744 :       return res;
    1373                 :             :     }
    1374                 :       78062 :   else if (INTEGRAL_TYPE_P (TREE_TYPE (arg))
    1375                 :       39320 :            || TREE_CODE (TREE_TYPE (arg)) == POINTER_TYPE)
    1376                 :             :     /* Determine the type of the provided non-constant argument.  */
    1377                 :       39009 :     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                 :          27 :     return fmtresult ();
    1383                 :             : 
    1384                 :       39326 :   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                 :       39326 :   tree argmin = NULL_TREE;
    1390                 :       39326 :   tree argmax = NULL_TREE;
    1391                 :             : 
    1392                 :       39326 :   if (arg
    1393                 :       39009 :       && TREE_CODE (arg) == SSA_NAME
    1394                 :       38990 :       && 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                 :       38752 :       value_range vr;
    1399                 :       38752 :       ptr_qry.rvals->range_of_expr (vr, arg, dir.info->callstmt);
    1400                 :             : 
    1401                 :       38752 :       if (!vr.varying_p () && !vr.undefined_p ())
    1402                 :             :         {
    1403                 :       18607 :           argmin = wide_int_to_tree (TREE_TYPE (arg), vr.lower_bound ());
    1404                 :       18607 :           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                 :       18607 :           res.knownrange
    1410                 :       18607 :             = ((!tree_int_cst_equal (TYPE_MIN_VALUE (dirtype), argmin)
    1411                 :        3336 :                 || !tree_int_cst_equal (TYPE_MAX_VALUE (dirtype), argmax))
    1412                 :       20118 :                && dir.known_width_and_precision ());
    1413                 :             : 
    1414                 :       18607 :           res.argmin = argmin;
    1415                 :       18607 :           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                 :       20145 :           gimple *def = SSA_NAME_DEF_STMT (arg);
    1424                 :       20145 :           if (is_gimple_assign (def))
    1425                 :             :             {
    1426                 :       10952 :               tree_code code = gimple_assign_rhs_code (def);
    1427                 :       10952 :               if (code == INTEGER_CST)
    1428                 :             :                 {
    1429                 :           1 :                   arg = gimple_assign_rhs1 (def);
    1430                 :           1 :                   return format_integer (dir, arg, ptr_qry);
    1431                 :             :                 }
    1432                 :             : 
    1433                 :       10951 :               if (code == NOP_EXPR)
    1434                 :             :                 {
    1435                 :         954 :                   tree type = TREE_TYPE (gimple_assign_rhs1 (def));
    1436                 :         954 :                   if (INTEGRAL_TYPE_P (type)
    1437                 :         954 :                       || TREE_CODE (type) == POINTER_TYPE)
    1438                 :       38751 :                     argtype = type;
    1439                 :             :                 }
    1440                 :             :             }
    1441                 :             :         }
    1442                 :       38752 :     }
    1443                 :             : 
    1444                 :       39325 :   if (!argmin)
    1445                 :             :     {
    1446                 :       20718 :       if (TREE_CODE (argtype) == POINTER_TYPE)
    1447                 :             :         {
    1448                 :         298 :           argmin = build_int_cst (pointer_sized_int_node, 0);
    1449                 :         298 :           argmax = build_all_ones_cst (pointer_sized_int_node);
    1450                 :             :         }
    1451                 :             :       else
    1452                 :             :         {
    1453                 :       20420 :           argmin = TYPE_MIN_VALUE (argtype);
    1454                 :       20420 :           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                 :       39325 :   if (adjust_range_for_overflow (dirtype, &argmin, &argmax))
    1463                 :             :     {
    1464                 :        2642 :       res.knownrange = false;
    1465                 :        2642 :       res.argmin = argmin;
    1466                 :        2642 :       res.argmax = argmax;
    1467                 :             :     }
    1468                 :             : 
    1469                 :             :   /* Recursively compute the minimum and maximum from the known range.  */
    1470                 :       39325 :   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                 :       10636 :       res.range.min = format_integer (dir, argmin, ptr_qry).range.min;
    1476                 :       10636 :       res.range.max = format_integer (dir, argmax, ptr_qry).range.max;
    1477                 :             :     }
    1478                 :       28689 :   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                 :       28664 :       unsigned HOST_WIDE_INT max1
    1493                 :       28664 :         = format_integer (dir, argmin, ptr_qry).range.max;
    1494                 :       28664 :       unsigned HOST_WIDE_INT max2
    1495                 :       28664 :         = format_integer (dir, argmax, ptr_qry).range.max;
    1496                 :       28664 :       res.range.min
    1497                 :       28664 :         = format_integer (dir, integer_zero_node, ptr_qry).range.min;
    1498                 :       28664 :       res.range.max = MAX (max1, max2);
    1499                 :             :     }
    1500                 :             : 
    1501                 :             :   /* If the range is known, use the maximum as the likely length.  */
    1502                 :       39325 :   if (res.knownrange)
    1503                 :       16439 :     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                 :       22886 :       res.range.likely = res.range.min;
    1512                 :       22886 :       if (maybebase
    1513                 :       22886 :           && base != 10
    1514                 :       22886 :           && (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                 :       39325 :   res.range.unlikely = res.range.max;
    1526                 :       39325 :   res.adjust_for_width_or_precision (dir.width, dirtype, base, adj);
    1527                 :       39325 :   res.adjust_for_width_or_precision (dir.prec, dirtype, base, adj);
    1528                 :             : 
    1529                 :       39325 :   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                 :        4949 : get_mpfr_format_length (mpfr_ptr x, const char *flags, HOST_WIDE_INT prec,
    1541                 :             :                         char spec, char rndspec)
    1542                 :             : {
    1543                 :        4949 :   char fmtstr[40];
    1544                 :             : 
    1545                 :        4949 :   HOST_WIDE_INT len = strlen (flags);
    1546                 :             : 
    1547                 :        4949 :   fmtstr[0] = '%';
    1548                 :        4949 :   memcpy (fmtstr + 1, flags, len);
    1549                 :        4949 :   memcpy (fmtstr + 1 + len, ".*R", 3);
    1550                 :        4949 :   fmtstr[len + 4] = rndspec;
    1551                 :        4949 :   fmtstr[len + 5] = spec;
    1552                 :        4949 :   fmtstr[len + 6] = '\0';
    1553                 :             : 
    1554                 :        4949 :   spec = TOUPPER (spec);
    1555                 :        4949 :   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                 :        3238 :       if (prec < 0)
    1560                 :        4949 :         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                 :        4949 :         prec = -1;
    1569                 :             :     }
    1570                 :             : 
    1571                 :        4949 :   HOST_WIDE_INT p = prec;
    1572                 :             : 
    1573                 :        4949 :   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                 :        3479 :       if (prec > 1024)
    1588                 :             :         p = 1024;
    1589                 :             :     }
    1590                 :             : 
    1591                 :        4949 :   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                 :        4949 :   if (len < 0)
    1596                 :           0 :     return target_dir_max () + 1;
    1597                 :             : 
    1598                 :             :   /* Adjust the return value by the difference.  */
    1599                 :        4949 :   if (p < prec)
    1600                 :         158 :     len += prec - p;
    1601                 :             : 
    1602                 :        4949 :   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                 :        3867 : format_floating_max (tree type, char spec, HOST_WIDE_INT prec)
    1611                 :             : {
    1612                 :        3867 :   machine_mode mode = TYPE_MODE (type);
    1613                 :             : 
    1614                 :             :   /* IBM Extended mode.  */
    1615                 :       27069 :   if (MODE_COMPOSITE_P (mode))
    1616                 :           0 :     mode = DFmode;
    1617                 :             : 
    1618                 :             :   /* Get the real type format description for the target.  */
    1619                 :        3867 :   const real_format *rfmt = REAL_MODE_FORMAT (mode);
    1620                 :        3867 :   REAL_VALUE_TYPE rv;
    1621                 :             : 
    1622                 :        3867 :   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                 :        3867 :   mpfr_t x;
    1628                 :        3867 :   mpfr_init2 (x, rfmt->p);
    1629                 :        3867 :   mpfr_from_real (x, &rv, MPFR_RNDN);
    1630                 :             : 
    1631                 :             :   /* Return a value one greater to account for the leading minus sign.  */
    1632                 :        3867 :   unsigned HOST_WIDE_INT r
    1633                 :        3867 :     = 1 + get_mpfr_format_length (x, "", prec, spec, 'D');
    1634                 :        3867 :   mpfr_clear (x);
    1635                 :        3867 :   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                 :        3959 : format_floating (const directive &dir, const HOST_WIDE_INT prec[2])
    1646                 :             : {
    1647                 :        3959 :   tree type;
    1648                 :             : 
    1649                 :        3959 :   switch (dir.modifier)
    1650                 :             :     {
    1651                 :        3488 :     case FMT_LEN_l:
    1652                 :        3488 :     case FMT_LEN_none:
    1653                 :        3488 :       type = double_type_node;
    1654                 :        3488 :       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                 :        3867 :   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                 :        3867 :   unsigned flagmin = (1 /* for the first digit */
    1675                 :        3867 :                       + (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                 :        3867 :   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                 :        3867 :   bool radix = dir.get_flag ('#');
    1686                 :             : 
    1687                 :        3867 :   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                 :        2102 :     case 'F':
    1742                 :        2102 :     case 'f':
    1743                 :        2102 :       {
    1744                 :             :         /* Minimum output attributable to precision and, when it's non-zero,
    1745                 :             :            decimal point.  */
    1746                 :        2102 :         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                 :        2102 :         unsigned HOST_WIDE_INT min = flagmin + radix + minprec;
    1755                 :        2102 :         if (min < res.range.min)
    1756                 :         162 :           res.range.min = min;
    1757                 :             : 
    1758                 :             :         /* Compute the upper bound for -TYPE_MAX.  */
    1759                 :        2102 :         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                 :        2102 :         if (dir.prec[0] < 0 && dir.prec[1] > 0)
    1764                 :          32 :           res.range.likely = 3;
    1765                 :             :         else
    1766                 :        2070 :           res.range.likely = min;
    1767                 :             : 
    1768                 :             :         /* The unlikely maximum accounts for the longest multibyte
    1769                 :             :            decimal point character.  */
    1770                 :        2102 :         if (dir.prec[0] != dir.prec[1]
    1771                 :        2055 :             || dir.prec[0] == -1 || dir.prec[0] > 0)
    1772                 :        1985 :           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                 :        3867 :   res.adjust_for_width_or_precision (dir.width);
    1836                 :        3867 :   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                 :        4521 : format_floating (const directive &dir, tree arg, pointer_query &)
    1845                 :             : {
    1846                 :        4521 :   HOST_WIDE_INT prec[] = { dir.prec[0], dir.prec[1] };
    1847                 :        9042 :   tree type = (dir.modifier == FMT_LEN_L || dir.modifier == FMT_LEN_ll
    1848                 :        4521 :                ? long_double_type_node : double_type_node);
    1849                 :             : 
    1850                 :             :   /* For an indeterminate precision the lower bound must be assumed
    1851                 :             :      to be zero.  */
    1852                 :        4521 :   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                 :        4326 :   else if (dir.prec[0] < 0)
    1887                 :             :     {
    1888                 :        3811 :       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                 :        3702 :           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                 :         109 :           prec[0] = 0;
    1902                 :         109 :           prec[1] = dir.prec[1] < 6 ? 6 : dir.prec[1];
    1903                 :             :         }
    1904                 :             :     }
    1905                 :             : 
    1906                 :        4521 :   if (!arg
    1907                 :        4422 :       || TREE_CODE (arg) != REAL_CST
    1908                 :        5084 :       || !useless_type_conversion_p (type, TREE_TYPE (arg)))
    1909                 :        3959 :     return format_floating (dir, prec);
    1910                 :             : 
    1911                 :             :   /* The minimum and maximum number of bytes produced by the directive.  */
    1912                 :         562 :   fmtresult res;
    1913                 :             : 
    1914                 :             :   /* Get the real type format description for the target.  */
    1915                 :         562 :   const REAL_VALUE_TYPE *rvp = TREE_REAL_CST_PTR (arg);
    1916                 :         562 :   const real_format *rfmt = REAL_MODE_FORMAT (TYPE_MODE (TREE_TYPE (arg)));
    1917                 :             : 
    1918                 :         562 :   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                 :          21 :       bool sign = dir.get_flag ('+') || real_isneg (rvp);
    1924                 :          21 :       res.range.min = 3 + sign;
    1925                 :             : 
    1926                 :          21 :       res.range.likely = res.range.min;
    1927                 :          21 :       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                 :          21 :       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                 :          21 :       res.knownrange = dir.known_width_and_precision ();
    1944                 :             : 
    1945                 :             :       /* Adjust the range for width but ignore precision.  */
    1946                 :          21 :       res.adjust_for_width_or_precision (dir.width);
    1947                 :             : 
    1948                 :          21 :       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                 :      189458 : get_string_length (tree str, gimple *stmt, unsigned HOST_WIDE_INT max_size,
    2039                 :             :                    unsigned eltsize, pointer_query &ptr_qry)
    2040                 :             : {
    2041                 :      189458 :   if (!str)
    2042                 :         578 :     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                 :      188880 :   c_strlen_data lendata = { };
    2048                 :      188880 :   lendata.maxbound = str;
    2049                 :      188880 :   if (eltsize == 1)
    2050                 :      188579 :     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                 :         301 :       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                 :      188880 :   if ((lendata.maxbound && !tree_fits_uhwi_p (lendata.maxbound))
    2067                 :      188880 :       || !tree_fits_uhwi_p (lendata.maxlen))
    2068                 :             :     {
    2069                 :           0 :       fmtresult res;
    2070                 :           0 :       res.nonstr = lendata.decl;
    2071                 :           0 :       return res;
    2072                 :             :     }
    2073                 :             : 
    2074                 :      188880 :   unsigned HOST_WIDE_INT lenmax = tree_to_uhwi (max_object_size ()) - 2;
    2075                 :      188880 :   if (integer_zerop (lendata.minlen)
    2076                 :       18203 :       && (!lendata.maxbound || lenmax <= tree_to_uhwi (lendata.maxbound))
    2077                 :      200946 :       && lenmax <= tree_to_uhwi (lendata.maxlen))
    2078                 :             :     {
    2079                 :       12060 :       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                 :       12026 :       fmtresult res;
    2094                 :       12026 :       res.nonstr = lendata.decl;
    2095                 :       12026 :       return res;
    2096                 :             :     }
    2097                 :             : 
    2098                 :             :   /* The minimum length of the string.  */
    2099                 :      353640 :   HOST_WIDE_INT min
    2100                 :      176820 :     = (tree_fits_uhwi_p (lendata.minlen)
    2101                 :      176820 :        ? 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                 :      353640 :   HOST_WIDE_INT max
    2107                 :      176809 :     = (lendata.maxbound && tree_fits_uhwi_p (lendata.maxbound)
    2108                 :      353629 :        ? 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                 :      176820 :   const bool unbounded
    2119                 :      176820 :     = (integer_all_onesp (lendata.maxlen)
    2120                 :      176820 :        || (lendata.maxbound
    2121                 :      175774 :            && 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                 :      176820 :   if (min
    2128                 :      176820 :       && (unsigned HOST_WIDE_INT)min < HOST_WIDE_INT_M1U
    2129                 :      170677 :       && unbounded)
    2130                 :      176820 :     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                 :      176820 :   if ((unsigned HOST_WIDE_INT)min == target_size_max ())
    2136                 :           0 :     min = HOST_WIDE_INT_M1U;
    2137                 :      176820 :   if ((unsigned HOST_WIDE_INT)max == target_size_max ())
    2138                 :         149 :     max = HOST_WIDE_INT_M1U;
    2139                 :             : 
    2140                 :      176820 :   fmtresult res (min, max);
    2141                 :      176820 :   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                 :      176820 :   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                 :         177 :       res.range.likely = res.range.min ? res.range.min : warn_level > 1;
    2159                 :         177 :       if (lendata.maxbound && !integer_all_onesp (lendata.maxbound))
    2160                 :             :         res.range.min = 0;
    2161                 :             :     }
    2162                 :             : 
    2163                 :      176820 :   res.range.unlikely = unbounded ? HOST_WIDE_INT_MAX : res.range.max;
    2164                 :             : 
    2165                 :      176820 :   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                 :        1069 : format_character (const directive &dir, tree arg, pointer_query &ptr_qry)
    2175                 :             : {
    2176                 :        1069 :   fmtresult res;
    2177                 :             : 
    2178                 :        1069 :   res.knownrange = true;
    2179                 :             : 
    2180                 :        1069 :   if (dir.specifier == 'C'
    2181                 :        1019 :       || dir.modifier == FMT_LEN_l)
    2182                 :             :     {
    2183                 :             :       /* A wide character can result in as few as zero bytes.  */
    2184                 :         122 :       res.range.min = 0;
    2185                 :             : 
    2186                 :         122 :       HOST_WIDE_INT min, max;
    2187                 :         122 :       if (get_int_range (arg, dir.info->callstmt, &min, &max, false, 0,
    2188                 :             :                          ptr_qry.rvals))
    2189                 :             :         {
    2190                 :          60 :           if (min == 0 && max == 0)
    2191                 :             :             {
    2192                 :             :               /* The NUL wide character results in no bytes.  */
    2193                 :          17 :               res.range.max = 0;
    2194                 :          17 :               res.range.likely = 0;
    2195                 :          17 :               res.range.unlikely = 0;
    2196                 :             :             }
    2197                 :          43 :           else if (min >= 0 && min < 128)
    2198                 :             :             {
    2199                 :             :               /* Be conservative if the target execution character set
    2200                 :             :                  is not a 1-to-1 mapping to the source character set or
    2201                 :             :                  if the source set is not ASCII.  */
    2202                 :          36 :               bool one_2_one_ascii
    2203                 :          36 :                 = (target_to_host_charmap[0] == 1 && target_to_host ('a') == 97);
    2204                 :             : 
    2205                 :             :               /* A wide character in the ASCII range most likely results
    2206                 :             :                  in a single byte, and only unlikely in up to MB_LEN_MAX.  */
    2207                 :          36 :               res.range.max = one_2_one_ascii ? 1 : target_mb_len_max ();;
    2208                 :          36 :               res.range.likely = 1;
    2209                 :          36 :               res.range.unlikely = target_mb_len_max ();
    2210                 :          36 :               res.mayfail = !one_2_one_ascii;
    2211                 :             :             }
    2212                 :             :           else
    2213                 :             :             {
    2214                 :             :               /* A wide character outside the ASCII range likely results
    2215                 :             :                  in up to two bytes, and only unlikely in up to MB_LEN_MAX.  */
    2216                 :           7 :               res.range.max = target_mb_len_max ();
    2217                 :           7 :               res.range.likely = 2;
    2218                 :           7 :               res.range.unlikely = res.range.max;
    2219                 :             :               /* Converting such a character may fail.  */
    2220                 :           7 :               res.mayfail = true;
    2221                 :             :             }
    2222                 :             :         }
    2223                 :             :       else
    2224                 :             :         {
    2225                 :             :           /* An unknown wide character is treated the same as a wide
    2226                 :             :              character outside the ASCII range.  */
    2227                 :          62 :           res.range.max = target_mb_len_max ();
    2228                 :          62 :           res.range.likely = 2;
    2229                 :          62 :           res.range.unlikely = res.range.max;
    2230                 :          62 :           res.mayfail = true;
    2231                 :             :         }
    2232                 :         122 :     }
    2233                 :             :   else
    2234                 :             :     {
    2235                 :             :       /* A plain '%c' directive.  Its output is exactly 1.  */
    2236                 :         947 :       res.range.min = res.range.max = 1;
    2237                 :         947 :       res.range.likely = res.range.unlikely = 1;
    2238                 :         947 :       res.knownrange = true;
    2239                 :             :     }
    2240                 :             : 
    2241                 :             :   /* Bump up the byte counters if WIDTH is greater.  */
    2242                 :        1069 :   return res.adjust_for_width_or_precision (dir.width);
    2243                 :             : }
    2244                 :             : 
    2245                 :             : /* If TYPE is an array or struct or union, increment *FLDOFF by the starting
    2246                 :             :    offset of the member that *OFF points into if one can be determined and
    2247                 :             :    set *FLDSIZE to its size in bytes and decrement *OFF by the same.
    2248                 :             :    Otherwise do nothing.  */
    2249                 :             : 
    2250                 :             : static void
    2251                 :        3696 : set_aggregate_size_and_offset (tree type, HOST_WIDE_INT *fldoff,
    2252                 :             :                                HOST_WIDE_INT *fldsize, HOST_WIDE_INT *off)
    2253                 :             : {
    2254                 :             :   /* The byte offset of the most basic struct member the byte
    2255                 :             :      offset *OFF corresponds to, or for a (multidimensional)
    2256                 :             :      array member, the byte offset of the array element.  */
    2257                 :        3696 :   if (TREE_CODE (type) == ARRAY_TYPE
    2258                 :        3696 :       && TREE_CODE (TREE_TYPE (type)) == ARRAY_TYPE)
    2259                 :             :     {
    2260                 :          32 :       HOST_WIDE_INT index = 0, arrsize = 0;
    2261                 :          32 :       if (array_elt_at_offset (type, *off, &index, &arrsize))
    2262                 :             :         {
    2263                 :          16 :           *fldoff += index;
    2264                 :          16 :           *fldsize = arrsize;
    2265                 :             :         }
    2266                 :             :       /* Otherwise leave *FLDOFF et al. unchanged.  */
    2267                 :             :     }
    2268                 :        3664 :   else if (RECORD_OR_UNION_TYPE_P (type))
    2269                 :             :     {
    2270                 :         547 :       HOST_WIDE_INT index = 0;
    2271                 :         547 :       tree sub = field_at_offset (type, NULL_TREE, *off, &index);
    2272                 :         547 :       if (sub)
    2273                 :             :         {
    2274                 :         533 :           tree subsize = DECL_SIZE_UNIT (sub);
    2275                 :         533 :           if (*fldsize < HOST_WIDE_INT_MAX
    2276                 :         533 :               && subsize
    2277                 :         524 :               && tree_fits_uhwi_p (subsize))
    2278                 :         524 :             *fldsize = tree_to_uhwi (subsize);
    2279                 :             :           else
    2280                 :           9 :             *fldsize = HOST_WIDE_INT_MAX;
    2281                 :         533 :           *fldoff += index;
    2282                 :         533 :           *off -= index;
    2283                 :             :         }
    2284                 :             :       /* Otherwise leave *FLDOFF et al. unchanged.  */
    2285                 :             :     }
    2286                 :        3696 : }
    2287                 :             : 
    2288                 :             : /* For an expression X of pointer type, recursively try to find its origin
    2289                 :             :    (either object DECL or pointer such as PARM_DECL) Y and return such a Y.
    2290                 :             :    When X refers to an array element or struct member, set *FLDOFF to
    2291                 :             :    the offset of the element or member from the beginning of the "most
    2292                 :             :    derived" object and *FLDSIZE to its size.  When nonnull, set *OFF to
    2293                 :             :    the overall offset from the beginning of the object so that
    2294                 :             :    *FLDOFF <= *OFF.  */
    2295                 :             : 
    2296                 :             : static tree
    2297                 :       23910 : get_origin_and_offset_r (tree x, HOST_WIDE_INT *fldoff, HOST_WIDE_INT *fldsize,
    2298                 :             :                          HOST_WIDE_INT *off)
    2299                 :             : {
    2300                 :       23910 :   HOST_WIDE_INT sizebuf = -1;
    2301                 :       23910 :   if (!fldsize)
    2302                 :        2053 :     fldsize = &sizebuf;
    2303                 :             : 
    2304                 :       23910 :   if (DECL_P (x))
    2305                 :             :     {
    2306                 :             :       /* Set the size if it hasn't been set yet.  */
    2307                 :        5873 :       if (tree size = DECL_SIZE_UNIT (x))
    2308                 :        4668 :         if (*fldsize < 0 && tree_fits_shwi_p (size))
    2309                 :        4615 :           *fldsize = tree_to_shwi (size);
    2310                 :        5873 :       return x;
    2311                 :             :     }
    2312                 :             : 
    2313                 :       18037 :   switch (TREE_CODE (x))
    2314                 :             :     {
    2315                 :        5884 :     case ADDR_EXPR:
    2316                 :        5884 :       x = TREE_OPERAND (x, 0);
    2317                 :        5884 :       return get_origin_and_offset_r (x, fldoff, fldsize, off);
    2318                 :             : 
    2319                 :        4632 :     case ARRAY_REF:
    2320                 :        4632 :       {
    2321                 :        4632 :         tree sub = TREE_OPERAND (x, 1);
    2322                 :        9264 :         unsigned HOST_WIDE_INT idx =
    2323                 :        4632 :           tree_fits_uhwi_p (sub) ? tree_to_uhwi (sub) : HOST_WIDE_INT_MAX;
    2324                 :             : 
    2325                 :        4632 :         tree elsz = array_ref_element_size (x);
    2326                 :        9264 :         unsigned HOST_WIDE_INT elbytes =
    2327                 :        4632 :           tree_fits_shwi_p (elsz) ? tree_to_shwi (elsz) : HOST_WIDE_INT_MAX;
    2328                 :             : 
    2329                 :        4632 :         unsigned HOST_WIDE_INT byteoff = idx * elbytes;
    2330                 :             : 
    2331                 :        4632 :         if (byteoff < HOST_WIDE_INT_MAX
    2332                 :        4632 :             && elbytes < HOST_WIDE_INT_MAX
    2333                 :        4632 :             && (elbytes == 0 || byteoff / elbytes == idx))
    2334                 :             :           {
    2335                 :             :             /* For in-bounds constant offsets into constant-sized arrays
    2336                 :             :                bump up *OFF, and for what's likely arrays or structs of
    2337                 :             :                arrays, also *FLDOFF, as necessary.  */
    2338                 :        4632 :             if (off)
    2339                 :        4632 :               *off += byteoff;
    2340                 :        4632 :             if (elbytes > 1)
    2341                 :        4580 :               *fldoff += byteoff;
    2342                 :             :           }
    2343                 :             :         else
    2344                 :           0 :           *fldoff = HOST_WIDE_INT_MAX;
    2345                 :             : 
    2346                 :        4632 :         x = TREE_OPERAND (x, 0);
    2347                 :        4632 :         return get_origin_and_offset_r (x, fldoff, fldsize, off);
    2348                 :             :       }
    2349                 :             : 
    2350                 :        1494 :     case MEM_REF:
    2351                 :        1494 :       if (off)
    2352                 :             :         {
    2353                 :        1494 :           tree offset = TREE_OPERAND (x, 1);
    2354                 :        1494 :           *off = (tree_fits_uhwi_p (offset)
    2355                 :        1494 :                   ? tree_to_uhwi (offset) : HOST_WIDE_INT_MAX);
    2356                 :             :         }
    2357                 :             : 
    2358                 :        1494 :       x = TREE_OPERAND (x, 0);
    2359                 :             : 
    2360                 :        1494 :       if (off)
    2361                 :             :         {
    2362                 :        1494 :           tree xtype
    2363                 :        1494 :             = (TREE_CODE (x) == ADDR_EXPR
    2364                 :        1494 :                ? TREE_TYPE (TREE_OPERAND (x, 0)) : TREE_TYPE (TREE_TYPE (x)));
    2365                 :             : 
    2366                 :        1494 :           set_aggregate_size_and_offset (xtype, fldoff, fldsize, off);
    2367                 :             :         }
    2368                 :             : 
    2369                 :        1494 :       return get_origin_and_offset_r (x, fldoff, fldsize, nullptr);
    2370                 :             : 
    2371                 :        2053 :     case COMPONENT_REF:
    2372                 :        2053 :       {
    2373                 :        2053 :         tree foff = component_ref_field_offset (x);
    2374                 :        2053 :         tree fld = TREE_OPERAND (x, 1);
    2375                 :        2053 :         if (!tree_fits_shwi_p (foff)
    2376                 :        4106 :             || !tree_fits_shwi_p (DECL_FIELD_BIT_OFFSET (fld)))
    2377                 :             :           return x;
    2378                 :        2053 :         *fldoff += (tree_to_shwi (foff)
    2379                 :        2053 :                     + (tree_to_shwi (DECL_FIELD_BIT_OFFSET (fld))
    2380                 :        2053 :                        / BITS_PER_UNIT));
    2381                 :             : 
    2382                 :        2053 :         get_origin_and_offset_r (fld, fldoff, fldsize, off);
    2383                 :        2053 :         x = TREE_OPERAND (x, 0);
    2384                 :        2053 :         return get_origin_and_offset_r (x, fldoff, nullptr, off);
    2385                 :             :       }
    2386                 :             : 
    2387                 :        3114 :     case SSA_NAME:
    2388                 :        3114 :       {
    2389                 :        3114 :         gimple *def = SSA_NAME_DEF_STMT (x);
    2390                 :        3114 :         if (is_gimple_assign (def))
    2391                 :             :           {
    2392                 :        1536 :             tree_code code = gimple_assign_rhs_code (def);
    2393                 :        1536 :             if (code == ADDR_EXPR)
    2394                 :             :               {
    2395                 :         423 :                 x = gimple_assign_rhs1 (def);
    2396                 :         423 :                 return get_origin_and_offset_r (x, fldoff, fldsize, off);
    2397                 :             :               }
    2398                 :             : 
    2399                 :        1113 :             if (code == POINTER_PLUS_EXPR)
    2400                 :             :               {
    2401                 :         374 :                 tree offset = gimple_assign_rhs2 (def);
    2402                 :         374 :                 if (off && tree_fits_uhwi_p (offset))
    2403                 :         163 :                   *off = tree_to_uhwi (offset);
    2404                 :             : 
    2405                 :         374 :                 x = gimple_assign_rhs1 (def);
    2406                 :         374 :                 x = get_origin_and_offset_r (x, fldoff, fldsize, off);
    2407                 :         374 :                 if (off && !tree_fits_uhwi_p (offset))
    2408                 :         208 :                   *off = HOST_WIDE_INT_MAX;
    2409                 :         208 :                 if (off)
    2410                 :             :                   {
    2411                 :         371 :                     tree xtype = TREE_TYPE (x);
    2412                 :         371 :                     set_aggregate_size_and_offset (xtype, fldoff, fldsize, off);
    2413                 :             :                   }
    2414                 :         374 :                 return x;
    2415                 :             :               }
    2416                 :         739 :             else if (code == VAR_DECL)
    2417                 :             :               {
    2418                 :          86 :                 x = gimple_assign_rhs1 (def);
    2419                 :          86 :                 return get_origin_and_offset_r (x, fldoff, fldsize, off);
    2420                 :             :               }
    2421                 :             :           }
    2422                 :        1578 :         else if (gimple_nop_p (def) && SSA_NAME_VAR (x))
    2423                 :             :           x = SSA_NAME_VAR (x);
    2424                 :             : 
    2425                 :        2231 :         tree xtype = TREE_TYPE (x);
    2426                 :        2231 :         if (POINTER_TYPE_P (xtype))
    2427                 :        2217 :           xtype = TREE_TYPE (xtype);
    2428                 :             : 
    2429                 :        2231 :         if (off)
    2430                 :        1831 :           set_aggregate_size_and_offset (xtype, fldoff, fldsize, off);
    2431                 :             :       }
    2432                 :             : 
    2433                 :             :     default:
    2434                 :             :       break;
    2435                 :             :     }
    2436                 :             : 
    2437                 :             :   return x;
    2438                 :             : }
    2439                 :             : 
    2440                 :             : /* Nonrecursive version of the above.
    2441                 :             :    The function never returns null unless X is null to begin with.  */
    2442                 :             : 
    2443                 :             : static tree
    2444                 :       33994 : get_origin_and_offset (tree x, HOST_WIDE_INT *fldoff, HOST_WIDE_INT *off,
    2445                 :             :                        HOST_WIDE_INT *fldsize = nullptr)
    2446                 :             : {
    2447                 :       33994 :   if (!x)
    2448                 :             :     return NULL_TREE;
    2449                 :             : 
    2450                 :        6911 :   HOST_WIDE_INT sizebuf;
    2451                 :        6911 :   if (!fldsize)
    2452                 :        3878 :     fldsize = &sizebuf;
    2453                 :             : 
    2454                 :             :   /* Invalidate *FLDSIZE.  */
    2455                 :        6911 :   *fldsize = -1;
    2456                 :        6911 :   *fldoff = *off = 0;
    2457                 :             : 
    2458                 :        6911 :   return get_origin_and_offset_r (x, fldoff, fldsize, off);
    2459                 :             : }
    2460                 :             : 
    2461                 :             : /* If ARG refers to the same (sub)object or array element as described
    2462                 :             :    by DST and DST_FLD, return the byte offset into the struct member or
    2463                 :             :    array element referenced by ARG and set *ARG_SIZE to the size of
    2464                 :             :    the (sub)object.  Otherwise return HOST_WIDE_INT_MIN to indicate
    2465                 :             :    that ARG and DST do not refer to the same object.  */
    2466                 :             : 
    2467                 :             : static HOST_WIDE_INT
    2468                 :       17972 : alias_offset (tree arg, HOST_WIDE_INT *arg_size,
    2469                 :             :               tree dst, HOST_WIDE_INT dst_fld)
    2470                 :             : {
    2471                 :             :   /* See if the argument refers to the same base object as the destination
    2472                 :             :      of the formatted function call, and if so, try to determine if they
    2473                 :             :      can alias.  */
    2474                 :       17972 :   if (!arg || !dst || !ptr_derefs_may_alias_p (arg, dst))
    2475                 :       14939 :     return HOST_WIDE_INT_MIN;
    2476                 :             : 
    2477                 :             :   /* The two arguments may refer to the same object.  If they both refer
    2478                 :             :      to a struct member, see if the members are one and the same.  If so,
    2479                 :             :      return the offset into the member.  */
    2480                 :        3033 :   HOST_WIDE_INT arg_off = 0, arg_fld = 0;
    2481                 :             : 
    2482                 :        3033 :   tree arg_orig = get_origin_and_offset (arg, &arg_fld, &arg_off, arg_size);
    2483                 :             : 
    2484                 :        3033 :   if (arg_orig == dst && arg_fld == dst_fld)
    2485                 :         262 :     return arg_off;
    2486                 :             : 
    2487                 :             :   return HOST_WIDE_INT_MIN;
    2488                 :             : }
    2489                 :             : 
    2490                 :             : /* Return the minimum and maximum number of characters formatted
    2491                 :             :    by the '%s' format directive and its wide character form for
    2492                 :             :    the argument ARG.  ARG can be null (for functions such as
    2493                 :             :    vsprinf).  */
    2494                 :             : 
    2495                 :             : static fmtresult
    2496                 :      189458 : format_string (const directive &dir, tree arg, pointer_query &ptr_qry)
    2497                 :             : {
    2498                 :      189458 :   fmtresult res;
    2499                 :             : 
    2500                 :             :   /* The size of the (sub)object ARG refers to.  Used to adjust
    2501                 :             :      the conservative get_string_length() result.  */
    2502                 :      189458 :   HOST_WIDE_INT arg_size = 0;
    2503                 :             : 
    2504                 :      189458 :   if (warn_restrict)
    2505                 :             :     {
    2506                 :             :       /* See if ARG might alias the destination of the call with
    2507                 :             :          DST_ORIGIN and DST_FIELD.  If so, store the starting offset
    2508                 :             :          so that the overlap can be determined for certain later,
    2509                 :             :          when the amount of output of the call (including subsequent
    2510                 :             :          directives) has been computed.  Otherwise, store HWI_MIN.  */
    2511                 :       35944 :       res.dst_offset = alias_offset (arg, &arg_size, dir.info->dst_origin,
    2512                 :       17972 :                                      dir.info->dst_field);
    2513                 :       17972 :       if (res.dst_offset >= 0 && res.dst_offset <= arg_size)
    2514                 :         140 :         arg_size -= res.dst_offset;
    2515                 :             :       else
    2516                 :       17832 :         arg_size = 0;
    2517                 :             :     }
    2518                 :             : 
    2519                 :             :   /* Compute the range the argument's length can be in.  */
    2520                 :      189458 :   int count_by = 1;
    2521                 :      189458 :   if (dir.specifier == 'S' || dir.modifier == FMT_LEN_l)
    2522                 :             :     {
    2523                 :             :       /* Get a node for a C type that will be the same size
    2524                 :             :          as a wchar_t on the target.  */
    2525                 :         301 :       tree node = get_typenode_from_name (MODIFIED_WCHAR_TYPE);
    2526                 :             : 
    2527                 :             :       /* Now that we have a suitable node, get the number of
    2528                 :             :          bytes it occupies.  */
    2529                 :         301 :       count_by = int_size_in_bytes (node);
    2530                 :         301 :       gcc_checking_assert (count_by == 2 || count_by == 4);
    2531                 :             :     }
    2532                 :             : 
    2533                 :      189458 :   fmtresult slen =
    2534                 :      189458 :     get_string_length (arg, dir.info->callstmt, arg_size, count_by, ptr_qry);
    2535                 :      189458 :   if (slen.range.min == slen.range.max
    2536                 :      183032 :       && slen.range.min < HOST_WIDE_INT_MAX)
    2537                 :             :     {
    2538                 :             :       /* The argument is either a string constant or it refers
    2539                 :             :          to one of a number of strings of the same length.  */
    2540                 :             : 
    2541                 :             :       /* A '%s' directive with a string argument with constant length.  */
    2542                 :      170428 :       res.range = slen.range;
    2543                 :             : 
    2544                 :      170428 :       if (dir.specifier == 'S'
    2545                 :      170424 :           || dir.modifier == FMT_LEN_l)
    2546                 :             :         {
    2547                 :             :           /* In the worst case the length of output of a wide string S
    2548                 :             :              is bounded by MB_LEN_MAX * wcslen (S).  */
    2549                 :         116 :           res.range.max *= target_mb_len_max ();
    2550                 :         116 :           res.range.unlikely = res.range.max;
    2551                 :             :           /* It's likely that the total length is not more that
    2552                 :             :              2 * wcslen (S).*/
    2553                 :         116 :           res.range.likely = res.range.min * 2;
    2554                 :             : 
    2555                 :         116 :           if (dir.prec[1] >= 0
    2556                 :          57 :               && (unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
    2557                 :             :             {
    2558                 :          51 :               res.range.max = dir.prec[1];
    2559                 :          51 :               res.range.likely = dir.prec[1];
    2560                 :          51 :               res.range.unlikely = dir.prec[1];
    2561                 :             :             }
    2562                 :             : 
    2563                 :         116 :           if (dir.prec[0] < 0 && dir.prec[1] > -1)
    2564                 :             :             res.range.min = 0;
    2565                 :         112 :           else if (dir.prec[0] >= 0)
    2566                 :          53 :             res.range.likely = dir.prec[0];
    2567                 :             : 
    2568                 :             :           /* Even a non-empty wide character string need not convert into
    2569                 :             :              any bytes.  */
    2570                 :         116 :           res.range.min = 0;
    2571                 :             : 
    2572                 :             :           /* A non-empty wide character conversion may fail.  */
    2573                 :         116 :           if (slen.range.max > 0)
    2574                 :          80 :             res.mayfail = true;
    2575                 :             :         }
    2576                 :             :       else
    2577                 :             :         {
    2578                 :      170312 :           res.knownrange = true;
    2579                 :             : 
    2580                 :      170312 :           if (dir.prec[0] < 0 && dir.prec[1] > -1)
    2581                 :          16 :             res.range.min = 0;
    2582                 :      170296 :           else if ((unsigned HOST_WIDE_INT)dir.prec[0] < res.range.min)
    2583                 :          65 :             res.range.min = dir.prec[0];
    2584                 :             : 
    2585                 :      170312 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < res.range.max)
    2586                 :             :             {
    2587                 :          47 :               res.range.max = dir.prec[1];
    2588                 :          47 :               res.range.likely = dir.prec[1];
    2589                 :          47 :               res.range.unlikely = dir.prec[1];
    2590                 :             :             }
    2591                 :             :         }
    2592                 :             :     }
    2593                 :       19030 :   else if (arg && integer_zerop (arg))
    2594                 :             :     {
    2595                 :             :       /* Handle null pointer argument.  */
    2596                 :             : 
    2597                 :          33 :       fmtresult res (0);
    2598                 :          33 :       res.nullp = true;
    2599                 :          33 :       return res;
    2600                 :             :     }
    2601                 :             :   else
    2602                 :             :     {
    2603                 :             :       /* For a '%s' and '%ls' directive with a non-constant string (either
    2604                 :             :          one of a number of strings of known length or an unknown string)
    2605                 :             :          the minimum number of characters is lesser of PRECISION[0] and
    2606                 :             :          the length of the shortest known string or zero, and the maximum
    2607                 :             :          is the lesser of the length of the longest known string or
    2608                 :             :          PTRDIFF_MAX and PRECISION[1].  The likely length is either
    2609                 :             :          the minimum at level 1 and the greater of the minimum and 1
    2610                 :             :          at level 2.  This result is adjust upward for width (if it's
    2611                 :             :          specified).  */
    2612                 :             : 
    2613                 :       18997 :       if (dir.specifier == 'S'
    2614                 :       18962 :           || dir.modifier == FMT_LEN_l)
    2615                 :             :         {
    2616                 :             :           /* A wide character converts to as few as zero bytes.  */
    2617                 :         179 :           slen.range.min = 0;
    2618                 :         179 :           if (slen.range.max < target_int_max ())
    2619                 :          43 :             slen.range.max *= target_mb_len_max ();
    2620                 :             : 
    2621                 :         179 :           if (slen.range.likely < target_int_max ())
    2622                 :          50 :             slen.range.likely *= 2;
    2623                 :             : 
    2624                 :         179 :           if (slen.range.likely < target_int_max ())
    2625                 :          50 :             slen.range.unlikely *= target_mb_len_max ();
    2626                 :             : 
    2627                 :             :           /* A non-empty wide character conversion may fail.  */
    2628                 :         179 :           if (slen.range.max > 0)
    2629                 :         179 :             res.mayfail = true;
    2630                 :             :         }
    2631                 :             : 
    2632                 :       18997 :       res.range = slen.range;
    2633                 :             : 
    2634                 :       18997 :       if (dir.prec[0] >= 0)
    2635                 :             :         {
    2636                 :             :           /* Adjust the minimum to zero if the string length is unknown,
    2637                 :             :              or at most the lower bound of the precision otherwise.  */
    2638                 :         293 :           if (slen.range.min >= target_int_max ())
    2639                 :         138 :             res.range.min = 0;
    2640                 :         155 :           else if ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.min)
    2641                 :          21 :             res.range.min = dir.prec[0];
    2642                 :             : 
    2643                 :             :           /* Make both maxima no greater than the upper bound of precision.  */
    2644                 :         293 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max
    2645                 :         293 :               || slen.range.max >= target_int_max ())
    2646                 :             :             {
    2647                 :         224 :               res.range.max = dir.prec[1];
    2648                 :         224 :               res.range.unlikely = dir.prec[1];
    2649                 :             :             }
    2650                 :             : 
    2651                 :             :           /* If precision is constant, set the likely counter to the lesser
    2652                 :             :              of it and the maximum string length.  Otherwise, if the lower
    2653                 :             :              bound of precision is greater than zero, set the likely counter
    2654                 :             :              to the minimum.  Otherwise set it to zero or one based on
    2655                 :             :              the warning level.  */
    2656                 :         293 :           if (dir.prec[0] == dir.prec[1])
    2657                 :         158 :             res.range.likely
    2658                 :         158 :               = ((unsigned HOST_WIDE_INT)dir.prec[0] < slen.range.max
    2659                 :         158 :                  ? dir.prec[0] : slen.range.max);
    2660                 :         135 :           else if (dir.prec[0] > 0)
    2661                 :          38 :             res.range.likely = res.range.min;
    2662                 :             :           else
    2663                 :          97 :             res.range.likely = warn_level > 1;
    2664                 :             :         }
    2665                 :       18704 :       else if (dir.prec[1] >= 0)
    2666                 :             :         {
    2667                 :          92 :           res.range.min = 0;
    2668                 :          92 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.max)
    2669                 :          92 :             res.range.max = dir.prec[1];
    2670                 :          92 :           res.range.likely = dir.prec[1] ? warn_level > 1 : 0;
    2671                 :          92 :           if ((unsigned HOST_WIDE_INT)dir.prec[1] < slen.range.unlikely)
    2672                 :          92 :             res.range.unlikely = dir.prec[1];
    2673                 :             :         }
    2674                 :       18612 :       else if (slen.range.min >= target_int_max ())
    2675                 :             :         {
    2676                 :       12226 :           res.range.min = 0;
    2677                 :       12226 :           res.range.max = HOST_WIDE_INT_MAX;
    2678                 :             :           /* At level 1 strings of unknown length are assumed to be
    2679                 :             :              empty, while at level 1 they are assumed to be one byte
    2680                 :             :              long.  */
    2681                 :       12226 :           res.range.likely = warn_level > 1;
    2682                 :       12226 :           res.range.unlikely = HOST_WIDE_INT_MAX;
    2683                 :             :         }
    2684                 :             :       else
    2685                 :             :         {
    2686                 :             :           /* A string of unknown length unconstrained by precision is
    2687                 :             :              assumed to be empty at level 1 and just one character long
    2688                 :             :              at higher levels.  */
    2689                 :        6386 :           if (res.range.likely >= target_int_max ())
    2690                 :         116 :             res.range.likely = warn_level > 1;
    2691                 :             :         }
    2692                 :             :     }
    2693                 :             : 
    2694                 :             :   /* If the argument isn't a nul-terminated string and the number
    2695                 :             :      of bytes on output isn't bounded by precision, set NONSTR.  */
    2696                 :      189425 :   if (slen.nonstr && slen.range.min < (unsigned HOST_WIDE_INT)dir.prec[0])
    2697                 :         135 :     res.nonstr = slen.nonstr;
    2698                 :             : 
    2699                 :             :   /* Bump up the byte counters if WIDTH is greater.  */
    2700                 :      189425 :   return res.adjust_for_width_or_precision (dir.width);
    2701                 :             : }
    2702                 :             : 
    2703                 :             : /* Format plain string (part of the format string itself).  */
    2704                 :             : 
    2705                 :             : static fmtresult
    2706                 :      415781 : format_plain (const directive &dir, tree, pointer_query &)
    2707                 :             : {
    2708                 :      415781 :   fmtresult res (dir.len);
    2709                 :      415781 :   return res;
    2710                 :             : }
    2711                 :             : 
    2712                 :             : /* Return true if the RESULT of a directive in a call describe by INFO
    2713                 :             :    should be diagnosed given the AVAILable space in the destination.  */
    2714                 :             : 
    2715                 :             : static bool
    2716                 :      712250 : should_warn_p (const call_info &info,
    2717                 :             :                const result_range &avail, const result_range &result)
    2718                 :             : {
    2719                 :      712250 :   if (result.max <= avail.min)
    2720                 :             :     {
    2721                 :             :       /* The least amount of space remaining in the destination is big
    2722                 :             :          enough for the longest output.  */
    2723                 :             :       return false;
    2724                 :             :     }
    2725                 :             : 
    2726                 :       15854 :   if (info.bounded)
    2727                 :             :     {
    2728                 :        1100 :       if (warn_format_trunc == 1 && result.min <= avail.max
    2729                 :        2767 :           && info.retval_used ())
    2730                 :             :         {
    2731                 :             :           /* The likely amount of space remaining in the destination is big
    2732                 :             :              enough for the least output and the return value is used.  */
    2733                 :             :           return false;
    2734                 :             :         }
    2735                 :             : 
    2736                 :        1038 :       if (warn_format_trunc == 1 && result.likely <= avail.likely
    2737                 :        2618 :           && !info.retval_used ())
    2738                 :             :         {
    2739                 :             :           /* The likely amount of space remaining in the destination is big
    2740                 :             :              enough for the likely output and the return value is unused.  */
    2741                 :             :           return false;
    2742                 :             :         }
    2743                 :             : 
    2744                 :         660 :       if (warn_format_trunc == 2
    2745                 :          84 :           && result.likely <= avail.min
    2746                 :          69 :           && (result.max <= avail.min
    2747                 :          69 :               || result.max > HOST_WIDE_INT_MAX))
    2748                 :             :         {
    2749                 :             :           /* The minimum amount of space remaining in the destination is big
    2750                 :             :              enough for the longest output.  */
    2751                 :             :           return false;
    2752                 :             :         }
    2753                 :             :     }
    2754                 :             :   else
    2755                 :             :     {
    2756                 :       14153 :       if (warn_level == 1 && result.likely <= avail.likely)
    2757                 :             :         {
    2758                 :             :           /* The likely amount of space remaining in the destination is big
    2759                 :             :              enough for the likely output.  */
    2760                 :             :           return false;
    2761                 :             :         }
    2762                 :             : 
    2763                 :        5659 :       if (warn_level == 2
    2764                 :         301 :           && result.likely <= avail.min
    2765                 :             :           && (result.max <= avail.min
    2766                 :         183 :               || result.max > HOST_WIDE_INT_MAX))
    2767                 :             :         {
    2768                 :             :           /* The minimum amount of space remaining in the destination is big
    2769                 :             :              enough for the longest output.  */
    2770                 :             :           return false;
    2771                 :             :         }
    2772                 :             :     }
    2773                 :             : 
    2774                 :             :   return true;
    2775                 :             : }
    2776                 :             : 
    2777                 :             : /* At format string location describe by DIRLOC in a call described
    2778                 :             :    by INFO, issue a warning for a directive DIR whose output may be
    2779                 :             :    in excess of the available space AVAIL_RANGE in the destination
    2780                 :             :    given the formatting result FMTRES.  This function does nothing
    2781                 :             :    except decide whether to issue a warning for a possible write
    2782                 :             :    past the end or truncation and, if so, format the warning.
    2783                 :             :    Return true if a warning has been issued.  */
    2784                 :             : 
    2785                 :             : static bool
    2786                 :      712250 : maybe_warn (substring_loc &dirloc, location_t argloc,
    2787                 :             :             const call_info &info,
    2788                 :             :             const result_range &avail_range, const result_range &res,
    2789                 :             :             const directive &dir)
    2790                 :             : {
    2791                 :      712250 :   if (!should_warn_p (info, avail_range, res))
    2792                 :             :     return false;
    2793                 :             : 
    2794                 :             :   /* A warning will definitely be issued below.  */
    2795                 :             : 
    2796                 :             :   /* The maximum byte count to reference in the warning.  Larger counts
    2797                 :             :      imply that the upper bound is unknown (and could be anywhere between
    2798                 :             :      RES.MIN + 1 and SIZE_MAX / 2) are printed as "N or more bytes" rather
    2799                 :             :      than "between N and X" where X is some huge number.  */
    2800                 :        6120 :   unsigned HOST_WIDE_INT maxbytes = target_dir_max ();
    2801                 :             : 
    2802                 :             :   /* True when there is enough room in the destination for the least
    2803                 :             :      amount of a directive's output but not enough for its likely or
    2804                 :             :      maximum output.  */
    2805                 :       12240 :   bool maybe = (res.min <= avail_range.max
    2806                 :        6120 :                 && (avail_range.min < res.likely
    2807                 :        3529 :                     || (res.max < HOST_WIDE_INT_MAX
    2808                 :         229 :                         && avail_range.min < res.max)));
    2809                 :             : 
    2810                 :             :   /* Buffer for the directive in the host character set (used when
    2811                 :             :      the source character set is different).  */
    2812                 :        6120 :   char hostdir[32];
    2813                 :             : 
    2814                 :        6120 :   if (avail_range.min == avail_range.max)
    2815                 :             :     {
    2816                 :             :       /* The size of the destination region is exact.  */
    2817                 :        5328 :       unsigned HOST_WIDE_INT navail = avail_range.max;
    2818                 :             : 
    2819                 :        5328 :       if (target_to_host (*dir.beg) != '%')
    2820                 :             :         {
    2821                 :             :           /* For plain character directives (i.e., the format string itself)
    2822                 :             :              but not others, point the caret at the first character that's
    2823                 :             :              past the end of the destination.  */
    2824                 :         642 :           if (navail < dir.len)
    2825                 :         642 :             dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
    2826                 :             :         }
    2827                 :             : 
    2828                 :        5328 :       if (*dir.beg == '\0')
    2829                 :             :         {
    2830                 :             :           /* This is the terminating nul.  */
    2831                 :         586 :           gcc_assert (res.min == 1 && res.min == res.max);
    2832                 :             : 
    2833                 :         586 :           return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    2834                 :         586 :                           info.bounded
    2835                 :             :                           ? (maybe
    2836                 :         137 :                              ? G_("%qE output may be truncated before the "
    2837                 :             :                                   "last format character")
    2838                 :             :                              : G_("%qE output truncated before the last "
    2839                 :             :                                   "format character"))
    2840                 :             :                           : (maybe
    2841                 :         449 :                              ? G_("%qE may write a terminating nul past the "
    2842                 :             :                                   "end of the destination")
    2843                 :             :                              : G_("%qE writing a terminating nul past the "
    2844                 :             :                                   "end of the destination")),
    2845                 :        1172 :                           info.func);
    2846                 :             :         }
    2847                 :             : 
    2848                 :        4742 :       if (res.min == res.max)
    2849                 :             :         {
    2850                 :         399 :           const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
    2851                 :         399 :           if (!info.bounded)
    2852                 :         349 :             return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2853                 :             :                               "%<%.*s%> directive writing %wu byte into a "
    2854                 :             :                               "region of size %wu",
    2855                 :             :                               "%<%.*s%> directive writing %wu bytes into a "
    2856                 :             :                               "region of size %wu",
    2857                 :         349 :                               (int) dir.len, d, res.min, navail);
    2858                 :          50 :           else if (maybe)
    2859                 :           0 :             return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2860                 :             :                               "%<%.*s%> directive output may be truncated "
    2861                 :             :                               "writing %wu byte into a region of size %wu",
    2862                 :             :                               "%<%.*s%> directive output may be truncated "
    2863                 :             :                               "writing %wu bytes into a region of size %wu",
    2864                 :           0 :                               (int) dir.len, d, res.min, navail);
    2865                 :             :           else
    2866                 :          50 :             return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2867                 :             :                               "%<%.*s%> directive output truncated writing "
    2868                 :             :                               "%wu byte into a region of size %wu",
    2869                 :             :                               "%<%.*s%> directive output truncated writing "
    2870                 :             :                               "%wu bytes into a region of size %wu",
    2871                 :          50 :                               (int) dir.len, d, res.min, navail);
    2872                 :             :         }
    2873                 :        4343 :       if (res.min == 0 && res.max < maxbytes)
    2874                 :         416 :         return fmtwarn (dirloc, argloc, NULL,
    2875                 :             :                         info.warnopt (),
    2876                 :         208 :                         info.bounded
    2877                 :             :                         ? (maybe
    2878                 :           5 :                            ? G_("%<%.*s%> directive output may be truncated "
    2879                 :             :                                 "writing up to %wu bytes into a region of "
    2880                 :             :                                 "size %wu")
    2881                 :             :                            : G_("%<%.*s%> directive output truncated writing "
    2882                 :             :                                 "up to %wu bytes into a region of size %wu"))
    2883                 :             :                         : G_("%<%.*s%> directive writing up to %wu bytes "
    2884                 :         208 :                              "into a region of size %wu"), (int) dir.len,
    2885                 :             :                         target_to_host (hostdir, sizeof hostdir, dir.beg),
    2886                 :         208 :                         res.max, navail);
    2887                 :             : 
    2888                 :        4135 :       if (res.min == 0 && maxbytes <= res.max)
    2889                 :             :         /* This is a special case to avoid issuing the potentially
    2890                 :             :            confusing warning:
    2891                 :             :              writing 0 or more bytes into a region of size 0.  */
    2892                 :        3304 :         return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2893                 :        3304 :                         info.bounded
    2894                 :             :                         ? (maybe
    2895                 :         167 :                            ? G_("%<%.*s%> directive output may be truncated "
    2896                 :             :                                 "writing likely %wu or more bytes into a "
    2897                 :             :                                 "region of size %wu")
    2898                 :             :                            : G_("%<%.*s%> directive output truncated writing "
    2899                 :             :                                 "likely %wu or more bytes into a region of "
    2900                 :             :                                 "size %wu"))
    2901                 :             :                         : G_("%<%.*s%> directive writing likely %wu or more "
    2902                 :        3304 :                              "bytes into a region of size %wu"), (int) dir.len,
    2903                 :             :                         target_to_host (hostdir, sizeof hostdir, dir.beg),
    2904                 :        6608 :                         res.likely, navail);
    2905                 :             : 
    2906                 :         831 :       if (res.max < maxbytes)
    2907                 :        1646 :         return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2908                 :         823 :                         info.bounded
    2909                 :             :                         ? (maybe
    2910                 :          72 :                            ? G_("%<%.*s%> directive output may be truncated "
    2911                 :             :                                 "writing between %wu and %wu bytes into a "
    2912                 :             :                                 "region of size %wu")
    2913                 :             :                            : G_("%<%.*s%> directive output truncated "
    2914                 :             :                                 "writing between %wu and %wu bytes into a "
    2915                 :             :                                 "region of size %wu"))
    2916                 :             :                         : G_("%<%.*s%> directive writing between %wu and "
    2917                 :             :                              "%wu bytes into a region of size %wu"),
    2918                 :         823 :                         (int) dir.len,
    2919                 :             :                         target_to_host (hostdir, sizeof hostdir, dir.beg),
    2920                 :         823 :                         res.min, res.max, navail);
    2921                 :             : 
    2922                 :          16 :       return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2923                 :           8 :                       info.bounded
    2924                 :             :                       ? (maybe
    2925                 :           3 :                          ? G_("%<%.*s%> directive output may be truncated "
    2926                 :             :                               "writing %wu or more bytes into a region of "
    2927                 :             :                               "size %wu")
    2928                 :             :                          : G_("%<%.*s%> directive output truncated writing "
    2929                 :             :                               "%wu or more bytes into a region of size %wu"))
    2930                 :             :                       : G_("%<%.*s%> directive writing %wu or more bytes "
    2931                 :           8 :                            "into a region of size %wu"), (int) dir.len,
    2932                 :             :                       target_to_host (hostdir, sizeof hostdir, dir.beg),
    2933                 :           8 :                       res.min, navail);
    2934                 :             :     }
    2935                 :             : 
    2936                 :             :   /* The size of the destination region is a range.  */
    2937                 :             : 
    2938                 :         792 :   if (target_to_host (*dir.beg) != '%')
    2939                 :             :     {
    2940                 :         598 :       unsigned HOST_WIDE_INT navail = avail_range.max;
    2941                 :             : 
    2942                 :             :       /* For plain character directives (i.e., the format string itself)
    2943                 :             :          but not others, point the caret at the first character that's
    2944                 :             :          past the end of the destination.  */
    2945                 :         598 :       if (navail < dir.len)
    2946                 :           1 :         dirloc.set_caret_index (dirloc.get_caret_idx () + navail);
    2947                 :             :     }
    2948                 :             : 
    2949                 :         792 :   if (*dir.beg == '\0')
    2950                 :             :     {
    2951                 :         455 :       gcc_assert (res.min == 1 && res.min == res.max);
    2952                 :             : 
    2953                 :         455 :       return fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    2954                 :         455 :                       info.bounded
    2955                 :             :                       ? (maybe
    2956                 :          82 :                          ? G_("%qE output may be truncated before the last "
    2957                 :             :                               "format character")
    2958                 :             :                          : G_("%qE output truncated before the last format "
    2959                 :             :                               "character"))
    2960                 :             :                       : (maybe
    2961                 :         373 :                          ? G_("%qE may write a terminating nul past the end "
    2962                 :             :                               "of the destination")
    2963                 :             :                          : G_("%qE writing a terminating nul past the end "
    2964                 :         910 :                               "of the destination")), info.func);
    2965                 :             :     }
    2966                 :             : 
    2967                 :         337 :   if (res.min == res.max)
    2968                 :             :     {
    2969                 :         145 :       const char *d = target_to_host (hostdir, sizeof hostdir, dir.beg);
    2970                 :         145 :       if (!info.bounded)
    2971                 :         129 :         return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2972                 :             :                           "%<%.*s%> directive writing %wu byte into a region "
    2973                 :             :                           "of size between %wu and %wu",
    2974                 :             :                           "%<%.*s%> directive writing %wu bytes into a region "
    2975                 :         129 :                           "of size between %wu and %wu", (int) dir.len, d,
    2976                 :         129 :                           res.min, avail_range.min, avail_range.max);
    2977                 :          16 :       else if (maybe)
    2978                 :          15 :         return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2979                 :             :                           "%<%.*s%> directive output may be truncated writing "
    2980                 :             :                           "%wu byte into a region of size between %wu and %wu",
    2981                 :             :                           "%<%.*s%> directive output may be truncated writing "
    2982                 :             :                           "%wu bytes into a region of size between %wu and "
    2983                 :          15 :                           "%wu", (int) dir.len, d, res.min, avail_range.min,
    2984                 :          15 :                           avail_range.max);
    2985                 :             :       else
    2986                 :           1 :         return fmtwarn_n (dirloc, argloc, NULL, info.warnopt (), res.min,
    2987                 :             :                           "%<%.*s%> directive output truncated writing %wu "
    2988                 :             :                           "byte into a region of size between %wu and %wu",
    2989                 :             :                           "%<%.*s%> directive output truncated writing %wu "
    2990                 :             :                           "bytes into a region of size between %wu and %wu",
    2991                 :           1 :                           (int) dir.len, d, res.min, avail_range.min,
    2992                 :           1 :                           avail_range.max);
    2993                 :             :     }
    2994                 :             : 
    2995                 :         192 :   if (res.min == 0 && res.max < maxbytes)
    2996                 :           4 :     return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    2997                 :           2 :                     info.bounded
    2998                 :             :                     ? (maybe
    2999                 :           0 :                        ? G_("%<%.*s%> directive output may be truncated "
    3000                 :             :                             "writing up to %wu bytes into a region of size "
    3001                 :             :                             "between %wu and %wu")
    3002                 :             :                        : G_("%<%.*s%> directive output truncated writing "
    3003                 :             :                             "up to %wu bytes into a region of size between "
    3004                 :             :                             "%wu and %wu"))
    3005                 :             :                     : G_("%<%.*s%> directive writing up to %wu bytes "
    3006                 :             :                          "into a region of size between %wu and %wu"),
    3007                 :           2 :                     (int) dir.len,
    3008                 :             :                     target_to_host (hostdir, sizeof hostdir, dir.beg),
    3009                 :           2 :                     res.max, avail_range.min, avail_range.max);
    3010                 :             : 
    3011                 :         190 :   if (res.min == 0 && maxbytes <= res.max)
    3012                 :             :     /* This is a special case to avoid issuing the potentially confusing
    3013                 :             :        warning:
    3014                 :             :          writing 0 or more bytes into a region of size between 0 and N.  */
    3015                 :           1 :     return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3016                 :           1 :                     info.bounded
    3017                 :             :                     ? (maybe
    3018                 :           0 :                        ? G_("%<%.*s%> directive output may be truncated "
    3019                 :             :                             "writing likely %wu or more bytes into a region "
    3020                 :             :                             "of size between %wu and %wu")
    3021                 :             :                        : G_("%<%.*s%> directive output truncated writing "
    3022                 :             :                             "likely %wu or more bytes into a region of size "
    3023                 :             :                             "between %wu and %wu"))
    3024                 :             :                     : G_("%<%.*s%> directive writing likely %wu or more bytes "
    3025                 :             :                          "into a region of size between %wu and %wu"),
    3026                 :           1 :                     (int) dir.len,
    3027                 :             :                     target_to_host (hostdir, sizeof hostdir, dir.beg),
    3028                 :           2 :                     res.likely, avail_range.min, avail_range.max);
    3029                 :             : 
    3030                 :         189 :   if (res.max < maxbytes)
    3031                 :         378 :     return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3032                 :         189 :                     info.bounded
    3033                 :             :                     ? (maybe
    3034                 :          59 :                        ? G_("%<%.*s%> directive output may be truncated "
    3035                 :             :                             "writing between %wu and %wu bytes into a region "
    3036                 :             :                             "of size between %wu and %wu")
    3037                 :             :                        : G_("%<%.*s%> directive output truncated writing "
    3038                 :             :                             "between %wu and %wu bytes into a region of size "
    3039                 :             :                             "between %wu and %wu"))
    3040                 :             :                     : G_("%<%.*s%> directive writing between %wu and "
    3041                 :             :                          "%wu bytes into a region of size between %wu and "
    3042                 :         189 :                          "%wu"), (int) dir.len,
    3043                 :             :                     target_to_host (hostdir, sizeof hostdir, dir.beg),
    3044                 :         189 :                     res.min, res.max, avail_range.min, avail_range.max);
    3045                 :             : 
    3046                 :           0 :   return fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3047                 :           0 :                   info.bounded
    3048                 :             :                   ? (maybe
    3049                 :           0 :                      ? G_("%<%.*s%> directive output may be truncated writing "
    3050                 :             :                           "%wu or more bytes into a region of size between "
    3051                 :             :                           "%wu and %wu")
    3052                 :             :                      : G_("%<%.*s%> directive output truncated writing "
    3053                 :             :                           "%wu or more bytes into a region of size between "
    3054                 :             :                           "%wu and %wu"))
    3055                 :             :                   : G_("%<%.*s%> directive writing %wu or more bytes "
    3056                 :             :                        "into a region of size between %wu and %wu"),
    3057                 :           0 :                   (int) dir.len,
    3058                 :             :                   target_to_host (hostdir, sizeof hostdir, dir.beg),
    3059                 :           0 :                   res.min, avail_range.min, avail_range.max);
    3060                 :             : }
    3061                 :             : 
    3062                 :             : /* Given the formatting result described by RES and NAVAIL, the number
    3063                 :             :    of available bytes in the destination, return the range of bytes
    3064                 :             :    remaining in the destination.  */
    3065                 :             : 
    3066                 :             : static inline result_range
    3067                 :      713630 : bytes_remaining (unsigned HOST_WIDE_INT navail, const format_result &res)
    3068                 :             : {
    3069                 :      713630 :   result_range range;
    3070                 :             : 
    3071                 :      713630 :   if (HOST_WIDE_INT_MAX <= navail)
    3072                 :             :     {
    3073                 :      695590 :       range.min = range.max = range.likely = range.unlikely = navail;
    3074                 :      695590 :       return range;
    3075                 :             :     }
    3076                 :             : 
    3077                 :             :   /* The lower bound of the available range is the available size
    3078                 :             :      minus the maximum output size, and the upper bound is the size
    3079                 :             :      minus the minimum.  */
    3080                 :       18040 :   range.max = res.range.min < navail ? navail - res.range.min : 0;
    3081                 :             : 
    3082                 :       18040 :   range.likely = res.range.likely < navail ? navail - res.range.likely : 0;
    3083                 :             : 
    3084                 :       18040 :   if (res.range.max < HOST_WIDE_INT_MAX)
    3085                 :       13032 :     range.min = res.range.max < navail ? navail - res.range.max : 0;
    3086                 :             :   else
    3087                 :        5008 :     range.min = range.likely;
    3088                 :             : 
    3089                 :       36080 :   range.unlikely = (res.range.unlikely < navail
    3090                 :       18040 :                     ? navail - res.range.unlikely : 0);
    3091                 :             : 
    3092                 :       18040 :   return range;
    3093                 :             : }
    3094                 :             : 
    3095                 :             : /* Compute the length of the output resulting from the directive DIR
    3096                 :             :    in a call described by INFO and update the overall result of the call
    3097                 :             :    in *RES.  Return true if the directive has been handled.  */
    3098                 :             : 
    3099                 :             : static bool
    3100                 :      716185 : format_directive (const call_info &info,
    3101                 :             :                   format_result *res, const directive &dir,
    3102                 :             :                   pointer_query &ptr_qry)
    3103                 :             : {
    3104                 :             :   /* Offset of the beginning of the directive from the beginning
    3105                 :             :      of the format string.  */
    3106                 :      716185 :   size_t offset = dir.beg - info.fmtstr;
    3107                 :      716185 :   size_t start = offset;
    3108                 :      716185 :   size_t length = offset + dir.len - !!dir.len;
    3109                 :             : 
    3110                 :             :   /* Create a location for the whole directive from the % to the format
    3111                 :             :      specifier.  */
    3112                 :     1432370 :   substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
    3113                 :      716185 :                         offset, start, length);
    3114                 :             : 
    3115                 :             :   /* Also get the location of the argument if possible.
    3116                 :             :      This doesn't work for integer literals or function calls.  */
    3117                 :      716185 :   location_t argloc = UNKNOWN_LOCATION;
    3118                 :      716185 :   if (dir.arg)
    3119                 :      296704 :     argloc = EXPR_LOCATION (dir.arg);
    3120                 :             : 
    3121                 :             :   /* Bail when there is no function to compute the output length,
    3122                 :             :      or when minimum length checking has been disabled.   */
    3123                 :      716185 :   if (!dir.fmtfunc || res->range.min >= HOST_WIDE_INT_MAX)
    3124                 :             :     return false;
    3125                 :             : 
    3126                 :             :   /* Compute the range of lengths of the formatted output.  */
    3127                 :      713782 :   fmtresult fmtres = dir.fmtfunc (dir, dir.arg, ptr_qry);
    3128                 :             : 
    3129                 :             :   /* Record whether the output of all directives is known to be
    3130                 :             :      bounded by some maximum, implying that their arguments are
    3131                 :             :      either known exactly or determined to be in a known range
    3132                 :             :      or, for strings, limited by the upper bounds of the arrays
    3133                 :             :      they refer to.  */
    3134                 :      713782 :   res->knownrange &= fmtres.knownrange;
    3135                 :             : 
    3136                 :      713782 :   if (!fmtres.knownrange)
    3137                 :             :     {
    3138                 :             :       /* Only when the range is known, check it against the host value
    3139                 :             :          of INT_MAX + (the number of bytes of the "%.*Lf" directive with
    3140                 :             :          INT_MAX precision, which is the longest possible output of any
    3141                 :             :          single directive).  That's the largest valid byte count (though
    3142                 :             :          not valid call to a printf-like function because it can never
    3143                 :             :          return such a count).  Otherwise, the range doesn't correspond
    3144                 :             :          to known values of the argument.  */
    3145                 :       46212 :       if (fmtres.range.max > target_dir_max ())
    3146                 :             :         {
    3147                 :             :           /* Normalize the MAX counter to avoid having to deal with it
    3148                 :             :              later.  The counter can be less than HOST_WIDE_INT_M1U
    3149                 :             :              when compiling for an ILP32 target on an LP64 host.  */
    3150                 :       12629 :           fmtres.range.max = HOST_WIDE_INT_M1U;
    3151                 :             :           /* Disable exact and maximum length checking after a failure
    3152                 :             :              to determine the maximum number of characters (for example
    3153                 :             :              for wide characters or wide character strings) but continue
    3154                 :             :              tracking the minimum number of characters.  */
    3155                 :       12629 :           res->range.max = HOST_WIDE_INT_M1U;
    3156                 :             :         }
    3157                 :             : 
    3158                 :       46212 :       if (fmtres.range.min > target_dir_max ())
    3159                 :             :         {
    3160                 :             :           /* Disable exact length checking after a failure to determine
    3161                 :             :              even the minimum number of characters (it shouldn't happen
    3162                 :             :              except in an error) but keep tracking the minimum and maximum
    3163                 :             :              number of characters.  */
    3164                 :             :           return true;
    3165                 :             :         }
    3166                 :             :     }
    3167                 :             : 
    3168                 :             :   /* Buffer for the directive in the host character set (used when
    3169                 :             :      the source character set is different).  */
    3170                 :      713663 :   char hostdir[32];
    3171                 :             : 
    3172                 :      713663 :   int dirlen = dir.len;
    3173                 :             : 
    3174                 :      713663 :   if (fmtres.nullp)
    3175                 :             :     {
    3176                 :          62 :       fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3177                 :             :                "%<%.*s%> directive argument is null",
    3178                 :          33 :                dirlen, target_to_host (hostdir, sizeof hostdir, dir.beg));
    3179                 :             : 
    3180                 :             :       /* Don't bother processing the rest of the format string.  */
    3181                 :          33 :       res->warned = true;
    3182                 :          33 :       res->range.min = HOST_WIDE_INT_M1U;
    3183                 :          33 :       res->range.max = HOST_WIDE_INT_M1U;
    3184                 :          33 :       return false;
    3185                 :             :     }
    3186                 :             : 
    3187                 :             :   /* Compute the number of available bytes in the destination.  There
    3188                 :             :      must always be at least one byte of space for the terminating
    3189                 :             :      NUL that's appended after the format string has been processed.  */
    3190                 :      713630 :   result_range avail_range = bytes_remaining (info.objsize, *res);
    3191                 :             : 
    3192                 :             :   /* If the argument aliases a part of the destination of the formatted
    3193                 :             :      call at offset FMTRES.DST_OFFSET append the directive and its result
    3194                 :             :      to the set of aliases for later processing.  */
    3195                 :      713630 :   if (fmtres.dst_offset != HOST_WIDE_INT_MIN)
    3196                 :         262 :     res->append_alias (dir, fmtres.dst_offset, fmtres.range);
    3197                 :             : 
    3198                 :      713630 :   bool warned = res->warned;
    3199                 :             : 
    3200                 :      713630 :   if (!warned)
    3201                 :      712250 :     warned = maybe_warn (dirloc, argloc, info, avail_range,
    3202                 :             :                          fmtres.range, dir);
    3203                 :             : 
    3204                 :             :   /* Bump up the total maximum if it isn't too big.  */
    3205                 :      713630 :   if (res->range.max < HOST_WIDE_INT_MAX
    3206                 :      672623 :       && fmtres.range.max < HOST_WIDE_INT_MAX)
    3207                 :      672621 :     res->range.max += fmtres.range.max;
    3208                 :             : 
    3209                 :             :   /* Raise the total unlikely maximum by the larger of the maximum
    3210                 :             :      and the unlikely maximum.  */
    3211                 :      713630 :   unsigned HOST_WIDE_INT save = res->range.unlikely;
    3212                 :      713630 :   if (fmtres.range.max < fmtres.range.unlikely)
    3213                 :        7085 :     res->range.unlikely += fmtres.range.unlikely;
    3214                 :             :   else
    3215                 :      706545 :     res->range.unlikely += fmtres.range.max;
    3216                 :             : 
    3217                 :      713630 :   if (res->range.unlikely < save)
    3218                 :       38979 :     res->range.unlikely = HOST_WIDE_INT_M1U;
    3219                 :             : 
    3220                 :      713630 :   res->range.min += fmtres.range.min;
    3221                 :      713630 :   res->range.likely += fmtres.range.likely;
    3222                 :             : 
    3223                 :             :   /* Has the minimum directive output length exceeded the maximum
    3224                 :             :      of 4095 bytes required to be supported?  */
    3225                 :      713630 :   bool minunder4k = fmtres.range.min < 4096;
    3226                 :      713630 :   bool maxunder4k = fmtres.range.max < 4096;
    3227                 :             :   /* Clear POSUNDER4K in the overall result if the maximum has exceeded
    3228                 :             :      the 4k (this is necessary to avoid the return value optimization
    3229                 :             :      that may not be safe in the maximum case).  */
    3230                 :      713630 :   if (!maxunder4k)
    3231                 :       13359 :     res->posunder4k = false;
    3232                 :             :   /* Also clear POSUNDER4K if the directive may fail.  */
    3233                 :      713630 :   if (fmtres.mayfail)
    3234                 :         333 :     res->posunder4k = false;
    3235                 :             : 
    3236                 :      713630 :   if (!warned
    3237                 :             :       /* Only warn at level 2.  */
    3238                 :      710439 :       && warn_level > 1
    3239                 :             :       /* Only warn for string functions.  */
    3240                 :        1156 :       && info.is_string_func ()
    3241                 :      714016 :       && (!minunder4k
    3242                 :         384 :           || (!maxunder4k && fmtres.range.max < HOST_WIDE_INT_MAX)))
    3243                 :             :     {
    3244                 :             :       /* The directive output may be longer than the maximum required
    3245                 :             :          to be handled by an implementation according to 7.21.6.1, p15
    3246                 :             :          of C11.  Warn on this only at level 2 but remember this and
    3247                 :             :          prevent folding the return value when done.  This allows for
    3248                 :             :          the possibility of the actual libc call failing due to ENOMEM
    3249                 :             :          (like Glibc does with very large precision or width).
    3250                 :             :          Issue the "may exceed" warning only for string functions and
    3251                 :             :          not for fprintf or printf.  */
    3252                 :             : 
    3253                 :           6 :       if (fmtres.range.min == fmtres.range.max)
    3254                 :           2 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3255                 :             :                           "%<%.*s%> directive output of %wu bytes exceeds "
    3256                 :             :                           "minimum required size of 4095", dirlen,
    3257                 :           2 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3258                 :             :                           fmtres.range.min);
    3259                 :           4 :       else if (!minunder4k)
    3260                 :           0 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3261                 :             :                           "%<%.*s%> directive output between %wu and %wu "
    3262                 :             :                           "bytes exceeds minimum required size of 4095",
    3263                 :             :                           dirlen,
    3264                 :           0 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3265                 :             :                           fmtres.range.min, fmtres.range.max);
    3266                 :           4 :       else if (!info.retval_used () && info.is_string_func ())
    3267                 :           2 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3268                 :             :                           "%<%.*s%> directive output between %wu and %wu "
    3269                 :             :                           "bytes may exceed minimum required size of "
    3270                 :             :                           "4095",
    3271                 :             :                           dirlen,
    3272                 :           2 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3273                 :             :                           fmtres.range.min, fmtres.range.max);
    3274                 :             :     }
    3275                 :             : 
    3276                 :             :   /* Has the likely and maximum directive output exceeded INT_MAX?  */
    3277                 :      713630 :   bool likelyximax = *dir.beg && res->range.likely > target_int_max ();
    3278                 :             :   /* Don't consider the maximum to be in excess when it's the result
    3279                 :             :      of a string of unknown length (i.e., whose maximum has been set
    3280                 :             :      to be greater than or equal to HOST_WIDE_INT_MAX.  */
    3281                 :      713630 :   bool maxximax = (*dir.beg
    3282                 :      609209 :                    && res->range.max > target_int_max ()
    3283                 :      743503 :                    && res->range.max < HOST_WIDE_INT_MAX);
    3284                 :             : 
    3285                 :      713630 :   if (!warned
    3286                 :             :       /* Warn for the likely output size at level 1.  */
    3287                 :      710435 :       && (likelyximax
    3288                 :             :           /* But only warn for the maximum at level 2.  */
    3289                 :      710297 :           || (warn_level > 1
    3290                 :        1048 :               && maxximax
    3291                 :          84 :               && fmtres.range.max < HOST_WIDE_INT_MAX)))
    3292                 :             :     {
    3293                 :         222 :       if (fmtres.range.min > target_int_max ())
    3294                 :             :         {
    3295                 :             :           /* The directive output exceeds INT_MAX bytes.  */
    3296                 :          32 :           if (fmtres.range.min == fmtres.range.max)
    3297                 :          40 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3298                 :             :                               "%<%.*s%> directive output of %wu bytes exceeds "
    3299                 :             :                               "%<INT_MAX%>", dirlen,
    3300                 :             :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3301                 :             :                               fmtres.range.min);
    3302                 :             :           else
    3303                 :          24 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3304                 :             :                               "%<%.*s%> directive output between %wu and "
    3305                 :             :                               "%wu bytes exceeds %<INT_MAX%>", dirlen,
    3306                 :             :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3307                 :             :                               fmtres.range.min, fmtres.range.max);
    3308                 :             :         }
    3309                 :         190 :       else if (res->range.min > target_int_max ())
    3310                 :             :         {
    3311                 :             :           /* The directive output is under INT_MAX but causes the result
    3312                 :             :              to exceed INT_MAX bytes.  */
    3313                 :         104 :           if (fmtres.range.min == fmtres.range.max)
    3314                 :         182 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3315                 :             :                               "%<%.*s%> directive output of %wu bytes causes "
    3316                 :             :                               "result to exceed %<INT_MAX%>", dirlen,
    3317                 :             :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3318                 :             :                               fmtres.range.min);
    3319                 :             :           else
    3320                 :          26 :             warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3321                 :             :                               "%<%.*s%> directive output between %wu and "
    3322                 :             :                               "%wu bytes causes result to exceed %<INT_MAX%>",
    3323                 :             :                               dirlen,
    3324                 :             :                               target_to_host (hostdir, sizeof hostdir, dir.beg),
    3325                 :             :                               fmtres.range.min, fmtres.range.max);
    3326                 :             :         }
    3327                 :          86 :       else if ((!info.retval_used () || !info.bounded)
    3328                 :          86 :                && (info.is_string_func ()))
    3329                 :             :         /* Warn for calls to string functions that either aren't bounded
    3330                 :             :            (sprintf) or whose return value isn't used.  */
    3331                 :           0 :         warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3332                 :             :                           "%<%.*s%> directive output between %wu and "
    3333                 :             :                           "%wu bytes may cause result to exceed "
    3334                 :             :                           "%<INT_MAX%>", dirlen,
    3335                 :           0 :                           target_to_host (hostdir, sizeof hostdir, dir.beg),
    3336                 :             :                           fmtres.range.min, fmtres.range.max);
    3337                 :             :     }
    3338                 :             : 
    3339                 :      710435 :   if (!warned && fmtres.nonstr)
    3340                 :             :     {
    3341                 :         268 :       warned = fmtwarn (dirloc, argloc, NULL, info.warnopt (),
    3342                 :             :                         "%<%.*s%> directive argument is not a nul-terminated "
    3343                 :             :                         "string",
    3344                 :             :                         dirlen,
    3345                 :         135 :                         target_to_host (hostdir, sizeof hostdir, dir.beg));
    3346                 :         135 :       if (warned && DECL_P (fmtres.nonstr))
    3347                 :          45 :         inform (DECL_SOURCE_LOCATION (fmtres.nonstr),
    3348                 :             :                 "referenced argument declared here");
    3349                 :         135 :       return false;
    3350                 :             :     }
    3351                 :             : 
    3352                 :        3331 :   if (warned && fmtres.range.min < fmtres.range.likely
    3353                 :         570 :       && fmtres.range.likely < fmtres.range.max)
    3354                 :         333 :     inform_n (info.fmtloc, fmtres.range.likely,
    3355                 :             :               "assuming directive output of %wu byte",
    3356                 :             :               "assuming directive output of %wu bytes",
    3357                 :             :               fmtres.range.likely);
    3358                 :             : 
    3359                 :        3331 :   if (warned && fmtres.argmin)
    3360                 :             :     {
    3361                 :         382 :       if (fmtres.argmin == fmtres.argmax)
    3362                 :           2 :         inform (info.fmtloc, "directive argument %qE", fmtres.argmin);
    3363                 :         380 :       else if (fmtres.knownrange)
    3364                 :         174 :         inform (info.fmtloc, "directive argument in the range [%E, %E]",
    3365                 :             :                 fmtres.argmin, fmtres.argmax);
    3366                 :             :       else
    3367                 :         206 :         inform (info.fmtloc,
    3368                 :             :                 "using the range [%E, %E] for directive argument",
    3369                 :             :                 fmtres.argmin, fmtres.argmax);
    3370                 :             :     }
    3371                 :             : 
    3372                 :      713495 :   res->warned |= warned;
    3373                 :             : 
    3374                 :      713495 :   if (!dir.beg[0] && res->warned)
    3375                 :             :     {
    3376                 :        1949 :       location_t callloc = gimple_location (info.callstmt);
    3377                 :             : 
    3378                 :        1949 :       unsigned HOST_WIDE_INT min = res->range.min;
    3379                 :        1949 :       unsigned HOST_WIDE_INT max = res->range.max;
    3380                 :             : 
    3381                 :        1949 :       if (info.objsize < HOST_WIDE_INT_MAX)
    3382                 :             :         {
    3383                 :             :           /* If a warning has been issued for buffer overflow or truncation
    3384                 :             :              help the user figure out how big a buffer they need.  */
    3385                 :             : 
    3386                 :        1811 :           if (min == max)
    3387                 :         673 :             inform_n (callloc, min,
    3388                 :             :                       "%qE output %wu byte into a destination of size %wu",
    3389                 :             :                       "%qE output %wu bytes into a destination of size %wu",
    3390                 :         673 :                       info.func, min, info.objsize);
    3391                 :        1138 :           else if (max < HOST_WIDE_INT_MAX)
    3392                 :        1093 :             inform (callloc,
    3393                 :             :                     "%qE output between %wu and %wu bytes into "
    3394                 :             :                     "a destination of size %wu",
    3395                 :        1093 :                     info.func, min, max, info.objsize);
    3396                 :          45 :           else if (min < res->range.likely && res->range.likely < max)
    3397                 :          25 :             inform (callloc,
    3398                 :             :                     "%qE output %wu or more bytes (assuming %wu) into "
    3399                 :             :                     "a destination of size %wu",
    3400                 :          25 :                     info.func, min, res->range.likely, info.objsize);
    3401                 :             :           else
    3402                 :          20 :             inform (callloc,
    3403                 :             :                     "%qE output %wu or more bytes into a destination of size "
    3404                 :             :                     "%wu",
    3405                 :          20 :                     info.func, min, info.objsize);
    3406                 :             :         }
    3407                 :         138 :       else if (!info.is_string_func ())
    3408                 :             :         {
    3409                 :             :           /* If the warning is for a file function like fprintf
    3410                 :             :              of printf with no destination size just print the computed
    3411                 :             :              result.  */
    3412                 :         129 :           if (min == max)
    3413                 :          77 :             inform_n (callloc, min,
    3414                 :             :                       "%qE output %wu byte", "%qE output %wu bytes",
    3415                 :          77 :                       info.func, min);
    3416                 :          52 :           else if (max < HOST_WIDE_INT_MAX)
    3417                 :          12 :             inform (callloc,
    3418                 :             :                     "%qE output between %wu and %wu bytes",
    3419                 :          12 :                     info.func, min, max);
    3420                 :          40 :           else if (min < res->range.likely && res->range.likely < max)
    3421                 :           0 :             inform (callloc,
    3422                 :             :                     "%qE output %wu or more bytes (assuming %wu)",
    3423                 :           0 :                     info.func, min, res->range.likely);
    3424                 :             :           else
    3425                 :          40 :             inform (callloc,
    3426                 :             :                     "%qE output %wu or more bytes",
    3427                 :          40 :                     info.func, min);
    3428                 :             :         }
    3429                 :             :     }
    3430                 :             : 
    3431                 :      713495 :   if (dump_file && *dir.beg)
    3432                 :             :     {
    3433                 :           0 :       fprintf (dump_file,
    3434                 :             :                "    Result: "
    3435                 :             :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", "
    3436                 :             :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC " ("
    3437                 :             :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ", "
    3438                 :             :                HOST_WIDE_INT_PRINT_DEC ", " HOST_WIDE_INT_PRINT_DEC ")\n",
    3439                 :             :                fmtres.range.min, fmtres.range.likely,
    3440                 :             :                fmtres.range.max, fmtres.range.unlikely,
    3441                 :             :                res->range.min, res->range.likely,
    3442                 :             :                res->range.max, res->range.unlikely);
    3443                 :             :     }
    3444                 :             : 
    3445                 :             :   return true;
    3446                 :             : }
    3447                 :             : 
    3448                 :             : /* Parse a format directive in function call described by INFO starting
    3449                 :             :    at STR and populate DIR structure.  Bump up *ARGNO by the number of
    3450                 :             :    arguments extracted for the directive.  Return the length of
    3451                 :             :    the directive.  */
    3452                 :             : 
    3453                 :             : static size_t
    3454                 :      716185 : parse_directive (call_info &info,
    3455                 :             :                  directive &dir, format_result *res,
    3456                 :             :                  const char *str, unsigned *argno,
    3457                 :             :                  range_query *query)
    3458                 :             : {
    3459                 :      716185 :   const char *pcnt = strchr (str, target_percent);
    3460                 :      716185 :   dir.beg = str;
    3461                 :             : 
    3462                 :      716185 :   if (size_t len = pcnt ? pcnt - str : *str ? strlen (str) : 1)
    3463                 :             :     {
    3464                 :             :       /* This directive is either a plain string or the terminating nul
    3465                 :             :          (which isn't really a directive but it simplifies things to
    3466                 :             :          handle it as if it were).  */
    3467                 :      415783 :       dir.len = len;
    3468                 :      415783 :       dir.fmtfunc = format_plain;
    3469                 :             : 
    3470                 :      415783 :       if (dump_file)
    3471                 :             :         {
    3472                 :           0 :           fprintf (dump_file, "  Directive %u at offset "
    3473                 :             :                    HOST_WIDE_INT_PRINT_UNSIGNED ": \"%.*s\", "
    3474                 :             :                    "length = " HOST_WIDE_INT_PRINT_UNSIGNED "\n",
    3475                 :             :                    dir.dirno,
    3476                 :           0 :                    (unsigned HOST_WIDE_INT)(size_t)(dir.beg - info.fmtstr),
    3477                 :             :                    (int)dir.len, dir.beg, (unsigned HOST_WIDE_INT) dir.len);
    3478                 :             :         }
    3479                 :             : 
    3480                 :      415783 :       return len - !*str;
    3481                 :             :     }
    3482                 :             : 
    3483                 :             :   /* Set the directive argument's number to correspond to its position
    3484                 :             :      in the formatted function call's argument list.  */
    3485                 :      300402 :   dir.argno = *argno;
    3486                 :             : 
    3487                 :      300402 :   const char *pf = pcnt + 1;
    3488                 :             : 
    3489                 :             :     /* POSIX numbered argument index or zero when none.  */
    3490                 :      300402 :   HOST_WIDE_INT dollar = 0;
    3491                 :             : 
    3492                 :             :   /* With and precision.  -1 when not specified, HOST_WIDE_INT_MIN
    3493                 :             :      when given by a va_list argument, and a non-negative value
    3494                 :             :      when specified in the format string itself.  */
    3495                 :      300402 :   HOST_WIDE_INT width = -1;
    3496                 :      300402 :   HOST_WIDE_INT precision = -1;
    3497                 :             : 
    3498                 :             :   /* Pointers to the beginning of the width and precision decimal
    3499                 :             :      string (if any) within the directive.  */
    3500                 :      300402 :   const char *pwidth = 0;
    3501                 :      300402 :   const char *pprec = 0;
    3502                 :             : 
    3503                 :             :   /* When the value of the decimal string that specifies width or
    3504                 :             :      precision is out of range, points to the digit that causes
    3505                 :             :      the value to exceed the limit.  */
    3506                 :      300402 :   const char *werange = NULL;
    3507                 :      300402 :   const char *perange = NULL;
    3508                 :             : 
    3509                 :             :   /* Width specified via the asterisk.  Need not be INTEGER_CST.
    3510                 :             :      For vararg functions set to void_node.  */
    3511                 :      300402 :   tree star_width = NULL_TREE;
    3512                 :             : 
    3513                 :             :   /* Width specified via the asterisk.  Need not be INTEGER_CST.
    3514                 :             :      For vararg functions set to void_node.  */
    3515                 :      300402 :   tree star_precision = NULL_TREE;
    3516                 :             : 
    3517                 :      300402 :   if (ISDIGIT (target_to_host (*pf)))
    3518                 :             :     {
    3519                 :             :       /* This could be either a POSIX positional argument, the '0'
    3520                 :             :          flag, or a width, depending on what follows.  Store it as
    3521                 :             :          width and sort it out later after the next character has
    3522                 :             :          been seen.  */
    3523                 :        1179 :       pwidth = pf;
    3524                 :        1179 :       width = target_strtowi (&pf, &werange);
    3525                 :             :     }
    3526                 :      299223 :   else if (target_to_host (*pf) == '*')
    3527                 :             :     {
    3528                 :             :       /* Similarly to the block above, this could be either a POSIX
    3529                 :             :          positional argument or a width, depending on what follows.  */
    3530                 :         771 :       if (*argno < gimple_call_num_args (info.callstmt))
    3531                 :         759 :         star_width = gimple_call_arg (info.callstmt, (*argno)++);
    3532                 :             :       else
    3533                 :          12 :         star_width = void_node;
    3534                 :         771 :       ++pf;
    3535                 :             :     }
    3536                 :             : 
    3537                 :      300402 :   if (target_to_host (*pf) == '$')
    3538                 :             :     {
    3539                 :             :       /* Handle the POSIX dollar sign which references the 1-based
    3540                 :             :          positional argument number.  */
    3541                 :         110 :       if (width != -1)
    3542                 :         110 :         dollar = width + info.argidx;
    3543                 :           0 :       else if (star_width
    3544                 :           0 :                && TREE_CODE (star_width) == INTEGER_CST
    3545                 :           0 :                && (TYPE_PRECISION (TREE_TYPE (star_width))
    3546                 :           0 :                    <= TYPE_PRECISION (integer_type_node)))
    3547                 :           0 :         dollar = width + tree_to_shwi (star_width);
    3548                 :             : 
    3549                 :             :       /* Bail when the numbered argument is out of range (it will
    3550                 :             :          have already been diagnosed by -Wformat).  */
    3551                 :         110 :       if (dollar == 0
    3552                 :         106 :           || dollar == (int)info.argidx
    3553                 :         214 :           || dollar > gimple_call_num_args (info.callstmt))
    3554                 :             :         return false;
    3555                 :             : 
    3556                 :          96 :       --dollar;
    3557                 :             : 
    3558                 :          96 :       star_width = NULL_TREE;
    3559                 :          96 :       width = -1;
    3560                 :          96 :       ++pf;
    3561                 :             :     }
    3562                 :             : 
    3563                 :      300388 :   if (dollar || !star_width)
    3564                 :             :     {
    3565                 :      299617 :       if (width != -1)
    3566                 :             :         {
    3567                 :        1069 :           if (width == 0)
    3568                 :             :             {
    3569                 :             :               /* The '0' that has been interpreted as a width above is
    3570                 :             :                  actually a flag.  Reset HAVE_WIDTH, set the '0' flag,
    3571                 :             :                  and continue processing other flags.  */
    3572                 :         142 :               width = -1;
    3573                 :         142 :               dir.set_flag ('0');
    3574                 :             :             }
    3575                 :         927 :           else if (!dollar)
    3576                 :             :             {
    3577                 :             :               /* (Non-zero) width has been seen.  The next character
    3578                 :             :                  is either a period or a digit.  */
    3579                 :         927 :               goto start_precision;
    3580                 :             :             }
    3581                 :             :         }
    3582                 :             :       /* When either '$' has been seen, or width has not been seen,
    3583                 :             :          the next field is the optional flags followed by an optional
    3584                 :             :          width.  */
    3585                 :      301984 :       for ( ; ; ) {
    3586                 :      300337 :         switch (target_to_host (*pf))
    3587                 :             :           {
    3588                 :        1647 :           case ' ':
    3589                 :        1647 :           case '0':
    3590                 :        1647 :           case '+':
    3591                 :        1647 :           case '-':
    3592                 :        1647 :           case '#':
    3593                 :        1647 :             dir.set_flag (target_to_host (*pf++));
    3594                 :        1647 :             break;
    3595                 :             : 
    3596                 :      298690 :           default:
    3597                 :      298690 :             goto start_width;
    3598                 :             :           }
    3599                 :             :       }
    3600                 :             : 
    3601                 :      298690 :     start_width:
    3602                 :      298690 :       if (ISDIGIT (target_to_host (*pf)))
    3603                 :             :         {
    3604                 :         319 :           werange = 0;
    3605                 :         319 :           pwidth = pf;
    3606                 :         319 :           width = target_strtowi (&pf, &werange);
    3607                 :             :         }
    3608                 :      298371 :       else if (target_to_host (*pf) == '*')
    3609                 :             :         {
    3610                 :          56 :           if (*argno < gimple_call_num_args (info.callstmt))
    3611                 :          56 :             star_width = gimple_call_arg (info.callstmt, (*argno)++);
    3612                 :             :           else
    3613                 :             :             {
    3614                 :             :               /* This is (likely) a va_list.  It could also be an invalid
    3615                 :             :                  call with insufficient arguments.  */
    3616                 :           0 :               star_width = void_node;
    3617                 :             :             }
    3618                 :          56 :           ++pf;
    3619                 :             :         }
    3620                 :      298315 :       else if (target_to_host (*pf) == '\'')
    3621                 :             :         {
    3622                 :             :           /* The POSIX apostrophe indicating a numeric grouping
    3623                 :             :              in the current locale.  Even though it's possible to
    3624                 :             :              estimate the upper bound on the size of the output
    3625                 :             :              based on the number of digits it probably isn't worth
    3626                 :             :              continuing.  */
    3627                 :             :           return 0;
    3628                 :             :         }
    3629                 :             :     }
    3630                 :             : 
    3631                 :         771 :  start_precision:
    3632                 :      300354 :   if (target_to_host (*pf) == '.')
    3633                 :             :     {
    3634                 :        1861 :       ++pf;
    3635                 :             : 
    3636                 :        1861 :       if (ISDIGIT (target_to_host (*pf)))
    3637                 :             :         {
    3638                 :         879 :           pprec = pf;
    3639                 :         879 :           precision = target_strtowi (&pf, &perange);
    3640                 :             :         }
    3641                 :         982 :       else if (target_to_host (*pf) == '*')
    3642                 :             :         {
    3643                 :         914 :           if (*argno < gimple_call_num_args (info.callstmt))
    3644                 :         891 :             star_precision = gimple_call_arg (info.callstmt, (*argno)++);
    3645                 :             :           else
    3646                 :             :             {
    3647                 :             :               /* This is (likely) a va_list.  It could also be an invalid
    3648                 :             :                  call with insufficient arguments.  */
    3649                 :          23 :               star_precision = void_node;
    3650                 :             :             }
    3651                 :         914 :           ++pf;
    3652                 :             :         }
    3653                 :             :       else
    3654                 :             :         {
    3655                 :             :           /* The decimal precision or the asterisk are optional.
    3656                 :             :              When neither is specified it's taken to be zero.  */
    3657                 :             :           precision = 0;
    3658                 :             :         }
    3659                 :             :     }
    3660                 :             : 
    3661                 :      300354 :   switch (target_to_host (*pf))
    3662                 :             :     {
    3663                 :        1008 :     case 'h':
    3664                 :        1008 :       if (target_to_host (pf[1]) == 'h')
    3665                 :             :         {
    3666                 :         649 :           ++pf;
    3667                 :         649 :           dir.modifier = FMT_LEN_hh;
    3668                 :             :         }
    3669                 :             :       else
    3670                 :         359 :         dir.modifier = FMT_LEN_h;
    3671                 :        1008 :       ++pf;
    3672                 :        1008 :       break;
    3673                 :             : 
    3674                 :         108 :     case 'j':
    3675                 :         108 :       dir.modifier = FMT_LEN_j;
    3676                 :         108 :       ++pf;
    3677                 :         108 :       break;
    3678                 :             : 
    3679                 :         516 :     case 'L':
    3680                 :         516 :       dir.modifier = FMT_LEN_L;
    3681                 :         516 :       ++pf;
    3682                 :         516 :       break;
    3683                 :             : 
    3684                 :       14003 :     case 'l':
    3685                 :       14003 :       if (target_to_host (pf[1]) == 'l')
    3686                 :             :         {
    3687                 :         589 :           ++pf;
    3688                 :         589 :           dir.modifier = FMT_LEN_ll;
    3689                 :             :         }
    3690                 :             :       else
    3691                 :       13414 :         dir.modifier = FMT_LEN_l;
    3692                 :       14003 :       ++pf;
    3693                 :       14003 :       break;
    3694                 :             : 
    3695                 :          49 :     case 't':
    3696                 :          49 :       dir.modifier = FMT_LEN_t;
    3697                 :          49 :       ++pf;
    3698                 :          49 :       break;
    3699                 :             : 
    3700                 :        1686 :     case 'z':
    3701                 :        1686 :       dir.modifier = FMT_LEN_z;
    3702                 :        1686 :       ++pf;
    3703                 :        1686 :       break;
    3704                 :             :     }
    3705                 :             : 
    3706                 :      300354 :   switch (target_to_host (*pf))
    3707                 :             :     {
    3708                 :             :       /* Handle a sole '%' character the same as "%%" but since it's
    3709                 :             :          undefined prevent the result from being folded.  */
    3710                 :           0 :     case '\0':
    3711                 :           0 :       --pf;
    3712                 :           0 :       res->range.min = res->range.max = HOST_WIDE_INT_M1U;
    3713                 :             :       /* FALLTHRU */
    3714                 :          94 :     case '%':
    3715                 :          94 :       dir.fmtfunc = format_percent;
    3716                 :          94 :       break;
    3717                 :             : 
    3718                 :        4521 :     case 'a':
    3719                 :        4521 :     case 'A':
    3720                 :        4521 :     case 'e':
    3721                 :        4521 :     case 'E':
    3722                 :        4521 :     case 'f':
    3723                 :        4521 :     case 'F':
    3724                 :        4521 :     case 'g':
    3725                 :        4521 :     case 'G':
    3726                 :        4521 :       res->floating = true;
    3727                 :        4521 :       dir.fmtfunc = format_floating;
    3728                 :        4521 :       break;
    3729                 :             : 
    3730                 :      102702 :     case 'd':
    3731                 :      102702 :     case 'i':
    3732                 :      102702 :     case 'o':
    3733                 :      102702 :     case 'u':
    3734                 :      102702 :     case 'x':
    3735                 :      102702 :     case 'X':
    3736                 :      102702 :       dir.fmtfunc = format_integer;
    3737                 :      102702 :       break;
    3738                 :             : 
    3739                 :          80 :     case 'b':
    3740                 :          80 :     case 'B':
    3741                 :          80 :       dir.fmtfunc = format_integer;
    3742                 :          80 :       break;
    3743                 :             : 
    3744                 :             :     case 'p':
    3745                 :             :       /* The %p output is implementation-defined.  It's possible
    3746                 :             :          to determine this format but due to extensions (especially
    3747                 :             :          those of the Linux kernel -- see bug 78512) the first %p
    3748                 :             :          in the format string disables any further processing.  */
    3749                 :             :       return false;
    3750                 :             : 
    3751                 :          77 :     case 'n':
    3752                 :             :       /* %n has side-effects even when nothing is actually printed to
    3753                 :             :          any buffer.  */
    3754                 :          77 :       info.nowrite = false;
    3755                 :          77 :       dir.fmtfunc = format_none;
    3756                 :          77 :       break;
    3757                 :             : 
    3758                 :        1069 :     case 'C':
    3759                 :        1069 :     case 'c':
    3760                 :             :       /* POSIX wide character and C/POSIX narrow character.  */
    3761                 :        1069 :       dir.fmtfunc = format_character;
    3762                 :        1069 :       break;
    3763                 :             : 
    3764                 :      189458 :     case 'S':
    3765                 :      189458 :     case 's':
    3766                 :             :       /* POSIX wide string and C/POSIX narrow character string.  */
    3767                 :      189458 :       dir.fmtfunc = format_string;
    3768                 :      189458 :       break;
    3769                 :             : 
    3770                 :             :     default:
    3771                 :             :       /* Unknown conversion specification.  */
    3772                 :             :       return 0;
    3773                 :             :     }
    3774                 :             : 
    3775                 :      298001 :   dir.specifier = target_to_host (*pf++);
    3776                 :             : 
    3777                 :             :   /* Store the length of the format directive.  */
    3778                 :      298001 :   dir.len = pf - pcnt;
    3779                 :             : 
    3780                 :             :   /* Buffer for the directive in the host character set (used when
    3781                 :             :      the source character set is different).  */
    3782                 :      298001 :   char hostdir[32];
    3783                 :             : 
    3784                 :      298001 :   if (star_width)
    3785                 :             :     {
    3786                 :         805 :       if (INTEGRAL_TYPE_P (TREE_TYPE (star_width)))
    3787                 :         786 :         dir.set_width (star_width, query);
    3788                 :             :       else
    3789                 :             :         {
    3790                 :             :           /* Width specified by a va_list takes on the range [0, -INT_MIN]
    3791                 :             :              (width is the absolute value of that specified).  */
    3792                 :          19 :           dir.width[0] = 0;
    3793                 :          19 :           dir.width[1] = target_int_max () + 1;
    3794                 :             :         }
    3795                 :             :     }
    3796                 :             :   else
    3797                 :             :     {
    3798                 :      297196 :       if (width == HOST_WIDE_INT_MAX && werange)
    3799                 :             :         {
    3800                 :           1 :           size_t begin = dir.beg - info.fmtstr + (pwidth - pcnt);
    3801                 :           1 :           size_t caret = begin + (werange - pcnt);
    3802                 :           1 :           size_t end = pf - info.fmtstr - 1;
    3803                 :             : 
    3804                 :             :           /* Create a location for the width part of the directive,
    3805                 :             :              pointing the caret at the first out-of-range digit.  */
    3806                 :           1 :           substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
    3807                 :           1 :                                 caret, begin, end);
    3808                 :             : 
    3809                 :           2 :           fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    3810                 :           1 :                    "%<%.*s%> directive width out of range", (int) dir.len,
    3811                 :             :                    target_to_host (hostdir, sizeof hostdir, dir.beg));
    3812                 :             :         }
    3813                 :             : 
    3814                 :      297196 :       dir.set_width (width);
    3815                 :             :     }
    3816                 :             : 
    3817                 :      298001 :   if (star_precision)
    3818                 :             :     {
    3819                 :         903 :       if (INTEGRAL_TYPE_P (TREE_TYPE (star_precision)))
    3820                 :         875 :         dir.set_precision (star_precision, query);
    3821                 :             :       else
    3822                 :             :         {
    3823                 :             :           /* Precision specified by a va_list takes on the range [-1, INT_MAX]
    3824                 :             :              (unlike width, negative precision is ignored).  */
    3825                 :          28 :           dir.prec[0] = -1;
    3826                 :          28 :           dir.prec[1] = target_int_max ();
    3827                 :             :         }
    3828                 :             :     }
    3829                 :             :   else
    3830                 :             :     {
    3831                 :      297098 :       if (precision == HOST_WIDE_INT_MAX && perange)
    3832                 :             :         {
    3833                 :           1 :           size_t begin = dir.beg - info.fmtstr + (pprec - pcnt) - 1;
    3834                 :           1 :           size_t caret = dir.beg - info.fmtstr + (perange - pcnt) - 1;
    3835                 :           1 :           size_t end = pf - info.fmtstr - 2;
    3836                 :             : 
    3837                 :             :           /* Create a location for the precision part of the directive,
    3838                 :             :              including the leading period, pointing the caret at the first
    3839                 :             :              out-of-range digit .  */
    3840                 :           1 :           substring_loc dirloc (info.fmtloc, TREE_TYPE (info.format),
    3841                 :           1 :                                 caret, begin, end);
    3842                 :             : 
    3843                 :           2 :           fmtwarn (dirloc, UNKNOWN_LOCATION, NULL, info.warnopt (),
    3844                 :           1 :                    "%<%.*s%> directive precision out of range", (int) dir.len,
    3845                 :             :                    target_to_host (hostdir, sizeof hostdir, dir.beg));
    3846                 :             :         }
    3847                 :             : 
    3848                 :      297098 :       dir.set_precision (precision);
    3849                 :             :     }
    3850                 :             : 
    3851                 :             :   /* Extract the argument if the directive takes one and if it's
    3852                 :             :      available (e.g., the function doesn't take a va_list).  Treat
    3853                 :             :      missing arguments the same as va_list, even though they will
    3854                 :             :      have likely already been diagnosed by -Wformat.  */
    3855                 :      298001 :   if (dir.specifier != '%'
    3856                 :      298001 :       && *argno < gimple_call_num_args (info.callstmt))
    3857                 :      296704 :     dir.arg = gimple_call_arg (info.callstmt, dollar ? dollar : (*argno)++);
    3858                 :             : 
    3859                 :      298001 :   if (dump_file)
    3860                 :             :     {
    3861                 :           0 :       fprintf (dump_file,
    3862                 :             :                "  Directive %u at offset " HOST_WIDE_INT_PRINT_UNSIGNED
    3863                 :             :                ": \"%.*s\"",
    3864                 :             :                dir.dirno,
    3865                 :           0 :                (unsigned HOST_WIDE_INT)(size_t)(dir.beg - info.fmtstr),
    3866                 :           0 :                (int)dir.len, dir.beg);
    3867                 :           0 :       if (star_width)
    3868                 :             :         {
    3869                 :           0 :           if (dir.width[0] == dir.width[1])
    3870                 :           0 :             fprintf (dump_file, ", width = " HOST_WIDE_INT_PRINT_DEC,
    3871                 :             :                      dir.width[0]);
    3872                 :             :           else
    3873                 :           0 :             fprintf (dump_file,
    3874                 :             :                      ", width in range [" HOST_WIDE_INT_PRINT_DEC
    3875                 :             :                      ", " HOST_WIDE_INT_PRINT_DEC "]",
    3876                 :             :                      dir.width[0], dir.width[1]);
    3877                 :             :         }
    3878                 :             : 
    3879                 :           0 :       if (star_precision)
    3880                 :             :         {
    3881                 :           0 :           if (dir.prec[0] == dir.prec[1])
    3882                 :           0 :             fprintf (dump_file, ", precision = " HOST_WIDE_INT_PRINT_DEC,
    3883                 :             :                      dir.prec[0]);
    3884                 :             :           else
    3885                 :           0 :             fprintf (dump_file,
    3886                 :             :                      ", precision in range [" HOST_WIDE_INT_PRINT_DEC
    3887                 :             :                      HOST_WIDE_INT_PRINT_DEC "]",
    3888                 :             :                      dir.prec[0], dir.prec[1]);
    3889                 :             :         }
    3890                 :           0 :       fputc ('\n', dump_file);
    3891                 :             :     }
    3892                 :             : 
    3893                 :      298001 :   return dir.len;
    3894                 :             : }
    3895                 :             : 
    3896                 :             : /* Diagnose overlap between destination and %s directive arguments.  */
    3897                 :             : 
    3898                 :             : static void
    3899                 :      104421 : maybe_warn_overlap (call_info &info, format_result *res)
    3900                 :             : {
    3901                 :             :   /* Two vectors of 1-based indices corresponding to either certainly
    3902                 :             :      or possibly aliasing arguments.  */
    3903                 :      522105 :   auto_vec<int, 16> aliasarg[2];
    3904                 :             : 
    3905                 :             :   /* Go through the array of potentially aliasing directives and collect
    3906                 :             :      argument numbers of those that do or may overlap the destination
    3907                 :             :      object given the full result.  */
    3908                 :      104683 :   for (unsigned i = 0; i != res->alias_count; ++i)
    3909                 :             :     {
    3910                 :         262 :       const format_result::alias_info &alias = res->aliases[i];
    3911                 :             : 
    3912                 :         262 :       enum { possible = -1, none = 0, certain = 1 } overlap = none;
    3913                 :             : 
    3914                 :             :       /* If the precision is zero there is no overlap.  (This only
    3915                 :             :          considers %s directives and ignores %n.)  */
    3916                 :         262 :       if (alias.dir.prec[0] == 0 && alias.dir.prec[1] == 0)
    3917                 :           6 :         continue;
    3918                 :             : 
    3919                 :         256 :       if (alias.offset == HOST_WIDE_INT_MAX
    3920                 :         200 :           || info.dst_offset == HOST_WIDE_INT_MAX)
    3921                 :             :         overlap = possible;
    3922                 :         182 :       else if (alias.offset == info.dst_offset)
    3923                 :          79 :         overlap = alias.dir.prec[0] == 0 ? possible : certain;
    3924                 :             :       else
    3925                 :             :         {
    3926                 :             :           /* Determine overlap from the range of output and offsets
    3927                 :             :              into the same destination as the source, and rule out
    3928                 :             :              impossible overlap.  */
    3929                 :         103 :           unsigned HOST_WIDE_INT albeg = alias.offset;
    3930                 :         103 :           unsigned HOST_WIDE_INT dstbeg = info.dst_offset;
    3931                 :             : 
    3932                 :         103 :           unsigned HOST_WIDE_INT alend = albeg + alias.range.min;
    3933                 :         103 :           unsigned HOST_WIDE_INT dstend = dstbeg + res->range.min - 1;
    3934                 :             : 
    3935                 :         103 :           if ((albeg <= dstbeg && alend > dstbeg)
    3936                 :          99 :               || (albeg >= dstbeg && albeg < dstend))
    3937                 :             :             overlap = certain;
    3938                 :             :           else
    3939                 :             :             {
    3940                 :          95 :               alend = albeg + alias.range.max;
    3941                 :          95 :               if (alend < albeg)
    3942                 :          13 :                 alend = HOST_WIDE_INT_M1U;
    3943                 :             : 
    3944                 :          95 :               dstend = dstbeg + res->range.max - 1;
    3945                 :          95 :               if (dstend < dstbeg)
    3946                 :           4 :                 dstend = HOST_WIDE_INT_M1U;
    3947                 :             : 
    3948                 :          95 :               if ((albeg >= dstbeg && albeg <= dstend)
    3949                 :          56 :                   || (alend >= dstbeg && alend <= dstend))
    3950                 :             :                 overlap = possible;
    3951                 :             :             }
    3952                 :             :         }
    3953                 :             : 
    3954                 :          20 :       if (overlap == none)
    3955                 :          20 :         continue;
    3956                 :             : 
    3957                 :             :       /* Append the 1-based argument number.  */
    3958                 :         236 :       aliasarg[overlap != certain].safe_push (alias.dir.argno + 1);
    3959                 :             : 
    3960                 :             :       /* Disable any kind of optimization.  */
    3961                 :         236 :       res->range.unlikely = HOST_WIDE_INT_M1U;
    3962                 :             :     }
    3963                 :             : 
    3964                 :      104421 :   tree arg0 = gimple_call_arg (info.callstmt, 0);
    3965                 :      104421 :   location_t loc = gimple_location (info.callstmt);
    3966                 :             : 
    3967                 :      104421 :   bool aliaswarn = false;
    3968                 :             : 
    3969                 :      104421 :   unsigned ncertain = aliasarg[0].length ();
    3970                 :      104421 :   unsigned npossible = aliasarg[1].length ();
    3971                 :      104421 :   if (ncertain && npossible)
    3972                 :             :     {
    3973                 :             :       /* If there are multiple arguments that overlap, some certainly
    3974                 :             :          and some possibly, handle both sets in a single diagnostic.  */
    3975                 :           1 :       aliaswarn
    3976                 :           3 :         = warning_at (loc, OPT_Wrestrict,
    3977                 :             :                       "%qE arguments %Z and maybe %Z overlap destination "
    3978                 :             :                       "object %qE",
    3979                 :             :                       info.func, aliasarg[0].address (), ncertain,
    3980                 :             :                       aliasarg[1].address (), npossible,
    3981                 :             :                       info.dst_origin);
    3982                 :             :     }
    3983                 :      104420 :   else if (ncertain)
    3984                 :             :     {
    3985                 :             :       /* There is only one set of two or more arguments and they all
    3986                 :             :          certainly overlap the destination.  */
    3987                 :          84 :       aliaswarn
    3988                 :         168 :         = warning_n (loc, OPT_Wrestrict, ncertain,
    3989                 :             :                      "%qE argument %Z overlaps destination object %qE",
    3990                 :             :                      "%qE arguments %Z overlap destination object %qE",
    3991                 :             :                      info.func, aliasarg[0].address (), ncertain,
    3992                 :             :                      info.dst_origin);
    3993                 :             :     }
    3994                 :      104336 :   else if (npossible)
    3995                 :             :     {
    3996                 :             :       /* There is only one set of two or more arguments and they all
    3997                 :             :          may overlap (but need not).  */
    3998                 :         148 :       aliaswarn
    3999                 :         296 :         = warning_n (loc, OPT_Wrestrict, npossible,
    4000                 :             :                      "%qE argument %Z may overlap destination object %qE",
    4001                 :             :                      "%qE arguments %Z may overlap destination object %qE",
    4002                 :             :                      info.func, aliasarg[1].address (), npossible,
    4003                 :             :                      info.dst_origin);
    4004                 :             :     }
    4005                 :             : 
    4006                 :         233 :   if (aliaswarn)
    4007                 :             :     {
    4008                 :         233 :       res->warned = true;
    4009                 :             : 
    4010                 :         233 :       if (info.dst_origin != arg0)
    4011                 :             :         {
    4012                 :             :           /* If its location is different from the first argument of the call
    4013                 :             :              point either at the destination object itself or at the expression
    4014                 :             :              that was used to determine the overlap.  */
    4015                 :      313717 :           loc = (DECL_P (info.dst_origin)
    4016                 :         233 :                  ? DECL_SOURCE_LOCATION (info.dst_origin)
    4017                 :          12 :                  : EXPR_LOCATION (info.dst_origin));
    4018                 :         221 :           if (loc != UNKNOWN_LOCATION)
    4019                 :         221 :             inform (loc,
    4020                 :             :                     "destination object referenced by %<restrict%>-qualified "
    4021                 :             :                     "argument 1 was declared here");
    4022                 :             :         }
    4023                 :             :     }
    4024                 :      313263 : }
    4025                 :             : 
    4026                 :             : /* Compute the length of the output resulting from the call to a formatted
    4027                 :             :    output function described by INFO and store the result of the call in
    4028                 :             :    *RES.  Issue warnings for detected past the end writes.  Return true
    4029                 :             :    if the complete format string has been processed and *RES can be relied
    4030                 :             :    on, false otherwise (e.g., when a unknown or unhandled directive was seen
    4031                 :             :    that caused the processing to be terminated early).  */
    4032                 :             : 
    4033                 :             : static bool
    4034                 :      106992 : compute_format_length (call_info &info, format_result *res,
    4035                 :             :                        pointer_query &ptr_qry)
    4036                 :             : {
    4037                 :      106992 :   if (dump_file)
    4038                 :             :     {
    4039                 :           0 :       location_t callloc = gimple_location (info.callstmt);
    4040                 :           0 :       fprintf (dump_file, "%s:%i: ",
    4041                 :           0 :                LOCATION_FILE (callloc), LOCATION_LINE (callloc));
    4042                 :           0 :       print_generic_expr (dump_file, info.func, dump_flags);
    4043                 :             : 
    4044                 :           0 :       fprintf (dump_file,
    4045                 :             :                ": objsize = " HOST_WIDE_INT_PRINT_UNSIGNED
    4046                 :             :                ", fmtstr = \"%s\"\n",
    4047                 :             :                info.objsize, info.fmtstr);
    4048                 :             :     }
    4049                 :             : 
    4050                 :             :   /* Reset the minimum and maximum byte counters.  */
    4051                 :      106992 :   res->range.min = res->range.max = 0;
    4052                 :             : 
    4053                 :             :   /* No directive has been seen yet so the length of output is bounded
    4054                 :             :      by the known range [0, 0] (with no conversion resulting in a failure
    4055                 :             :      or producing more than 4K bytes) until determined otherwise.  */
    4056                 :      106992 :   res->knownrange = true;
    4057                 :      106992 :   res->floating = false;
    4058                 :      106992 :   res->warned = false;
    4059                 :             : 
    4060                 :             :   /* 1-based directive counter.  */
    4061                 :      106992 :   unsigned dirno = 1;
    4062                 :             : 
    4063                 :             :   /* The variadic argument counter.  */
    4064                 :      106992 :   unsigned argno = info.argidx;
    4065                 :             : 
    4066                 :      106992 :   bool success = true;
    4067                 :             : 
    4068                 :      106992 :   for (const char *pf = info.fmtstr; ; ++dirno)
    4069                 :             :     {
    4070                 :      716185 :       directive dir (&info, dirno);
    4071                 :             : 
    4072                 :      716185 :       size_t n = parse_directive (info, dir, res, pf, &argno, ptr_qry.rvals);
    4073                 :             : 
    4074                 :             :       /* Return failure if the format function fails.  */
    4075                 :      716185 :       if (!format_directive (info, res, dir, ptr_qry))
    4076                 :        2571 :         return false;
    4077                 :             : 
    4078                 :             :       /* Return success when the directive is zero bytes long and it's
    4079                 :             :          the last thing in the format string (i.e., it's the terminating
    4080                 :             :          nul, which isn't really a directive but handling it as one makes
    4081                 :             :          things simpler).  */
    4082                 :      713614 :       if (!n)
    4083                 :             :         {
    4084                 :      104421 :           success = *pf == '\0';
    4085                 :      104421 :           break;
    4086                 :             :         }
    4087                 :             : 
    4088                 :      609193 :       pf += n;
    4089                 :      609193 :     }
    4090                 :             : 
    4091                 :      104421 :   maybe_warn_overlap (info, res);
    4092                 :             : 
    4093                 :             :   /* The complete format string was processed (with or without warnings).  */
    4094                 :      104421 :   return success;
    4095                 :             : }
    4096                 :             : 
    4097                 :             : /* Return the size of the object referenced by the expression DEST in
    4098                 :             :    statement STMT, if available, or the maximum possible size otherwise.  */
    4099                 :             : 
    4100                 :             : static unsigned HOST_WIDE_INT
    4101                 :      108363 : get_destination_size (tree dest, gimple *stmt, pointer_query &ptr_qry)
    4102                 :             : {
    4103                 :             :   /* When there is no destination return the maximum.  */
    4104                 :      108363 :   if (!dest)
    4105                 :             :     return HOST_WIDE_INT_MAX;
    4106                 :             : 
    4107                 :             :   /* Use compute_objsize to determine the size of the destination object.  */
    4108                 :        8444 :   access_ref aref;
    4109                 :        8444 :   if (!ptr_qry.get_ref (dest, stmt, &aref))
    4110                 :             :     return HOST_WIDE_INT_MAX;
    4111                 :             : 
    4112                 :        8444 :   offset_int remsize = aref.size_remaining ();
    4113                 :        8444 :   if (!wi::fits_uhwi_p (remsize))
    4114                 :             :     return HOST_WIDE_INT_MAX;
    4115                 :             : 
    4116                 :        8444 :   return remsize.to_uhwi ();
    4117                 :             : }
    4118                 :             : 
    4119                 :             : /* Return true if the call described by INFO with result RES safe to
    4120                 :             :    optimize (i.e., no undefined behavior), and set RETVAL to the range
    4121                 :             :    of its return values.  */
    4122                 :             : 
    4123                 :             : static bool
    4124                 :      193629 : is_call_safe (const call_info &info,
    4125                 :             :               const format_result &res, bool under4k,
    4126                 :             :               unsigned HOST_WIDE_INT retval[2])
    4127                 :             : {
    4128                 :      193629 :   if (under4k && !res.posunder4k)
    4129                 :             :     return false;
    4130                 :             : 
    4131                 :             :   /* The minimum return value.  */
    4132                 :       99299 :   retval[0] = res.range.min;
    4133                 :             : 
    4134                 :             :   /* The maximum return value is in most cases bounded by RES.RANGE.MAX
    4135                 :             :      but in cases involving multibyte characters could be as large as
    4136                 :             :      RES.RANGE.UNLIKELY.  */
    4137                 :       99299 :   retval[1]
    4138                 :       99299 :     = res.range.unlikely < res.range.max ? res.range.max : res.range.unlikely;
    4139                 :             : 
    4140                 :             :   /* Adjust the number of bytes which includes the terminating nul
    4141                 :             :      to reflect the return value of the function which does not.
    4142                 :             :      Because the valid range of the function is [INT_MIN, INT_MAX],
    4143                 :             :      a valid range before the adjustment below is [0, INT_MAX + 1]
    4144                 :             :      (the functions only return negative values on error or undefined
    4145                 :             :      behavior).  */
    4146                 :       99299 :   if (retval[0] <= target_int_max () + 1)
    4147                 :       99169 :     --retval[0];
    4148                 :       99299 :   if (retval[1] <= target_int_max () + 1)
    4149                 :       85399 :     --retval[1];
    4150                 :             : 
    4151                 :             :   /* Avoid the return value optimization when the behavior of the call
    4152                 :             :      is undefined either because any directive may have produced 4K or
    4153                 :             :      more of output, or the return value exceeds INT_MAX, or because
    4154                 :             :      the output overflows the destination object (but leave it enabled
    4155                 :             :      when the function is bounded because then the behavior is well-
    4156                 :             :      defined).  */
    4157                 :       99299 :   if (retval[0] == retval[1]
    4158                 :       66370 :       && (info.bounded || retval[0] < info.objsize)
    4159                 :      165183 :       && retval[0] <= target_int_max ())
    4160                 :             :     return true;
    4161                 :             : 
    4162                 :       31846 :   if ((info.bounded || retval[1] < info.objsize)
    4163                 :       50516 :       && (retval[0] < target_int_max ()
    4164                 :       18571 :           && retval[1] < target_int_max ()))
    4165                 :             :     return true;
    4166                 :             : 
    4167                 :       15925 :   if (!under4k && (info.bounded || retval[0] < info.objsize))
    4168                 :             :     return true;
    4169                 :             : 
    4170                 :             :   return false;
    4171                 :             : }
    4172                 :             : 
    4173                 :             : /* Given a suitable result RES of a call to a formatted output function
    4174                 :             :    described by INFO, substitute the result for the return value of
    4175                 :             :    the call.  The result is suitable if the number of bytes it represents
    4176                 :             :    is known and exact.  A result that isn't suitable for substitution may
    4177                 :             :    have its range set to the range of return values, if that is known.
    4178                 :             :    Return true if the call is removed and gsi_next should not be performed
    4179                 :             :    in the caller.  */
    4180                 :             : 
    4181                 :             : static bool
    4182                 :       96810 : try_substitute_return_value (gimple_stmt_iterator *gsi,
    4183                 :             :                              const call_info &info,
    4184                 :             :                              const format_result &res)
    4185                 :             : {
    4186                 :       96810 :   tree lhs = gimple_get_lhs (info.callstmt);
    4187                 :             : 
    4188                 :             :   /* Set to true when the entire call has been removed.  */
    4189                 :       96810 :   bool removed = false;
    4190                 :             : 
    4191                 :             :   /* The minimum and maximum return value.  */
    4192                 :       96810 :   unsigned HOST_WIDE_INT retval[2] = {0};
    4193                 :       96810 :   bool safe = is_call_safe (info, res, true, retval);
    4194                 :             : 
    4195                 :       96810 :   if (safe
    4196                 :        2204 :       && retval[0] == retval[1]
    4197                 :             :       /* Not prepared to handle possibly throwing calls here; they shouldn't
    4198                 :             :          appear in non-artificial testcases, except when the __*_chk routines
    4199                 :             :          are badly declared.  */
    4200                 :       97874 :       && !stmt_ends_bb_p (info.callstmt))
    4201                 :             :     {
    4202                 :        1033 :       tree cst = build_int_cst (lhs ? TREE_TYPE (lhs) : integer_type_node,
    4203                 :             :                                 retval[0]);
    4204                 :             : 
    4205                 :        1033 :       if (lhs == NULL_TREE && info.nowrite)
    4206                 :             :         {
    4207                 :             :           /* Remove the call to the bounded function with a zero size
    4208                 :             :              (e.g., snprintf(0, 0, "%i", 123)) if there is no lhs.  */
    4209                 :          13 :           unlink_stmt_vdef (info.callstmt);
    4210                 :          13 :           gsi_remove (gsi, true);
    4211                 :          13 :           removed = true;
    4212                 :             :         }
    4213                 :        1020 :       else if (info.nowrite)
    4214                 :             :         {
    4215                 :             :           /* Replace the call to the bounded function with a zero size
    4216                 :             :              (e.g., snprintf(0, 0, "%i", 123) with the constant result
    4217                 :             :              of the function.  */
    4218                 :         172 :           gimplify_and_update_call_from_tree (gsi, cst);
    4219                 :         172 :           gimple *callstmt = gsi_stmt (*gsi);
    4220                 :         172 :           update_stmt (callstmt);
    4221                 :             :         }
    4222                 :         848 :       else if (lhs)
    4223                 :             :         {
    4224                 :             :           /* Replace the left-hand side of the call with the constant
    4225                 :             :              result of the formatted function.  */
    4226                 :         343 :           gimple_call_set_lhs (info.callstmt, NULL_TREE);
    4227                 :         343 :           gimple *g = gimple_build_assign (lhs, cst);
    4228                 :         343 :           gsi_insert_after (gsi, g, GSI_NEW_STMT);
    4229                 :         343 :           update_stmt (info.callstmt);
    4230                 :             :         }
    4231                 :             : 
    4232                 :        1033 :       if (dump_file)
    4233                 :             :         {
    4234                 :           0 :           if (removed)
    4235                 :           0 :             fprintf (dump_file, "  Removing call statement.");
    4236                 :             :           else
    4237                 :             :             {
    4238                 :           0 :               fprintf (dump_file, "  Substituting ");
    4239                 :           0 :               print_generic_expr (dump_file, cst, dump_flags);
    4240                 :           0 :               fprintf (dump_file, " for %s.\n",
    4241                 :           0 :                        info.nowrite ? "statement" : "return value");
    4242                 :             :             }
    4243                 :             :         }
    4244                 :             :     }
    4245                 :       95777 :   else if (lhs && types_compatible_p (TREE_TYPE (lhs), integer_type_node))
    4246                 :             :     {
    4247                 :        2425 :       bool setrange = false;
    4248                 :             : 
    4249                 :        2425 :       if (safe
    4250                 :         494 :           && (info.bounded || retval[1] < info.objsize)
    4251                 :        2919 :           && (retval[0] < target_int_max ()
    4252                 :         494 :               && retval[1] < target_int_max ()))
    4253                 :             :         {
    4254                 :             :           /* If the result is in a valid range bounded by the size of
    4255                 :             :              the destination set it so that it can be used for subsequent
    4256                 :             :              optimizations.  */
    4257                 :         494 :           int prec = TYPE_PRECISION (integer_type_node);
    4258                 :             : 
    4259                 :         494 :           wide_int min = wi::shwi (retval[0], prec);
    4260                 :         494 :           wide_int max = wi::shwi (retval[1], prec);
    4261                 :         494 :           value_range r (TREE_TYPE (lhs), min, max);
    4262                 :         494 :           set_range_info (lhs, r);
    4263                 :             : 
    4264                 :         494 :           setrange = true;
    4265                 :         494 :         }
    4266                 :             : 
    4267                 :        2425 :       if (dump_file)
    4268                 :             :         {
    4269                 :           0 :           const char *inbounds
    4270                 :           0 :             = (retval[0] < info.objsize
    4271                 :           0 :                ? (retval[1] < info.objsize
    4272                 :           0 :                   ? "in" : "potentially out-of")
    4273                 :             :                : "out-of");
    4274                 :             : 
    4275                 :           0 :           const char *what = setrange ? "Setting" : "Discarding";
    4276                 :           0 :           if (retval[0] != retval[1])
    4277                 :           0 :             fprintf (dump_file,
    4278                 :             :                      "  %s %s-bounds return value range ["
    4279                 :             :                      HOST_WIDE_INT_PRINT_UNSIGNED ", "
    4280                 :             :                      HOST_WIDE_INT_PRINT_UNSIGNED "].\n",
    4281                 :             :                      what, inbounds, retval[0], retval[1]);
    4282                 :             :           else
    4283                 :           0 :             fprintf (dump_file, "  %s %s-bounds return value "
    4284                 :             :                      HOST_WIDE_INT_PRINT_UNSIGNED ".\n",
    4285                 :             :                      what, inbounds, retval[0]);
    4286                 :             :         }
    4287                 :             :     }
    4288                 :             : 
    4289                 :       96810 :   if (dump_file)
    4290                 :           0 :     fputc ('\n', dump_file);
    4291                 :             : 
    4292                 :       96810 :   return removed;
    4293                 :             : }
    4294                 :             : 
    4295                 :             : /* Try to simplify a s{,n}printf call described by INFO with result
    4296                 :             :    RES by replacing it with a simpler and presumably more efficient
    4297                 :             :    call (such as strcpy).  */
    4298                 :             : 
    4299                 :             : static bool
    4300                 :       96819 : try_simplify_call (gimple_stmt_iterator *gsi,
    4301                 :             :                    const call_info &info,
    4302                 :             :                    const format_result &res)
    4303                 :             : {
    4304                 :       96819 :   unsigned HOST_WIDE_INT dummy[2];
    4305                 :       96819 :   if (!is_call_safe (info, res, info.retval_used (), dummy))
    4306                 :             :     return false;
    4307                 :             : 
    4308                 :       94193 :   switch (info.fncode)
    4309                 :             :     {
    4310                 :        1483 :     case BUILT_IN_SNPRINTF:
    4311                 :        1483 :       return gimple_fold_builtin_snprintf (gsi);
    4312                 :             : 
    4313                 :        2228 :     case BUILT_IN_SPRINTF:
    4314                 :        2228 :       return gimple_fold_builtin_sprintf (gsi);
    4315                 :             : 
    4316                 :             :     default:
    4317                 :             :       ;
    4318                 :             :     }
    4319                 :             : 
    4320                 :             :   return false;
    4321                 :             : }
    4322                 :             : 
    4323                 :             : /* Return the zero-based index of the format string argument of a printf
    4324                 :             :    like function and set *IDX_ARGS to the first format argument.  When
    4325                 :             :    no such index exists return UINT_MAX.  */
    4326                 :             : 
    4327                 :             : static unsigned
    4328                 :     3631910 : get_user_idx_format (tree fndecl, unsigned *idx_args)
    4329                 :             : {
    4330                 :     3631910 :   tree attrs = lookup_attribute ("format", DECL_ATTRIBUTES (fndecl));
    4331                 :     3631910 :   if (!attrs)
    4332                 :     3631910 :     attrs = lookup_attribute ("format", TYPE_ATTRIBUTES (TREE_TYPE (fndecl)));
    4333                 :             : 
    4334                 :     3631910 :   if (!attrs)
    4335                 :             :     return UINT_MAX;
    4336                 :             : 
    4337                 :       18659 :   attrs = TREE_VALUE (attrs);
    4338                 :             : 
    4339                 :       18659 :   tree archetype = TREE_VALUE (attrs);
    4340                 :       18659 :   if (strcmp ("printf", IDENTIFIER_POINTER (archetype)))
    4341                 :             :     return UINT_MAX;
    4342                 :             : 
    4343                 :       14825 :   attrs = TREE_CHAIN (attrs);
    4344                 :       14825 :   tree fmtarg = TREE_VALUE (attrs);
    4345                 :             : 
    4346                 :       14825 :   attrs = TREE_CHAIN (attrs);
    4347                 :       14825 :   tree elliparg = TREE_VALUE (attrs);
    4348                 :             : 
    4349                 :             :   /* Attribute argument indices are 1-based but we use zero-based.  */
    4350                 :       14825 :   *idx_args = tree_to_uhwi (elliparg) - 1;
    4351                 :       14825 :   return tree_to_uhwi (fmtarg) - 1;
    4352                 :             : }
    4353                 :             : 
    4354                 :             : }   /* Unnamed namespace.  */
    4355                 :             : 
    4356                 :             : /* Determine if a GIMPLE call at *GSI is to one of the sprintf-like built-in
    4357                 :             :    functions and if so, handle it.  Return true if the call is removed and
    4358                 :             :    gsi_next should not be performed in the caller.  */
    4359                 :             : 
    4360                 :             : bool
    4361                 :     4673371 : handle_printf_call (gimple_stmt_iterator *gsi, pointer_query &ptr_qry)
    4362                 :             : {
    4363                 :     4673371 :   init_target_to_host_charmap ();
    4364                 :             : 
    4365                 :     4673371 :   call_info info = call_info ();
    4366                 :             : 
    4367                 :     4673371 :   info.callstmt = gsi_stmt (*gsi);
    4368                 :     4673371 :   info.func = gimple_call_fndecl (info.callstmt);
    4369                 :     4673371 :   if (!info.func)
    4370                 :             :     return false;
    4371                 :             : 
    4372                 :             :   /* Format string argument number (valid for all functions).  */
    4373                 :     4498197 :   unsigned idx_format = UINT_MAX;
    4374                 :     4498197 :   if (gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL))
    4375                 :      866287 :     info.fncode = DECL_FUNCTION_CODE (info.func);
    4376                 :             :   else
    4377                 :             :     {
    4378                 :     3631910 :       unsigned idx_args;
    4379                 :     3631910 :       idx_format = get_user_idx_format (info.func, &idx_args);
    4380                 :     3631910 :       if (idx_format == UINT_MAX
    4381                 :       14825 :           || idx_format >= gimple_call_num_args (info.callstmt)
    4382                 :       14825 :           || idx_args > gimple_call_num_args (info.callstmt)
    4383                 :     3646707 :           || !POINTER_TYPE_P (TREE_TYPE (gimple_call_arg (info.callstmt,
    4384                 :             :                                                           idx_format))))
    4385                 :     3617113 :         return false;
    4386                 :       14797 :       info.fncode = BUILT_IN_NONE;
    4387                 :       14797 :       info.argidx = idx_args;
    4388                 :             :     }
    4389                 :             : 
    4390                 :             :   /* The size of the destination as in snprintf(dest, size, ...).  */
    4391                 :      881084 :   unsigned HOST_WIDE_INT dstsize = HOST_WIDE_INT_M1U;
    4392                 :             : 
    4393                 :             :   /* The size of the destination determined by __builtin_object_size.  */
    4394                 :      881084 :   unsigned HOST_WIDE_INT objsize = HOST_WIDE_INT_M1U;
    4395                 :             : 
    4396                 :             :   /* Zero-based buffer size argument number (snprintf and vsnprintf).  */
    4397                 :      881084 :   unsigned idx_dstsize = UINT_MAX;
    4398                 :             : 
    4399                 :             :   /* Object size argument number (snprintf_chk and vsnprintf_chk).  */
    4400                 :      881084 :   unsigned idx_objsize = UINT_MAX;
    4401                 :             : 
    4402                 :             :   /* Destinaton argument number (valid for sprintf functions only).  */
    4403                 :      881084 :   unsigned idx_dstptr = 0;
    4404                 :             : 
    4405                 :      881084 :   switch (info.fncode)
    4406                 :             :     {
    4407                 :             :     case BUILT_IN_NONE:
    4408                 :             :       // User-defined function with attribute format (printf).
    4409                 :             :       idx_dstptr = -1;
    4410                 :             :       break;
    4411                 :             : 
    4412                 :       59221 :     case BUILT_IN_FPRINTF:
    4413                 :             :       // Signature:
    4414                 :             :       //   __builtin_fprintf (FILE*, format, ...)
    4415                 :       59221 :       idx_format = 1;
    4416                 :       59221 :       info.argidx = 2;
    4417                 :       59221 :       idx_dstptr = -1;
    4418                 :       59221 :       break;
    4419                 :             : 
    4420                 :         148 :     case BUILT_IN_FPRINTF_CHK:
    4421                 :             :       // Signature:
    4422                 :             :       //   __builtin_fprintf_chk (FILE*, ost, format, ...)
    4423                 :         148 :       idx_format = 2;
    4424                 :         148 :       info.argidx = 3;
    4425                 :         148 :       idx_dstptr = -1;
    4426                 :         148 :       break;
    4427                 :             : 
    4428                 :          64 :     case BUILT_IN_FPRINTF_UNLOCKED:
    4429                 :             :       // Signature:
    4430                 :             :       //   __builtin_fprintf_unnlocked (FILE*, format, ...)
    4431                 :          64 :       idx_format = 1;
    4432                 :          64 :       info.argidx = 2;
    4433                 :          64 :       idx_dstptr = -1;
    4434                 :          64 :       break;
    4435                 :             : 
    4436                 :       24772 :     case BUILT_IN_PRINTF:
    4437                 :             :       // Signature:
    4438                 :             :       //   __builtin_printf (format, ...)
    4439                 :       24772 :       idx_format = 0;
    4440                 :       24772 :       info.argidx = 1;
    4441                 :       24772 :       idx_dstptr = -1;
    4442                 :       24772 :       break;
    4443                 :             : 
    4444                 :         151 :     case BUILT_IN_PRINTF_CHK:
    4445                 :             :       // Signature:
    4446                 :             :       //   __builtin_printf_chk (ost, format, ...)
    4447                 :         151 :       idx_format = 1;
    4448                 :         151 :       info.argidx = 2;
    4449                 :         151 :       idx_dstptr = -1;
    4450                 :         151 :       break;
    4451                 :             : 
    4452                 :          63 :     case BUILT_IN_PRINTF_UNLOCKED:
    4453                 :             :       // Signature:
    4454                 :             :       //   __builtin_printf (format, ...)
    4455                 :          63 :       idx_format = 0;
    4456                 :          63 :       info.argidx = 1;
    4457                 :          63 :       idx_dstptr = -1;
    4458                 :          63 :       break;
    4459                 :             : 
    4460                 :        4098 :     case BUILT_IN_SPRINTF:
    4461                 :             :       // Signature:
    4462                 :             :       //   __builtin_sprintf (dst, format, ...)
    4463                 :        4098 :       idx_format = 1;
    4464                 :        4098 :       info.argidx = 2;
    4465                 :        4098 :       break;
    4466                 :             : 
    4467                 :        1117 :     case BUILT_IN_SPRINTF_CHK:
    4468                 :             :       // Signature:
    4469                 :             :       //   __builtin___sprintf_chk (dst, ost, objsize, format, ...)
    4470                 :        1117 :       idx_objsize = 2;
    4471                 :        1117 :       idx_format = 3;
    4472                 :        1117 :       info.argidx = 4;
    4473                 :        1117 :       break;
    4474                 :             : 
    4475                 :        2042 :     case BUILT_IN_SNPRINTF:
    4476                 :             :       // Signature:
    4477                 :             :       //   __builtin_snprintf (dst, size, format, ...)
    4478                 :        2042 :       idx_dstsize = 1;
    4479                 :        2042 :       idx_format = 2;
    4480                 :        2042 :       info.argidx = 3;
    4481                 :        2042 :       info.bounded = true;
    4482                 :        2042 :       break;
    4483                 :             : 
    4484                 :         140 :     case BUILT_IN_SNPRINTF_CHK:
    4485                 :             :       // Signature:
    4486                 :             :       //   __builtin___snprintf_chk (dst, size, ost, objsize, format, ...)
    4487                 :         140 :       idx_dstsize = 1;
    4488                 :         140 :       idx_objsize = 3;
    4489                 :         140 :       idx_format = 4;
    4490                 :         140 :       info.argidx = 5;
    4491                 :         140 :       info.bounded = true;
    4492                 :         140 :       break;
    4493                 :             : 
    4494                 :         359 :     case BUILT_IN_VFPRINTF:
    4495                 :             :       // Signature:
    4496                 :             :       //   __builtin_vprintf (FILE*, format, va_list)
    4497                 :         359 :       idx_format = 1;
    4498                 :         359 :       info.argidx = -1;
    4499                 :         359 :       idx_dstptr = -1;
    4500                 :         359 :       break;
    4501                 :             : 
    4502                 :         139 :     case BUILT_IN_VFPRINTF_CHK:
    4503                 :             :       // Signature:
    4504                 :             :       //   __builtin___vfprintf_chk (FILE*, ost, format, va_list)
    4505                 :         139 :       idx_format = 2;
    4506                 :         139 :       info.argidx = -1;
    4507                 :         139 :       idx_dstptr = -1;
    4508                 :         139 :       break;
    4509                 :             : 
    4510                 :          58 :     case BUILT_IN_VPRINTF:
    4511                 :             :       // Signature:
    4512                 :             :       //   __builtin_vprintf (format, va_list)
    4513                 :          58 :       idx_format = 0;
    4514                 :          58 :       info.argidx = -1;
    4515                 :          58 :       idx_dstptr = -1;
    4516                 :          58 :       break;
    4517                 :             : 
    4518                 :         147 :     case BUILT_IN_VPRINTF_CHK:
    4519                 :             :       // Signature:
    4520                 :             :       //   __builtin___vprintf_chk (ost, format, va_list)
    4521                 :         147 :       idx_format = 1;
    4522                 :         147 :       info.argidx = -1;
    4523                 :         147 :       idx_dstptr = -1;
    4524                 :         147 :       break;
    4525                 :             : 
    4526                 :        1479 :     case BUILT_IN_VSNPRINTF:
    4527                 :             :       // Signature:
    4528                 :             :       //   __builtin_vsprintf (dst, size, format, va)
    4529                 :        1479 :       idx_dstsize = 1;
    4530                 :        1479 :       idx_format = 2;
    4531                 :        1479 :       info.argidx = -1;
    4532                 :        1479 :       info.bounded = true;
    4533                 :        1479 :       break;
    4534                 :             : 
    4535                 :         131 :     case BUILT_IN_VSNPRINTF_CHK:
    4536                 :             :       // Signature:
    4537                 :             :       //   __builtin___vsnprintf_chk (dst, size, ost, objsize, format, va)
    4538                 :         131 :       idx_dstsize = 1;
    4539                 :         131 :       idx_objsize = 3;
    4540                 :         131 :       idx_format = 4;
    4541                 :         131 :       info.argidx = -1;
    4542                 :         131 :       info.bounded = true;
    4543                 :         131 :       break;
    4544                 :             : 
    4545                 :        3051 :     case BUILT_IN_VSPRINTF:
    4546                 :             :       // Signature:
    4547                 :             :       //   __builtin_vsprintf (dst, format, va)
    4548                 :        3051 :       idx_format = 1;
    4549                 :        3051 :       info.argidx = -1;
    4550                 :        3051 :       break;
    4551                 :             : 
    4552                 :         178 :     case BUILT_IN_VSPRINTF_CHK:
    4553                 :             :       // Signature:
    4554                 :             :       //   __builtin___vsprintf_chk (dst, ost, objsize, format, va)
    4555                 :         178 :       idx_format = 3;
    4556                 :         178 :       idx_objsize = 2;
    4557                 :         178 :       info.argidx = -1;
    4558                 :         178 :       break;
    4559                 :             : 
    4560                 :             :     default:
    4561                 :             :       return false;
    4562                 :             :     }
    4563                 :             : 
    4564                 :             :   /* Set the global warning level for this function.  */
    4565                 :      112155 :   warn_level = info.bounded ? warn_format_trunc : warn_format_overflow;
    4566                 :             : 
    4567                 :             :   /* For all string functions the first argument is a pointer to
    4568                 :             :      the destination.  */
    4569                 :      112155 :   tree dstptr = (idx_dstptr < gimple_call_num_args (info.callstmt)
    4570                 :      112155 :                  ? gimple_call_arg (info.callstmt, 0) : NULL_TREE);
    4571                 :             : 
    4572                 :      112155 :   info.format = gimple_call_arg (info.callstmt, idx_format);
    4573                 :             : 
    4574                 :             :   /* True when the destination size is constant as opposed to the lower
    4575                 :             :      or upper bound of a range.  */
    4576                 :      112155 :   bool dstsize_cst_p = true;
    4577                 :      112155 :   bool posunder4k = true;
    4578                 :             : 
    4579                 :      112155 :   if (idx_dstsize == UINT_MAX)
    4580                 :             :     {
    4581                 :             :       /* For non-bounded functions like sprintf, determine the size
    4582                 :             :          of the destination from the object or pointer passed to it
    4583                 :             :          as the first argument.  */
    4584                 :      108363 :       dstsize = get_destination_size (dstptr, info.callstmt, ptr_qry);
    4585                 :             :     }
    4586                 :        3792 :   else if (tree size = gimple_call_arg (info.callstmt, idx_dstsize))
    4587                 :             :     {
    4588                 :             :       /* For bounded functions try to get the size argument.  */
    4589                 :             : 
    4590                 :        3792 :       if (TREE_CODE (size) == INTEGER_CST)
    4591                 :             :         {
    4592                 :        3212 :           dstsize = tree_to_uhwi (size);
    4593                 :             :           /* No object can be larger than SIZE_MAX bytes (half the address
    4594                 :             :              space) on the target.
    4595                 :             :              The functions are defined only for output of at most INT_MAX
    4596                 :             :              bytes.  Specifying a bound in excess of that limit effectively
    4597                 :             :              defeats the bounds checking (and on some implementations such
    4598                 :             :              as Solaris cause the function to fail with EINVAL).  */
    4599                 :        3212 :           if (dstsize > target_size_max () / 2)
    4600                 :             :             {
    4601                 :             :               /* Avoid warning if -Wstringop-overflow is specified since
    4602                 :             :                  it also warns for the same thing though only for the
    4603                 :             :                  checking built-ins.  */
    4604                 :          10 :               if ((idx_objsize == UINT_MAX
    4605                 :           1 :                    || !warn_stringop_overflow))
    4606                 :           9 :                 warning_at (gimple_location (info.callstmt), info.warnopt (),
    4607                 :             :                             "specified bound %wu exceeds maximum object size "
    4608                 :             :                             "%wu",
    4609                 :             :                             dstsize, target_size_max () / 2);
    4610                 :             :               /* POSIX requires snprintf to fail if DSTSIZE is greater
    4611                 :             :                  than INT_MAX.  Even though not all POSIX implementations
    4612                 :             :                  conform to the requirement, avoid folding in this case.  */
    4613                 :             :               posunder4k = false;
    4614                 :             :             }
    4615                 :        3202 :           else if (dstsize > target_int_max ())
    4616                 :             :             {
    4617                 :          16 :               warning_at (gimple_location (info.callstmt), info.warnopt (),
    4618                 :             :                           "specified bound %wu exceeds %<INT_MAX%>",
    4619                 :             :                           dstsize);
    4620                 :             :               /* POSIX requires snprintf to fail if DSTSIZE is greater
    4621                 :             :                  than INT_MAX.  Avoid folding in that case.  */
    4622                 :          16 :               posunder4k = false;
    4623                 :             :             }
    4624                 :             :         }
    4625                 :         580 :       else if (TREE_CODE (size) == SSA_NAME)
    4626                 :             :         {
    4627                 :             :           /* Try to determine the range of values of the argument
    4628                 :             :              and use the greater of the two at level 1 and the smaller
    4629                 :             :              of them at level 2.  */
    4630                 :         580 :           value_range vr;
    4631                 :         580 :           ptr_qry.rvals->range_of_expr (vr, size, info.callstmt);
    4632                 :             : 
    4633                 :         580 :           if (!vr.undefined_p ())
    4634                 :             :             {
    4635                 :         580 :               tree type = TREE_TYPE (size);
    4636                 :         580 :               tree tmin = wide_int_to_tree (type, vr.lower_bound ());
    4637                 :         580 :               tree tmax = wide_int_to_tree (type, vr.upper_bound ());
    4638                 :         580 :               unsigned HOST_WIDE_INT minsize = TREE_INT_CST_LOW (tmin);
    4639                 :         580 :               unsigned HOST_WIDE_INT maxsize = TREE_INT_CST_LOW (tmax);
    4640                 :         580 :               dstsize = warn_level < 2 ? maxsize : minsize;
    4641                 :             : 
    4642                 :         580 :               if (minsize > target_int_max ())
    4643                 :           8 :                 warning_at (gimple_location (info.callstmt), info.warnopt (),
    4644                 :             :                             "specified bound range [%wu, %wu] exceeds "
    4645                 :             :                             "%<INT_MAX%>",
    4646                 :             :                             minsize, maxsize);
    4647                 :             : 
    4648                 :             :               /* POSIX requires snprintf to fail if DSTSIZE is greater
    4649                 :             :                  than INT_MAX.  Avoid folding if that's possible.  */
    4650                 :         580 :               if (maxsize > target_int_max ())
    4651                 :         539 :                 posunder4k = false;
    4652                 :             :             }
    4653                 :             : 
    4654                 :             :           /* The destination size is not constant.  If the function is
    4655                 :             :              bounded (e.g., snprintf) a lower bound of zero doesn't
    4656                 :             :              necessarily imply it can be eliminated.  */
    4657                 :         580 :           dstsize_cst_p = false;
    4658                 :         580 :         }
    4659                 :             :     }
    4660                 :             : 
    4661                 :      112155 :   if (idx_objsize != UINT_MAX)
    4662                 :        1566 :     if (tree size = gimple_call_arg (info.callstmt, idx_objsize))
    4663                 :        1566 :       if (tree_fits_uhwi_p (size))
    4664                 :        1553 :         objsize = tree_to_uhwi (size);
    4665                 :             : 
    4666                 :      112155 :   if (info.bounded && !dstsize)
    4667                 :             :     {
    4668                 :             :       /* As a special case, when the explicitly specified destination
    4669                 :             :          size argument (to a bounded function like snprintf) is zero
    4670                 :             :          it is a request to determine the number of bytes on output
    4671                 :             :          without actually producing any.  Pretend the size is
    4672                 :             :          unlimited in this case.  */
    4673                 :         463 :       info.objsize = HOST_WIDE_INT_MAX;
    4674                 :         463 :       info.nowrite = dstsize_cst_p;
    4675                 :             :     }
    4676                 :             :   else
    4677                 :             :     {
    4678                 :             :       /* For calls to non-bounded functions or to those of bounded
    4679                 :             :          functions with a non-zero size, warn if the destination
    4680                 :             :          pointer is null.  */
    4681                 :      111692 :       if (dstptr && integer_zerop (dstptr))
    4682                 :             :         {
    4683                 :             :           /* This is diagnosed with -Wformat only when the null is a constant
    4684                 :             :              pointer.  The warning here diagnoses instances where the pointer
    4685                 :             :              is not constant.  */
    4686                 :          19 :           location_t loc = gimple_location (info.callstmt);
    4687                 :          38 :           warning_at (EXPR_LOC_OR_LOC (dstptr, loc),
    4688                 :          19 :                       info.warnopt (), "null destination pointer");
    4689                 :          19 :           return false;
    4690                 :             :         }
    4691                 :             : 
    4692                 :             :       /* Set the object size to the smaller of the two arguments
    4693                 :             :          of both have been specified and they're not equal.  */
    4694                 :      111673 :       info.objsize = dstsize < objsize ? dstsize : objsize;
    4695                 :             : 
    4696                 :      111673 :       if (info.bounded
    4697                 :        3320 :           && dstsize < target_size_max () / 2 && objsize < dstsize
    4698                 :             :           /* Avoid warning if -Wstringop-overflow is specified since
    4699                 :             :              it also warns for the same thing though only for the
    4700                 :             :              checking built-ins.  */
    4701                 :      111744 :           && (idx_objsize == UINT_MAX
    4702                 :          71 :               || !warn_stringop_overflow))
    4703                 :             :         {
    4704                 :           4 :           warning_at (gimple_location (info.callstmt), info.warnopt (),
    4705                 :             :                       "specified bound %wu exceeds the size %wu "
    4706                 :             :                       "of the destination object", dstsize, objsize);
    4707                 :             :         }
    4708                 :             :     }
    4709                 :             : 
    4710                 :             :   /* Determine if the format argument may be null and warn if not
    4711                 :             :      and if the argument is null.  */
    4712                 :      112136 :   if (integer_zerop (info.format)
    4713                 :      112136 :       && gimple_call_builtin_p (info.callstmt, BUILT_IN_NORMAL))
    4714                 :             :     {
    4715                 :          57 :       location_t loc = gimple_location (info.callstmt);
    4716                 :         114 :       warning_at (EXPR_LOC_OR_LOC (info.format, loc),
    4717                 :          57 :                   info.warnopt (), "null format string");
    4718                 :          57 :       return false;
    4719                 :             :     }
    4720                 :             : 
    4721                 :      112079 :   info.fmtstr = get_format_string (info.format, &info.fmtloc);
    4722                 :      112079 :   if (!info.fmtstr)
    4723                 :             :     return false;
    4724                 :             : 
    4725                 :      106992 :   if (warn_restrict)
    4726                 :             :     {
    4727                 :             :       /* Compute the origin of the destination pointer and its offset
    4728                 :             :          from the base object/pointer if possible.  */
    4729                 :       30961 :       info.dst_offset = 0;
    4730                 :       30961 :       info.dst_origin = get_origin_and_offset (dstptr, &info.dst_field,
    4731                 :             :                                                &info.dst_offset);
    4732                 :             :     }
    4733                 :             : 
    4734                 :             :   /* The result is the number of bytes output by the formatted function,
    4735                 :             :      including the terminating NUL.  */
    4736                 :      213984 :   format_result res;
    4737                 :             : 
    4738                 :             :   /* I/O functions with no destination argument (i.e., all forms of fprintf
    4739                 :             :      and printf) may fail under any conditions.  Others (i.e., all forms of
    4740                 :             :      sprintf) may only fail under specific conditions determined for each
    4741                 :             :      directive.  Clear POSUNDER4K for the former set of functions and set
    4742                 :             :      it to true for the latter (it can only be cleared later, but it is
    4743                 :             :      never set to true again).  */
    4744                 :      106992 :   res.posunder4k = posunder4k && dstptr;
    4745                 :             : 
    4746                 :      106992 :   bool success = compute_format_length (info, &res, ptr_qry);
    4747                 :      106992 :   if (res.warned)
    4748                 :        4349 :     suppress_warning (info.callstmt, info.warnopt ());
    4749                 :             : 
    4750                 :             :   /* When optimizing and the printf return value optimization is enabled,
    4751                 :             :      attempt to substitute the computed result for the return value of
    4752                 :             :      the call.  Avoid this optimization when -frounding-math is in effect
    4753                 :             :      and the format string contains a floating point directive.  */
    4754                 :      106992 :   bool call_removed = false;
    4755                 :      106992 :   if (success && optimize > 0)
    4756                 :             :     {
    4757                 :             :       /* Save a copy of the iterator pointing at the call.  The iterator
    4758                 :             :          may change to point past the call in try_substitute_return_value
    4759                 :             :          but the original value is needed in try_simplify_call.  */
    4760                 :       96832 :       gimple_stmt_iterator gsi_call = *gsi;
    4761                 :             : 
    4762                 :       96832 :       if (flag_printf_return_value
    4763                 :       96810 :           && (!flag_rounding_math || !res.floating))
    4764                 :       96810 :         call_removed = try_substitute_return_value (gsi, info, res);
    4765                 :             : 
    4766                 :       96810 :       if (!call_removed)
    4767                 :       96819 :         try_simplify_call (&gsi_call, info, res);
    4768                 :             :     }
    4769                 :             : 
    4770                 :      106992 :   return call_removed;
    4771                 :             : }
        

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.