(root)/
grep-3.11/
gnulib-tests/
test-calloc-gnu.c
       1  /* Test of calloc function.
       2     Copyright (C) 2010-2023 Free Software Foundation, Inc.
       3  
       4     This program is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU General Public License as published by
       6     the Free Software Foundation, either version 3 of the License, or
       7     (at your option) any later version.
       8  
       9     This program is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU General Public License for more details.
      13  
      14     You should have received a copy of the GNU General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  #include <config.h>
      18  
      19  /* Specification.  */
      20  #include <stdlib.h>
      21  
      22  #include <errno.h>
      23  #include <stdint.h>
      24  
      25  #include "macros.h"
      26  
      27  /* Return N.
      28     Usual compilers are not able to infer something about the return value.  */
      29  static size_t
      30  identity (size_t n)
      31  {
      32    unsigned int x = rand ();
      33    unsigned int y = x * x * x * x;
      34    x++; y |= x * x * x * x;
      35    x++; y |= x * x * x * x;
      36    x++; y |= x * x * x * x;
      37    y = y >> 1;
      38    y &= -y;
      39    y -= 8;
      40    /* At this point Y is zero but GCC doesn't infer this.  */
      41    return n + y;
      42  }
      43  
      44  int
      45  main ()
      46  {
      47    /* Check that calloc (0, 0) is not a NULL pointer.  */
      48    {
      49      void * volatile p = calloc (0, 0);
      50      ASSERT (p != NULL);
      51      free (p);
      52    }
      53  
      54    /* Check that calloc fails when requested to allocate a block of memory
      55       larger than PTRDIFF_MAX or SIZE_MAX bytes.
      56       Use 'identity' to avoid a compiler warning from GCC 7.
      57       'volatile' is needed to defeat an incorrect optimization by clang 10,
      58       see <https://bugs.llvm.org/show_bug.cgi?id=46055>.  */
      59    {
      60      for (size_t n = 2; n != 0; n <<= 1)
      61        {
      62          void *volatile p = calloc (PTRDIFF_MAX / n + 1, identity (n));
      63          ASSERT (p == NULL);
      64          ASSERT (errno == ENOMEM);
      65  
      66          p = calloc (SIZE_MAX / n + 1, identity (n));
      67          ASSERT (p == NULL);
      68          ASSERT (errno == ENOMEM);
      69        }
      70    }
      71  
      72    return 0;
      73  }