(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstringop-overflow-49.c
       1  /* Verify the handling of anti-ranges/multi-ranges by allocation functions
       2     and subsequent accesses.
       3     { dg-do compile }
       4     { dg-options "-O2" } */
       5  
       6  typedef __SIZE_TYPE__ size_t;
       7  
       8  void* malloc (size_t);
       9  void  bzero (void*, size_t);
      10  void* memset (void*, int, size_t);
      11  
      12  
      13  /* Exercise size_t (via malloc and memset) and unsigned/signed int.  */
      14  
      15  __attribute__ ((alloc_size (1))) void*
      16  alloc_int (int);
      17  
      18  __attribute__ ((access (write_only, 1, 2))) void
      19  access_int (void*, int);
      20  
      21  __attribute__ ((alloc_size (1))) void*
      22  alloc_uint (unsigned);
      23  
      24  __attribute__ ((access (write_only, 1, 2))) void
      25  access_uint (void*, unsigned);
      26  
      27  
      28  void* nowarn_malloc_memset_same_anti_range (size_t n)
      29  {
      30    /* Set N to the anti-range ~[3, 3].  */
      31    if (n == 3)
      32      n = 4;
      33    void *p = malloc (n);
      34  
      35    /* Verify there is no warning for an access to N bytes at P.
      36       This means the warning has to assume the value of N in the call
      37       to alloc() is in the larger subrange [4, UINT_MAX], while in
      38       the call to access() in [0, 3].  */
      39    return memset (p, 0, n);
      40  }
      41  
      42  /* Same as above but with two valid ranges.  */
      43  
      44  void* nowarn_malloc_memset_anti_range (size_t n1, size_t n2)
      45  {
      46    /* Set N1 to the anti-range ~[3, 3].  */
      47    if (n1 == 3)
      48      n1 = 4;
      49    void *p = malloc (n1);
      50  
      51    /* Set N2 to the anti-range ~[7, 7].  */
      52    if (n2 == 7)
      53      n2 = 8;
      54  
      55    return memset (p, 0, n2);
      56  }
      57  
      58  
      59  void nowarn_alloc_access_same_anti_range_int (int n)
      60  {
      61    /* Set N to the anti-range ~[3, 3].  */
      62    if (n == 3)
      63      n = 4;
      64    void *p = alloc_int (n);
      65  
      66    /* Verify there is no warning for an access to N bytes at P.
      67       This means the warning has to assume the value of N in the call
      68       to alloc() is in the larger subrange [4, UINT_MAX], while in
      69       the call to access() in [0, 3].  */
      70    access_int (p, n);
      71  }
      72  
      73  /* Same as above but with two valid ranges.  */
      74  
      75  void nowarn_alloc_access_anti_range_int (int n1, int n2)
      76  {
      77    /* Set N1 to the anti-range ~[3, 3].  */
      78    if (n1 == 3)
      79      n1 = 4;
      80    void *p = alloc_int (n1);
      81  
      82    /* Set N2 to the anti-range ~[7, 7].  */
      83    if (n2 == 7)
      84      n2 = 8;
      85  
      86    access_int (p, n2);
      87  }
      88  
      89  
      90  void nowarn_alloc_access_same_anti_range_uint (unsigned n)
      91  {
      92    /* Set N to the anti-range ~[3, 3].  */
      93    if (n == 3)
      94      n = 4;
      95    void *p = alloc_uint (n);
      96  
      97    /* Verify there is no warning for an access to N bytes at P.
      98       This means the warning has to assume the value of N in the call
      99       to alloc() is in the larger subrange [4, UINT_MAX], while in
     100       the call to access() in [0, 3].  */
     101    access_uint (p, n);
     102  }
     103  
     104  /* Same as above but with two valid ranges.  */
     105  
     106  void nowarn_alloc_access_anti_range_uint (unsigned n1, unsigned n2)
     107  {
     108    /* Set N1 to the anti-range ~[3, 3].  */
     109    if (n1 == 3)
     110      n1 = 4;
     111    void *p = alloc_uint (n1);
     112  
     113    /* Set N2 to the anti-range ~[7, 7].  */
     114    if (n2 == 7)
     115      n2 = 8;
     116  
     117    access_uint (p, n2);
     118  }
     119  
     120  
     121  void* nowarn_malloc_anti_range_memset_range (size_t n1, size_t n2)
     122  {
     123    /* Set N1 to the anti-range ~[3, 3].  */
     124    if (n1 == 3)
     125      n1 = 4;
     126    void *p = malloc (n1);
     127  
     128    /* Set N2 to the range [5, MAX].  */
     129    if (n2 < 5)
     130      n2 = 5;
     131    return memset (p, 0, n2);
     132  }
     133  
     134  void* nowarn_malloc_range_bzero_anti_range (size_t n1, size_t n2)
     135  {
     136    /* Set N1 to the anti-range ~[3, 3].  */
     137    if (n1 > 4)
     138      n1 = 4;
     139    void *p = malloc (n1);
     140  
     141    /* Set N2 to the range [5, MAX].  */
     142    if (n2 <= 3 || 5 <= n2)
     143      n2 = 4;
     144    bzero (p, n2);
     145    return p;
     146  }