(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
attr-alloc_size-4.c
       1  /* PR c/77531 - __attribute__((alloc_size(1,2))) could also warn on
       2     multiplication overflow
       3     PR c/78284 - warn on malloc with very large arguments
       4     Test exercising the ability to detect and diagnose calls to allocation
       5     functions decorated with attribute alloc_size that either overflow or
       6     exceed the maximum object size specified by -Walloc-size-larger-than.  */
       7  /* { dg-do compile } */
       8  /* { dg-options "-O2 -Wall -Walloc-size-larger-than=1234" } */
       9  
      10  #define INT_MAX    __INT_MAX__
      11  #define INT_MIN    (-INT_MAX - 1)
      12  #define UINT_MAX   (INT_MAX * 2U + 1)
      13  
      14  #define SIZE_MAX   __SIZE_MAX__
      15  
      16  typedef __SIZE_TYPE__ size_t;
      17  
      18  #define ALLOC_SIZE(...) __attribute__ ((alloc_size (__VA_ARGS__)))
      19  
      20  void* f_uint_1 (unsigned) ALLOC_SIZE (1);
      21  void* f_uint_2 (unsigned, unsigned) ALLOC_SIZE (1, 2);
      22  void* f_int_1 (int) ALLOC_SIZE (1);
      23  void* f_int_2 (int, int) ALLOC_SIZE (1, 2);
      24  
      25  void* f_size_1 (size_t) ALLOC_SIZE (1);
      26  void* f_size_2 (size_t, size_t) ALLOC_SIZE (1, 2);
      27  
      28  static size_t
      29  unsigned_range (size_t min, size_t max)
      30  {
      31    extern size_t random_unsigned_value (void);
      32    size_t val = random_unsigned_value ();
      33    if (val < min || max < val) val = min;
      34    return val;
      35  }
      36  
      37  static int
      38  signed_range (int min, int max)
      39  {
      40    extern int random_signed_value (void);
      41    int val = random_signed_value ();
      42    if (val < min || max < val) val = min;
      43    return val;
      44  }
      45  
      46  static size_t
      47  unsigned_anti_range (size_t min, size_t max)
      48  {
      49    extern size_t random_unsigned_value (void);
      50    size_t val = random_unsigned_value ();
      51    if (min <= val && val <= max)
      52      val = min - 1;
      53    return val;
      54  }
      55  
      56  static int
      57  signed_anti_range (int min, int max)
      58  {
      59    extern int random_signed_value (void);
      60    int val = random_signed_value ();
      61    if (min <= val && val <= max)
      62      val = min - 1;
      63    return val;
      64  }
      65  
      66  #define UR(min, max) unsigned_range (min, max)
      67  #define SR(min, max) signed_range (min, max)
      68  
      69  #define UAR(min, max) unsigned_anti_range (min, max)
      70  #define SAR(min, max) signed_anti_range (min, max)
      71  
      72  
      73  void sink (void*);
      74  
      75  void
      76  test_uint_cst (void)
      77  {
      78    const unsigned max = UINT_MAX;
      79  
      80    sink (f_uint_1 (0));
      81    sink (f_uint_1 (1));
      82    sink (f_uint_1 (1233));
      83    sink (f_uint_1 (1234));
      84    sink (f_uint_1 (1235));       /* { dg-warning "argument 1 value .1235u?. exceeds maximum object size 1234" } */
      85    sink (f_uint_1 (max - 1));    /* { dg-warning "argument 1 value .\[0-9\]+u?. exceeds maximum object size 1234" } */
      86    sink (f_uint_1 (max));        /* { dg-warning "argument 1 value .\[0-9\]+u?. exceeds maximum object size 1234" } */
      87  }
      88  
      89  void
      90  test_uint_range (unsigned n)
      91  {
      92    const unsigned max = UINT_MAX;
      93  
      94    sink (f_uint_1 (n));
      95    sink (f_uint_1 (UR (0, 1)));
      96    sink (f_uint_1 (UR (0, 1233)));
      97    sink (f_uint_1 (UR (0, 1234)));
      98    sink (f_uint_1 (UR (0, 1235)));
      99    sink (f_uint_1 (UR (1, 1235)));
     100    sink (f_uint_1 (UR (1234, 1235)));
     101    sink (f_uint_1 (UR (1235, 1236)));   /* { dg-warning "argument 1 range \\\[\[0-9\]+u?, \[0-9\]+u?\\\] exceeds maximum object size 1234" } */
     102    sink (f_uint_1 (UR (1, max - 1)));
     103    sink (f_uint_1 (UR (1, max)));
     104  }
     105  
     106  void
     107  test_int_cst (void)
     108  {
     109    const int min = INT_MIN;
     110    const int max = INT_MAX;
     111  
     112    sink (f_int_1 (min));   /* { dg-warning "argument 1 value .-\[0-9\]+. is negative" } */
     113    sink (f_int_1 (-1));    /* { dg-warning "argument 1 value .-1. is negative" } */
     114    sink (f_int_1 (0));
     115    sink (f_int_1 (1));
     116    sink (f_int_1 (1233));
     117    sink (f_int_1 (1234));
     118    sink (f_int_1 (max));   /* { dg-warning "argument 1 value .\[0-9\]+u?. exceeds maximum object size 1234" } */
     119  }
     120  
     121  void
     122  test_int_range (int n)
     123  {
     124    const int min = INT_MIN;
     125    const int max = INT_MAX;
     126  
     127    sink (f_int_1 (n));
     128  
     129    sink (f_int_1 (SR (min, 1234)));
     130    sink (f_int_1 (SR (-2, -1)));   /* { dg-warning "argument 1 range \\\[-2, -1\\\] is negative" } */
     131  
     132    sink (f_int_1 (SR (1235, 2345)));  /* { dg-warning "argument 1 range \\\[1235, 2345\\\] exceeds maximum object size 1234" } */
     133    sink (f_int_1 (SR (max - 1, max)));   /* { dg-warning "argument 1 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size 1234" } */
     134  
     135    sink (f_int_1 (SAR (-1, 1)));
     136    sink (f_int_1 (SAR (-2, 12)));
     137    sink (f_int_1 (SAR (-3, 123)));
     138    sink (f_int_1 (SAR (-4, 1234)));   /* { dg-warning "argument 1 range \\\[1235, \[0-9\]+\\\] exceeds maximum object size 1234" } */
     139    sink (f_int_1 (SAR (min + 1, 1233)));
     140  
     141  #if __i386__ || __x86_64__
     142    /* Avoid failures described in bug 79051.  */
     143    sink (f_int_1 (SAR (min + 2, 1235)));   /* { dg-warning "argument 1 range \\\[1236, \[0-9\]+\\\] exceeds maximum object size 1234" "" { target { i?86-*-* x86_64-*-* } } } */
     144  #endif
     145  
     146    sink (f_int_1 (SAR (0, max)));   /* { dg-warning "argument 1 range \\\[-\[0-9\]*, -1\\\] is negative" } */
     147    /* The range below includes zero which would be diagnosed by
     148       -Walloc-size-zero but since all other values are negative it
     149       is diagnosed by -Walloc-size-larger-than.  */
     150    sink (f_int_1 (SAR (1, max)));   /* { dg-warning "argument 1 range \\\[-\[0-9\]*, 0\\\] is negative" } */
     151    sink (f_int_1 (SAR (2, max)));
     152  }
     153  
     154  void
     155  test_size_cst (void)
     156  {
     157    const size_t max = __SIZE_MAX__;
     158  
     159    sink (f_size_1 (0));
     160    sink (f_size_1 (1));
     161  
     162    sink (f_size_2 (   0, 1234));
     163    sink (f_size_2 (   1, 1234));
     164    sink (f_size_2 (   2, 1234));  /* { dg-warning "product .2 \\* 1234. of arguments 1 and 2 exceeds maximum object size \[0-9\]+" } */
     165    sink (f_size_2 (1234, 1234));  /* { dg-warning "product .1234 \\* 1234. of arguments 1 and 2 exceeds (.SIZE_MAX.|maximum object size 1234)" } */
     166    sink (f_size_2 (1235, 1234));  /* { dg-warning "argument 1 value .1235. exceeds maximum object size 1234" } */
     167    sink (f_size_2 (1234, 1235));  /* { dg-warning "argument 2 value .1235. exceeds maximum object size 1234" } */
     168    sink (f_size_2 (1234, max));  /* { dg-warning "argument 2 value .\[0-9\]+. exceeds maximum object size 1234" } */
     169    sink (f_size_2 (max, 1234));  /* { dg-warning "argument 1 value .\[0-9\]+. exceeds maximum object size 1234" } */
     170  }
     171  
     172  void
     173  test_size_range (size_t n)
     174  {
     175    const size_t max = __SIZE_MAX__;
     176  
     177    sink (f_size_1 (n));
     178  
     179    sink (f_size_1 (UR (0, 1)));
     180    sink (f_size_1 (UR (0, max - 1)));
     181    sink (f_size_1 (UR (1, max - 1)));
     182    sink (f_size_1 (UR (1, max)));
     183  
     184    sink (f_size_1 (UAR (1, 1)));
     185    /* Since the only valid argument in the anti-range below is zero
     186       a warning is expected even though -Walloc-zero is not specified.  */
     187    sink (f_size_1 (UAR (1, 1234)));   /* { dg-warning "argument 1 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " } */
     188    /* The only valid argument in this range is 1.  */
     189    sink (f_size_1 (UAR (2, max / 2)));
     190  
     191    sink (f_size_2 (n, n));
     192    sink (f_size_2 (n, 1234));
     193    sink (f_size_2 (1234, n));
     194  
     195    sink (f_size_2 (UR (0, 1), 1234));
     196    sink (f_size_2 (UR (0, 1), 1235));   /* { dg-warning "argument 2 value .1235. exceeds maximum object size 1234" } */
     197  
     198    sink (f_size_2 (UR (1235, 1236), n));  /* { dg-warning "argument 1 range \\\[1235, 1236\\\] exceeds maximum object size 1234" } */
     199  
     200    sink (f_size_2 (UR (1235, 1236), UR (max / 2, max)));  /* { dg-warning "argument 1 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " } */
     201  /* { dg-warning "argument 2 range \\\[\[0-9\]+, \[0-9\]+\\\] exceeds maximum object size " "argument 2" { target *-*-* } .-1 } */
     202  
     203  }