LCOV - code coverage report
Current view: top level - gcc - pointer-query.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 89.2 % 1171 1044
Test Date: 2024-04-13 14:00:49 Functions: 95.3 % 43 41
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Definitions of the pointer_query and related classes.
       2                 :             : 
       3                 :             :    Copyright (C) 2020-2024 Free Software Foundation, Inc.
       4                 :             : 
       5                 :             :    This file is part of GCC.
       6                 :             : 
       7                 :             :    GCC is free software; you can redistribute it and/or modify it under
       8                 :             :    the terms of the GNU General Public License as published by the Free
       9                 :             :    Software Foundation; either version 3, or (at your option) any later
      10                 :             :    version.
      11                 :             : 
      12                 :             :    GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             :    WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :             :    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :             :    for more details.
      16                 :             : 
      17                 :             :    You should have received a copy of the GNU General Public License
      18                 :             :    along with GCC; see the file COPYING3.  If not see
      19                 :             :    <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "coretypes.h"
      24                 :             : #include "backend.h"
      25                 :             : #include "tree.h"
      26                 :             : #include "gimple.h"
      27                 :             : #include "stringpool.h"
      28                 :             : #include "tree-vrp.h"
      29                 :             : #include "diagnostic-core.h"
      30                 :             : #include "fold-const.h"
      31                 :             : #include "tree-object-size.h"
      32                 :             : #include "tree-ssa-strlen.h"
      33                 :             : #include "langhooks.h"
      34                 :             : #include "stringpool.h"
      35                 :             : #include "attribs.h"
      36                 :             : #include "gimple-iterator.h"
      37                 :             : #include "gimple-fold.h"
      38                 :             : #include "gimple-ssa.h"
      39                 :             : #include "intl.h"
      40                 :             : #include "attr-fnspec.h"
      41                 :             : #include "gimple-range.h"
      42                 :             : #include "pointer-query.h"
      43                 :             : #include "tree-pretty-print.h"
      44                 :             : #include "tree-ssanames.h"
      45                 :             : #include "target.h"
      46                 :             : 
      47                 :             : static bool compute_objsize_r (tree, gimple *, bool, int, access_ref *,
      48                 :             :                                ssa_name_limit_t &, pointer_query *);
      49                 :             : 
      50                 :             : /* Wrapper around the wide_int overload of get_range that accepts
      51                 :             :    offset_int instead.  For middle end expressions returns the same
      52                 :             :    result.  For a subset of nonconstamt expressions emitted by the front
      53                 :             :    end determines a more precise range than would be possible otherwise.  */
      54                 :             : 
      55                 :             : static bool
      56                 :     3975044 : get_offset_range (tree x, gimple *stmt, offset_int r[2], range_query *rvals)
      57                 :             : {
      58                 :     3975044 :   offset_int add = 0;
      59                 :     3975044 :   if (TREE_CODE (x) == PLUS_EXPR)
      60                 :             :     {
      61                 :             :       /* Handle constant offsets in pointer addition expressions seen
      62                 :             :          n the front end IL.  */
      63                 :          52 :       tree op = TREE_OPERAND (x, 1);
      64                 :          52 :       if (TREE_CODE (op) == INTEGER_CST)
      65                 :             :         {
      66                 :          52 :           op = fold_convert (signed_type_for (TREE_TYPE (op)), op);
      67                 :          52 :           add = wi::to_offset (op);
      68                 :          52 :           x = TREE_OPERAND (x, 0);
      69                 :             :         }
      70                 :             :     }
      71                 :             : 
      72                 :     3975044 :   if (TREE_CODE (x) == NOP_EXPR)
      73                 :             :     /* Also handle conversions to sizetype seen in the front end IL.  */
      74                 :         156 :     x = TREE_OPERAND (x, 0);
      75                 :             : 
      76                 :     3975044 :   tree type = TREE_TYPE (x);
      77                 :     3975044 :   if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
      78                 :             :     return false;
      79                 :             : 
      80                 :     3975032 :    if (TREE_CODE (x) != INTEGER_CST
      81                 :      600982 :       && TREE_CODE (x) != SSA_NAME)
      82                 :             :     {
      83                 :         240 :       if (TYPE_UNSIGNED (type)
      84                 :         240 :           && TYPE_PRECISION (type) == TYPE_PRECISION (sizetype))
      85                 :          64 :         type = signed_type_for (type);
      86                 :             : 
      87                 :         240 :       r[0] = wi::to_offset (TYPE_MIN_VALUE (type)) + add;
      88                 :         240 :       r[1] = wi::to_offset (TYPE_MAX_VALUE (type)) + add;
      89                 :         240 :       return x;
      90                 :             :     }
      91                 :             : 
      92                 :    19873960 :   wide_int wr[2];
      93                 :     3974792 :   if (!get_range (x, stmt, wr, rvals))
      94                 :             :     return false;
      95                 :             : 
      96                 :     3695949 :   signop sgn = SIGNED;
      97                 :             :   /* Only convert signed integers or unsigned sizetype to a signed
      98                 :             :      offset and avoid converting large positive values in narrower
      99                 :             :      types to negative offsets.  */
     100                 :     3695949 :   if (TYPE_UNSIGNED (type)
     101                 :     3695949 :       && wr[0].get_precision () < TYPE_PRECISION (sizetype))
     102                 :             :     sgn = UNSIGNED;
     103                 :             : 
     104                 :     3695949 :   r[0] = offset_int::from (wr[0], sgn);
     105                 :     3695949 :   r[1] = offset_int::from (wr[1], sgn);
     106                 :     3695949 :   return true;
     107                 :    11924376 : }
     108                 :             : 
     109                 :             : /* Return the argument that the call STMT to a built-in function returns
     110                 :             :    or null if it doesn't.  On success, set OFFRNG[] to the range of offsets
     111                 :             :    from the argument reflected in the value returned by the built-in if it
     112                 :             :    can be determined, otherwise to 0 and HWI_M1U respectively.  Set
     113                 :             :    *PAST_END for functions like mempcpy that might return a past the end
     114                 :             :    pointer (most functions return a dereferenceable pointer to an existing
     115                 :             :    element of an array).  */
     116                 :             : 
     117                 :             : static tree
     118                 :      300728 : gimple_call_return_array (gimple *stmt, offset_int offrng[2], bool *past_end,
     119                 :             :                           ssa_name_limit_t &snlim, pointer_query *qry)
     120                 :             : {
     121                 :             :   /* Clear and set below for the rare function(s) that might return
     122                 :             :      a past-the-end pointer.  */
     123                 :      300728 :   *past_end = false;
     124                 :             : 
     125                 :      300728 :   {
     126                 :             :     /* Check for attribute fn spec to see if the function returns one
     127                 :             :        of its arguments.  */
     128                 :      300728 :     attr_fnspec fnspec = gimple_call_fnspec (as_a <gcall *>(stmt));
     129                 :      300728 :     unsigned int argno;
     130                 :      300728 :     if (fnspec.returns_arg (&argno))
     131                 :             :       {
     132                 :             :         /* Functions return the first argument (not a range).  */
     133                 :        3825 :         offrng[0] = offrng[1] = 0;
     134                 :        3825 :         return gimple_call_arg (stmt, argno);
     135                 :             :       }
     136                 :             :   }
     137                 :             : 
     138                 :      296903 :   if (gimple_call_num_args (stmt) < 1)
     139                 :             :     return NULL_TREE;
     140                 :             : 
     141                 :      284871 :   tree fn = gimple_call_fndecl (stmt);
     142                 :      284871 :   if (!gimple_call_builtin_p (stmt, BUILT_IN_NORMAL))
     143                 :             :     {
     144                 :             :       /* See if this is a call to placement new.  */
     145                 :      234006 :       if (!fn
     146                 :      219439 :           || !DECL_IS_OPERATOR_NEW_P (fn)
     147                 :      242154 :           || DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fn))
     148                 :             :         return NULL_TREE;
     149                 :             : 
     150                 :             :       /* Check the mangling, keeping in mind that operator new takes
     151                 :             :          a size_t which could be unsigned int or unsigned long.  */
     152                 :        8142 :       tree fname = DECL_ASSEMBLER_NAME (fn);
     153                 :        8142 :       if (!id_equal (fname, "_ZnwjPv")       // ordinary form
     154                 :        8100 :           && !id_equal (fname, "_ZnwmPv")    // ordinary form
     155                 :         672 :           && !id_equal (fname, "_ZnajPv")    // array form
     156                 :        8810 :           && !id_equal (fname, "_ZnamPv"))   // array form
     157                 :             :         return NULL_TREE;
     158                 :             : 
     159                 :        7586 :       if (gimple_call_num_args (stmt) != 2)
     160                 :             :         return NULL_TREE;
     161                 :             : 
     162                 :             :       /* Allocation functions return a pointer to the beginning.  */
     163                 :        7586 :       offrng[0] = offrng[1] = 0;
     164                 :        7586 :       return gimple_call_arg (stmt, 1);
     165                 :             :     }
     166                 :             : 
     167                 :       50865 :   switch (DECL_FUNCTION_CODE (fn))
     168                 :             :     {
     169                 :           0 :     case BUILT_IN_MEMCPY:
     170                 :           0 :     case BUILT_IN_MEMCPY_CHK:
     171                 :           0 :     case BUILT_IN_MEMMOVE:
     172                 :           0 :     case BUILT_IN_MEMMOVE_CHK:
     173                 :           0 :     case BUILT_IN_MEMSET:
     174                 :           0 :     case BUILT_IN_STRCAT:
     175                 :           0 :     case BUILT_IN_STRCAT_CHK:
     176                 :           0 :     case BUILT_IN_STRCPY:
     177                 :           0 :     case BUILT_IN_STRCPY_CHK:
     178                 :           0 :     case BUILT_IN_STRNCAT:
     179                 :           0 :     case BUILT_IN_STRNCAT_CHK:
     180                 :           0 :     case BUILT_IN_STRNCPY:
     181                 :           0 :     case BUILT_IN_STRNCPY_CHK:
     182                 :             :       /* Functions return the first argument (not a range).  */
     183                 :           0 :       offrng[0] = offrng[1] = 0;
     184                 :           0 :       return gimple_call_arg (stmt, 0);
     185                 :             : 
     186                 :         199 :     case BUILT_IN_MEMPCPY:
     187                 :         199 :     case BUILT_IN_MEMPCPY_CHK:
     188                 :         199 :       {
     189                 :             :         /* The returned pointer is in a range constrained by the smaller
     190                 :             :            of the upper bound of the size argument and the source object
     191                 :             :            size.  */
     192                 :         199 :         offrng[0] = 0;
     193                 :         199 :         offrng[1] = HOST_WIDE_INT_M1U;
     194                 :         199 :         tree off = gimple_call_arg (stmt, 2);
     195                 :         199 :         bool off_valid = get_offset_range (off, stmt, offrng, qry->rvals);
     196                 :         199 :         if (!off_valid || offrng[0] != offrng[1])
     197                 :             :           {
     198                 :             :             /* If the offset is either indeterminate or in some range,
     199                 :             :                try to constrain its upper bound to at most the size
     200                 :             :                of the source object.  */
     201                 :          82 :             access_ref aref;
     202                 :          82 :             tree src = gimple_call_arg (stmt, 1);
     203                 :          82 :             if (compute_objsize_r (src, stmt, false, 1, &aref, snlim, qry)
     204                 :          82 :                 && aref.sizrng[1] < offrng[1])
     205                 :          27 :               offrng[1] = aref.sizrng[1];
     206                 :             :           }
     207                 :             : 
     208                 :             :         /* Mempcpy may return a past-the-end pointer.  */
     209                 :         199 :         *past_end = true;
     210                 :         199 :         return gimple_call_arg (stmt, 0);
     211                 :             :       }
     212                 :             : 
     213                 :         492 :     case BUILT_IN_MEMCHR:
     214                 :         492 :       {
     215                 :         492 :         tree off = gimple_call_arg (stmt, 2);
     216                 :         492 :         if (get_offset_range (off, stmt, offrng, qry->rvals))
     217                 :         442 :           offrng[1] -= 1;
     218                 :             :         else
     219                 :          50 :           offrng[1] = HOST_WIDE_INT_M1U;
     220                 :             : 
     221                 :         492 :         offrng[0] = 0;
     222                 :         492 :         return gimple_call_arg (stmt, 0);
     223                 :             :       }
     224                 :             : 
     225                 :         315 :     case BUILT_IN_STRCHR:
     226                 :         315 :     case BUILT_IN_STRRCHR:
     227                 :         315 :     case BUILT_IN_STRSTR:
     228                 :         315 :       offrng[0] = 0;
     229                 :         315 :       offrng[1] = HOST_WIDE_INT_M1U;
     230                 :         315 :       return gimple_call_arg (stmt, 0);
     231                 :             : 
     232                 :         626 :     case BUILT_IN_STPCPY:
     233                 :         626 :     case BUILT_IN_STPCPY_CHK:
     234                 :         626 :       {
     235                 :         626 :         access_ref aref;
     236                 :         626 :         tree src = gimple_call_arg (stmt, 1);
     237                 :         626 :         if (compute_objsize_r (src, stmt, false, 1, &aref, snlim, qry))
     238                 :         626 :           offrng[1] = aref.sizrng[1] - 1;
     239                 :             :         else
     240                 :           0 :           offrng[1] = HOST_WIDE_INT_M1U;
     241                 :             :         
     242                 :         626 :         offrng[0] = 0;
     243                 :         626 :         return gimple_call_arg (stmt, 0);
     244                 :             :       }
     245                 :             : 
     246                 :         100 :     case BUILT_IN_STPNCPY:
     247                 :         100 :     case BUILT_IN_STPNCPY_CHK:
     248                 :         100 :       {
     249                 :             :         /* The returned pointer is in a range between the first argument
     250                 :             :            and it plus the smaller of the upper bound of the size argument
     251                 :             :            and the source object size.  */
     252                 :         100 :         offrng[1] = HOST_WIDE_INT_M1U;
     253                 :         100 :         tree off = gimple_call_arg (stmt, 2);
     254                 :         100 :         if (!get_offset_range (off, stmt, offrng, qry->rvals)
     255                 :         100 :             || offrng[0] != offrng[1])
     256                 :             :           {
     257                 :             :             /* If the offset is either indeterminate or in some range,
     258                 :             :                try to constrain its upper bound to at most the size
     259                 :             :                of the source object.  */
     260                 :          13 :             access_ref aref;
     261                 :          13 :             tree src = gimple_call_arg (stmt, 1);
     262                 :          13 :             if (compute_objsize_r (src, stmt, false, 1, &aref, snlim, qry)
     263                 :          13 :                 && aref.sizrng[1] < offrng[1])
     264                 :          13 :               offrng[1] = aref.sizrng[1];
     265                 :             :           }
     266                 :             : 
     267                 :             :         /* When the source is the empty string the returned pointer is
     268                 :             :            a copy of the argument.  Otherwise stpcpy can also return
     269                 :             :            a past-the-end pointer.  */
     270                 :         100 :         offrng[0] = 0;
     271                 :         100 :         *past_end = true;
     272                 :         100 :         return gimple_call_arg (stmt, 0);
     273                 :             :       }
     274                 :             : 
     275                 :             :     default:
     276                 :             :       break;
     277                 :             :     }
     278                 :             : 
     279                 :             :   return NULL_TREE;
     280                 :             : }
     281                 :             : 
     282                 :             : /* Return true when EXP's range can be determined and set RANGE[] to it
     283                 :             :    after adjusting it if necessary to make EXP a represents a valid size
     284                 :             :    of object, or a valid size argument to an allocation function declared
     285                 :             :    with attribute alloc_size (whose argument may be signed), or to a string
     286                 :             :    manipulation function like memset.
     287                 :             :    When ALLOW_ZERO is set in FLAGS, allow returning a range of [0, 0] for
     288                 :             :    a size in an anti-range [1, N] where N > PTRDIFF_MAX.  A zero range is
     289                 :             :    a (nearly) invalid argument to allocation functions like malloc but it
     290                 :             :    is a valid argument to functions like memset.
     291                 :             :    When USE_LARGEST is set in FLAGS set RANGE to the largest valid subrange
     292                 :             :    in a multi-range, otherwise to the smallest valid subrange.  */
     293                 :             : 
     294                 :             : bool
     295                 :     1210708 : get_size_range (range_query *query, tree exp, gimple *stmt, tree range[2],
     296                 :             :                 int flags /* = 0 */)
     297                 :             : {
     298                 :     1210708 :   if (!exp)
     299                 :             :     return false;
     300                 :             : 
     301                 :     1210708 :   if (tree_fits_uhwi_p (exp))
     302                 :             :     {
     303                 :             :       /* EXP is a constant.  */
     304                 :      985279 :       range[0] = range[1] = exp;
     305                 :      985279 :       return true;
     306                 :             :     }
     307                 :             : 
     308                 :      225429 :   tree exptype = TREE_TYPE (exp);
     309                 :      225429 :   bool integral = INTEGRAL_TYPE_P (exptype);
     310                 :             : 
     311                 :      225429 :   wide_int min, max;
     312                 :      225429 :   enum value_range_kind range_type;
     313                 :             : 
     314                 :      225429 :   if (!query)
     315                 :       22754 :     query = get_range_query (cfun);
     316                 :             : 
     317                 :      225429 :   if (integral)
     318                 :             :     {
     319                 :      225407 :       value_range vr;
     320                 :      225407 :       tree tmin, tmax;
     321                 :             : 
     322                 :      225407 :       query->range_of_expr (vr, exp, stmt);
     323                 :             : 
     324                 :      225407 :       if (vr.undefined_p ())
     325                 :           4 :         vr.set_varying (TREE_TYPE (exp));
     326                 :      225407 :       range_type = get_legacy_range (vr, tmin, tmax);
     327                 :      225407 :       min = wi::to_wide (tmin);
     328                 :      225407 :       max = wi::to_wide (tmax);
     329                 :      225407 :     }
     330                 :             :   else
     331                 :             :     range_type = VR_VARYING;
     332                 :             : 
     333                 :      225407 :   if (range_type == VR_VARYING)
     334                 :             :     {
     335                 :       49530 :       if (integral)
     336                 :             :         {       
     337                 :             :           /* Use the full range of the type of the expression when
     338                 :             :              no value range information is available.  */
     339                 :       49508 :           range[0] = TYPE_MIN_VALUE (exptype);
     340                 :       49508 :           range[1] = TYPE_MAX_VALUE (exptype);
     341                 :       49508 :           return true;
     342                 :             :         }
     343                 :             : 
     344                 :          22 :       range[0] = NULL_TREE;
     345                 :          22 :       range[1] = NULL_TREE;
     346                 :          22 :       return false;
     347                 :             :     }
     348                 :             : 
     349                 :      175899 :   unsigned expprec = TYPE_PRECISION (exptype);
     350                 :             : 
     351                 :      175899 :   bool signed_p = !TYPE_UNSIGNED (exptype);
     352                 :             : 
     353                 :      175899 :   if (range_type == VR_ANTI_RANGE)
     354                 :             :     {
     355                 :       31816 :       if (signed_p)
     356                 :             :         {
     357                 :          65 :           if (wi::les_p (max, 0))
     358                 :             :             {
     359                 :             :               /* EXP is not in a strictly negative range.  That means
     360                 :             :                  it must be in some (not necessarily strictly) positive
     361                 :             :                  range which includes zero.  Since in signed to unsigned
     362                 :             :                  conversions negative values end up converted to large
     363                 :             :                  positive values, and otherwise they are not valid sizes,
     364                 :             :                  the resulting range is in both cases [0, TYPE_MAX].  */
     365                 :           9 :               min = wi::zero (expprec);
     366                 :           9 :               max = wi::to_wide (TYPE_MAX_VALUE (exptype));
     367                 :             :             }
     368                 :          56 :           else if (wi::les_p (min - 1, 0))
     369                 :             :             {
     370                 :             :               /* EXP is not in a negative-positive range.  That means EXP
     371                 :             :                  is either negative, or greater than max.  Since negative
     372                 :             :                  sizes are invalid make the range [MAX + 1, TYPE_MAX].  */
     373                 :          30 :               min = max + 1;
     374                 :          30 :               max = wi::to_wide (TYPE_MAX_VALUE (exptype));
     375                 :             :             }
     376                 :             :           else
     377                 :             :             {
     378                 :          26 :               max = min - 1;
     379                 :          26 :               min = wi::zero (expprec);
     380                 :             :             }
     381                 :             :         }
     382                 :             :       else
     383                 :             :         {
     384                 :       31751 :           wide_int maxsize = wi::to_wide (max_object_size ());
     385                 :       31751 :           min = wide_int::from (min, maxsize.get_precision (), UNSIGNED);
     386                 :       31751 :           max = wide_int::from (max, maxsize.get_precision (), UNSIGNED);
     387                 :       31751 :           if (wi::eq_p (0, min - 1))
     388                 :             :             {
     389                 :             :               /* EXP is unsigned and not in the range [1, MAX].  That means
     390                 :             :                  it's either zero or greater than MAX.  Even though 0 would
     391                 :             :                  normally be detected by -Walloc-zero, unless ALLOW_ZERO
     392                 :             :                  is set, set the range to [MAX, TYPE_MAX] so that when MAX
     393                 :             :                  is greater than the limit the whole range is diagnosed.  */
     394                 :        9176 :               wide_int maxsize = wi::to_wide (max_object_size ());
     395                 :        9176 :               if (flags & SR_ALLOW_ZERO)
     396                 :             :                 {
     397                 :       10076 :                   if (wi::leu_p (maxsize, max + 1)
     398                 :        5038 :                       || !(flags & SR_USE_LARGEST))
     399                 :        3773 :                     min = max = wi::zero (expprec);
     400                 :             :                   else
     401                 :             :                     {
     402                 :        1265 :                       min = max + 1;
     403                 :        1265 :                       max = wi::to_wide (TYPE_MAX_VALUE (exptype));
     404                 :             :                     }
     405                 :             :                 }
     406                 :             :               else
     407                 :             :                 {
     408                 :        4138 :                   min = max + 1;
     409                 :        4138 :                   max = wi::to_wide (TYPE_MAX_VALUE (exptype));
     410                 :             :                 }
     411                 :        9176 :             }
     412                 :       45150 :           else if ((flags & SR_USE_LARGEST)
     413                 :       33507 :                    && wi::ltu_p (max + 1, maxsize))
     414                 :             :             {
     415                 :             :               /* When USE_LARGEST is set and the larger of the two subranges
     416                 :             :                  is a valid size, use it...  */
     417                 :         106 :               min = max + 1;
     418                 :         106 :               max = maxsize;
     419                 :             :             }
     420                 :             :           else
     421                 :             :             {
     422                 :             :               /* ...otherwise use the smaller subrange.  */
     423                 :       22469 :               max = min - 1;
     424                 :       22469 :               min = wi::zero (expprec);
     425                 :             :             }
     426                 :       31751 :         }
     427                 :             :     }
     428                 :             : 
     429                 :      175899 :   range[0] = wide_int_to_tree (exptype, min);
     430                 :      175899 :   range[1] = wide_int_to_tree (exptype, max);
     431                 :             : 
     432                 :      175899 :   return true;
     433                 :      225429 : }
     434                 :             : 
     435                 :             : bool
     436                 :       28647 : get_size_range (tree exp, tree range[2], int flags /* = 0 */)
     437                 :             : {
     438                 :       28647 :   return get_size_range (/*query=*/NULL, exp, /*stmt=*/NULL, range, flags);
     439                 :             : }
     440                 :             : 
     441                 :             : /* If STMT is a call to an allocation function, returns the constant
     442                 :             :    maximum size of the object allocated by the call represented as
     443                 :             :    sizetype.  If nonnull, sets RNG1[] to the range of the size.
     444                 :             :    When nonnull, uses RVALS for range information, otherwise gets global
     445                 :             :    range info.
     446                 :             :    Returns null when STMT is not a call to a valid allocation function.  */
     447                 :             : 
     448                 :             : tree
     449                 :      384839 : gimple_call_alloc_size (gimple *stmt, wide_int rng1[2] /* = NULL */,
     450                 :             :                         range_query *qry /* = NULL */)
     451                 :             : {
     452                 :      384839 :   if (!stmt || !is_gimple_call (stmt))
     453                 :             :     return NULL_TREE;
     454                 :             : 
     455                 :      384835 :   tree allocfntype;
     456                 :      384835 :   if (tree fndecl = gimple_call_fndecl (stmt))
     457                 :      369961 :     allocfntype = TREE_TYPE (fndecl);
     458                 :             :   else
     459                 :       14874 :     allocfntype = gimple_call_fntype (stmt);
     460                 :             : 
     461                 :      384835 :   if (!allocfntype)
     462                 :             :     return NULL_TREE;
     463                 :             : 
     464                 :      384332 :   unsigned argidx1 = UINT_MAX, argidx2 = UINT_MAX;
     465                 :      384332 :   tree at = lookup_attribute ("alloc_size", TYPE_ATTRIBUTES (allocfntype));
     466                 :      384332 :   if (!at)
     467                 :             :     {
     468                 :      304829 :       if (!gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
     469                 :             :         return NULL_TREE;
     470                 :             : 
     471                 :             :       argidx1 = 0;
     472                 :             :     }
     473                 :             : 
     474                 :       84109 :   unsigned nargs = gimple_call_num_args (stmt);
     475                 :             : 
     476                 :       84109 :   if (argidx1 == UINT_MAX)
     477                 :             :     {
     478                 :       79503 :       tree atval = TREE_VALUE (at);
     479                 :       79503 :       if (!atval)
     480                 :             :         return NULL_TREE;
     481                 :             : 
     482                 :       79503 :       argidx1 = TREE_INT_CST_LOW (TREE_VALUE (atval)) - 1;
     483                 :       79503 :       if (nargs <= argidx1)
     484                 :             :         return NULL_TREE;
     485                 :             : 
     486                 :       79503 :       atval = TREE_CHAIN (atval);
     487                 :       79503 :       if (atval)
     488                 :             :         {
     489                 :        1078 :           argidx2 = TREE_INT_CST_LOW (TREE_VALUE (atval)) - 1;
     490                 :        1078 :           if (nargs <= argidx2)
     491                 :             :             return NULL_TREE;
     492                 :             :         }
     493                 :             :     }
     494                 :             : 
     495                 :       84109 :   tree size = gimple_call_arg (stmt, argidx1);
     496                 :             : 
     497                 :      504654 :   wide_int rng1_buf[2];
     498                 :             :   /* If RNG1 is not set, use the buffer.  */
     499                 :       84109 :   if (!rng1)
     500                 :          42 :     rng1 = rng1_buf;
     501                 :             : 
     502                 :             :   /* Use maximum precision to avoid overflow below.  */
     503                 :       84109 :   const int prec = ADDR_MAX_PRECISION;
     504                 :             : 
     505                 :       84109 :   {
     506                 :       84109 :     tree r[2];
     507                 :             :     /* Determine the largest valid range size, including zero.  */
     508                 :       84109 :     if (!get_size_range (qry, size, stmt, r, SR_ALLOW_ZERO | SR_USE_LARGEST))
     509                 :           2 :       return NULL_TREE;
     510                 :       84107 :     rng1[0] = wi::to_wide (r[0], prec);
     511                 :       84107 :     rng1[1] = wi::to_wide (r[1], prec);
     512                 :             :   }
     513                 :             : 
     514                 :       84107 :   if (argidx2 > nargs && TREE_CODE (size) == INTEGER_CST)
     515                 :       36992 :     return fold_convert (sizetype, size);
     516                 :             : 
     517                 :             :   /* To handle ranges do the math in wide_int and return the product
     518                 :             :      of the upper bounds as a constant.  Ignore anti-ranges.  */
     519                 :       47115 :   tree n = argidx2 < nargs ? gimple_call_arg (stmt, argidx2) : integer_one_node;
     520                 :      235575 :   wide_int rng2[2];
     521                 :       47115 :   {
     522                 :       47115 :     tree r[2];
     523                 :             :       /* As above, use the full non-negative range on failure.  */
     524                 :       47115 :     if (!get_size_range (qry, n, stmt, r, SR_ALLOW_ZERO | SR_USE_LARGEST))
     525                 :           0 :       return NULL_TREE;
     526                 :       47115 :     rng2[0] = wi::to_wide (r[0], prec);
     527                 :       47115 :     rng2[1] = wi::to_wide (r[1], prec);
     528                 :             :   }
     529                 :             : 
     530                 :             :   /* Compute products of both bounds for the caller but return the lesser
     531                 :             :      of SIZE_MAX and the product of the upper bounds as a constant.  */
     532                 :       47115 :   rng1[0] = rng1[0] * rng2[0];
     533                 :       47115 :   rng1[1] = rng1[1] * rng2[1];
     534                 :             : 
     535                 :       47115 :   const tree size_max = TYPE_MAX_VALUE (sizetype);
     536                 :       47115 :   if (wi::gtu_p (rng1[1], wi::to_wide (size_max, prec)))
     537                 :             :     {
     538                 :          91 :       rng1[1] = wi::to_wide (size_max, prec);
     539                 :          91 :       return size_max;
     540                 :             :     }
     541                 :             : 
     542                 :       47024 :   return wide_int_to_tree (sizetype, rng1[1]);
     543                 :      393672 : }
     544                 :             : 
     545                 :             : /* For an access to an object referenced to by the function parameter PTR
     546                 :             :    of pointer type, and set RNG[] to the range of sizes of the object
     547                 :             :    obtainedfrom the attribute access specification for the current function.
     548                 :             :    Set STATIC_ARRAY if the array parameter has been declared [static].
     549                 :             :    Return the function parameter on success and null otherwise.  */
     550                 :             : 
     551                 :             : static tree
     552                 :      738272 : gimple_parm_array_size (tree ptr, wide_int rng[2],
     553                 :             :                         bool *static_array /* = NULL */)
     554                 :             : {
     555                 :             :   /* For a function argument try to determine the byte size of the array
     556                 :             :      from the current function declaratation (e.g., attribute access or
     557                 :             :      related).  */
     558                 :      738272 :   tree var = SSA_NAME_VAR (ptr);
     559                 :      738272 :   if (TREE_CODE (var) != PARM_DECL || !POINTER_TYPE_P (TREE_TYPE (var)))
     560                 :             :     return NULL_TREE;
     561                 :             : 
     562                 :      697587 :   const unsigned prec = TYPE_PRECISION (sizetype);
     563                 :             : 
     564                 :      697587 :   rdwr_map rdwr_idx;
     565                 :      697587 :   attr_access *access = get_parm_access (rdwr_idx, var);
     566                 :      697587 :   if (!access)
     567                 :             :     return NULL_TREE;
     568                 :             : 
     569                 :        2719 :   if (access->sizarg != UINT_MAX)
     570                 :             :     {
     571                 :             :       /* TODO: Try to extract the range from the argument based on
     572                 :             :          those of subsequent assertions or based on known calls to
     573                 :             :          the current function.  */
     574                 :             :       return NULL_TREE;
     575                 :             :     }
     576                 :             : 
     577                 :        2695 :   if (!access->minsize)
     578                 :             :     return NULL_TREE;
     579                 :             : 
     580                 :             :   /* Only consider ordinary array bound at level 2 (or above if it's
     581                 :             :      ever added).  */
     582                 :        1872 :   if (warn_array_parameter < 2 && !access->static_p)
     583                 :             :     return NULL_TREE;
     584                 :             : 
     585                 :         220 :   if (static_array)
     586                 :         220 :     *static_array = access->static_p;
     587                 :             : 
     588                 :         220 :   rng[0] = wi::zero (prec);
     589                 :         220 :   rng[1] = wi::uhwi (access->minsize, prec);
     590                 :             :   /* Multiply the array bound encoded in the attribute by the size
     591                 :             :      of what the pointer argument to which it decays points to.  */
     592                 :         220 :   tree eltype = TREE_TYPE (TREE_TYPE (ptr));
     593                 :         220 :   tree size = TYPE_SIZE_UNIT (eltype);
     594                 :         220 :   if (!size || TREE_CODE (size) != INTEGER_CST)
     595                 :             :     return NULL_TREE;
     596                 :             : 
     597                 :         190 :   rng[1] *= wi::to_wide (size, prec);
     598                 :         190 :   return var;
     599                 :      697587 : }
     600                 :             : 
     601                 :             : /* Initialize the object.  */
     602                 :             : 
     603                 :    17599378 : access_ref::access_ref ()
     604                 :    17599378 :   : ref (), eval ([](tree x){ return x; }), deref (), ref_nullptr_p (false),
     605                 :    17599378 :     trail1special (true), base0 (true), parmarray ()
     606                 :             : {
     607                 :             :   /* Set to valid.  */
     608                 :    17599378 :   offrng[0] = offrng[1] = 0;
     609                 :    17599378 :   offmax[0] = offmax[1] = 0;
     610                 :             :   /* Invalidate.   */
     611                 :    17599378 :   sizrng[0] = sizrng[1] = -1;
     612                 :    17599378 : }
     613                 :             : 
     614                 :             : /* Return the PHI node REF refers to or null if it doesn't.  */
     615                 :             : 
     616                 :             : gphi *
     617                 :      542566 : access_ref::phi () const
     618                 :             : {
     619                 :      542566 :   if (!ref || TREE_CODE (ref) != SSA_NAME)
     620                 :             :     return NULL;
     621                 :             : 
     622                 :      539371 :   gimple *def_stmt = SSA_NAME_DEF_STMT (ref);
     623                 :      539371 :   if (!def_stmt || gimple_code (def_stmt) != GIMPLE_PHI)
     624                 :             :     return NULL;
     625                 :             : 
     626                 :      538291 :   return as_a <gphi *> (def_stmt);
     627                 :             : }
     628                 :             : 
     629                 :             : /* Determine the size and offset for ARG, append it to ALL_REFS, and
     630                 :             :    merge the result with *THIS.  Ignore ARG if SKIP_NULL is set and
     631                 :             :    ARG refers to the null pointer.  Return true on success and false
     632                 :             :    on failure.  */
     633                 :             : 
     634                 :             : void
     635                 :      600976 : access_ref::merge_ref (vec<access_ref> *all_refs, tree arg, gimple *stmt,
     636                 :             :                        int ostype, bool skip_null,
     637                 :             :                        ssa_name_limit_t &snlim, pointer_query &qry)
     638                 :             : {
     639                 :      600976 :   access_ref aref;
     640                 :      600976 :   if (!compute_objsize_r (arg, stmt, false, ostype, &aref, snlim, &qry)
     641                 :      600976 :       || aref.sizrng[0] < 0)
     642                 :             :     {
     643                 :             :       /* This may be a PHI with all null pointer arguments.  Handle it
     644                 :             :          conservatively by setting all properties to the most permissive
     645                 :             :          values. */
     646                 :       57315 :       base0 = false;
     647                 :       57315 :       offrng[0] = offrng[1] = 0;
     648                 :       57315 :       add_max_offset ();
     649                 :       57315 :       set_max_size_range ();
     650                 :       57315 :       return;
     651                 :             :     }
     652                 :             : 
     653                 :      543661 :   if (all_refs)
     654                 :             :     {
     655                 :         265 :       access_ref dummy_ref;
     656                 :         265 :       aref.get_ref (all_refs, &dummy_ref, ostype, &snlim, &qry);
     657                 :             :     }
     658                 :             : 
     659                 :      543661 :   if (TREE_CODE (arg) == SSA_NAME)
     660                 :      447284 :     qry.put_ref (arg, aref, ostype);
     661                 :             : 
     662                 :      543661 :   if (all_refs)
     663                 :         265 :     all_refs->safe_push (aref);
     664                 :             : 
     665                 :      543661 :   aref.deref += deref;
     666                 :             : 
     667                 :      543661 :   bool merged_parmarray = aref.parmarray;
     668                 :             : 
     669                 :      543661 :   const bool nullp = skip_null && integer_zerop (arg);
     670                 :      543661 :   const offset_int maxobjsize = wi::to_offset (max_object_size ());
     671                 :      543661 :   offset_int minsize = sizrng[0];
     672                 :             : 
     673                 :      543661 :   if (sizrng[0] < 0)
     674                 :             :     {
     675                 :             :       /* If *THIS doesn't contain a meaningful result yet set it to AREF
     676                 :             :          unless the argument is null and it's okay to ignore it.  */
     677                 :      476535 :       if (!nullp)
     678                 :      456325 :         *this = aref;
     679                 :             : 
     680                 :             :       /* Set if the current argument refers to one or more objects of
     681                 :             :          known size (or range of sizes), as opposed to referring to
     682                 :             :          one or more unknown object(s).  */
     683                 :      476535 :       const bool arg_known_size = (aref.sizrng[0] != 0
     684                 :      875565 :                                    || aref.sizrng[1] != maxobjsize);
     685                 :      396178 :       if (arg_known_size)
     686                 :       80357 :         sizrng[0] = aref.sizrng[0];
     687                 :             : 
     688                 :      476535 :       return;
     689                 :             :     }
     690                 :             : 
     691                 :             :   /* Disregard null pointers in PHIs with two or more arguments.
     692                 :             :      TODO: Handle this better!  */
     693                 :       67126 :   if (nullp)
     694                 :             :     return;
     695                 :             : 
     696                 :       64296 :   const bool known_size = (sizrng[0] != 0 || sizrng[1] != maxobjsize);
     697                 :             : 
     698                 :       64296 :   if (known_size && aref.sizrng[0] < minsize)
     699                 :       19739 :     minsize = aref.sizrng[0];
     700                 :             : 
     701                 :             :   /* Extend the size and offset of *THIS to account for AREF.  The result
     702                 :             :      can be cached but results in false negatives.  */
     703                 :             : 
     704                 :       64296 :   offset_int orng[2];
     705                 :       64296 :   if (sizrng[1] < aref.sizrng[1])
     706                 :             :     {
     707                 :       22310 :       orng[0] = offrng[0];
     708                 :       22310 :       orng[1] = offrng[1];
     709                 :       22310 :       *this = aref;
     710                 :             :     }
     711                 :             :   else
     712                 :             :     {
     713                 :       41986 :       orng[0] = aref.offrng[0];
     714                 :       41986 :       orng[1] = aref.offrng[1];
     715                 :             :     }
     716                 :             : 
     717                 :       64296 :   if (orng[0] < offrng[0])
     718                 :        4589 :     offrng[0] = orng[0];
     719                 :       64296 :   if (offrng[1] < orng[1])
     720                 :       14753 :     offrng[1] = orng[1];
     721                 :             : 
     722                 :             :   /* Reset the PHI's BASE0 flag if any of the nonnull arguments
     723                 :             :      refers to an object at an unknown offset.  */
     724                 :       64296 :   if (!aref.base0)
     725                 :       18185 :     base0 = false;
     726                 :             : 
     727                 :       64296 :   sizrng[0] = minsize;
     728                 :       64296 :   parmarray = merged_parmarray;
     729                 :             : 
     730                 :       64296 :   return;
     731                 :             : }
     732                 :             : 
     733                 :             : /* Determine and return the largest object to which *THIS refers.  If
     734                 :             :    *THIS refers to a PHI and PREF is nonnull, fill *PREF with the details
     735                 :             :    of the object determined by compute_objsize(ARG, OSTYPE) for each PHI
     736                 :             :    argument ARG.  */
     737                 :             : 
     738                 :             : tree
     739                 :      538347 : access_ref::get_ref (vec<access_ref> *all_refs,
     740                 :             :                      access_ref *pref /* = NULL */,
     741                 :             :                      int ostype /* = 1 */,
     742                 :             :                      ssa_name_limit_t *psnlim /* = NULL */,
     743                 :             :                      pointer_query *qry /* = NULL */) const
     744                 :             : {
     745                 :      538347 :   if (!ref || TREE_CODE (ref) != SSA_NAME)
     746                 :             :     return NULL;
     747                 :             : 
     748                 :             :   /* FIXME: Calling get_ref() with a null PSNLIM is dangerous and might
     749                 :             :      cause unbounded recursion.  */
     750                 :      538141 :   ssa_name_limit_t snlim_buf;
     751                 :      538141 :   if (!psnlim)
     752                 :          82 :     psnlim = &snlim_buf;
     753                 :             : 
     754                 :      538141 :   pointer_query empty_qry;
     755                 :      538141 :   if (!qry)
     756                 :          82 :     qry = &empty_qry;
     757                 :             : 
     758                 :      538141 :   if (gimple *def_stmt = SSA_NAME_DEF_STMT (ref))
     759                 :             :     {
     760                 :      538141 :       if (is_gimple_assign (def_stmt))
     761                 :             :         {
     762                 :           0 :           tree_code code = gimple_assign_rhs_code (def_stmt);
     763                 :           0 :           if (code != MIN_EXPR && code != MAX_EXPR)
     764                 :             :             return NULL_TREE;
     765                 :             : 
     766                 :           0 :           access_ref aref;
     767                 :           0 :           tree arg1 = gimple_assign_rhs1 (def_stmt);
     768                 :           0 :           aref.merge_ref (all_refs, arg1, def_stmt, ostype, false,
     769                 :             :                           *psnlim, *qry);
     770                 :             : 
     771                 :           0 :           tree arg2 = gimple_assign_rhs2 (def_stmt);
     772                 :           0 :           aref.merge_ref (all_refs, arg2, def_stmt, ostype, false,
     773                 :             :                           *psnlim, *qry);
     774                 :             : 
     775                 :           0 :           if (pref && pref != this)
     776                 :             :             {
     777                 :           0 :               tree ref = pref->ref;
     778                 :           0 :               *pref = aref;
     779                 :           0 :               pref->ref = ref;
     780                 :             :             }
     781                 :             : 
     782                 :           0 :           return aref.ref;
     783                 :             :         }
     784                 :             :     }
     785                 :             :   else
     786                 :             :     return NULL_TREE;
     787                 :             : 
     788                 :      538141 :   gphi *phi_stmt = this->phi ();
     789                 :      538141 :   if (!phi_stmt)
     790                 :          23 :     return ref;
     791                 :             : 
     792                 :      538118 :   if (!psnlim->visit_phi (ref))
     793                 :             :     return NULL_TREE;
     794                 :             : 
     795                 :             :   /* The conservative result of the PHI reflecting the offset and size
     796                 :             :      of the largest PHI argument, regardless of whether or not they all
     797                 :             :      refer to the same object.  */
     798                 :      480803 :   access_ref phi_ref;
     799                 :      480803 :   if (pref)
     800                 :             :     {
     801                 :             :       /* The identity of the object has not been determined yet but
     802                 :             :          PREF->REF is set by the caller to the PHI for convenience.
     803                 :             :          The size is negative/invalid and the offset is zero (it's
     804                 :             :          updated only after the identity of the object has been
     805                 :             :          established).  */
     806                 :      480803 :       gcc_assert (pref->sizrng[0] < 0);
     807                 :      480803 :       gcc_assert (pref->offrng[0] == 0 && pref->offrng[1] == 0);
     808                 :             : 
     809                 :      480803 :       phi_ref = *pref;
     810                 :             :     }
     811                 :             : 
     812                 :      480803 :   const offset_int maxobjsize = wi::to_offset (max_object_size ());
     813                 :      480803 :   const unsigned nargs = gimple_phi_num_args (phi_stmt);
     814                 :      632850 :   for (unsigned i = 0; i < nargs; ++i)
     815                 :             :     {
     816                 :      600976 :       access_ref phi_arg_ref;
     817                 :      600976 :       bool skip_null = i || i + 1 < nargs;
     818                 :      600976 :       tree arg = gimple_phi_arg_def (phi_stmt, i);
     819                 :      600976 :       phi_ref.merge_ref (all_refs, arg, phi_stmt, ostype, skip_null,
     820                 :             :                          *psnlim, *qry);
     821                 :             : 
     822                 :      600976 :       if (!phi_ref.base0
     823                 :     1049905 :           && phi_ref.sizrng[0] == 0
     824                 :     1049905 :           && phi_ref.sizrng[1] >= maxobjsize)
     825                 :             :         /* When an argument results in the most permissive result,
     826                 :             :            the remaining arguments cannot constrain it.  Short-circuit
     827                 :             :            the evaluation.  */
     828                 :             :         break;
     829                 :             :     }
     830                 :             : 
     831                 :      480803 :   if (phi_ref.sizrng[0] < 0)
     832                 :             :     {
     833                 :             :       /* Fail if none of the PHI's arguments resulted in updating PHI_REF
     834                 :             :          (perhaps because they have all been already visited by prior
     835                 :             :          recursive calls).  */
     836                 :           3 :       psnlim->leave_phi (ref);
     837                 :           3 :       return NULL_TREE;
     838                 :             :     }
     839                 :             : 
     840                 :             :   /* Avoid changing *THIS.  */
     841                 :      480800 :   if (pref && pref != this)
     842                 :             :     {
     843                 :             :       /* Keep the SSA_NAME of the PHI unchanged so that all PHI arguments
     844                 :             :          can be referred to later if necessary.  This is useful even if
     845                 :             :          they all refer to the same object.  */
     846                 :      480800 :       tree ref = pref->ref;
     847                 :      480800 :       *pref = phi_ref;
     848                 :      480800 :       pref->ref = ref;
     849                 :             :     }
     850                 :             : 
     851                 :      480800 :   psnlim->leave_phi (ref);
     852                 :             : 
     853                 :      480800 :   return phi_ref.ref;
     854                 :      538141 : }
     855                 :             : 
     856                 :             : /* Return the maximum amount of space remaining and if non-null, set
     857                 :             :    argument to the minimum.  */
     858                 :             : 
     859                 :             : offset_int
     860                 :    13970671 : access_ref::size_remaining (offset_int *pmin /* = NULL */) const
     861                 :             : {
     862                 :    13970671 :   offset_int minbuf;
     863                 :    13970671 :   if (!pmin)
     864                 :    10272788 :     pmin = &minbuf;
     865                 :             : 
     866                 :    13970671 :   if (sizrng[0] < 0)
     867                 :             :     {
     868                 :             :       /* If the identity of the object hasn't been determined return
     869                 :             :          the maximum size range.  */
     870                 :           0 :       *pmin = 0;
     871                 :           0 :       return wi::to_offset (max_object_size ());
     872                 :             :     }
     873                 :             : 
     874                 :             :   /* add_offset() ensures the offset range isn't inverted.  */
     875                 :    13970671 :   gcc_checking_assert (offrng[0] <= offrng[1]);
     876                 :             : 
     877                 :    13970671 :   if (base0)
     878                 :             :     {
     879                 :             :       /* The offset into referenced object is zero-based (i.e., it's
     880                 :             :          not referenced by a pointer into middle of some unknown object).  */
     881                 :     9086353 :       if (offrng[0] < 0 && offrng[1] < 0)
     882                 :             :         {
     883                 :             :           /* If the offset is negative the remaining size is zero.  */
     884                 :        2449 :           *pmin = 0;
     885                 :        2449 :           return 0;
     886                 :             :         }
     887                 :             : 
     888                 :     9083904 :       if (sizrng[1] <= offrng[0])
     889                 :             :         {
     890                 :             :           /* If the starting offset is greater than or equal to the upper
     891                 :             :              bound on the size of the object, the space remaining is zero.
     892                 :             :              As a special case, if it's equal, set *PMIN to -1 to let
     893                 :             :              the caller know the offset is valid and just past the end.  */
     894                 :       74725 :           *pmin = sizrng[1] == offrng[0] ? -1 : 0;
     895                 :       69617 :           return 0;
     896                 :             :         }
     897                 :             : 
     898                 :             :       /* Otherwise return the size minus the lower bound of the offset.  */
     899                 :     9014287 :       offset_int or0 = offrng[0] < 0 ? 0 : offrng[0];
     900                 :             : 
     901                 :     9014287 :       *pmin = sizrng[0] - or0;
     902                 :     9014287 :       return sizrng[1] - or0;
     903                 :             :     }
     904                 :             : 
     905                 :             :   /* The offset to the referenced object isn't zero-based (i.e., it may
     906                 :             :      refer to a byte other than the first.  The size of such an object
     907                 :             :      is constrained only by the size of the address space (the result
     908                 :             :      of max_object_size()).  */
     909                 :     4884318 :   if (sizrng[1] <= offrng[0])
     910                 :             :     {
     911                 :           6 :       *pmin = 0;
     912                 :           6 :       return 0;
     913                 :             :     }
     914                 :             : 
     915                 :     4884312 :   offset_int or0 = offrng[0] < 0 ? 0 : offrng[0];
     916                 :             : 
     917                 :     4884312 :   *pmin = sizrng[0] - or0;
     918                 :     4884312 :   return sizrng[1] - or0;
     919                 :             : }
     920                 :             : 
     921                 :             : /* Return true if the offset and object size are in range for SIZE.  */
     922                 :             : 
     923                 :             : bool
     924                 :      585179 : access_ref::offset_in_range (const offset_int &size) const
     925                 :             : {
     926                 :      585179 :   if (size_remaining () < size)
     927                 :             :     return false;
     928                 :             : 
     929                 :      574053 :   if (base0)
     930                 :       61858 :     return offmax[0] >= 0 && offmax[1] <= sizrng[1];
     931                 :             : 
     932                 :      512213 :   offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
     933                 :      512213 :   return offmax[0] > -maxoff && offmax[1] < maxoff;
     934                 :             : }
     935                 :             : 
     936                 :             : /* Add the range [MIN, MAX] to the offset range.  For known objects (with
     937                 :             :    zero-based offsets) at least one of whose offset's bounds is in range,
     938                 :             :    constrain the other (or both) to the bounds of the object (i.e., zero
     939                 :             :    and the upper bound of its size).  This improves the quality of
     940                 :             :    diagnostics.  */
     941                 :             : 
     942                 :     7078815 : void access_ref::add_offset (const offset_int &min, const offset_int &max)
     943                 :             : {
     944                 :     7078815 :   if (min <= max)
     945                 :             :     {
     946                 :             :       /* To add an ordinary range just add it to the bounds.  */
     947                 :     6988291 :       offrng[0] += min;
     948                 :     6988291 :       offrng[1] += max;
     949                 :             :     }
     950                 :       90524 :   else if (!base0)
     951                 :             :     {
     952                 :             :       /* To add an inverted range to an offset to an unknown object
     953                 :             :          expand it to the maximum.  */
     954                 :       75098 :       add_max_offset ();
     955                 :     3788272 :       return;
     956                 :             :     }
     957                 :             :   else
     958                 :             :     {
     959                 :             :       /* To add an inverted range to an offset to an known object set
     960                 :             :          the upper bound to the maximum representable offset value
     961                 :             :          (which may be greater than MAX_OBJECT_SIZE).
     962                 :             :          The lower bound is either the sum of the current offset and
     963                 :             :          MIN when abs(MAX) is greater than the former, or zero otherwise.
     964                 :             :          Zero because then the inverted range includes the negative of
     965                 :             :          the lower bound.  */
     966                 :       15426 :       offset_int maxoff = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
     967                 :       15426 :       offrng[1] = maxoff;
     968                 :             : 
     969                 :       15426 :       if (max >= 0)
     970                 :             :         {
     971                 :           0 :           offrng[0] = 0;
     972                 :           0 :           if (offmax[0] > 0)
     973                 :           0 :             offmax[0] = 0;
     974                 :           0 :           return;
     975                 :             :         }
     976                 :             : 
     977                 :       15426 :       offset_int absmax = wi::abs (max);
     978                 :       15426 :       if (offrng[0] < absmax)
     979                 :             :         {
     980                 :       15230 :           offrng[0] += min;
     981                 :             :           /* Cap the lower bound at the upper (set to MAXOFF above)
     982                 :             :              to avoid inadvertently recreating an inverted range.  */
     983                 :       15230 :           if (offrng[1] < offrng[0])
     984                 :           2 :             offrng[0] = offrng[1];
     985                 :             :         }
     986                 :             :       else
     987                 :         196 :         offrng[0] = 0;
     988                 :             :     }
     989                 :             : 
     990                 :             :   /* Set the minimum and maximmum computed so far. */
     991                 :     7003717 :   if (offrng[1] < 0 && offrng[1] < offmax[0])
     992                 :       25785 :     offmax[0] = offrng[1];
     993                 :     7003717 :   if (offrng[0] > 0 && offrng[0] > offmax[1])
     994                 :     2460976 :     offmax[1] = offrng[0];
     995                 :             : 
     996                 :     7003717 :   if (!base0)
     997                 :             :     return;
     998                 :             : 
     999                 :             :   /* When referencing a known object check to see if the offset computed
    1000                 :             :      so far is in bounds... */
    1001                 :     3365641 :   offset_int remrng[2];
    1002                 :     3365641 :   remrng[1] = size_remaining (remrng);
    1003                 :     3365641 :   if (remrng[1] > 0 || remrng[0] < 0)
    1004                 :             :     {
    1005                 :             :       /* ...if so, constrain it so that neither bound exceeds the size of
    1006                 :             :          the object.  Out of bounds offsets are left unchanged, and, for
    1007                 :             :          better or worse, become in bounds later.  They should be detected
    1008                 :             :          and diagnosed at the point they first become invalid by
    1009                 :             :          -Warray-bounds.  */
    1010                 :     3362060 :       if (offrng[0] < 0)
    1011                 :      114651 :         offrng[0] = 0;
    1012                 :     3362060 :       if (offrng[1] > sizrng[1])
    1013                 :      132348 :         offrng[1] = sizrng[1];
    1014                 :             :     }
    1015                 :             : }
    1016                 :             : 
    1017                 :             : /* Issue one inform message describing each target of an access REF.
    1018                 :             :    WRITE is set for a write access and clear for a read access.  */
    1019                 :             : 
    1020                 :             : void
    1021                 :        3970 : access_ref::inform_access (access_mode mode, int ostype /* = 1 */) const
    1022                 :             : {
    1023                 :        3970 :   const access_ref &aref = *this;
    1024                 :        3970 :   if (!aref.ref)
    1025                 :        3342 :     return;
    1026                 :             : 
    1027                 :        3807 :   if (phi ())
    1028                 :             :     {
    1029                 :             :       /* Set MAXREF to refer to the largest object and fill ALL_REFS
    1030                 :             :          with data for all objects referenced by the PHI arguments.  */
    1031                 :          82 :       access_ref maxref;
    1032                 :          82 :       auto_vec<access_ref> all_refs;
    1033                 :          82 :       if (!get_ref (&all_refs, &maxref, ostype))
    1034                 :             :         return;
    1035                 :             : 
    1036                 :          82 :       if (all_refs.length ())
    1037                 :             :         {
    1038                 :             :           /* Except for MAXREF, the rest of the arguments' offsets need not
    1039                 :             :              reflect one added to the PHI itself.  Determine the latter from
    1040                 :             :              MAXREF on which the result is based.  */
    1041                 :          82 :           const offset_int orng[] =
    1042                 :             :             {
    1043                 :          82 :              offrng[0] - maxref.offrng[0],
    1044                 :          82 :              wi::smax (offrng[1] - maxref.offrng[1], offrng[0]),
    1045                 :             :             };
    1046                 :             : 
    1047                 :             :           /* Add the final PHI's offset to that of each of the arguments
    1048                 :             :              and recurse to issue an inform message for it.  */
    1049                 :         694 :           for (unsigned i = 0; i != all_refs.length (); ++i)
    1050                 :             :             {
    1051                 :             :               /* Skip any PHIs; those could lead to infinite recursion.  */
    1052                 :         265 :               if (all_refs[i].phi ())
    1053                 :          36 :                 continue;
    1054                 :             : 
    1055                 :         229 :               all_refs[i].add_offset (orng[0], orng[1]);
    1056                 :         229 :               all_refs[i].inform_access (mode, ostype);
    1057                 :             :             }
    1058                 :          82 :           return;
    1059                 :             :         }
    1060                 :          82 :     }
    1061                 :             : 
    1062                 :             :   /* Convert offset range and avoid including a zero range since it
    1063                 :             :      isn't necessarily meaningful.  */
    1064                 :        3725 :   HOST_WIDE_INT diff_min = tree_to_shwi (TYPE_MIN_VALUE (ptrdiff_type_node));
    1065                 :        3725 :   HOST_WIDE_INT diff_max = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));
    1066                 :        3725 :   HOST_WIDE_INT minoff;
    1067                 :        3725 :   HOST_WIDE_INT maxoff = diff_max;
    1068                 :        3725 :   if (wi::fits_shwi_p (aref.offrng[0]))
    1069                 :        3725 :     minoff = aref.offrng[0].to_shwi ();
    1070                 :             :   else
    1071                 :           0 :     minoff = aref.offrng[0] < 0 ? diff_min : diff_max;
    1072                 :             : 
    1073                 :        3725 :   if (wi::fits_shwi_p (aref.offrng[1]))
    1074                 :        3722 :     maxoff = aref.offrng[1].to_shwi ();
    1075                 :             : 
    1076                 :        3725 :   if (maxoff <= diff_min || maxoff >= diff_max)
    1077                 :             :     /* Avoid mentioning an upper bound that's equal to or in excess
    1078                 :             :        of the maximum of ptrdiff_t.  */
    1079                 :         135 :     maxoff = minoff;
    1080                 :             : 
    1081                 :             :   /* Convert size range and always include it since all sizes are
    1082                 :             :      meaningful. */
    1083                 :        3725 :   unsigned long long minsize = 0, maxsize = 0;
    1084                 :        3725 :   if (wi::fits_shwi_p (aref.sizrng[0])
    1085                 :        3725 :       && wi::fits_shwi_p (aref.sizrng[1]))
    1086                 :             :     {
    1087                 :        3725 :       minsize = aref.sizrng[0].to_shwi ();
    1088                 :        3725 :       maxsize = aref.sizrng[1].to_shwi ();
    1089                 :             :     }
    1090                 :             : 
    1091                 :             :   /* SIZRNG doesn't necessarily have the same range as the allocation
    1092                 :             :      size determined by gimple_call_alloc_size ().  */
    1093                 :        3725 :   char sizestr[80];
    1094                 :        3725 :   if (minsize == maxsize)
    1095                 :        3457 :     sprintf (sizestr, "%llu", minsize);
    1096                 :             :   else
    1097                 :         268 :     sprintf (sizestr, "[%llu, %llu]", minsize, maxsize);
    1098                 :             : 
    1099                 :        3725 :   char offstr[80];
    1100                 :        3725 :   if (minoff == 0
    1101                 :        3725 :       && (maxoff == 0 || aref.sizrng[1] <= maxoff))
    1102                 :        1103 :     offstr[0] = '\0';
    1103                 :        2622 :   else if (minoff == maxoff)
    1104                 :        2357 :     sprintf (offstr, "%lli", (long long) minoff);
    1105                 :             :   else
    1106                 :         265 :     sprintf (offstr, "[%lli, %lli]", (long long) minoff, (long long) maxoff);
    1107                 :             : 
    1108                 :        3725 :   location_t loc = UNKNOWN_LOCATION;
    1109                 :             : 
    1110                 :        3725 :   tree ref = this->ref;
    1111                 :        3725 :   tree allocfn = NULL_TREE;
    1112                 :        3725 :   if (TREE_CODE (ref) == SSA_NAME)
    1113                 :             :     {
    1114                 :         925 :       gimple *stmt = SSA_NAME_DEF_STMT (ref);
    1115                 :         925 :       if (!stmt)
    1116                 :             :         return;
    1117                 :             : 
    1118                 :         925 :       if (is_gimple_call (stmt))
    1119                 :             :         {
    1120                 :         885 :           loc = gimple_location (stmt);
    1121                 :         885 :           if (gimple_call_builtin_p (stmt, BUILT_IN_ALLOCA_WITH_ALIGN))
    1122                 :             :             {
    1123                 :             :               /* Strip the SSA_NAME suffix from the variable name and
    1124                 :             :                  recreate an identifier with the VLA's original name.  */
    1125                 :          24 :               ref = gimple_call_lhs (stmt);
    1126                 :          24 :               if (SSA_NAME_IDENTIFIER (ref))
    1127                 :             :                 {
    1128                 :          23 :                   ref = SSA_NAME_IDENTIFIER (ref);
    1129                 :          23 :                   const char *id = IDENTIFIER_POINTER (ref);
    1130                 :          23 :                   size_t len = strcspn (id, ".$");
    1131                 :          23 :                   if (!len)
    1132                 :           0 :                     len = strlen (id);
    1133                 :          23 :                   ref = get_identifier_with_length (id, len);
    1134                 :             :                 }
    1135                 :             :             }
    1136                 :             :           else
    1137                 :             :             {
    1138                 :             :               /* Except for VLAs, retrieve the allocation function.  */
    1139                 :         861 :               allocfn = gimple_call_fndecl (stmt);
    1140                 :         861 :               if (!allocfn)
    1141                 :           8 :                 allocfn = gimple_call_fn (stmt);
    1142                 :         861 :               if (TREE_CODE (allocfn) == SSA_NAME)
    1143                 :             :                 {
    1144                 :             :                   /* For an ALLOC_CALL via a function pointer make a small
    1145                 :             :                      effort to determine the destination of the pointer.  */
    1146                 :           4 :                   gimple *def = SSA_NAME_DEF_STMT (allocfn);
    1147                 :           4 :                   if (gimple_assign_single_p (def))
    1148                 :             :                     {
    1149                 :           3 :                       tree rhs = gimple_assign_rhs1 (def);
    1150                 :           3 :                       if (DECL_P (rhs))
    1151                 :             :                         allocfn = rhs;
    1152                 :           2 :                       else if (TREE_CODE (rhs) == COMPONENT_REF)
    1153                 :           1 :                         allocfn = TREE_OPERAND (rhs, 1);
    1154                 :             :                     }
    1155                 :             :                 }
    1156                 :             :             }
    1157                 :             :         }
    1158                 :          40 :       else if (gimple_nop_p (stmt))
    1159                 :             :         /* Handle DECL_PARM below.  */
    1160                 :           5 :         ref = SSA_NAME_VAR (ref);
    1161                 :          35 :       else if (is_gimple_assign (stmt)
    1162                 :          35 :                && (gimple_assign_rhs_code (stmt) == MIN_EXPR
    1163                 :          18 :                    || gimple_assign_rhs_code (stmt) == MAX_EXPR))
    1164                 :             :         {
    1165                 :             :           /* MIN or MAX_EXPR here implies a reference to a known object
    1166                 :             :              and either an unknown or distinct one (the latter being
    1167                 :             :              the result of an invalid relational expression).  Determine
    1168                 :             :              the identity of the former and point to it in the note.
    1169                 :             :              TODO: Consider merging with PHI handling.  */
    1170                 :         105 :           access_ref arg_ref[2];
    1171                 :          35 :           tree arg = gimple_assign_rhs1 (stmt);
    1172                 :          35 :           compute_objsize (arg, /* ostype = */ 1 , &arg_ref[0]);
    1173                 :          35 :           arg = gimple_assign_rhs2 (stmt);
    1174                 :          35 :           compute_objsize (arg, /* ostype = */ 1 , &arg_ref[1]);
    1175                 :             : 
    1176                 :             :           /* Use the argument that references a known object with more
    1177                 :             :              space remaining.  */
    1178                 :          35 :           const bool idx
    1179                 :          35 :             = (!arg_ref[0].ref || !arg_ref[0].base0
    1180                 :          67 :                || (arg_ref[0].base0 && arg_ref[1].base0
    1181                 :          11 :                    && (arg_ref[0].size_remaining ()
    1182                 :          22 :                        < arg_ref[1].size_remaining ())));
    1183                 :             : 
    1184                 :          35 :           arg_ref[idx].offrng[0] = offrng[0];
    1185                 :          35 :           arg_ref[idx].offrng[1] = offrng[1];
    1186                 :          35 :           arg_ref[idx].inform_access (mode);
    1187                 :          35 :           return;
    1188                 :             :         }
    1189                 :             :     }
    1190                 :             : 
    1191                 :        3690 :   if (DECL_P (ref))
    1192                 :        2699 :     loc = DECL_SOURCE_LOCATION (ref);
    1193                 :         991 :   else if (EXPR_P (ref) && EXPR_HAS_LOCATION (ref))
    1194                 :           0 :     loc = EXPR_LOCATION (ref);
    1195                 :         991 :   else if (TREE_CODE (ref) != IDENTIFIER_NODE
    1196                 :         991 :            && TREE_CODE (ref) != SSA_NAME)
    1197                 :             :     {
    1198                 :         106 :       if (TREE_CODE (ref) == INTEGER_CST && ref_nullptr_p)
    1199                 :             :         {
    1200                 :           3 :           if (mode == access_read_write || mode == access_write_only)
    1201                 :           1 :             inform (loc, "destination object is likely at address zero");
    1202                 :             :           else
    1203                 :           2 :             inform (loc, "source object is likely at address zero");
    1204                 :             :         }
    1205                 :         106 :       return;
    1206                 :             :     }
    1207                 :             : 
    1208                 :        3584 :   if (mode == access_read_write || mode == access_write_only)
    1209                 :             :     {
    1210                 :        1764 :       if (allocfn == NULL_TREE)
    1211                 :             :         {
    1212                 :        1538 :           if (*offstr)
    1213                 :        1226 :             inform (loc, "at offset %s into destination object %qE of size %s",
    1214                 :             :                     offstr, ref, sizestr);
    1215                 :             :           else
    1216                 :         312 :             inform (loc, "destination object %qE of size %s", ref, sizestr);
    1217                 :        1538 :           return;
    1218                 :             :         }
    1219                 :             : 
    1220                 :         226 :       if (*offstr)
    1221                 :          57 :         inform (loc,
    1222                 :             :                 "at offset %s into destination object of size %s "
    1223                 :             :                 "allocated by %qE", offstr, sizestr, allocfn);
    1224                 :             :       else
    1225                 :         169 :         inform (loc, "destination object of size %s allocated by %qE",
    1226                 :             :                 sizestr, allocfn);
    1227                 :         226 :       return;
    1228                 :             :     }
    1229                 :             : 
    1230                 :        1820 :   if (mode == access_read_only)
    1231                 :             :     {
    1232                 :         430 :       if (allocfn == NULL_TREE)
    1233                 :             :         {
    1234                 :         423 :           if (*offstr)
    1235                 :         292 :             inform (loc, "at offset %s into source object %qE of size %s",
    1236                 :             :                     offstr, ref, sizestr);
    1237                 :             :           else
    1238                 :         131 :             inform (loc, "source object %qE of size %s", ref, sizestr);
    1239                 :             : 
    1240                 :         423 :           return;
    1241                 :             :         }
    1242                 :             : 
    1243                 :           7 :       if (*offstr)
    1244                 :           0 :         inform (loc,
    1245                 :             :                 "at offset %s into source object of size %s allocated by %qE",
    1246                 :             :                 offstr, sizestr, allocfn);
    1247                 :             :       else
    1248                 :           7 :         inform (loc, "source object of size %s allocated by %qE",
    1249                 :             :                 sizestr, allocfn);
    1250                 :           7 :       return;
    1251                 :             :     }
    1252                 :             : 
    1253                 :        1390 :   if (allocfn == NULL_TREE)
    1254                 :             :     {
    1255                 :         762 :       if (*offstr)
    1256                 :         613 :         inform (loc, "at offset %s into object %qE of size %s",
    1257                 :             :                 offstr, ref, sizestr);
    1258                 :             :       else
    1259                 :         149 :         inform (loc, "object %qE of size %s", ref, sizestr);
    1260                 :             : 
    1261                 :         762 :       return;
    1262                 :             :     }
    1263                 :             : 
    1264                 :         628 :   if (*offstr)
    1265                 :         319 :     inform (loc,
    1266                 :             :             "at offset %s into object of size %s allocated by %qE",
    1267                 :             :             offstr, sizestr, allocfn);
    1268                 :             :   else
    1269                 :         309 :     inform (loc, "object of size %s allocated by %qE",
    1270                 :             :             sizestr, allocfn);
    1271                 :             : }
    1272                 :             : 
    1273                 :             : /* Dump *THIS to FILE.  */
    1274                 :             : 
    1275                 :             : void
    1276                 :           0 : access_ref::dump (FILE *file) const
    1277                 :             : {
    1278                 :           0 :   for (int i = deref; i < 0; ++i)
    1279                 :           0 :     fputc ('&', file);
    1280                 :             : 
    1281                 :           0 :   for (int i = 0; i < deref; ++i)
    1282                 :           0 :     fputc ('*', file);
    1283                 :             : 
    1284                 :           0 :   if (gphi *phi_stmt = phi ())
    1285                 :             :     {
    1286                 :           0 :       fputs ("PHI <", file);
    1287                 :           0 :       unsigned nargs = gimple_phi_num_args (phi_stmt);
    1288                 :           0 :       for (unsigned i = 0; i != nargs; ++i)
    1289                 :             :         {
    1290                 :           0 :           tree arg = gimple_phi_arg_def (phi_stmt, i);
    1291                 :           0 :           print_generic_expr (file, arg);
    1292                 :           0 :           if (i + 1 < nargs)
    1293                 :           0 :             fputs (", ", file);
    1294                 :             :         }
    1295                 :           0 :       fputc ('>', file);
    1296                 :             :     }
    1297                 :             :   else
    1298                 :           0 :     print_generic_expr (file, ref);
    1299                 :             : 
    1300                 :           0 :   if (offrng[0] != offrng[1])
    1301                 :           0 :     fprintf (file, " + [%lli, %lli]",
    1302                 :           0 :              (long long) offrng[0].to_shwi (),
    1303                 :           0 :              (long long) offrng[1].to_shwi ());
    1304                 :           0 :   else if (offrng[0] != 0)
    1305                 :           0 :     fprintf (file, " %c %lli",
    1306                 :           0 :              offrng[0] < 0 ? '-' : '+',
    1307                 :           0 :              (long long) offrng[0].to_shwi ());
    1308                 :             : 
    1309                 :           0 :   if (base0)
    1310                 :           0 :     fputs (" (base0)", file);
    1311                 :             : 
    1312                 :           0 :   fputs ("; size: ", file);
    1313                 :           0 :   if (sizrng[0] != sizrng[1])
    1314                 :             :     {
    1315                 :           0 :       offset_int maxsize = wi::to_offset (max_object_size ());
    1316                 :           0 :       if (sizrng[0] == 0 && sizrng[1] >= maxsize)
    1317                 :           0 :         fputs ("unknown", file);
    1318                 :             :       else
    1319                 :           0 :         fprintf (file, "[%llu, %llu]",
    1320                 :           0 :                  (unsigned long long) sizrng[0].to_uhwi (),
    1321                 :           0 :                  (unsigned long long) sizrng[1].to_uhwi ());
    1322                 :             :     }
    1323                 :           0 :   else if (sizrng[0] != 0)
    1324                 :           0 :     fprintf (file, "%llu",
    1325                 :           0 :              (unsigned long long) sizrng[0].to_uhwi ());
    1326                 :             : 
    1327                 :           0 :   fputc ('\n', file);
    1328                 :           0 : }
    1329                 :             : 
    1330                 :             : /* Set the access to at most MAXWRITE and MAXREAD bytes, and at least 1
    1331                 :             :    when MINWRITE or MINREAD, respectively, is set.  */
    1332                 :      810717 : access_data::access_data (range_query *query, gimple *stmt, access_mode mode,
    1333                 :             :                           tree maxwrite /* = NULL_TREE */,
    1334                 :             :                           bool minwrite /* = false */,
    1335                 :             :                           tree maxread /* = NULL_TREE */,
    1336                 :      810717 :                           bool minread /* = false */)
    1337                 :      810717 :   : stmt (stmt), call (), dst (), src (), mode (mode), ostype ()
    1338                 :             : {
    1339                 :      810717 :   set_bound (dst_bndrng, maxwrite, minwrite, query, stmt);
    1340                 :      810717 :   set_bound (src_bndrng, maxread, minread, query, stmt);
    1341                 :      810717 : }
    1342                 :             : 
    1343                 :             : /* Set the access to at most MAXWRITE and MAXREAD bytes, and at least 1
    1344                 :             :    when MINWRITE or MINREAD, respectively, is set.  */
    1345                 :         111 : access_data::access_data (range_query *query, tree expr, access_mode mode,
    1346                 :             :                           tree maxwrite /* = NULL_TREE */,
    1347                 :             :                           bool minwrite /* = false */,
    1348                 :             :                           tree maxread /* = NULL_TREE */,
    1349                 :         111 :                           bool minread /* = false */)
    1350                 :         111 :   : stmt (), call (expr),  dst (), src (), mode (mode), ostype ()
    1351                 :             : {
    1352                 :         111 :   set_bound (dst_bndrng, maxwrite, minwrite, query, stmt);
    1353                 :         111 :   set_bound (src_bndrng, maxread, minread, query, stmt);
    1354                 :         111 : }
    1355                 :             : 
    1356                 :             : /* Set BNDRNG to the range of BOUND for the statement STMT.  */
    1357                 :             : 
    1358                 :             : void
    1359                 :     1621656 : access_data::set_bound (offset_int bndrng[2], tree bound, bool minaccess,
    1360                 :             :                         range_query *query, gimple *stmt)
    1361                 :             : {
    1362                 :             :   /* Set the default bounds of the access and adjust below.  */
    1363                 :     2822967 :   bndrng[0] = minaccess ? 1 : 0;
    1364                 :     1621656 :   bndrng[1] = HOST_WIDE_INT_M1U;
    1365                 :             : 
    1366                 :             :   /* When BOUND is nonnull and a range can be extracted from it,
    1367                 :             :      set the bounds of the access to reflect both it and MINACCESS.
    1368                 :             :      BNDRNG[0] is the size of the minimum access.  */
    1369                 :     1621656 :   tree rng[2];
    1370                 :     1621656 :   if (bound && get_size_range (query, bound, stmt, rng, SR_ALLOW_ZERO))
    1371                 :             :     {
    1372                 :      123218 :       bndrng[0] = wi::to_offset (rng[0]);
    1373                 :      123218 :       bndrng[1] = wi::to_offset (rng[1]);
    1374                 :      130522 :       bndrng[0] = bndrng[0] > 0 && minaccess ? 1 : 0;
    1375                 :             :     }
    1376                 :     1621656 : }
    1377                 :             : 
    1378                 :             : /* Set a bit for the PHI in VISITED and return true if it wasn't
    1379                 :             :    already set.  */
    1380                 :             : 
    1381                 :             : bool
    1382                 :      654045 : ssa_name_limit_t::visit_phi (tree ssa_name)
    1383                 :             : {
    1384                 :      654045 :   if (!visited)
    1385                 :      424380 :     visited = BITMAP_ALLOC (NULL);
    1386                 :             : 
    1387                 :             :   /* Return false if SSA_NAME has already been visited.  */
    1388                 :      654045 :   return bitmap_set_bit (visited, SSA_NAME_VERSION (ssa_name));
    1389                 :             : }
    1390                 :             : 
    1391                 :             : /* Clear a bit for the PHI in VISITED.  */
    1392                 :             : 
    1393                 :             : void
    1394                 :      480803 : ssa_name_limit_t::leave_phi (tree ssa_name)
    1395                 :             : {
    1396                 :             :   /* Return false if SSA_NAME has already been visited.  */
    1397                 :      480803 :   bitmap_clear_bit (visited, SSA_NAME_VERSION (ssa_name));
    1398                 :      480803 : }
    1399                 :             : 
    1400                 :             : /* Return false if the SSA_NAME chain length counter has reached
    1401                 :             :    the limit, otherwise increment the counter and return true.  */
    1402                 :             : 
    1403                 :             : bool
    1404                 :     5966384 : ssa_name_limit_t::next ()
    1405                 :             : {
    1406                 :             :   /* Return a negative value to let caller avoid recursing beyond
    1407                 :             :      the specified limit.  */
    1408                 :     5966384 :   if (ssa_def_max == 0)
    1409                 :             :     return false;
    1410                 :             : 
    1411                 :     5966359 :   --ssa_def_max;
    1412                 :     5966359 :   return true;
    1413                 :             : }
    1414                 :             : 
    1415                 :             : /* If the SSA_NAME has already been "seen" return a positive value.
    1416                 :             :    Otherwise add it to VISITED.  If the SSA_NAME limit has been
    1417                 :             :    reached, return a negative value.  Otherwise return zero.  */
    1418                 :             : 
    1419                 :             : int
    1420                 :      115927 : ssa_name_limit_t::next_phi (tree ssa_name)
    1421                 :             : {
    1422                 :      115927 :   {
    1423                 :      115927 :     gimple *def_stmt = SSA_NAME_DEF_STMT (ssa_name);
    1424                 :             :     /* Return a positive value if the PHI has already been visited.  */
    1425                 :      115927 :     if (gimple_code (def_stmt) == GIMPLE_PHI
    1426                 :      115927 :         && !visit_phi (ssa_name))
    1427                 :             :       return 1;
    1428                 :             :   }
    1429                 :             : 
    1430                 :             :   /* Return a negative value to let caller avoid recursing beyond
    1431                 :             :      the specified limit.  */
    1432                 :       79895 :   if (ssa_def_max == 0)
    1433                 :             :     return -1;
    1434                 :             : 
    1435                 :       79895 :   --ssa_def_max;
    1436                 :             : 
    1437                 :       79895 :   return 0;
    1438                 :             : }
    1439                 :             : 
    1440                 :    10865611 : ssa_name_limit_t::~ssa_name_limit_t ()
    1441                 :             : {
    1442                 :    10865611 :   if (visited)
    1443                 :      424380 :     BITMAP_FREE (visited);
    1444                 :    10865611 : }
    1445                 :             : 
    1446                 :             : /* Default ctor.  Initialize object with pointers to the range_query
    1447                 :             :    instance to use or null.  */
    1448                 :             : 
    1449                 :    12628163 : pointer_query::pointer_query (range_query *qry /* = NULL */)
    1450                 :    12628163 :   : rvals (qry), hits (), misses (), failures (), depth (), max_depth (),
    1451                 :    12628163 :     var_cache ()
    1452                 :             : {
    1453                 :             :   /* No op.  */
    1454                 :    12628163 : }
    1455                 :             : 
    1456                 :             : /* Return a pointer to the cached access_ref instance for the SSA_NAME
    1457                 :             :    PTR if it's there or null otherwise.  */
    1458                 :             : 
    1459                 :             : const access_ref *
    1460                 :     5966359 : pointer_query::get_ref (tree ptr, int ostype /* = 1 */) const
    1461                 :             : {
    1462                 :     5966359 :   unsigned version = SSA_NAME_VERSION (ptr);
    1463                 :     5966359 :   unsigned idx = version << 1 | (ostype & 1);
    1464                 :    10085942 :   if (var_cache.indices.length () <= idx)
    1465                 :             :     {
    1466                 :     2663296 :       ++misses;
    1467                 :     2663296 :       return NULL;
    1468                 :             :     }
    1469                 :             : 
    1470                 :     3303063 :   unsigned cache_idx = var_cache.indices[idx];
    1471                 :     6606126 :   if (var_cache.access_refs.length () <= cache_idx)
    1472                 :             :     {
    1473                 :           0 :       ++misses;
    1474                 :           0 :       return NULL;
    1475                 :             :     }
    1476                 :             : 
    1477                 :     3303063 :   const access_ref &cache_ref = var_cache.access_refs[cache_idx];
    1478                 :     3303063 :   if (cache_ref.ref)
    1479                 :             :     {
    1480                 :     1640889 :       ++hits;
    1481                 :     1640889 :       return &cache_ref;
    1482                 :             :     }
    1483                 :             : 
    1484                 :     1662174 :   ++misses;
    1485                 :     1662174 :   return NULL;
    1486                 :             : }
    1487                 :             : 
    1488                 :             : /* Retrieve the access_ref instance for a variable from the cache if it's
    1489                 :             :    there or compute it and insert it into the cache if it's nonnonull.  */
    1490                 :             : 
    1491                 :             : bool
    1492                 :     7772089 : pointer_query::get_ref (tree ptr, gimple *stmt, access_ref *pref,
    1493                 :             :                         int ostype /* = 1 */)
    1494                 :             : {
    1495                 :     7772089 :   const unsigned version
    1496                 :     7772089 :     = TREE_CODE (ptr) == SSA_NAME ? SSA_NAME_VERSION (ptr) : 0;
    1497                 :             : 
    1498                 :     1891954 :   if (version)
    1499                 :             :     {
    1500                 :     1891954 :       unsigned idx = version << 1 | (ostype & 1);
    1501                 :     1891954 :       if (idx < var_cache.indices.length ())
    1502                 :             :         {
    1503                 :      994401 :           unsigned cache_idx = var_cache.indices[idx] - 1;
    1504                 :      994401 :           if (cache_idx < var_cache.access_refs.length ()
    1505                 :      994401 :               && var_cache.access_refs[cache_idx].ref)
    1506                 :             :             {
    1507                 :           0 :               ++hits;
    1508                 :           0 :               *pref = var_cache.access_refs[cache_idx];
    1509                 :           0 :               return true;
    1510                 :             :             }
    1511                 :             :         }
    1512                 :             : 
    1513                 :     1891954 :       ++misses;
    1514                 :             :     }
    1515                 :             : 
    1516                 :     7772089 :   if (!compute_objsize (ptr, stmt, ostype, pref, this))
    1517                 :             :     {
    1518                 :       10019 :       ++failures;
    1519                 :       10019 :       return false;
    1520                 :             :     }
    1521                 :             : 
    1522                 :             :   return true;
    1523                 :             : }
    1524                 :             : 
    1525                 :             : /* Add a copy of the access_ref REF for the SSA_NAME to the cache if it's
    1526                 :             :    nonnull.  */
    1527                 :             : 
    1528                 :             : void
    1529                 :     3169776 : pointer_query::put_ref (tree ptr, const access_ref &ref, int ostype /* = 1 */)
    1530                 :             : {
    1531                 :             :   /* Only add populated/valid entries.  */
    1532                 :     3169776 :   if (!ref.ref || ref.sizrng[0] < 0)
    1533                 :           0 :     return;
    1534                 :             : 
    1535                 :             :   /* Add REF to the two-level cache.  */
    1536                 :     3169776 :   unsigned version = SSA_NAME_VERSION (ptr);
    1537                 :     3169776 :   unsigned idx = version << 1 | (ostype & 1);
    1538                 :             : 
    1539                 :             :   /* Grow INDICES if necessary.  An index is valid if it's nonzero.
    1540                 :             :      Its value minus one is the index into ACCESS_REFS.  Not all
    1541                 :             :      entries are valid.  */
    1542                 :     5433484 :   if (var_cache.indices.length () <= idx)
    1543                 :     1649356 :     var_cache.indices.safe_grow_cleared (idx + 1);
    1544                 :             : 
    1545                 :     3169776 :   if (!var_cache.indices[idx])
    1546                 :     4819996 :     var_cache.indices[idx] = var_cache.access_refs.length () + 1;
    1547                 :             : 
    1548                 :             :   /* Grow ACCESS_REF cache if necessary.  An entry is valid if its
    1549                 :             :      REF member is nonnull.  All entries except for the last two
    1550                 :             :      are valid.  Once nonnull, the REF value must stay unchanged.  */
    1551                 :     3169776 :   unsigned cache_idx = var_cache.indices[idx];
    1552                 :     5433484 :   if (var_cache.access_refs.length () <= cache_idx)
    1553                 :     2863032 :     var_cache.access_refs.safe_grow_cleared (cache_idx + 1);
    1554                 :             : 
    1555                 :     3169776 :   access_ref &cache_ref = var_cache.access_refs[cache_idx];
    1556                 :     3169776 :   if (cache_ref.ref)
    1557                 :             :   {
    1558                 :      306744 :     gcc_checking_assert (cache_ref.ref == ref.ref);
    1559                 :             :     return;
    1560                 :             :   }
    1561                 :             : 
    1562                 :     2863032 :   cache_ref = ref;
    1563                 :             : }
    1564                 :             : 
    1565                 :             : /* Flush the cache if it's nonnull.  */
    1566                 :             : 
    1567                 :             : void
    1568                 :     7709733 : pointer_query::flush_cache ()
    1569                 :             : {
    1570                 :     7709733 :   var_cache.indices.release ();
    1571                 :     7709733 :   var_cache.access_refs.release ();
    1572                 :     7709733 : }
    1573                 :             : 
    1574                 :             : /* Dump statistics and, optionally, cache contents to DUMP_FILE.  */
    1575                 :             : 
    1576                 :             : void
    1577                 :         149 : pointer_query::dump (FILE *dump_file, bool contents /* = false */)
    1578                 :             : {
    1579                 :         149 :   unsigned nused = 0, nrefs = 0;
    1580                 :         149 :   unsigned nidxs = var_cache.indices.length ();
    1581                 :         149 :   for (unsigned i = 0; i != nidxs; ++i)
    1582                 :             :     {
    1583                 :           0 :       unsigned ari = var_cache.indices[i];
    1584                 :           0 :       if (!ari)
    1585                 :           0 :         continue;
    1586                 :             : 
    1587                 :           0 :       ++nused;
    1588                 :             : 
    1589                 :           0 :       const access_ref &aref = var_cache.access_refs[ari];
    1590                 :           0 :       if (!aref.ref)
    1591                 :           0 :         continue;
    1592                 :             : 
    1593                 :           0 :       ++nrefs;
    1594                 :             :     }
    1595                 :             : 
    1596                 :         149 :   fprintf (dump_file, "pointer_query counters:\n"
    1597                 :             :            "  index cache size:   %u\n"
    1598                 :             :            "  index entries:      %u\n"
    1599                 :             :            "  access cache size:  %u\n"
    1600                 :             :            "  access entries:     %u\n"
    1601                 :             :            "  hits:               %u\n"
    1602                 :             :            "  misses:             %u\n"
    1603                 :             :            "  failures:           %u\n"
    1604                 :             :            "  max_depth:          %u\n",
    1605                 :             :            nidxs, nused,
    1606                 :             :            var_cache.access_refs.length (), nrefs,
    1607                 :             :            hits, misses, failures, max_depth);
    1608                 :             : 
    1609                 :         149 :   if (!contents || !nidxs)
    1610                 :             :     return;
    1611                 :             : 
    1612                 :           0 :   fputs ("\npointer_query cache contents:\n", dump_file);
    1613                 :             : 
    1614                 :           0 :   for (unsigned i = 0; i != nidxs; ++i)
    1615                 :             :     {
    1616                 :           0 :       unsigned ari = var_cache.indices[i];
    1617                 :           0 :       if (!ari)
    1618                 :           0 :         continue;
    1619                 :             : 
    1620                 :           0 :       const access_ref &aref = var_cache.access_refs[ari];
    1621                 :           0 :       if (!aref.ref)
    1622                 :           0 :         continue;
    1623                 :             : 
    1624                 :             :       /* The level-1 cache index corresponds to the SSA_NAME_VERSION
    1625                 :             :          shifted left by one and ORed with the Object Size Type in
    1626                 :             :          the lowest bit.  Print the two separately.  */
    1627                 :           0 :       unsigned ver = i >> 1;
    1628                 :           0 :       unsigned ost = i & 1;
    1629                 :             : 
    1630                 :           0 :       fprintf (dump_file, "  %u.%u[%u]: ", ver, ost, ari);
    1631                 :           0 :       if (tree name = ssa_name (ver))
    1632                 :             :         {
    1633                 :           0 :           print_generic_expr (dump_file, name);
    1634                 :           0 :           fputs (" = ", dump_file);
    1635                 :             :         }
    1636                 :             :       else
    1637                 :           0 :         fprintf (dump_file, "  _%u = ", ver);
    1638                 :             : 
    1639                 :           0 :       aref.dump (dump_file);
    1640                 :             :     }
    1641                 :             : 
    1642                 :           0 :   fputc ('\n', dump_file);
    1643                 :             : }
    1644                 :             : 
    1645                 :             : /* A helper of compute_objsize_r() to determine the size from an assignment
    1646                 :             :    statement STMT with the RHS of either MIN_EXPR or MAX_EXPR.  On success
    1647                 :             :    set PREF->REF to the operand with more or less space remaining,
    1648                 :             :    respectively, if both refer to the same (sub)object, or to PTR if they
    1649                 :             :    might not, and return true.  Otherwise, if the identity of neither
    1650                 :             :    operand can be determined, return false.  */
    1651                 :             : 
    1652                 :             : static bool
    1653                 :         916 : handle_min_max_size (tree ptr, int ostype, access_ref *pref,
    1654                 :             :                      ssa_name_limit_t &snlim, pointer_query *qry)
    1655                 :             : {
    1656                 :         916 :   gimple *stmt = SSA_NAME_DEF_STMT (ptr);
    1657                 :         916 :   const tree_code code = gimple_assign_rhs_code (stmt);
    1658                 :             : 
    1659                 :             :   /* In a valid MAX_/MIN_EXPR both operands must refer to the same array.
    1660                 :             :      Determine the size/offset of each and use the one with more or less
    1661                 :             :      space remaining, respectively.  If either fails, use the information
    1662                 :             :      determined from the other instead, adjusted up or down as appropriate
    1663                 :             :      for the expression.  */
    1664                 :         916 :   access_ref aref[2] = { *pref, *pref };
    1665                 :         916 :   tree arg1 = gimple_assign_rhs1 (stmt);
    1666                 :         916 :   if (!compute_objsize_r (arg1, stmt, false, ostype, &aref[0], snlim, qry))
    1667                 :             :     {
    1668                 :           5 :       aref[0].base0 = false;
    1669                 :           5 :       aref[0].offrng[0] = aref[0].offrng[1] = 0;
    1670                 :           5 :       aref[0].add_max_offset ();
    1671                 :           5 :       aref[0].set_max_size_range ();
    1672                 :             :     }
    1673                 :             : 
    1674                 :         916 :   tree arg2 = gimple_assign_rhs2 (stmt);
    1675                 :         916 :   if (!compute_objsize_r (arg2, stmt, false, ostype, &aref[1], snlim, qry))
    1676                 :             :     {
    1677                 :           4 :       aref[1].base0 = false;
    1678                 :           4 :       aref[1].offrng[0] = aref[1].offrng[1] = 0;
    1679                 :           4 :       aref[1].add_max_offset ();
    1680                 :           4 :       aref[1].set_max_size_range ();
    1681                 :             :     }
    1682                 :             : 
    1683                 :         916 :   if (!aref[0].ref && !aref[1].ref)
    1684                 :             :     /* Fail if the identity of neither argument could be determined.  */
    1685                 :             :     return false;
    1686                 :             : 
    1687                 :         916 :   bool i0 = false;
    1688                 :         916 :   if (aref[0].ref && aref[0].base0)
    1689                 :             :     {
    1690                 :         177 :       if (aref[1].ref && aref[1].base0)
    1691                 :             :         {
    1692                 :             :           /* If the object referenced by both arguments has been determined
    1693                 :             :              set *PREF to the one with more or less space remainng, whichever
    1694                 :             :              is appopriate for CODE.
    1695                 :             :              TODO: Indicate when the objects are distinct so it can be
    1696                 :             :              diagnosed.  */
    1697                 :          81 :           i0 = code == MAX_EXPR;
    1698                 :          81 :           const bool i1 = !i0;
    1699                 :             : 
    1700                 :          81 :           if (aref[i0].size_remaining () < aref[i1].size_remaining ())
    1701                 :          20 :             *pref = aref[i1];
    1702                 :             :           else
    1703                 :          61 :             *pref = aref[i0];
    1704                 :             : 
    1705                 :          81 :           if (aref[i0].ref != aref[i1].ref)
    1706                 :             :             /* If the operands don't refer to the same (sub)object set
    1707                 :             :                PREF->REF to the SSA_NAME from which STMT was obtained
    1708                 :             :                so that both can be identified in a diagnostic.  */
    1709                 :          63 :             pref->ref = ptr;
    1710                 :             : 
    1711                 :          81 :           return true;
    1712                 :             :         }
    1713                 :             : 
    1714                 :             :       /* If only the object referenced by one of the arguments could be
    1715                 :             :          determined, use it and...  */
    1716                 :          96 :       *pref = aref[0];
    1717                 :          96 :       i0 = true;
    1718                 :          96 :     }
    1719                 :             :   else
    1720                 :         739 :     *pref = aref[1];
    1721                 :             : 
    1722                 :         835 :   const bool i1 = !i0;
    1723                 :             :   /* ...see if the offset obtained from the other pointer can be used
    1724                 :             :      to tighten up the bound on the offset obtained from the first.  */
    1725                 :         373 :   if ((code == MAX_EXPR && aref[i1].offrng[1] < aref[i0].offrng[0])
    1726                 :        1196 :       || (code == MIN_EXPR && aref[i0].offrng[0] < aref[i1].offrng[1]))
    1727                 :             :     {
    1728                 :          79 :       pref->offrng[0] = aref[i0].offrng[0];
    1729                 :          79 :       pref->offrng[1] = aref[i0].offrng[1];
    1730                 :             :     }
    1731                 :             : 
    1732                 :             :   /* Replace PTR->REF with the SSA_NAME to indicate the expression
    1733                 :             :      might not refer to the same (sub)object.  */
    1734                 :         835 :   pref->ref = ptr;
    1735                 :         835 :   return true;
    1736                 :             : }
    1737                 :             : 
    1738                 :             : /* A helper of compute_objsize_r() to determine the size of a DECL.
    1739                 :             :    Return true on success and (possibly in the future) false on failure.  */
    1740                 :             : 
    1741                 :             : static bool
    1742                 :     4661023 : handle_decl (tree decl, bool addr, access_ref *pref)
    1743                 :             : {
    1744                 :     4661023 :   tree decl_type = TREE_TYPE (decl);
    1745                 :             : 
    1746                 :     4661023 :   pref->ref = decl;
    1747                 :             : 
    1748                 :             :   /* Reset the offset in case it was set by a prior call and not
    1749                 :             :      cleared by the caller.  The offset is only adjusted after
    1750                 :             :      the identity of the object has been determined.  */
    1751                 :     4661023 :   pref->offrng[0] = pref->offrng[1] = 0;
    1752                 :             : 
    1753                 :     4661023 :   if (!addr && POINTER_TYPE_P (decl_type))
    1754                 :             :     {
    1755                 :             :       /* Set the maximum size if the reference is to the pointer
    1756                 :             :          itself (as opposed to what it points to), and clear
    1757                 :             :          BASE0 since the offset isn't necessarily zero-based.  */
    1758                 :       41249 :       pref->set_max_size_range ();
    1759                 :       41249 :       pref->base0 = false;
    1760                 :       41249 :       return true;
    1761                 :             :     }
    1762                 :             : 
    1763                 :             :   /* Valid offsets into the object are nonnegative.  */
    1764                 :     4619774 :   pref->base0 = true;
    1765                 :             : 
    1766                 :     4619774 :   if (tree size = decl_init_size (decl, false))
    1767                 :     4596974 :     if (TREE_CODE (size) == INTEGER_CST)
    1768                 :             :       {
    1769                 :     4596838 :         pref->sizrng[0] = wi::to_offset (size);
    1770                 :     4596838 :         pref->sizrng[1] = pref->sizrng[0];
    1771                 :     4596838 :         return true;
    1772                 :             :       }
    1773                 :             : 
    1774                 :       22936 :   pref->set_max_size_range ();
    1775                 :       22936 :   return true;
    1776                 :             : }
    1777                 :             : 
    1778                 :             : /* A helper of compute_objsize_r() to determine the size from ARRAY_REF
    1779                 :             :    AREF.  ADDR is true if PTR is the operand of ADDR_EXPR.  Return true
    1780                 :             :    on success and false on failure.  */
    1781                 :             : 
    1782                 :             : static bool
    1783                 :      818151 : handle_array_ref (tree aref, gimple *stmt, bool addr, int ostype,
    1784                 :             :                   access_ref *pref, ssa_name_limit_t &snlim,
    1785                 :             :                   pointer_query *qry)
    1786                 :             : {
    1787                 :      818151 :   gcc_assert (TREE_CODE (aref) == ARRAY_REF);
    1788                 :             : 
    1789                 :      818151 :   tree arefop = TREE_OPERAND (aref, 0);
    1790                 :      818151 :   tree reftype = TREE_TYPE (arefop);
    1791                 :      818151 :   if (!addr && TREE_CODE (TREE_TYPE (reftype)) == POINTER_TYPE)
    1792                 :             :     /* Avoid arrays of pointers.  FIXME: Hande pointers to arrays
    1793                 :             :        of known bound.  */
    1794                 :             :     return false;
    1795                 :             : 
    1796                 :      808122 :   if (!compute_objsize_r (arefop, stmt, addr, ostype, pref, snlim, qry))
    1797                 :             :     return false;
    1798                 :             : 
    1799                 :      808122 :   offset_int orng[2];
    1800                 :      808122 :   tree off = pref->eval (TREE_OPERAND (aref, 1));
    1801                 :      808122 :   range_query *const rvals = qry ? qry->rvals : NULL;
    1802                 :      808122 :   if (!get_offset_range (off, stmt, orng, rvals))
    1803                 :             :     {
    1804                 :             :       /* Set ORNG to the maximum offset representable in ptrdiff_t.  */
    1805                 :       41872 :       orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
    1806                 :       41872 :       orng[0] = -orng[1] - 1;
    1807                 :             :     }
    1808                 :             : 
    1809                 :             :   /* Convert the array index range determined above to a byte offset.  */
    1810                 :      808122 :   tree lowbnd = array_ref_low_bound (aref);
    1811                 :      808122 :   if (TREE_CODE (lowbnd) == INTEGER_CST && !integer_zerop (lowbnd))
    1812                 :             :     {
    1813                 :             :       /* Adjust the index by the low bound of the array domain (0 in C/C++,
    1814                 :             :          1 in Fortran and anything in Ada) by applying the same processing
    1815                 :             :          as in get_offset_range.  */
    1816                 :       17857 :       const wide_int wlb = wi::to_wide (lowbnd);
    1817                 :       17857 :       signop sgn = SIGNED;
    1818                 :       17857 :       if (TYPE_UNSIGNED (TREE_TYPE (lowbnd))
    1819                 :       17857 :           && wlb.get_precision () < TYPE_PRECISION (sizetype))
    1820                 :             :         sgn = UNSIGNED;
    1821                 :       17857 :       const offset_int lb = offset_int::from (wlb, sgn);
    1822                 :       17857 :       orng[0] -= lb;
    1823                 :       17857 :       orng[1] -= lb;
    1824                 :       17857 :     }
    1825                 :             : 
    1826                 :      808122 :   tree eltype = TREE_TYPE (aref);
    1827                 :      808122 :   tree tpsize = TYPE_SIZE_UNIT (eltype);
    1828                 :      808122 :   if (!tpsize || TREE_CODE (tpsize) != INTEGER_CST)
    1829                 :             :     {
    1830                 :         396 :       pref->add_max_offset ();
    1831                 :         396 :       return true;
    1832                 :             :     }
    1833                 :             : 
    1834                 :      807726 :   offset_int sz = wi::to_offset (tpsize);
    1835                 :      807726 :   orng[0] *= sz;
    1836                 :      807726 :   orng[1] *= sz;
    1837                 :             : 
    1838                 :      807726 :   if (ostype && TREE_CODE (eltype) == ARRAY_TYPE)
    1839                 :             :     {
    1840                 :             :       /* Except for the permissive raw memory functions which use
    1841                 :             :          the size of the whole object determined above, use the size
    1842                 :             :          of the referenced array.  Because the overall offset is from
    1843                 :             :          the beginning of the complete array object add this overall
    1844                 :             :          offset to the size of array.  */
    1845                 :        5781 :       offset_int sizrng[2] =
    1846                 :             :         {
    1847                 :        5781 :          pref->offrng[0] + orng[0] + sz,
    1848                 :        5781 :          pref->offrng[1] + orng[1] + sz
    1849                 :             :         };
    1850                 :        5781 :       if (sizrng[1] < sizrng[0])
    1851                 :           2 :         std::swap (sizrng[0], sizrng[1]);
    1852                 :        5781 :       if (sizrng[0] >= 0 && sizrng[0] <= pref->sizrng[0])
    1853                 :        5335 :         pref->sizrng[0] = sizrng[0];
    1854                 :        5781 :       if (sizrng[1] >= 0 && sizrng[1] <= pref->sizrng[1])
    1855                 :        5438 :         pref->sizrng[1] = sizrng[1];
    1856                 :             :     }
    1857                 :             : 
    1858                 :      807726 :   pref->add_offset (orng[0], orng[1]);
    1859                 :      807726 :   return true;
    1860                 :             : }
    1861                 :             : 
    1862                 :             : /* Given a COMPONENT_REF CREF, set *PREF size to the size of the referenced
    1863                 :             :    member.  */
    1864                 :             : 
    1865                 :             : static void
    1866                 :       49995 : set_component_ref_size (tree cref, access_ref *pref)
    1867                 :             : {
    1868                 :       49995 :   const tree base = TREE_OPERAND (cref, 0);
    1869                 :       49995 :   const tree base_type = TREE_TYPE (base);
    1870                 :             : 
    1871                 :             :   /* SAM is set for array members that might need special treatment.  */
    1872                 :       49995 :   special_array_member sam;
    1873                 :       49995 :   tree size = component_ref_size (cref, &sam);
    1874                 :       49995 :   if (sam == special_array_member::int_0)
    1875                 :         252 :     pref->sizrng[0] = pref->sizrng[1] = 0;
    1876                 :       49743 :   else if (!pref->trail1special && sam == special_array_member::trail_1)
    1877                 :          36 :     pref->sizrng[0] = pref->sizrng[1] = 1;
    1878                 :       49707 :   else if (size && TREE_CODE (size) == INTEGER_CST)
    1879                 :       47324 :     pref->sizrng[0] = pref->sizrng[1] = wi::to_offset (size);
    1880                 :             :   else
    1881                 :             :     {
    1882                 :             :       /* When the size of the member is unknown it's either a flexible
    1883                 :             :          array member or a trailing special array member (either zero
    1884                 :             :          length or one-element).  Set the size to the maximum minus
    1885                 :             :          the constant size of the base object's type.  */
    1886                 :        2383 :       pref->sizrng[0] = 0;
    1887                 :        2383 :       pref->sizrng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
    1888                 :        2383 :       if (tree base_size = TYPE_SIZE_UNIT (base_type))
    1889                 :        2383 :         if (TREE_CODE (base_size) == INTEGER_CST)
    1890                 :        2344 :           pref->sizrng[1] -= wi::to_offset (base_size);
    1891                 :             :     }
    1892                 :       49995 : }
    1893                 :             : 
    1894                 :             : /* A helper of compute_objsize_r() to determine the size from COMPONENT_REF
    1895                 :             :    CREF.  Return true on success and false on failure.  */
    1896                 :             : 
    1897                 :             : static bool
    1898                 :     2942822 : handle_component_ref (tree cref, gimple *stmt, bool addr, int ostype,
    1899                 :             :                       access_ref *pref, ssa_name_limit_t &snlim,
    1900                 :             :                       pointer_query *qry)
    1901                 :             : {
    1902                 :     2942822 :   gcc_assert (TREE_CODE (cref) == COMPONENT_REF);
    1903                 :             : 
    1904                 :     2942822 :   const tree base = TREE_OPERAND (cref, 0);
    1905                 :     2942822 :   const tree field = TREE_OPERAND (cref, 1);
    1906                 :     2942822 :   access_ref base_ref = *pref;
    1907                 :             : 
    1908                 :             :   /* Unconditionally determine the size of the base object (it could
    1909                 :             :      be smaller than the referenced member when the object is stored
    1910                 :             :      in a buffer with an insufficient size).  */
    1911                 :     2942822 :   if (!compute_objsize_r (base, stmt, addr, 0, &base_ref, snlim, qry))
    1912                 :             :     return false;
    1913                 :             : 
    1914                 :             :   /* Add the offset of the member to the offset into the object computed
    1915                 :             :      so far.  */
    1916                 :     2942822 :   tree offset = byte_position (field);
    1917                 :     2942822 :   if (TREE_CODE (offset) == INTEGER_CST)
    1918                 :     2942795 :     base_ref.add_offset (wi::to_offset (offset));
    1919                 :             :   else
    1920                 :          27 :     base_ref.add_max_offset ();
    1921                 :             : 
    1922                 :     2942822 :   if (!base_ref.ref)
    1923                 :             :     /* PREF->REF may have been already set to an SSA_NAME earlier
    1924                 :             :        to provide better context for diagnostics.  In that case,
    1925                 :             :        leave it unchanged.  */
    1926                 :           0 :     base_ref.ref = base;
    1927                 :             : 
    1928                 :     2942822 :   const tree base_type = TREE_TYPE (base);
    1929                 :     2942822 :   if (TREE_CODE (base_type) == UNION_TYPE)
    1930                 :             :     /* In accesses through union types consider the entire unions
    1931                 :             :        rather than just their members.  */
    1932                 :             :     ostype = 0;
    1933                 :             : 
    1934                 :     2569406 :   if (ostype == 0)
    1935                 :             :     {
    1936                 :             :       /* In OSTYPE zero (for raw memory functions like memcpy), use
    1937                 :             :          the maximum size instead if the identity of the enclosing
    1938                 :             :          object cannot be determined.  */
    1939                 :     2892813 :       *pref = base_ref;
    1940                 :     2892813 :       return true;
    1941                 :             :     }
    1942                 :             : 
    1943                 :       50009 :   pref->ref = field;
    1944                 :             : 
    1945                 :       50009 :   if (!addr && POINTER_TYPE_P (TREE_TYPE (field)))
    1946                 :             :     {
    1947                 :             :       /* Set maximum size if the reference is to the pointer member
    1948                 :             :          itself (as opposed to what it points to).  */
    1949                 :          14 :       pref->set_max_size_range ();
    1950                 :          14 :       return true;
    1951                 :             :     }
    1952                 :             : 
    1953                 :       49995 :   set_component_ref_size (cref, pref);
    1954                 :             : 
    1955                 :       49995 :   if (base_ref.size_remaining () < pref->size_remaining ())
    1956                 :             :     /* Use the base object if it's smaller than the member.  */
    1957                 :         474 :     *pref = base_ref;
    1958                 :             : 
    1959                 :             :   return true;
    1960                 :             : }
    1961                 :             : 
    1962                 :             : /* A helper of compute_objsize_r() to determine the size from MEM_REF
    1963                 :             :    MREF.  Return true on success and false on failure.  */
    1964                 :             : 
    1965                 :             : static bool
    1966                 :     2516170 : handle_mem_ref (tree mref, gimple *stmt, int ostype, access_ref *pref,
    1967                 :             :                 ssa_name_limit_t &snlim, pointer_query *qry)
    1968                 :             : {
    1969                 :     2516170 :   gcc_assert (TREE_CODE (mref) == MEM_REF);
    1970                 :             : 
    1971                 :     2516170 :   tree mreftype = TYPE_MAIN_VARIANT (TREE_TYPE (mref));
    1972                 :     2516170 :   if (VECTOR_TYPE_P (mreftype))
    1973                 :             :       {
    1974                 :             :       /* Hack: Handle MEM_REFs of vector types as those to complete
    1975                 :             :          objects; those may be synthesized from multiple assignments
    1976                 :             :          to consecutive data members (see PR 93200 and 96963).
    1977                 :             :          FIXME: Vectorized assignments should only be present after
    1978                 :             :          vectorization so this hack is only necessary after it has
    1979                 :             :          run and could be avoided in calls from prior passes (e.g.,
    1980                 :             :          tree-ssa-strlen.cc).
    1981                 :             :          FIXME: Deal with this more generally, e.g., by marking up
    1982                 :             :          such MEM_REFs at the time they're created.  */
    1983                 :       62579 :       ostype = 0;
    1984                 :             :     }
    1985                 :             : 
    1986                 :     2516170 :   tree mrefop = TREE_OPERAND (mref, 0);
    1987                 :     2516170 :   if (!compute_objsize_r (mrefop, stmt, false, ostype, pref, snlim, qry))
    1988                 :             :     return false;
    1989                 :             : 
    1990                 :     2516161 :   ++pref->deref;
    1991                 :             : 
    1992                 :     2516161 :   offset_int orng[2];
    1993                 :     2516161 :   tree off = pref->eval (TREE_OPERAND (mref, 1));
    1994                 :     2516161 :   range_query *const rvals = qry ? qry->rvals : NULL;
    1995                 :     2516161 :   if (!get_offset_range (off, stmt, orng, rvals))
    1996                 :             :     {
    1997                 :             :       /* Set ORNG to the maximum offset representable in ptrdiff_t.  */
    1998                 :           0 :       orng[1] = wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node));
    1999                 :           0 :       orng[0] = -orng[1] - 1;
    2000                 :             :     }
    2001                 :             : 
    2002                 :     2516161 :   pref->add_offset (orng[0], orng[1]);
    2003                 :     2516161 :   return true;
    2004                 :             : }
    2005                 :             : 
    2006                 :             : /* A helper of compute_objsize_r() to determine the size from SSA_NAME
    2007                 :             :    PTR.  Return true on success and false on failure.  */
    2008                 :             : 
    2009                 :             : static bool
    2010                 :     5966384 : handle_ssa_name (tree ptr, bool addr, int ostype,
    2011                 :             :                  access_ref *pref, ssa_name_limit_t &snlim,
    2012                 :             :                  pointer_query *qry)
    2013                 :             : {
    2014                 :     5966384 :   if (!snlim.next ())
    2015                 :             :     return false;
    2016                 :             : 
    2017                 :             :   /* Only process an SSA_NAME if the recursion limit has not yet
    2018                 :             :      been reached.  */
    2019                 :     5966359 :   if (qry)
    2020                 :             :     {
    2021                 :     5966359 :       if (++qry->depth > qry->max_depth)
    2022                 :      667382 :         qry->max_depth = qry->depth;
    2023                 :     5966359 :       if (const access_ref *cache_ref = qry->get_ref (ptr, ostype))
    2024                 :             :         {
    2025                 :             :           /* Add the number of DEREFerences accummulated so far.  */
    2026                 :     1640889 :           const int deref = pref->deref;
    2027                 :     1640889 :           *pref = *cache_ref;
    2028                 :     1640889 :           pref->deref += deref;
    2029                 :     1640889 :           return true;
    2030                 :             :         }
    2031                 :             :     }
    2032                 :             : 
    2033                 :     4325470 :   gimple *stmt = SSA_NAME_DEF_STMT (ptr);
    2034                 :     4325470 :   if (is_gimple_call (stmt))
    2035                 :             :     {
    2036                 :             :       /* If STMT is a call to an allocation function get the size
    2037                 :             :          from its argument(s).  If successful, also set *PREF->REF
    2038                 :             :          to PTR for the caller to include in diagnostics.  */
    2039                 :     1923965 :       wide_int wr[2];
    2040                 :      384793 :       range_query *const rvals = qry ? qry->rvals : NULL;
    2041                 :      384793 :       if (gimple_call_alloc_size (stmt, wr, rvals))
    2042                 :             :         {
    2043                 :       84065 :           pref->ref = ptr;
    2044                 :       84065 :           pref->sizrng[0] = offset_int::from (wr[0], UNSIGNED);
    2045                 :       84065 :           pref->sizrng[1] = offset_int::from (wr[1], UNSIGNED);
    2046                 :             :           /* Constrain both bounds to a valid size.  */
    2047                 :       84065 :           offset_int maxsize = wi::to_offset (max_object_size ());
    2048                 :       84065 :           if (pref->sizrng[0] > maxsize)
    2049                 :         192 :             pref->sizrng[0] = maxsize;
    2050                 :       84065 :           if (pref->sizrng[1] > maxsize)
    2051                 :       11932 :             pref->sizrng[1] = maxsize;
    2052                 :             :         }
    2053                 :             :       else
    2054                 :             :         {
    2055                 :             :           /* For functions known to return one of their pointer arguments
    2056                 :             :              try to determine what the returned pointer points to, and on
    2057                 :             :              success add OFFRNG which was set to the offset added by
    2058                 :             :              the function (e.g., memchr) to the overall offset.  */
    2059                 :             :           bool past_end;
    2060                 :      300728 :           offset_int offrng[2];
    2061                 :      300728 :           if (tree ret = gimple_call_return_array (stmt, offrng, &past_end,
    2062                 :             :                                                    snlim, qry))
    2063                 :             :             {
    2064                 :       13143 :               if (!compute_objsize_r (ret, stmt, addr, ostype, pref, snlim, qry))
    2065                 :         204 :                 return false;
    2066                 :             : 
    2067                 :             :               /* Cap OFFRNG[1] to at most the remaining size of
    2068                 :             :                  the object.  */
    2069                 :       12939 :               offset_int remrng[2];
    2070                 :       12939 :               remrng[1] = pref->size_remaining (remrng);
    2071                 :       12939 :               if (remrng[1] != 0 && !past_end)
    2072                 :             :                 /* Decrement the size for functions that never return
    2073                 :             :                    a past-the-end pointer.  */
    2074                 :       12635 :                 remrng[1] -= 1;
    2075                 :             : 
    2076                 :       12939 :               if (remrng[1] < offrng[1])
    2077                 :         879 :                 offrng[1] = remrng[1];
    2078                 :       12939 :               pref->add_offset (offrng[0], offrng[1]);
    2079                 :             :             }
    2080                 :             :           else
    2081                 :             :             {
    2082                 :             :               /* For other calls that might return arbitrary pointers
    2083                 :             :                  including into the middle of objects set the size
    2084                 :             :                  range to maximum, clear PREF->BASE0, and also set
    2085                 :             :                  PREF->REF to include in diagnostics.  */
    2086                 :      287585 :               pref->set_max_size_range ();
    2087                 :      287585 :               pref->base0 = false;
    2088                 :      287585 :               pref->ref = ptr;
    2089                 :             :             }
    2090                 :             :         }
    2091                 :      384589 :       qry->put_ref (ptr, *pref, ostype);
    2092                 :      384589 :       return true;
    2093                 :     1154379 :     }
    2094                 :             : 
    2095                 :     3940677 :   if (gimple_nop_p (stmt))
    2096                 :             :     {
    2097                 :             :       /* For a function argument try to determine the byte size
    2098                 :             :          of the array from the current function declaratation
    2099                 :             :          (e.g., attribute access or related).  */
    2100                 :     3691360 :       wide_int wr[2];
    2101                 :      738272 :       bool static_array = false;
    2102                 :      738272 :       if (tree ref = gimple_parm_array_size (ptr, wr, &static_array))
    2103                 :             :         {
    2104                 :         190 :           pref->parmarray = !static_array;
    2105                 :         190 :           pref->sizrng[0] = offset_int::from (wr[0], UNSIGNED);
    2106                 :         190 :           pref->sizrng[1] = offset_int::from (wr[1], UNSIGNED);
    2107                 :         190 :           pref->ref = ref;
    2108                 :         190 :           qry->put_ref (ptr, *pref, ostype);
    2109                 :         190 :           return true;
    2110                 :             :         }
    2111                 :             : 
    2112                 :      738082 :       pref->set_max_size_range ();
    2113                 :      738082 :       pref->base0 = false;
    2114                 :      738082 :       pref->ref = ptr;
    2115                 :      738082 :       qry->put_ref (ptr, *pref, ostype);
    2116                 :      738082 :       return true;
    2117                 :     2214816 :     }
    2118                 :             : 
    2119                 :     3202405 :   if (gimple_code (stmt) == GIMPLE_PHI)
    2120                 :             :     {
    2121                 :             :       /* Pass PTR to get_ref() via PREF.  If all PHI arguments refer
    2122                 :             :          to the same object the function will replace it with it.  */
    2123                 :      538000 :       pref->ref = ptr;
    2124                 :      538000 :       access_ref phi_ref = *pref;
    2125                 :      538000 :       if (!pref->get_ref (NULL, &phi_ref, ostype, &snlim, qry))
    2126                 :             :         return false;
    2127                 :      480682 :       *pref = phi_ref;
    2128                 :      480682 :       qry->put_ref (ptr, *pref, ostype);
    2129                 :      480682 :       return true;
    2130                 :             :     }
    2131                 :             : 
    2132                 :     2664405 :   if (!is_gimple_assign (stmt))
    2133                 :             :     {
    2134                 :             :       /* Clear BASE0 since the assigned pointer might point into
    2135                 :             :          the middle of the object, set the maximum size range and,
    2136                 :             :          if the SSA_NAME refers to a function argumnent, set
    2137                 :             :          PREF->REF to it.  */
    2138                 :        8885 :       pref->base0 = false;
    2139                 :        8885 :       pref->set_max_size_range ();
    2140                 :        8885 :       pref->ref = ptr;
    2141                 :        8885 :       return true;
    2142                 :             :     }
    2143                 :             : 
    2144                 :     2655520 :   tree_code code = gimple_assign_rhs_code (stmt);
    2145                 :             : 
    2146                 :     2655520 :   if (code == MAX_EXPR || code == MIN_EXPR)
    2147                 :             :     {
    2148                 :         916 :       if (!handle_min_max_size (ptr, ostype, pref, snlim, qry))
    2149                 :             :         return false;
    2150                 :             : 
    2151                 :         916 :       qry->put_ref (ptr, *pref, ostype);
    2152                 :         916 :       return true;
    2153                 :             :     }
    2154                 :             : 
    2155                 :     2654604 :   tree rhs = gimple_assign_rhs1 (stmt);
    2156                 :             : 
    2157                 :     2654604 :   if (code == POINTER_PLUS_EXPR
    2158                 :     2654604 :       && TREE_CODE (TREE_TYPE (rhs)) == POINTER_TYPE)
    2159                 :             :     {
    2160                 :             :       /* Compute the size of the object first. */
    2161                 :      693666 :       if (!compute_objsize_r (rhs, stmt, addr, ostype, pref, snlim, qry))
    2162                 :             :         return false;
    2163                 :             : 
    2164                 :      649390 :       offset_int orng[2];
    2165                 :      649390 :       tree off = gimple_assign_rhs2 (stmt);
    2166                 :      649390 :       range_query *const rvals = qry ? qry->rvals : NULL;
    2167                 :      649390 :       if (get_offset_range (off, stmt, orng, rvals))
    2168                 :      412505 :         pref->add_offset (orng[0], orng[1]);
    2169                 :             :       else
    2170                 :      236885 :         pref->add_max_offset ();
    2171                 :             : 
    2172                 :      649390 :       qry->put_ref (ptr, *pref, ostype);
    2173                 :      649390 :       return true;
    2174                 :             :     }
    2175                 :             : 
    2176                 :     1960938 :   if (code == ADDR_EXPR || code == SSA_NAME)
    2177                 :             :     {
    2178                 :      469806 :       if (!compute_objsize_r (rhs, stmt, addr, ostype, pref, snlim, qry))
    2179                 :             :         return false;
    2180                 :      468643 :       qry->put_ref (ptr, *pref, ostype);
    2181                 :      468643 :       return true;
    2182                 :             :     }
    2183                 :             : 
    2184                 :     1491132 :   if (ostype > 1 && POINTER_TYPE_P (TREE_TYPE (rhs)))
    2185                 :             :     {
    2186                 :             :       /* When determining the qualifiers follow the pointer but
    2187                 :             :          avoid caching the result.  As the pointer is added to
    2188                 :             :          and/or dereferenced the computed size and offset need
    2189                 :             :          not be meaningful for other queries involving the same
    2190                 :             :          pointer.  */
    2191                 :           0 :       if (!compute_objsize_r (rhs, stmt, addr, ostype, pref, snlim, qry))
    2192                 :             :         return false;
    2193                 :             : 
    2194                 :           0 :       rhs = pref->ref;
    2195                 :             :     }
    2196                 :             : 
    2197                 :             :   /* (This could also be an assignment from a nonlocal pointer.)  Save
    2198                 :             :      PTR to mention in diagnostics but otherwise treat it as a pointer
    2199                 :             :      to an unknown object.  */
    2200                 :     1491132 :   pref->ref = rhs;
    2201                 :     1491132 :   pref->base0 = false;
    2202                 :     1491132 :   pref->set_max_size_range ();
    2203                 :     1491132 :   return true;
    2204                 :             : }
    2205                 :             : 
    2206                 :             : /* Helper to compute the size of the object referenced by the PTR
    2207                 :             :    expression which must have pointer type, using Object Size type
    2208                 :             :    OSTYPE (only the least significant 2 bits are used).
    2209                 :             :    On success, sets PREF->REF to the DECL of the referenced object
    2210                 :             :    if it's unique, otherwise to null, PREF->OFFRNG to the range of
    2211                 :             :    offsets into it, and PREF->SIZRNG to the range of sizes of
    2212                 :             :    the object(s).
    2213                 :             :    ADDR is true for an enclosing ADDR_EXPR.
    2214                 :             :    SNLIM is used to avoid visiting the same PHI operand multiple
    2215                 :             :    times, and, when nonnull, RVALS to determine range information.
    2216                 :             :    Returns true on success, false when a meaningful size (or range)
    2217                 :             :    cannot be determined.
    2218                 :             : 
    2219                 :             :    The function is intended for diagnostics and should not be used
    2220                 :             :    to influence code generation or optimization.  */
    2221                 :             : 
    2222                 :             : static bool
    2223                 :    19132359 : compute_objsize_r (tree ptr, gimple *stmt, bool addr, int ostype,
    2224                 :             :                    access_ref *pref, ssa_name_limit_t &snlim,
    2225                 :             :                    pointer_query *qry)
    2226                 :             : {
    2227                 :    19132359 :   STRIP_NOPS (ptr);
    2228                 :             : 
    2229                 :    19132359 :   if (DECL_P (ptr))
    2230                 :     4661023 :     return handle_decl (ptr, addr, pref);
    2231                 :             : 
    2232                 :    14471336 :   switch (TREE_CODE (ptr))
    2233                 :             :     {
    2234                 :     1597946 :     case ADDR_EXPR:
    2235                 :     1597946 :       {
    2236                 :     1597946 :         tree ref = TREE_OPERAND (ptr, 0);
    2237                 :     1597946 :         if (!compute_objsize_r (ref, stmt, true, ostype, pref, snlim, qry))
    2238                 :             :           return false;
    2239                 :             : 
    2240                 :     1597946 :         --pref->deref;
    2241                 :     1597946 :         return true;
    2242                 :             :       }
    2243                 :             : 
    2244                 :        4240 :     case BIT_FIELD_REF:
    2245                 :        4240 :       {
    2246                 :        4240 :         tree ref = TREE_OPERAND (ptr, 0);
    2247                 :        4240 :         if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
    2248                 :             :           return false;
    2249                 :             : 
    2250                 :        4240 :         offset_int off = wi::to_offset (pref->eval (TREE_OPERAND (ptr, 2)));
    2251                 :        4240 :         pref->add_offset (off / BITS_PER_UNIT);
    2252                 :        4240 :         return true;
    2253                 :             :       }
    2254                 :             : 
    2255                 :      818151 :     case ARRAY_REF:
    2256                 :      818151 :       return handle_array_ref (ptr, stmt, addr, ostype, pref, snlim, qry);
    2257                 :             : 
    2258                 :     2942822 :     case COMPONENT_REF:
    2259                 :     2942822 :       return handle_component_ref (ptr, stmt, addr, ostype, pref, snlim, qry);
    2260                 :             : 
    2261                 :     2516170 :     case MEM_REF:
    2262                 :     2516170 :       return handle_mem_ref (ptr, stmt, ostype, pref, snlim, qry);
    2263                 :             : 
    2264                 :       11910 :     case TARGET_MEM_REF:
    2265                 :       11910 :       {
    2266                 :       11910 :         tree ref = TREE_OPERAND (ptr, 0);
    2267                 :       11910 :         if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
    2268                 :             :           return false;
    2269                 :             : 
    2270                 :             :         /* TODO: Handle remaining operands.  Until then, add maximum offset.  */
    2271                 :       11910 :         pref->ref = ptr;
    2272                 :       11910 :         pref->add_max_offset ();
    2273                 :       11910 :         return true;
    2274                 :             :       }
    2275                 :             : 
    2276                 :      283846 :     case INTEGER_CST:
    2277                 :             :       /* Pointer constants other than null smaller than param_min_pagesize
    2278                 :             :          might be the result of erroneous null pointer addition/subtraction.
    2279                 :             :          Unless zero is a valid address set size to zero.  For null pointers,
    2280                 :             :          set size to the maximum for now since those may be the result of
    2281                 :             :          jump threading.  Similarly, for values >= param_min_pagesize in
    2282                 :             :          order to support (type *) 0x7cdeab00.  */
    2283                 :      283846 :       if (integer_zerop (ptr)
    2284                 :      328121 :           || wi::to_widest (ptr) >= param_min_pagesize)
    2285                 :      242427 :         pref->set_max_size_range ();
    2286                 :       41419 :       else if (POINTER_TYPE_P (TREE_TYPE (ptr)))
    2287                 :             :         {
    2288                 :         515 :           tree deref_type = TREE_TYPE (TREE_TYPE (ptr));
    2289                 :         515 :           addr_space_t as = TYPE_ADDR_SPACE (deref_type);
    2290                 :         515 :           if (targetm.addr_space.zero_address_valid (as))
    2291                 :           0 :             pref->set_max_size_range ();
    2292                 :             :           else
    2293                 :             :             {
    2294                 :         515 :               pref->sizrng[0] = pref->sizrng[1] = 0;
    2295                 :         515 :               pref->ref_nullptr_p = true;
    2296                 :             :             }
    2297                 :             :         }
    2298                 :             :       else
    2299                 :       40904 :         pref->sizrng[0] = pref->sizrng[1] = 0;
    2300                 :             : 
    2301                 :      283846 :       pref->ref = ptr;
    2302                 :      283846 :       return true;
    2303                 :             : 
    2304                 :      270858 :     case STRING_CST:
    2305                 :      270858 :       pref->sizrng[0] = pref->sizrng[1] = TREE_STRING_LENGTH (ptr);
    2306                 :      270858 :       pref->ref = ptr;
    2307                 :      270858 :       return true;
    2308                 :             : 
    2309                 :         639 :     case POINTER_PLUS_EXPR:
    2310                 :         639 :     {
    2311                 :         639 :       tree ref = TREE_OPERAND (ptr, 0);
    2312                 :         639 :       if (!compute_objsize_r (ref, stmt, addr, ostype, pref, snlim, qry))
    2313                 :             :         return false;
    2314                 :             : 
    2315                 :             :       /* The below only makes sense if the offset is being applied to the
    2316                 :             :          address of the object.  */
    2317                 :         639 :       if (pref->deref != -1)
    2318                 :             :         return false;
    2319                 :             : 
    2320                 :         580 :       offset_int orng[2];
    2321                 :         580 :       tree off = pref->eval (TREE_OPERAND (ptr, 1));
    2322                 :         580 :       if (get_offset_range (off, stmt, orng, qry->rvals))
    2323                 :         568 :         pref->add_offset (orng[0], orng[1]);
    2324                 :             :       else
    2325                 :          12 :         pref->add_max_offset ();
    2326                 :             :       return true;
    2327                 :             :     }
    2328                 :             : 
    2329                 :         483 :     case VIEW_CONVERT_EXPR:
    2330                 :         483 :       ptr = TREE_OPERAND (ptr, 0);
    2331                 :         483 :       return compute_objsize_r (ptr, stmt, addr, ostype, pref, snlim, qry);
    2332                 :             : 
    2333                 :     5966384 :     case SSA_NAME:
    2334                 :     5966384 :       return handle_ssa_name (ptr, addr, ostype, pref, snlim, qry);
    2335                 :             : 
    2336                 :       57887 :     default:
    2337                 :       57887 :       break;
    2338                 :             :     }
    2339                 :             : 
    2340                 :             :   /* Assume all other expressions point into an unknown object
    2341                 :             :      of the maximum valid size.  */
    2342                 :       57887 :   pref->ref = ptr;
    2343                 :       57887 :   pref->base0 = false;
    2344                 :       57887 :   pref->set_max_size_range ();
    2345                 :       57887 :   if (TREE_CODE (ptr) == SSA_NAME)
    2346                 :           0 :     qry->put_ref (ptr, *pref);
    2347                 :             :   return true;
    2348                 :             : }
    2349                 :             : 
    2350                 :             : /* A "public" wrapper around the above.  Clients should use this overload
    2351                 :             :    instead.  */
    2352                 :             : 
    2353                 :             : tree
    2354                 :     9469883 : compute_objsize (tree ptr, gimple *stmt, int ostype, access_ref *pref,
    2355                 :             :                  pointer_query *ptr_qry)
    2356                 :             : {
    2357                 :     9469883 :   pointer_query qry;
    2358                 :     9469883 :   if (ptr_qry)
    2359                 :     9468678 :     ptr_qry->depth = 0;
    2360                 :             :   else
    2361                 :             :     ptr_qry = &qry;
    2362                 :             : 
    2363                 :             :   /* Clear and invalidate in case *PREF is being reused.  */
    2364                 :     9469883 :   pref->offrng[0] = pref->offrng[1] = 0;
    2365                 :     9469883 :   pref->sizrng[0] = pref->sizrng[1] = -1;
    2366                 :             : 
    2367                 :     9469883 :   ssa_name_limit_t snlim;
    2368                 :     9469883 :   if (!compute_objsize_r (ptr, stmt, false, ostype, pref, snlim, ptr_qry))
    2369                 :             :     return NULL_TREE;
    2370                 :             : 
    2371                 :     9459783 :   offset_int maxsize = pref->size_remaining ();
    2372                 :     9459783 :   if (pref->base0 && pref->offrng[0] < 0 && pref->offrng[1] >= 0)
    2373                 :          96 :     pref->offrng[0] = 0;
    2374                 :     9459783 :   return wide_int_to_tree (sizetype, maxsize);
    2375                 :     9469883 : }
    2376                 :             : 
    2377                 :             : /* Transitional wrapper.  The function should be removed once callers
    2378                 :             :    transition to the pointer_query API.  */
    2379                 :             : 
    2380                 :             : tree
    2381                 :      308658 : compute_objsize (tree ptr, gimple *stmt, int ostype, access_ref *pref,
    2382                 :             :                  range_query *rvals /* = NULL */)
    2383                 :             : {
    2384                 :      308658 :   pointer_query qry;
    2385                 :      308658 :   qry.rvals = rvals;
    2386                 :      308658 :   return compute_objsize (ptr, stmt, ostype, pref, &qry);
    2387                 :      308658 : }
    2388                 :             : 
    2389                 :             : /* Legacy wrapper around the above.  The function should be removed
    2390                 :             :    once callers transition to one of the two above.  */
    2391                 :             : 
    2392                 :             : tree
    2393                 :           0 : compute_objsize (tree ptr, gimple *stmt, int ostype, tree *pdecl /* = NULL */,
    2394                 :             :                  tree *poff /* = NULL */, range_query *rvals /* = NULL */)
    2395                 :             : {
    2396                 :             :   /* Set the initial offsets to zero and size to negative to indicate
    2397                 :             :      none has been computed yet.  */
    2398                 :           0 :   access_ref ref;
    2399                 :           0 :   tree size = compute_objsize (ptr, stmt, ostype, &ref, rvals);
    2400                 :           0 :   if (!size || !ref.base0)
    2401                 :             :     return NULL_TREE;
    2402                 :             : 
    2403                 :           0 :   if (pdecl)
    2404                 :           0 :     *pdecl = ref.ref;
    2405                 :             : 
    2406                 :           0 :   if (poff)
    2407                 :           0 :     *poff = wide_int_to_tree (ptrdiff_type_node, ref.offrng[ref.offrng[0] < 0]);
    2408                 :             : 
    2409                 :             :   return size;
    2410                 :             : }
    2411                 :             : 
    2412                 :             : /* Determine the offset *FLDOFF of the first byte of a struct member
    2413                 :             :    of TYPE (possibly recursively) into which the byte offset OFF points,
    2414                 :             :    starting after the field START_AFTER if it's non-null.  On success,
    2415                 :             :    if nonnull, set *FLDOFF to the offset of the first byte, and return
    2416                 :             :    the field decl.  If nonnull, set *NEXTOFF to the offset of the next
    2417                 :             :    field (which reflects any padding between the returned field and
    2418                 :             :    the next).  Otherwise, if no such member can be found, return null.  */
    2419                 :             : 
    2420                 :             : tree
    2421                 :        1404 : field_at_offset (tree type, tree start_after, HOST_WIDE_INT off,
    2422                 :             :                  HOST_WIDE_INT *fldoff /* = nullptr */,
    2423                 :             :                  HOST_WIDE_INT *nextoff /* = nullptr */)
    2424                 :             : {
    2425                 :        1404 :   tree first_fld = TYPE_FIELDS (type);
    2426                 :             : 
    2427                 :        1404 :   HOST_WIDE_INT offbuf = 0, nextbuf = 0;
    2428                 :        1404 :   if (!fldoff)
    2429                 :           9 :     fldoff = &offbuf;
    2430                 :        1404 :   if (!nextoff)
    2431                 :         556 :     nextoff = &nextbuf;
    2432                 :             : 
    2433                 :        1404 :   *nextoff = 0;
    2434                 :             : 
    2435                 :             :   /* The field to return.  */
    2436                 :        1404 :   tree last_fld = NULL_TREE;
    2437                 :             :   /* The next field to advance to.  */
    2438                 :        1404 :   tree next_fld = NULL_TREE;
    2439                 :             : 
    2440                 :             :   /* NEXT_FLD's cached offset.  */
    2441                 :        1404 :   HOST_WIDE_INT next_pos = -1;
    2442                 :             : 
    2443                 :        1664 :   for (tree fld = first_fld; fld; fld = next_fld)
    2444                 :             :     {
    2445                 :             :       next_fld = fld;
    2446                 :        1645 :       do
    2447                 :             :         /* Advance to the next relevant data member.  */
    2448                 :        1645 :         next_fld = TREE_CHAIN (next_fld);
    2449                 :             :       while (next_fld
    2450                 :        3170 :              && (TREE_CODE (next_fld) != FIELD_DECL
    2451                 :        1525 :                  || DECL_ARTIFICIAL (next_fld)));
    2452                 :             : 
    2453                 :        1645 :       if (TREE_CODE (fld) != FIELD_DECL || DECL_ARTIFICIAL (fld))
    2454                 :           0 :         continue;
    2455                 :             : 
    2456                 :        1645 :       if (fld == start_after)
    2457                 :           0 :         continue;
    2458                 :             : 
    2459                 :        1645 :       tree fldtype = TREE_TYPE (fld);
    2460                 :             :       /* The offset of FLD within its immediately enclosing structure.  */
    2461                 :        1645 :       HOST_WIDE_INT fldpos = next_pos < 0 ? int_byte_position (fld) : next_pos;
    2462                 :             : 
    2463                 :        1645 :       tree typesize = TYPE_SIZE_UNIT (fldtype);
    2464                 :        1645 :       if (typesize && TREE_CODE (typesize) != INTEGER_CST)
    2465                 :             :         /* Bail if FLD is a variable length member.  */
    2466                 :             :         return NULL_TREE;
    2467                 :             : 
    2468                 :             :       /* If the size is not available the field is a flexible array
    2469                 :             :          member.  Treat this case as success.  */
    2470                 :        3290 :       HOST_WIDE_INT fldsize = (tree_fits_uhwi_p (typesize)
    2471                 :        1645 :                                ? tree_to_uhwi (typesize)
    2472                 :             :                                : off);
    2473                 :             : 
    2474                 :             :       /* If OFF is beyond the end of the current field continue.  */
    2475                 :        1645 :       HOST_WIDE_INT fldend = fldpos + fldsize;
    2476                 :        1645 :       if (fldend < off)
    2477                 :         236 :         continue;
    2478                 :             : 
    2479                 :        1409 :       if (next_fld)
    2480                 :             :         {
    2481                 :             :           /* If OFF is equal to the offset of the next field continue
    2482                 :             :              to it and skip the array/struct business below.  */
    2483                 :        1303 :           tree pos = byte_position (next_fld);
    2484                 :        1303 :           if (!tree_fits_shwi_p (pos))
    2485                 :             :             /* Bail if NEXT_FLD is a variable length member.  */
    2486                 :             :             return NULL_TREE;
    2487                 :        1303 :           next_pos = tree_to_shwi (pos);
    2488                 :        1303 :           *nextoff = *fldoff + next_pos;
    2489                 :        1303 :           if (*nextoff == off && TREE_CODE (type) != UNION_TYPE)
    2490                 :          19 :             continue;
    2491                 :             :         }
    2492                 :             :       else
    2493                 :         106 :         *nextoff = HOST_WIDE_INT_MAX;
    2494                 :             : 
    2495                 :             :       /* OFF refers somewhere into the current field or just past its end,
    2496                 :             :          which could mean it refers to the next field.  */
    2497                 :        1390 :       if (TREE_CODE (fldtype) == ARRAY_TYPE)
    2498                 :             :         {
    2499                 :             :           /* Will be set to the offset of the first byte of the array
    2500                 :             :              element (which may be an array) of FLDTYPE into which
    2501                 :             :              OFF - FLDPOS points (which may be past ELTOFF).  */
    2502                 :         549 :           HOST_WIDE_INT eltoff = 0;
    2503                 :         549 :           if (tree ft = array_elt_at_offset (fldtype, off - fldpos, &eltoff))
    2504                 :         549 :             fldtype = ft;
    2505                 :             :           else
    2506                 :           0 :             continue;
    2507                 :             : 
    2508                 :             :           /* Advance the position to include the array element above.
    2509                 :             :              If OFF - FLPOS refers to a member of FLDTYPE, the member
    2510                 :             :              will be determined below.  */
    2511                 :         549 :           fldpos += eltoff;
    2512                 :             :         }
    2513                 :             : 
    2514                 :        1390 :       *fldoff += fldpos;
    2515                 :             : 
    2516                 :        1390 :       if (TREE_CODE (fldtype) == RECORD_TYPE)
    2517                 :             :         /* Drill down into the current field if it's a struct.  */
    2518                 :         848 :         fld = field_at_offset (fldtype, start_after, off - fldpos,
    2519                 :             :                                fldoff, nextoff);
    2520                 :             : 
    2521                 :        1390 :       last_fld = fld;
    2522                 :             : 
    2523                 :             :       /* Unless the offset is just past the end of the field return it.
    2524                 :             :          Otherwise save it and return it only if the offset of the next
    2525                 :             :          next field is greater (i.e., there is padding between the two)
    2526                 :             :          or if there is no next field.  */
    2527                 :        1390 :       if (off < fldend)
    2528                 :             :         break;
    2529                 :             :     }
    2530                 :             : 
    2531                 :        1404 :   if (*nextoff == HOST_WIDE_INT_MAX && next_fld)
    2532                 :          35 :     *nextoff = next_pos;
    2533                 :             : 
    2534                 :             :   return last_fld;
    2535                 :             : }
    2536                 :             : 
    2537                 :             : /* Determine the offset *ELTOFF of the first byte of the array element
    2538                 :             :    of array ARTYPE into which the byte offset OFF points.  On success
    2539                 :             :    set *ELTOFF to the offset of the first byte and return type.
    2540                 :             :    Otherwise, if no such element can be found, return null.  */
    2541                 :             : 
    2542                 :             : tree
    2543                 :         581 : array_elt_at_offset (tree artype, HOST_WIDE_INT off,
    2544                 :             :                      HOST_WIDE_INT *eltoff /* = nullptr */,
    2545                 :             :                      HOST_WIDE_INT *subar_size /* = nullptr */)
    2546                 :             : {
    2547                 :         581 :   gcc_assert (TREE_CODE (artype) == ARRAY_TYPE);
    2548                 :             : 
    2549                 :         581 :   HOST_WIDE_INT dummy;
    2550                 :         581 :   if (!eltoff)
    2551                 :           0 :     eltoff = &dummy;
    2552                 :         581 :   if (!subar_size)
    2553                 :         549 :     subar_size = &dummy;
    2554                 :             : 
    2555                 :         581 :   tree eltype = artype;
    2556                 :         613 :   while (TREE_CODE (TREE_TYPE (eltype)) == ARRAY_TYPE)
    2557                 :          32 :     eltype = TREE_TYPE (eltype);
    2558                 :             : 
    2559                 :         581 :   tree subartype = eltype;
    2560                 :         581 :   if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (eltype))
    2561                 :         565 :       || TYPE_MODE (TREE_TYPE (eltype)) != TYPE_MODE (char_type_node))
    2562                 :          16 :     eltype = TREE_TYPE (eltype);
    2563                 :             : 
    2564                 :         581 :   *subar_size = int_size_in_bytes (subartype);
    2565                 :             : 
    2566                 :         581 :   if (eltype == artype)
    2567                 :             :     {
    2568                 :         533 :       *eltoff = 0;
    2569                 :         533 :       return artype;
    2570                 :             :     }
    2571                 :             : 
    2572                 :          48 :   HOST_WIDE_INT artype_size = int_size_in_bytes (artype);
    2573                 :          48 :   HOST_WIDE_INT eltype_size = int_size_in_bytes (eltype);
    2574                 :             : 
    2575                 :          48 :   if (off < artype_size)// * eltype_size)
    2576                 :             :     {
    2577                 :          32 :       *eltoff = (off / eltype_size) * eltype_size;
    2578                 :          32 :       return TREE_CODE (eltype) == ARRAY_TYPE ? TREE_TYPE (eltype) : eltype;
    2579                 :             :     }
    2580                 :             : 
    2581                 :             :   return NULL_TREE;
    2582                 :             : }
    2583                 :             : 
    2584                 :             : /* Wrapper around build_array_type_nelts that makes sure the array
    2585                 :             :    can be created at all and handles zero sized arrays specially.  */
    2586                 :             : 
    2587                 :             : tree
    2588                 :       11217 : build_printable_array_type (tree eltype, unsigned HOST_WIDE_INT nelts)
    2589                 :             : {
    2590                 :       11217 :   if (TYPE_SIZE_UNIT (eltype)
    2591                 :       11212 :       && TREE_CODE (TYPE_SIZE_UNIT (eltype)) == INTEGER_CST
    2592                 :       11195 :       && !integer_zerop (TYPE_SIZE_UNIT (eltype))
    2593                 :       11093 :       && TYPE_ALIGN_UNIT (eltype) > 1
    2594                 :       27501 :       && wi::zext (wi::to_wide (TYPE_SIZE_UNIT (eltype)),
    2595                 :       27501 :                    ffs_hwi (TYPE_ALIGN_UNIT (eltype)) - 1) != 0)
    2596                 :           4 :     eltype = TYPE_MAIN_VARIANT (eltype);
    2597                 :             : 
    2598                 :             :   /* Consider excessive NELTS an array of unknown bound.  */
    2599                 :       11217 :   tree idxtype = NULL_TREE;
    2600                 :       11217 :   if (nelts < HOST_WIDE_INT_MAX)
    2601                 :             :     {
    2602                 :       11182 :       if (nelts)
    2603                 :       10557 :         return build_array_type_nelts (eltype, nelts);
    2604                 :         625 :       idxtype = build_range_type (sizetype, size_zero_node, NULL_TREE);
    2605                 :             :     }
    2606                 :             : 
    2607                 :         660 :   tree arrtype = build_array_type (eltype, idxtype);
    2608                 :         660 :   arrtype = build_distinct_type_copy (TYPE_MAIN_VARIANT (arrtype));
    2609                 :         660 :   TYPE_SIZE (arrtype) = bitsize_zero_node;
    2610                 :         660 :   TYPE_SIZE_UNIT (arrtype) = size_zero_node;
    2611                 :         660 :   return arrtype;
    2612                 :             : }
        

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.