(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
Wstring-compare-2.c
       1  /* PR tree-optimization/90879 - fold zero-equality of strcmp between
       2     a longer string and a smaller array
       3     Test for a warning for strcmp of a longer string against smaller
       4     array.
       5     { dg-do compile }
       6     { dg-options "-O2 -Wall -Wstring-compare -Wno-stringop-truncation -ftrack-macro-expansion=0" } */
       7  
       8  typedef __SIZE_TYPE__ size_t;
       9  
      10  extern void* memcpy (void*, const void*, size_t);
      11  
      12  extern int strcmp (const char*, const char*);
      13  extern size_t strlen (const char*);
      14  extern char* strcpy (char*, const char*);
      15  extern char* strncpy (char*, const char*, size_t);
      16  extern int strncmp (const char*, const char*, size_t);
      17  
      18  void sink (int, ...);
      19  #define sink(...) sink (__LINE__, __VA_ARGS__)
      20  
      21  
      22  extern char a1[1], a2[2], a3[3], a4[4], a5[5], a6[6], a7[7], a8[8], a9[9];
      23  
      24  #define T(a, b) sink (0 == strcmp (a, b))
      25  
      26  
      27  void test_string_cst (void)
      28  {
      29    const char *s1 = "1", *s2 = "12";
      30  
      31    T (s1, a1);                 // { dg-warning ".strcmp. of a string of length 1 and an array of size 1 evaluates to nonzero" }
      32    T (s1, a2);
      33    T (s1, a3);
      34  
      35    T (a1, s1);                 // { dg-warning ".strcmp. of a string of length 1 and an array of size 1 evaluates to nonzero" }
      36    T (a2, s1);
      37    T (a3, s1);
      38  
      39    T (s2, a1);                 // { dg-warning ".strcmp. of a string of length 2 and an array of size 1 evaluates to nonzero" }
      40    T (s2, a2);                 // { dg-warning ".strcmp. of a string of length 2 and an array of size 2 evaluates to nonzero" }
      41    T (s2, a3);
      42  
      43    T (a1, s2);                 // { dg-warning ".strcmp. of a string of length 2 and an array of size 1 evaluates to nonzero" }
      44    T (a2, s2);                 // { dg-warning ".strcmp. of a string of length 2 and an array of size 2 evaluates to nonzero" }
      45    T (a3, s2);
      46  }
      47  
      48  
      49  void test_string_cst_off_cst (void)
      50  {
      51    const char *s1 = "1", *s2 = "12", *s3 = "123", *s4 = "1234";
      52  
      53    T (s1, a2 + 1);              // { dg-warning ".strcmp. of a string of length 1 and an array of size 1 evaluates to nonzero" }
      54    T (a2 + 1, s1);              // { dg-warning ".strcmp. of a string of length 1 and an array of size 1 evaluates to nonzero" }
      55  
      56  
      57    T (s3 + 1, a2);             // { dg-warning ".strcmp. of a string of length 2 and an array of size 2 evaluates to nonzero" }
      58    T (s3 + 1, a3);
      59  
      60    T (s2, a4 + 1);
      61    T (s2, a4 + 2);             // { dg-warning ".strcmp. of a string of length 2 and an array of size 2 evaluates to nonzero" }
      62  
      63    T (s4, a4 + 1);             // { dg-warning ".strcmp. of a string of length 4 and an array of size 3 evaluates to nonzero" }
      64    T (s3, a5 + 1);
      65  }
      66  
      67  
      68  /* Use strncpy below rather than memcpy until PR 91183 is resolved.  */
      69  
      70  #undef T
      71  #define T(s, n, a)					\
      72    do {							\
      73      char arr[32];					\
      74      sink (arr);						\
      75      strncpy (arr, s, n < 0 ? strlen (s) + 1: n);	\
      76      sink (0 == strcmp (arr, a));			\
      77    } while (0)
      78  
      79  void test_string_exact_length (void)
      80  {
      81    const char *s1 = "1", *s2 = "12";
      82  
      83    T (s1, -1, a1);             // { dg-warning ".strcmp. of a string of length 1 and an array of size 1 evaluates to nonzero" }
      84    T (s1, -1, a2);
      85    T (s1, -1, a3);
      86  
      87    T (s2, -1, a1);             // { dg-warning ".strcmp. of a string of length 2 and an array of size 1 evaluates to nonzero" }
      88    T (s2, -1, a2);             // { dg-warning ".strcmp. of a string of length 2 and an array of size 2 evaluates to nonzero" }
      89    T (s2, -1, a3);
      90  }
      91  
      92  
      93  void test_string_min_length (void)
      94  {
      95    const char *s1 = "1", *s2 = "12";
      96  
      97    T (s1,  1, a1);             // { dg-warning ".strcmp. of a string of length 1 or more and an array of size 1 evaluates to nonzero" }
      98    T (s1,  1, a2);
      99    T (s1,  1, a3);
     100  
     101    T (s2,  2, a1);             // { dg-warning ".strcmp. of a string of length 2 or more and an array of size 1 evaluates to nonzero" }
     102    T (s2,  2, a2);             // { dg-warning ".strcmp. of a string of length 2 or more and an array of size 2 evaluates to nonzero" }
     103    T (s2,  2, a3);
     104  }
     105  
     106  
     107  int test_strncmp_str_lit_var (const char *s, long n)
     108  {
     109    if (strncmp (s, "123456", n) == 0)    // { dg-bogus "\\\[-Wstring-compare" }
     110      return 1;
     111  
     112    return 0;
     113  }
     114  
     115  int test_strlen_strncmp_str_lit_var (const char *s, long n)
     116  {
     117    if (__builtin_strlen (s) < n)
     118      return -1;
     119  
     120    if (n == 6)
     121      if (strncmp (s, "123456", n) == 0)  // { dg-bogus "\\\[-Wstring-compare" }
     122        return 1;
     123  
     124    return 0;
     125  }
     126  
     127