(root)/
bison-3.8.2/
lib/
xmalloc.c
       1  /* xmalloc.c -- malloc with out of memory checking
       2  
       3     Copyright (C) 1990-2000, 2002-2006, 2008-2021 Free Software Foundation, Inc.
       4  
       5     This program is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU General Public License as published by
       7     the Free Software Foundation; either version 3 of the License, or
       8     (at your option) any later version.
       9  
      10     This program is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU General Public License for more details.
      14  
      15     You should have received a copy of the GNU General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <config.h>
      19  
      20  #define XALLOC_INLINE _GL_EXTERN_INLINE
      21  
      22  #include "xalloc.h"
      23  
      24  #include "ialloc.h"
      25  #include "intprops.h"
      26  #include "minmax.h"
      27  
      28  #include <stdlib.h>
      29  #include <string.h>
      30  
      31  static void * _GL_ATTRIBUTE_PURE
      32  nonnull (void *p)
      33  {
      34    if (!p)
      35      xalloc_die ();
      36    return p;
      37  }
      38  
      39  /* Allocate S bytes of memory dynamically, with error checking.  */
      40  
      41  void *
      42  xmalloc (size_t s)
      43  {
      44    return nonnull (malloc (s));
      45  }
      46  
      47  void *
      48  ximalloc (idx_t s)
      49  {
      50    return nonnull (imalloc (s));
      51  }
      52  
      53  char *
      54  xcharalloc (size_t n)
      55  {
      56    return XNMALLOC (n, char);
      57  }
      58  
      59  /* Change the size of an allocated block of memory P to S bytes,
      60     with error checking.  */
      61  
      62  void *
      63  xrealloc (void *p, size_t s)
      64  {
      65    void *r = realloc (p, s);
      66    if (!r && (!p || s))
      67      xalloc_die ();
      68    return r;
      69  }
      70  
      71  void *
      72  xirealloc (void *p, idx_t s)
      73  {
      74    return nonnull (irealloc (p, s));
      75  }
      76  
      77  /* Change the size of an allocated block of memory P to an array of N
      78     objects each of S bytes, with error checking.  */
      79  
      80  void *
      81  xreallocarray (void *p, size_t n, size_t s)
      82  {
      83    void *r = reallocarray (p, n, s);
      84    if (!r && (!p || (n && s)))
      85      xalloc_die ();
      86    return r;
      87  }
      88  
      89  void *
      90  xireallocarray (void *p, idx_t n, idx_t s)
      91  {
      92    return nonnull (ireallocarray (p, n, s));
      93  }
      94  
      95  /* Allocate an array of N objects, each with S bytes of memory,
      96     dynamically, with error checking.  S must be nonzero.  */
      97  
      98  void *
      99  xnmalloc (size_t n, size_t s)
     100  {
     101    return xreallocarray (NULL, n, s);
     102  }
     103  
     104  /* If P is null, allocate a block of at least *PS bytes; otherwise,
     105     reallocate P so that it contains more than *PS bytes.  *PS must be
     106     nonzero unless P is null.  Set *PS to the new block's size, and
     107     return the pointer to the new block.  *PS is never set to zero, and
     108     the returned pointer is never null.  */
     109  
     110  void *
     111  x2realloc (void *p, size_t *ps)
     112  {
     113    return x2nrealloc (p, ps, 1);
     114  }
     115  
     116  /* If P is null, allocate a block of at least *PN such objects;
     117     otherwise, reallocate P so that it contains more than *PN objects
     118     each of S bytes.  S must be nonzero.  Set *PN to the new number of
     119     objects, and return the pointer to the new block.  *PN is never set
     120     to zero, and the returned pointer is never null.
     121  
     122     Repeated reallocations are guaranteed to make progress, either by
     123     allocating an initial block with a nonzero size, or by allocating a
     124     larger block.
     125  
     126     In the following implementation, nonzero sizes are increased by a
     127     factor of approximately 1.5 so that repeated reallocations have
     128     O(N) overall cost rather than O(N**2) cost, but the
     129     specification for this function does not guarantee that rate.
     130  
     131     Here is an example of use:
     132  
     133       int *p = NULL;
     134       size_t used = 0;
     135       size_t allocated = 0;
     136  
     137       void
     138       append_int (int value)
     139         {
     140           if (used == allocated)
     141             p = x2nrealloc (p, &allocated, sizeof *p);
     142           p[used++] = value;
     143         }
     144  
     145     This causes x2nrealloc to allocate a block of some nonzero size the
     146     first time it is called.
     147  
     148     To have finer-grained control over the initial size, set *PN to a
     149     nonzero value before calling this function with P == NULL.  For
     150     example:
     151  
     152       int *p = NULL;
     153       size_t used = 0;
     154       size_t allocated = 0;
     155       size_t allocated1 = 1000;
     156  
     157       void
     158       append_int (int value)
     159         {
     160           if (used == allocated)
     161             {
     162               p = x2nrealloc (p, &allocated1, sizeof *p);
     163               allocated = allocated1;
     164             }
     165           p[used++] = value;
     166         }
     167  
     168     */
     169  
     170  void *
     171  x2nrealloc (void *p, size_t *pn, size_t s)
     172  {
     173    size_t n = *pn;
     174  
     175    if (! p)
     176      {
     177        if (! n)
     178          {
     179            /* The approximate size to use for initial small allocation
     180               requests, when the invoking code specifies an old size of
     181               zero.  This is the largest "small" request for the GNU C
     182               library malloc.  */
     183            enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
     184  
     185            n = DEFAULT_MXFAST / s;
     186            n += !n;
     187          }
     188      }
     189    else
     190      {
     191        /* Set N = floor (1.5 * N) + 1 to make progress even if N == 0.  */
     192        if (INT_ADD_WRAPV (n, (n >> 1) + 1, &n))
     193          xalloc_die ();
     194      }
     195  
     196    p = xreallocarray (p, n, s);
     197    *pn = n;
     198    return p;
     199  }
     200  
     201  /* Grow PA, which points to an array of *PN items, and return the
     202     location of the reallocated array, updating *PN to reflect its
     203     new size.  The new array will contain at least N_INCR_MIN more
     204     items, but will not contain more than N_MAX items total.
     205     S is the size of each item, in bytes.
     206  
     207     S and N_INCR_MIN must be positive.  *PN must be
     208     nonnegative.  If N_MAX is -1, it is treated as if it were
     209     infinity.
     210  
     211     If PA is null, then allocate a new array instead of reallocating
     212     the old one.
     213  
     214     Thus, to grow an array A without saving its old contents, do
     215     { free (A); A = xpalloc (NULL, &AITEMS, ...); }.  */
     216  
     217  void *
     218  xpalloc (void *pa, idx_t *pn, idx_t n_incr_min, ptrdiff_t n_max, idx_t s)
     219  {
     220    idx_t n0 = *pn;
     221  
     222    /* The approximate size to use for initial small allocation
     223       requests.  This is the largest "small" request for the GNU C
     224       library malloc.  */
     225    enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
     226  
     227    /* If the array is tiny, grow it to about (but no greater than)
     228       DEFAULT_MXFAST bytes.  Otherwise, grow it by about 50%.
     229       Adjust the growth according to three constraints: N_INCR_MIN,
     230       N_MAX, and what the C language can represent safely.  */
     231  
     232    idx_t n;
     233    if (INT_ADD_WRAPV (n0, n0 >> 1, &n))
     234      n = IDX_MAX;
     235    if (0 <= n_max && n_max < n)
     236      n = n_max;
     237  
     238    /* NBYTES is of a type suitable for holding the count of bytes in an object.
     239       This is typically idx_t, but it should be size_t on (theoretical?)
     240       platforms where SIZE_MAX < IDX_MAX so xpalloc does not pass
     241       values greater than SIZE_MAX to xrealloc.  */
     242  #if IDX_MAX <= SIZE_MAX
     243    idx_t nbytes;
     244  #else
     245    size_t nbytes;
     246  #endif
     247    idx_t adjusted_nbytes
     248      = (INT_MULTIPLY_WRAPV (n, s, &nbytes)
     249         ? MIN (IDX_MAX, SIZE_MAX)
     250         : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0);
     251    if (adjusted_nbytes)
     252      {
     253        n = adjusted_nbytes / s;
     254        nbytes = adjusted_nbytes - adjusted_nbytes % s;
     255      }
     256  
     257    if (! pa)
     258      *pn = 0;
     259    if (n - n0 < n_incr_min
     260        && (INT_ADD_WRAPV (n0, n_incr_min, &n)
     261            || (0 <= n_max && n_max < n)
     262            || INT_MULTIPLY_WRAPV (n, s, &nbytes)))
     263      xalloc_die ();
     264    pa = xrealloc (pa, nbytes);
     265    *pn = n;
     266    return pa;
     267  }
     268  
     269  /* Allocate S bytes of zeroed memory dynamically, with error checking.
     270     There's no need for xnzalloc (N, S), since it would be equivalent
     271     to xcalloc (N, S).  */
     272  
     273  void *
     274  xzalloc (size_t s)
     275  {
     276    return xcalloc (s, 1);
     277  }
     278  
     279  void *
     280  xizalloc (idx_t s)
     281  {
     282    return xicalloc (s, 1);
     283  }
     284  
     285  /* Allocate zeroed memory for N elements of S bytes, with error
     286     checking.  S must be nonzero.  */
     287  
     288  void *
     289  xcalloc (size_t n, size_t s)
     290  {
     291    return nonnull (calloc (n, s));
     292  }
     293  
     294  void *
     295  xicalloc (idx_t n, idx_t s)
     296  {
     297    return nonnull (icalloc (n, s));
     298  }
     299  
     300  /* Clone an object P of size S, with error checking.  There's no need
     301     for xnmemdup (P, N, S), since xmemdup (P, N * S) works without any
     302     need for an arithmetic overflow check.  */
     303  
     304  void *
     305  xmemdup (void const *p, size_t s)
     306  {
     307    return memcpy (xmalloc (s), p, s);
     308  }
     309  
     310  void *
     311  ximemdup (void const *p, idx_t s)
     312  {
     313    return memcpy (ximalloc (s), p, s);
     314  }
     315  
     316  /* Clone an object P of size S, with error checking.  Append
     317     a terminating NUL byte.  */
     318  
     319  char *
     320  ximemdup0 (void const *p, idx_t s)
     321  {
     322    char *result = ximalloc (s + 1);
     323    result[s] = 0;
     324    return memcpy (result, p, s);
     325  }
     326  
     327  /* Clone STRING.  */
     328  
     329  char *
     330  xstrdup (char const *string)
     331  {
     332    return xmemdup (string, strlen (string) + 1);
     333  }