(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
attr-nonstring-2.c
       1  /* PR middle-end/81384 - built-in form of strnlen missing
       2     { dg-do compile }
       3     { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
       4  
       5  #include "range.h"
       6  
       7  extern void* memcpy (void*, const void*, size_t);
       8  extern size_t strnlen (const char*, size_t);
       9  
      10  #define NONSTRING __attribute__ ((nonstring))
      11  
      12  #define _CAT(s, n)   s ## n
      13  #define CAT(s, n)    _CAT (s, n)
      14  #define UNIQ(n)      CAT (n, __LINE__)
      15  
      16  void sink (size_t, ...);
      17  
      18  #define T(expr)   sink (expr)
      19  
      20  void test_strnlen_array_cst (void)
      21  {
      22    NONSTRING char ns3[3];
      23    sink (0, ns3);    // "initialize" ns3
      24  
      25    T (strnlen (ns3, 0));
      26    T (strnlen (ns3, 1));
      27    T (strnlen (ns3, 2));
      28    T (strnlen (ns3, 3));
      29    T (strnlen (ns3, 4));             /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 4|specified bound 4 exceeds source size 3" } */
      30    T (strnlen (ns3, DIFF_MAX));      /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound|specified bound \[0-9\]+ exceeds source size" } */
      31    T (strnlen (ns3, SIZE_MAX));      /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
      32  
      33    NONSTRING char ns5[5];
      34    sink (0, ns5);
      35  
      36    T (strnlen (ns5, 0));
      37    T (strnlen (ns5, 1));
      38    T (strnlen (ns5, 2));
      39    T (strnlen (ns5, 3));
      40    T (strnlen (ns5, 6));             /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 6|specified bound 6 exceeds source size 5" } */
      41    T (strnlen (ns5, DIFF_MAX));      /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound|specified bound \[0-9\]+ exceeds source size 5" } */
      42    T (strnlen (ns5, SIZE_MAX));      /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
      43  }
      44  
      45  
      46  void test_strnlen_array_range (void)
      47  {
      48    NONSTRING char ns3[3];
      49    sink (0, ns3);    // "initialize" ns3
      50  
      51    T (strnlen (ns3, UR (0, 3)));
      52    T (strnlen (ns3, UR (0, 9)));
      53    T (strnlen (ns3, UR (3, 4)));
      54    T (strnlen (ns3, UR (3, DIFF_MAX)));
      55    T (strnlen (ns3, UR (4, 5)));     /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[4, 5]|specified bound \\\[4, 5] exceeds source size 3" } */
      56    T (strnlen (ns3, UR (DIFF_MAX, SIZE_MAX)));  /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[\[0-9\]+, \[0-9\]+] |specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds source size 3 " } */
      57  }
      58  
      59  
      60  #undef T
      61  #define T(N, init, nelts, bound)			\
      62    do {							\
      63      extern NONSTRING char UNIQ (arr)[N];		\
      64      memcpy (UNIQ (arr), init, nelts);			\
      65      sink (strnlen (UNIQ (arr), bound), UNIQ (arr));	\
      66    } while (0)
      67  
      68  void test_strnlen_string_cst (void)
      69  {
      70    T (3, "1",   2, 1);
      71    T (3, "1",   2, 2);
      72    T (3, "1",   2, 3);
      73    T (3, "12",  3, 1);
      74    T (3, "12",  3, 9);
      75    T (3, "123", 3, 1);
      76    T (3, "123", 3, 4);               /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 4|specified bound 4 exceeds source size 3" } */
      77    T (3, "123", 3, 9);               /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 9|specified bound 9 exceeds source size 3" } */
      78  
      79    T (5, "1",   2, 1);
      80    T (5, "1",   2, 2);
      81    T (5, "1",   2, 9);
      82  
      83    T (5, "12",  3, 1);
      84    T (5, "12",  3, 9);
      85    T (5, "123", 3, 1);
      86    T (5, "123", 3, 5);
      87    T (5, "123", 3, 6);               /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound 6|specified bound 6 exceeds source size 5" } */
      88  
      89    /* Strnlen shouldn't trigger a warning for arrays of unknown size
      90       (except for accesses to uninitialized elements when those are
      91       detected).  */
      92    T (/* [] */, "1", 1, 1);
      93    T (/* [] */, "1", 1, 2);
      94    T (/* [] */, "1", 2, 1);
      95    T (/* [] */, "1", 2, 2);
      96    T (/* [] */, "1", 2, 3);
      97    T (/* [] */, "1", 2, 9);
      98    T (/* [] */, "1", 2, DIFF_MAX);
      99    T (/* [] */, "1", 2, SIZE_MAX);
     100  
     101    size_t n = DIFF_MAX;
     102    T (/* [] */, "123", 3, n);
     103    T (/* [] */, "123", 3, n + 1);    /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size " } */
     104    n = SIZE_MAX;
     105    T (/* [] */, "123", 3, n);        /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size " } */
     106  }
     107  
     108  
     109  void test_strnlen_string_range (void)
     110  {
     111    T (3, "1",   2, UR (0, 1));
     112    T (3, "1",   2, UR (3, 9));
     113    T (3, "123", 3, UR (4, 5));       /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[4, 5]|specified bound \\\[4, 5] exceeds source size 3" } */
     114    T (3, "123", 3, UR (5, 9));       /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \\\[5, 9]|specified bound \\\[5, 9] exceeds source size 3" } */
     115  }