(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
attr-alloc_size-5.c
       1  /* PR c/78284 - warn on malloc with very large arguments
       2     Test exercising the ability to detect and diagnose calls to allocation
       3     functions decorated with attribute alloc_size that attempt to allocate
       4     zero bytes.  For standard allocation functions the return value is
       5     implementation-defined and so relying on it may be a source of bugs.  */
       6  /* { dg-do compile } */
       7  /* { dg-options "-O1 -Wall -Walloc-zero" } */
       8  
       9  #define SCHAR_MAX  __SCHAR_MAX__
      10  #define SCHAR_MIN  (-SCHAR_MAX - 1)
      11  #define UCHAR_MAX  (SCHAR_MAX * 2 + 1)
      12  
      13  #define SHRT_MAX   __SHRT_MAX__
      14  #define SHRT_MIN   (-SHRT_MAX - 1)
      15  #define USHRT_MAX  (SHRT_MAX * 2U + 1)
      16  
      17  #define INT_MAX    __INT_MAX__
      18  #define INT_MIN    (-INT_MAX - 1)
      19  #define UINT_MAX   (INT_MAX * 2U + 1)
      20  
      21  #define LONG_MAX   __LONG_MAX__
      22  #define LONG_MIN   (-LONG_MAX - 1L)
      23  #define ULONG_MAX  (LONG_MAX * 2LU + 1)
      24  
      25  #define LLONG_MAX  __LLONG_MAX__
      26  #define LLONG_MIN  (-LLONG_MAX - 1LL)
      27  #define ULLONG_MAX (ULLONG_MAX * 2LLU + 1)
      28  
      29  #define SIZE_MAX   __SIZE_MAX__
      30  
      31  typedef __SIZE_TYPE__ size_t;
      32  
      33  
      34  #define ALLOC_SIZE(...) __attribute__ ((alloc_size (__VA_ARGS__)))
      35  
      36  void* f_uchar_1 (unsigned char) ALLOC_SIZE (1);
      37  void* f_uchar_2 (unsigned char, unsigned char) ALLOC_SIZE (1, 2);
      38  void* f_schar_1 (signed char) ALLOC_SIZE (1);
      39  void* f_schar_2 (signed char, signed char) ALLOC_SIZE (1, 2);
      40  
      41  void* f_ushrt_1 (unsigned short) ALLOC_SIZE (1);
      42  void* f_ushrt_2 (unsigned short, unsigned short) ALLOC_SIZE (1, 2);
      43  void* f_shrt_1 (signed short) ALLOC_SIZE (1);
      44  void* f_shrt_2 (signed short, signed short) ALLOC_SIZE (1, 2);
      45  
      46  void* f_uint_1 (unsigned) ALLOC_SIZE (1);
      47  void* f_uint_2 (unsigned, unsigned) ALLOC_SIZE (1, 2);
      48  void* f_int_1 (int) ALLOC_SIZE (1);
      49  void* f_int_2 (int, int) ALLOC_SIZE (1, 2);
      50  
      51  void* f_ulong_1 (unsigned long) ALLOC_SIZE (1);
      52  void* f_ulong_2 (unsigned long, unsigned long) ALLOC_SIZE (1, 2);
      53  void* f_long_1 (long) ALLOC_SIZE (1);
      54  void* f_long_2 (long, long) ALLOC_SIZE (1, 2);
      55  
      56  void* f_ullong_1 (unsigned long long) ALLOC_SIZE (1);
      57  void* f_ullong_2 (unsigned long long, unsigned long long) ALLOC_SIZE (1, 2);
      58  void* f_llong_1 (long long) ALLOC_SIZE (1);
      59  void* f_llong_2 (long long, long long) ALLOC_SIZE (1, 2);
      60  
      61  void* f_size_1 (size_t) ALLOC_SIZE (1);
      62  void* f_size_2 (size_t, size_t) ALLOC_SIZE (1, 2);
      63  
      64  void* f_size_1_nonnull (size_t)
      65       ALLOC_SIZE (1)  __attribute__ ((returns_nonnull));
      66  void* f_size_2_nonnull (size_t, size_t)
      67       ALLOC_SIZE (1, 2) __attribute__ ((returns_nonnull));
      68  
      69  void sink (void*);
      70  
      71  void
      72  test_uchar (unsigned char n)
      73  {
      74    sink (f_uchar_1 (0));     /* { dg-warning "argument 1 value is zero" } */
      75    sink (f_uchar_2 (0, 1));  /* { dg-warning "argument 1 value is zero" } */
      76    sink (f_uchar_2 (1, 0));  /* { dg-warning "argument 2 value is zero" } */
      77    sink (f_uchar_2 (n, 0));  /* { dg-warning "argument 2 value is zero" } */
      78    sink (f_uchar_2 (0, n));  /* { dg-warning "argument 1 value is zero" } */
      79  
      80    sink (f_uchar_1 (n));
      81    n = 0;
      82    sink (f_uchar_1 (n));     /* { dg-warning "argument 1 value is zero" } */
      83    sink (f_uchar_2 (1, n));  /* { dg-warning "argument 2 value is zero" } */
      84  }
      85  
      86  void
      87  test_schar (signed char n)
      88  {
      89    sink (f_schar_1 (0));     /* { dg-warning "argument 1 value is zero" } */
      90    sink (f_schar_2 (0, 1));  /* { dg-warning "argument 1 value is zero" } */
      91    sink (f_schar_2 (1, 0));  /* { dg-warning "argument 2 value is zero" } */
      92    sink (f_schar_2 (n, 0));  /* { dg-warning "argument 2 value is zero" } */
      93    sink (f_schar_2 (0, n));  /* { dg-warning "argument 1 value is zero" } */
      94  
      95    sink (f_schar_1 (n));
      96    n = 0;
      97    sink (f_schar_1 (n));     /* { dg-warning "argument 1 value is zero" } */
      98    sink (f_schar_2 (1, n));  /* { dg-warning "argument 2 value is zero" } */
      99  }
     100  
     101  void
     102  test_ushrt (unsigned short n)
     103  {
     104    sink (f_ushrt_1 (0));     /* { dg-warning "argument 1 value is zero" } */
     105    sink (f_ushrt_2 (0, 1));  /* { dg-warning "argument 1 value is zero" } */
     106    sink (f_ushrt_2 (1, 0));  /* { dg-warning "argument 2 value is zero" } */
     107    sink (f_ushrt_2 (n, 0));  /* { dg-warning "argument 2 value is zero" } */
     108    sink (f_ushrt_2 (0, n));  /* { dg-warning "argument 1 value is zero" } */
     109  
     110    sink (f_ushrt_1 (n));
     111    n = 0;
     112    sink (f_ushrt_1 (n));     /* { dg-warning "argument 1 value is zero" } */
     113    sink (f_ushrt_2 (1, n));  /* { dg-warning "argument 2 value is zero" } */
     114  }
     115  
     116  void
     117  test_shrt (short n)
     118  {
     119    sink (f_shrt_1 (0));      /* { dg-warning "argument 1 value is zero" } */
     120    sink (f_shrt_2 (0, 1));   /* { dg-warning "argument 1 value is zero" } */
     121    sink (f_shrt_2 (1, 0));   /* { dg-warning "argument 2 value is zero" } */
     122    sink (f_shrt_2 (n, 0));   /* { dg-warning "argument 2 value is zero" } */
     123    sink (f_shrt_2 (0, n));   /* { dg-warning "argument 1 value is zero" } */
     124  
     125    sink (f_shrt_1 (n));
     126    n = 0;
     127    sink (f_shrt_1 (n));      /* { dg-warning "argument 1 value is zero" } */
     128    sink (f_shrt_2 (1, n));   /* { dg-warning "argument 2 value is zero" } */
     129  }
     130  
     131  void
     132  test_uint (unsigned n)
     133  {
     134    sink (f_uint_1 (0));      /* { dg-warning "argument 1 value is zero" } */
     135    sink (f_uint_2 (0, 1));   /* { dg-warning "argument 1 value is zero" } */
     136    sink (f_uint_2 (1, 0));   /* { dg-warning "argument 2 value is zero" } */
     137    sink (f_uint_2 (n, 0));   /* { dg-warning "argument 2 value is zero" } */
     138    sink (f_uint_2 (0, n));   /* { dg-warning "argument 1 value is zero" } */
     139  
     140    sink (f_uint_1 (n));
     141    n = 0;
     142    sink (f_uint_1 (n));      /* { dg-warning "argument 1 value is zero" } */
     143    sink (f_uint_2 (1, n));   /* { dg-warning "argument 2 value is zero" } */
     144  }
     145  
     146  void
     147  test_int (int n)
     148  {
     149    sink (f_int_1 (0));       /* { dg-warning "argument 1 value is zero" } */
     150    sink (f_int_2 (0, 1));    /* { dg-warning "argument 1 value is zero" } */
     151    sink (f_int_2 (1, 0));    /* { dg-warning "argument 2 value is zero" } */
     152    sink (f_int_2 (n, 0));    /* { dg-warning "argument 2 value is zero" } */
     153    sink (f_int_2 (0, n));    /* { dg-warning "argument 1 value is zero" } */
     154  
     155    sink (f_int_1 (n));
     156    n = 0;
     157    sink (f_int_1 (n));       /* { dg-warning "argument 1 value is zero" } */
     158    sink (f_int_2 (1, n));    /* { dg-warning "argument 2 value is zero" } */
     159  }
     160  
     161  void
     162  test_ulong (unsigned long n)
     163  {
     164    sink (f_ulong_1 (0));     /* { dg-warning "argument 1 value is zero" } */
     165    sink (f_ulong_2 (0, 1));  /* { dg-warning "argument 1 value is zero" } */
     166    sink (f_ulong_2 (1, 0));  /* { dg-warning "argument 2 value is zero" } */
     167    sink (f_ulong_2 (n, 0));  /* { dg-warning "argument 2 value is zero" } */
     168    sink (f_ulong_2 (0, n));  /* { dg-warning "argument 1 value is zero" } */
     169  
     170    sink (f_ulong_1 (n));
     171    n = 0;
     172    sink (f_ulong_1 (n));     /* { dg-warning "argument 1 value is zero" } */
     173    sink (f_ulong_2 (1, n));  /* { dg-warning "argument 2 value is zero" } */
     174  }
     175  
     176  void
     177  test_long (long n)
     178  {
     179    sink (f_long_1 (0));      /* { dg-warning "argument 1 value is zero" } */
     180    sink (f_long_2 (0, 1));   /* { dg-warning "argument 1 value is zero" } */
     181    sink (f_long_2 (1, 0));   /* { dg-warning "argument 2 value is zero" } */
     182    sink (f_long_2 (n, 0));   /* { dg-warning "argument 2 value is zero" } */
     183    sink (f_long_2 (0, n));   /* { dg-warning "argument 1 value is zero" } */
     184  
     185    sink (f_long_1 (n));
     186    n = 0;
     187    sink (f_long_1 (n));      /* { dg-warning "argument 1 value is zero" } */
     188    sink (f_long_2 (1, n));   /* { dg-warning "argument 2 value is zero" } */
     189  }
     190  
     191  void
     192  test_size (size_t n)
     193  {
     194    sink (f_size_1 (0));      /* { dg-warning "argument 1 value is zero" } */
     195    sink (f_size_2 (0, 1));   /* { dg-warning "argument 1 value is zero" } */
     196    sink (f_size_2 (1, 0));   /* { dg-warning "argument 2 value is zero" } */
     197    sink (f_size_2 (n, 0));   /* { dg-warning "argument 2 value is zero" } */
     198    sink (f_size_2 (0, n));   /* { dg-warning "argument 1 value is zero" } */
     199  
     200    sink (f_size_1 (n));
     201    n = 0;
     202    sink (f_size_1 (n));      /* { dg-warning "argument 1 value is zero" } */
     203    sink (f_size_2 (1, n));   /* { dg-warning "argument 2 value is zero" } */
     204  }
     205  
     206  /* Verify that calls to allocation function decorated with attribute
     207     returns_nonnull don't cause warnings (unlike functions like malloc
     208     that can return null in this case there's nothing to warn about
     209     because a returns_nonnull function guarantees success).  */
     210  
     211  void
     212  test_size_nonnull (size_t n)
     213  {
     214    sink (f_size_1_nonnull (0));
     215    sink (f_size_2_nonnull (0, 1));
     216    sink (f_size_2_nonnull (1, 0));
     217    sink (f_size_2_nonnull (n, 0));
     218    sink (f_size_2_nonnull (0, n));
     219  
     220    sink (f_size_1_nonnull (n));
     221    n = 0;
     222    sink (f_size_1_nonnull (n));
     223    sink (f_size_2_nonnull (1, n));
     224  }
     225  
     226  /* Verify that call to plain alloca(0) is not diagnosed.  */
     227  
     228  void
     229  test_alloca (size_t n)
     230  {
     231    extern void* alloca (size_t);
     232  
     233    alloca (0); /* { dg-warning "ignoring return value of '.*' declared with attribute 'warn_unused_result'" } */
     234  }