1 /* PR tree-optimization/83456 - -Wrestrict false positive on a non-overlapping
2    memcpy in an inline function
3    Verify that calls to built-in functions are diagnosed when the pointer
4    arguments to their restrict-qualified parameters are the same (the absence
5    of the false positives reported in PR 83456 is tested in Wrestrict-12.c.
6    { dg-do compile }
7    { dg-options "-O2 -Wall -Wrestrict -Wno-stringop-truncation" }  */
8 
9 typedef __SIZE_TYPE__ size_t;
10 
11 extern void* memcpy (void* restrict, const void* restrict, size_t);
12 extern void* mempcpy (void* restrict, const void* restrict, size_t);
13 extern char* stpncpy (char* restrict, const char* restrict, size_t);
14 extern char* stpcpy (char* restrict, const char* restrict);
15 extern char* strncat (char* restrict, const char* restrict, size_t);
16 extern char* strcat (char* restrict, const char* restrict);
17 extern char* strncpy (char* restrict, const char* restrict, size_t);
18 extern char* strcpy (char* restrict, const char* restrict);
19 
20 struct S
21 {
22   char a[4];
23   char *p;
24 } s;
25 
26 void sink (void*);
27 
test_memcpy(char * p,struct S * q,size_t n)28 void test_memcpy (char *p, struct S *q, size_t n)
29 {
30   /* The behavior of memcpy() is undefined only when when copying takes
31      place between overlapping objects.  Since a call with a size of zero
32      does nothing, it should not be diagnosed.  */
33   memcpy (p, p, 0);
34   sink (p);
35 
36   memcpy (p, p, 1);               /* { dg-warning "\\\[-Wrestrict]" } */
37   sink (p);
38 
39   memcpy (p, p, n);               /* { dg-warning "\\\[-Wrestrict]" } */
40   sink (p);
41 
42   memcpy (q->a, q->a, 0);
43   sink (q);
44 
45   memcpy (q->p, q->p, 1);         /* { dg-warning "\\\[-Wrestrict]" } */
46   sink (q);
47 
48   memcpy (&q->a[0], q->a, n);     /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */
49   sink (q);
50 
51   memcpy (q, q->a, n);            /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */
52   sink (q);
53 }
54 
test_mempcpy(char * p,struct S * q,size_t n)55 void test_mempcpy (char *p, struct S *q, size_t n)
56 {
57   mempcpy (p, p, 0);
58   sink (p);
59 
60   mempcpy (p, p, 1);              /* { dg-warning "\\\[-Wrestrict]" } */
61   sink (p);
62 
63   mempcpy (p, p, n);              /* { dg-warning "\\\[-Wrestrict]" } */
64   sink (p);
65 
66   mempcpy (q->a, q->a, 0);
67   sink (q);
68 
69   mempcpy (q->p, q->p, 1);        /* { dg-warning "\\\[-Wrestrict]" } */
70   sink (q);
71 
72   mempcpy (&q->a[0], q->a, n);    /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */
73   sink (q);
74 
75   mempcpy (q, q->a, n);           /* { dg-warning "\\\[-Wrestrict]" "bug ????" { xfail *-*-* } } */
76   sink (q);
77 }
78 
test_strncat(char * p,struct S * q,size_t n)79 void test_strncat (char *p, struct S *q, size_t n)
80 {
81   strncat (p, p, 0);
82   sink (p);
83 
84   strncat (p, p, 1);              /* { dg-warning "\\\[-Wrestrict]" } */
85   sink (p);
86 
87   strncat (p, p, n);              /* { dg-warning "\\\[-Wrestrict]" } */
88   sink (p);
89 
90   strncat (q->a, q->a, n);        /* { dg-warning "\\\[-Wrestrict]" } */
91   sink (q);
92 
93   strncat (&q->a[0], &q->a[0], n);/* { dg-warning "\\\[-Wrestrict]" } */
94   sink (q);
95 
96   strncat (q->a, &q->a[0], n);    /* { dg-warning "\\\[-Wrestrict]" } */
97   sink (q);
98 
99   strncat (q->p, &q->p[0], n);    /* { dg-warning "\\\[-Wrestrict]" } */
100   sink (q);
101 }
102 
test_strcat(char * p,struct S * q,size_t n)103 void test_strcat (char *p, struct S *q, size_t n)
104 {
105   strcat (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
106   sink (p);
107 
108   strcat (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
109   sink (p);
110 
111   strcat (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
112   sink (p);
113 
114   strcat (q->a, q->a);            /* { dg-warning "\\\[-Wrestrict]" } */
115   sink (q);
116 
117   strcat (&q->a[0], &q->a[0]);    /* { dg-warning "\\\[-Wrestrict]" } */
118   sink (q);
119 
120   strcat (q->a, &q->a[0]);        /* { dg-warning "\\\[-Wrestrict]" } */
121   sink (q);
122 
123   strcat (q->p, &q->p[0]);        /* { dg-warning "\\\[-Wrestrict]" } */
124   sink (q);
125 }
126 
test_stpncpy(char * p,struct S * q,size_t n)127 void test_stpncpy (char *p, struct S *q, size_t n)
128 {
129   stpncpy (p, p, 0);              /* { dg-warning "\\\[-Wrestrict]" } */
130   sink (p);
131 
132   stpncpy (p, p, 1);              /* { dg-warning "\\\[-Wrestrict]" } */
133   sink (p);
134 
135   stpncpy (p, p, n);              /* { dg-warning "\\\[-Wrestrict]" } */
136   sink (p);
137 
138   stpncpy (q->a, q->a, n);        /* { dg-warning "\\\[-Wrestrict]" } */
139   sink (q);
140 
141   stpncpy (&q->a[0], &q->a[0], n);/* { dg-warning "\\\[-Wrestrict]" } */
142   sink (q);
143 
144   stpncpy (q->a, &q->a[0], n);    /* { dg-warning "\\\[-Wrestrict]" } */
145   sink (q);
146 
147   stpncpy (q->p, &q->p[0], n);    /* { dg-warning "\\\[-Wrestrict]" } */
148   sink (q);
149 }
150 
test_stpcpy(char * p,struct S * q,size_t n)151 void test_stpcpy (char *p, struct S *q, size_t n)
152 {
153   stpcpy (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
154   sink (p);
155 
156   stpcpy (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
157   sink (p);
158 
159   stpcpy (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
160   sink (p);
161 
162   stpcpy (q->a, q->a);            /* { dg-warning "\\\[-Wrestrict]" } */
163   sink (q);
164 
165   stpcpy (&q->a[0], &q->a[0]);    /* { dg-warning "\\\[-Wrestrict]" } */
166   sink (q);
167 
168   stpcpy (q->a, &q->a[0]);        /* { dg-warning "\\\[-Wrestrict]" } */
169   sink (q);
170 
171   stpcpy (q->p, &q->p[0]);        /* { dg-warning "\\\[-Wrestrict]" } */
172   sink (q);
173 }
174 
test_strncpy(char * p,struct S * q,size_t n)175 void test_strncpy (char *p, struct S *q, size_t n)
176 {
177   strncpy (p, p, 0);
178   sink (p);
179 
180   strncpy (p, p, 1);              /* { dg-warning "\\\[-Wrestrict]" } */
181   sink (p);
182 
183   strncpy (p, p, n);              /* { dg-warning "\\\[-Wrestrict]" } */
184   sink (p);
185 
186   strncpy (q->a, q->a, n);        /* { dg-warning "\\\[-Wrestrict]" } */
187   sink (q);
188 
189   strncpy (&q->a[0], &q->a[0], n);/* { dg-warning "\\\[-Wrestrict]" } */
190   sink (q);
191 
192   strncpy (q->a, &q->a[0], n);    /* { dg-warning "\\\[-Wrestrict]" } */
193   sink (q);
194 
195   strncpy (q->p, &q->p[0], n);    /* { dg-warning "\\\[-Wrestrict]" } */
196   sink (q);
197 }
198 
test_strcpy(char * p,struct S * q,size_t n)199 void test_strcpy (char *p, struct S *q, size_t n)
200 {
201   strcpy (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
202   sink (p);
203 
204   strcpy (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
205   sink (p);
206 
207   strcpy (p, p);                  /* { dg-warning "\\\[-Wrestrict]" } */
208   sink (p);
209 
210   strcpy (q->a, q->a);            /* { dg-warning "\\\[-Wrestrict]" } */
211   sink (q);
212 
213   strcpy (&q->a[0], &q->a[0]);    /* { dg-warning "\\\[-Wrestrict]" } */
214   sink (q);
215 
216   strcpy (q->a, &q->a[0]);        /* { dg-warning "\\\[-Wrestrict]" } */
217   sink (q);
218 
219   strcpy (q->p, &q->p[0]);        /* { dg-warning "\\\[-Wrestrict]" } */
220   sink (q);
221 }
222