1 /* Test -Wsizeof-pointer-memaccess warnings.  */
2 /* { dg-do compile } */
3 /* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument" } */
4 /* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-c++-compat" { 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
f1(void * x)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
f2(void * x)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
f3(void * x,char * y,int z,X w)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
f4(char x[64],char * y,__builtin_va_list ap)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