(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
warn-sprintf-no-nul.c
       1  /* PR tree-optimization/86552 - missing warning for reading past the end
       2     of non-string arrays
       3     Exercise non-string detection in sprintf.
       4     { dg-do compile }
       5     { dg-options "-O2 -Wno-array-bounds -Wall -ftrack-macro-expansion=0" } */
       6  
       7  #include "range.h"
       8  
       9  typedef __WCHAR_TYPE__ wchar_t;
      10  
      11  extern int sprintf (char*, const char*, ...);
      12  
      13  extern char *dst;
      14  
      15  int i0 = 0;
      16  int i1 = 1;
      17  
      18  void sink (int, ...);
      19  
      20  #define CONCAT(a, b)   a ## b
      21  #define CAT(a, b)      CONCAT(a, b)
      22  
      23  #define T(fmt, ...)				\
      24    sink (sprintf (dst, fmt, __VA_ARGS__))
      25  
      26  const char a[5] = "12345";    /* { dg-message "declared here" } */
      27  const char b[6] = "123456";   /* { dg-message "declared here" } */
      28  const char a2[][3] = {
      29    "", "1", "12", "123", "123\000"   /* { dg-warning "initializer-string for array of 'char' is too long" } */
      30  };
      31  
      32  
      33  void test_narrow (void)
      34  {
      35    /* Verify that precision suppresses the warning when it's less
      36       than the size of the array.  */
      37    T ("%.0s%.1s%.2s%.3s%.4s%.5s", a, a, a, a, a, a);
      38  
      39    T ("%s", a);          /* { dg-warning ".%s. directive argument is not a nul-terminated string" } */
      40    T ("%.6s", a);        /* { dg-warning ".%.6s. directive argument is not a nul-terminated string" } */
      41  
      42    /* Exercise conditional expressions involving strings and non-strings.  */
      43    const char *s0 = i0 < 0 ? a2[0] : a2[3];
      44    T ("%s", s0);         /* { dg-warning ".%s. directive argument is not a nul-terminated string" } */
      45    s0 = i0 < 0 ? "123456" : a2[4];
      46    T ("%s", s0);         /* { dg-warning ".%s. directive argument is not a nul-terminated string" } */
      47  
      48    const char *s1 = i0 < 0 ? a2[3] : a2[0];
      49    T ("%s", s1);         /* { dg-warning ".%s. directive argument is not a nul-terminated string" } */
      50  
      51    const char *s2 = i0 < 0 ? a2[3] : a2[4];
      52    T ("%s", s2);         /* { dg-warning ".%s. directive argument is not a nul-terminated string" } */
      53  
      54    s0 = i0 < 0 ? a : b;
      55    T ("%.5s", s0);
      56  
      57    /* Verify that the warning triggers even if precision prevents
      58       reading past the end of one of the non-terminated arrays but
      59       not the other.  */
      60    T ("%.6s", s0);       /* { dg-warning ".%.6s. directive argument is not a nul-terminated string" } */
      61  
      62    s0 = i0 < 0 ? b : a;
      63    T ("%.7s", s0);       /* { dg-warning ".%.7s. directive argument is not a nul-terminated string" } */
      64  
      65    /* Verify that at -Wformat-overflow=1 the lower bound of precision
      66       given by a range is used to determine whether or not to warn.  */
      67    int r = SR (4, 5);
      68  
      69    T ("%.*s", r, a);
      70    T ("%.*s", r, b);
      71  
      72    r = SR (5, 6);
      73    T ("%.*s", r, a);
      74    T ("%.*s", r, b);
      75  
      76    r = SR (6, 7);
      77    T ("%.*s", r, a);     /* { dg-warning ".%.\\\*s. directive argument is not a nul-terminated string" } */
      78    T ("%.*s", r, b);
      79  }
      80  
      81  
      82  const wchar_t wa[5] = L"12345";   /* { dg-message "declared here" } */
      83  
      84  void test_wide (void)
      85  {
      86    T ("%.0ls%.1ls%.2ls%.3ls%.4ls%.5ls", wa, wa, wa, wa, wa, wa);
      87  
      88    T ("%ls", wa);        /* { dg-warning ".%ls. directive argument is not a nul-terminated string" } */
      89    T ("%.6ls", wa);      /* { dg-warning ".%.6ls. directive argument is not a nul-terminated string" } */
      90  }