(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
Wsizeof-pointer-memaccess1.c
       1  /* Test -Wsizeof-pointer-memaccess warnings.  */
       2  /* { dg-do compile } */
       3  /* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-overflow -Wno-stringop-overread" } */
       4  /* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-c++-compat -Wno-stringop-overflow -Wno-stringop-overread" { target c } } */
       5  /* { dg-require-effective-target alloca } */
       6  
       7  typedef __SIZE_TYPE__ size_t;
       8  #ifdef __cplusplus
       9  extern "C" {
      10  #endif
      11  extern int snprintf (char *, size_t, const char *, ...);
      12  extern int vsnprintf (char *, size_t, const char *, __builtin_va_list);
      13  extern void *memchr (const void *, int, size_t);
      14  #ifdef __cplusplus
      15  }
      16  #endif
      17  
      18  struct A { short a, b; int c, d; long e, f; };
      19  typedef struct A TA;
      20  typedef struct A *PA;
      21  typedef TA *PTA;
      22  struct B {};
      23  typedef struct B TB;
      24  typedef struct B *PB;
      25  typedef TB *PTB;
      26  typedef int X[3][3][3];
      27  
      28  void foo (void **);
      29  
      30  void
      31  f1 (void *x)
      32  {
      33    struct A a, *pa1 = &a;
      34    TA *pa2 = &a;
      35    PA pa3 = &a;
      36    PTA pa4 = &a;
      37    void *arr[100];
      38    int i = 0;
      39    arr[i++] = memchr (&a, 0, sizeof (&a));		/* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
      40    arr[i++] = memchr (pa1, 0, sizeof (pa1));		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      41    arr[i++] = memchr (pa2, 0, sizeof pa2);		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      42    arr[i++] = memchr (pa3, 0, sizeof (pa3));		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      43    arr[i++] = memchr (pa4, 0, sizeof pa4);		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      44    arr[i++] = memchr (pa1, 0, sizeof (struct A *));	/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      45    arr[i++] = memchr (pa2, 0, sizeof (PTA));		/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      46    arr[i++] = memchr (pa3, 0, sizeof (PA));		/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      47    arr[i++] = memchr (pa4, 0, sizeof (__typeof (pa4)));	/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      48  
      49    /* These are correct, no warning.  */
      50    arr[i++] = memchr (&a, 0, sizeof a);
      51    arr[i++] = memchr (&a, 0, sizeof (a));
      52    arr[i++] = memchr (&a, 0, sizeof (struct A));
      53    arr[i++] = memchr (&a, 0, sizeof (const struct A));
      54    arr[i++] = memchr (&a, 0, sizeof (volatile struct A));
      55    arr[i++] = memchr (&a, 0, sizeof (volatile const struct A));
      56    arr[i++] = memchr (&a, 0, sizeof (TA));
      57    arr[i++] = memchr (&a, 0, sizeof (__typeof (*&a)));
      58    arr[i++] = memchr (pa1, 0, sizeof (*pa1));
      59    arr[i++] = memchr (pa2, 0, sizeof (*pa3));
      60    arr[i++] = memchr (pa3, 0, sizeof (__typeof (*pa3)));
      61    /* These are probably broken, but obfuscated, no warning.  */
      62    arr[i++] = memchr ((void *) &a, 0, sizeof (&a));
      63    arr[i++] = memchr ((char *) &a, 0, sizeof (&a));
      64    arr[i++] = memchr (&a, 0, sizeof (&a) + 0);
      65    arr[i++] = memchr (&a, 0, 0 + sizeof (&a));
      66  
      67    foo (arr);
      68  }
      69  
      70  void
      71  f2 (void *x)
      72  {
      73    struct B b, *pb1 = &b;
      74    TB *pb2 = &b;
      75    PB pb3 = &b;
      76    PTB pb4 = &b;
      77    void *arr[100];
      78    int i = 0;
      79    arr[i++] = memchr (&b, 0, sizeof (&b));		/* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
      80    arr[i++] = memchr (pb1, 0, sizeof (pb1));		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      81    arr[i++] = memchr (pb2, 0, sizeof pb2);		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      82    arr[i++] = memchr (pb3, 0, sizeof (pb3));		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      83    arr[i++] = memchr (pb4, 0, sizeof pb4);		/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
      84    arr[i++] = memchr (pb1, 0, sizeof (struct B *));	/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      85    arr[i++] = memchr (pb2, 0, sizeof (PTB));		/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      86    arr[i++] = memchr (pb3, 0, sizeof (PB));		/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      87    arr[i++] = memchr (pb4, 0, sizeof (__typeof (pb4)));	/* { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" } */
      88  
      89    /* These are correct, no warning.  */
      90    arr[i++] = memchr (&b, 0, sizeof b);
      91    arr[i++] = memchr (&b, 0, sizeof (b));
      92    arr[i++] = memchr (&b, 0, sizeof (struct B));
      93    arr[i++] = memchr (&b, 0, sizeof (const struct B));
      94    arr[i++] = memchr (&b, 0, sizeof (volatile struct B));
      95    arr[i++] = memchr (&b, 0, sizeof (volatile const struct B));
      96    arr[i++] = memchr (&b, 0, sizeof (TB));
      97    arr[i++] = memchr (&b, 0, sizeof (__typeof (*&b)));
      98    arr[i++] = memchr (pb1, 0, sizeof (*pb1));
      99    arr[i++] = memchr (pb2, 0, sizeof (*pb3));
     100    arr[i++] = memchr (pb3, 0, sizeof (__typeof (*pb3)));
     101    /* These are probably broken, but obfuscated, no warning.  */
     102    arr[i++] = memchr ((void *) &b, 0, sizeof (&b));
     103    arr[i++] = memchr ((char *) &b, 0, sizeof (&b));
     104    arr[i++] = memchr (&b, 0, sizeof (&b) + 0);
     105    arr[i++] = memchr (&b, 0, 0 + sizeof (&b));
     106  
     107    foo (arr);
     108  }
     109  
     110  void
     111  f3 (void *x, char *y, int z, X w)
     112  {
     113    unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
     114    char buf1[7];
     115    signed char buf2[z + 32];
     116    long buf3[17];
     117    int *buf4[9];
     118    signed char *y2 = buf2;
     119    char c;
     120    void *arr[100];
     121    int i = 0;
     122    arr[i++] = memchr (y, 0, sizeof (y));			/* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     123    arr[i++] = memchr (y1, 0, sizeof (y1));		/* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     124    arr[i++] = memchr (y2, 0, sizeof (y2));		/* { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" } */
     125    arr[i++] = memchr (&c, 0, sizeof (&c));		/* { dg-warning "call is the same expression as the source; did you mean to remove the addressof" } */
     126    arr[i++] = memchr (w, 0, sizeof w);			/* { dg-warning "call is the same expression as the source; did you mean to dereference it" } */
     127  
     128    /* These are correct, no warning.  */
     129    arr[i++] = memchr (y, 0, sizeof (*y));
     130    arr[i++] = memchr (y1, 0, sizeof (*y2));
     131    arr[i++] = memchr (buf1, 0, sizeof buf1);
     132    arr[i++] = memchr (buf3, 0, sizeof (buf3));
     133    arr[i++] = memchr (&buf3[0], 0, sizeof (buf3));
     134    arr[i++] = memchr (&buf4[0], 0, sizeof (buf4));
     135    arr[i++] = memchr (w, 0, sizeof (X));
     136    /* These are probably broken, but obfuscated, no warning.  */
     137    arr[i++] = memchr ((void *) y, 0, sizeof (y));
     138    arr[i++] = memchr ((char *) y1, 0, sizeof (y2));
     139    arr[i++] = memchr (y, 0, sizeof (y) + 0);
     140    arr[i++] = memchr (y1, 0, 0 + sizeof (y2));
     141    arr[i++] = memchr ((void *) &c, 0, sizeof (&c));
     142    arr[i++] = memchr ((signed char *) &c, 0, sizeof (&c));
     143    arr[i++] = memchr (&c, 0, sizeof (&c) + 0);
     144    arr[i++] = memchr (&c, 0, 0 + sizeof (&c));
     145  
     146    foo (arr);
     147  }
     148  
     149  void
     150  f4 (char x[64], char *y, __builtin_va_list ap)
     151  {
     152    char buf[128], *p = buf;
     153    snprintf (x, sizeof (x), "%s", y);	    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     154    vsnprintf (x, sizeof (x), "%s", ap);	    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     155    snprintf (p, sizeof (p), "%s", y);	    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     156    vsnprintf (p, sizeof (p), "%s", ap);	    /* { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" } */
     157  
     158    /* These are correct, no warning.  */
     159    snprintf (buf, sizeof (buf), "%s", y);
     160    vsnprintf (buf, sizeof (buf), "%s", ap);
     161    snprintf (p, sizeof (buf), "%s", y);
     162    vsnprintf (p, sizeof (buf), "%s", ap);
     163  }
     164  
     165  /* { dg-prune-output "-Wuninitialized" } */