1 /* PR tree-optimization/101397 - spurious warning writing to the result
2    of stpcpy minus 1
3    Verify warnings for indexing into a pointer returned from mempcpy.
4    The call mempcpy(S1, S2, N) returns &S1[N].
5    { dg-do compile }
6    { dg-options "-O2 -Wall" } */
7 
8 typedef __SIZE_TYPE__ size_t;
9 
10 void* mempcpy (void*, const void*, size_t);
11 
12 extern char ax[], a3[3], a5[5], a7[7], *s;
13 
14 volatile int x;
15 
16 /* Verify warnings for indexing into the result of mempcpy with a source
17    pointing to an array of unknown bound.  */
18 
test_mempcpy_from_ptr(int i)19 void test_mempcpy_from_ptr (int i)
20 {
21   {
22     char *p = mempcpy (ax, s, 5);
23     x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
24     x = p[-5];
25     x = p[-1];
26     x = p[ 0];
27     x = p[ 9];
28   }
29 
30   {
31     char *p = mempcpy (a5, s, 3);
32     x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
33     x = p[-3];
34     x = p[-2];
35     x = p[-1];
36     x = p[ 0];
37     x = p[ 1];
38     x = p[ 2];                          // { dg-warning "\\\[-Warray-bounds" }
39   }
40 
41   {
42     char *p = mempcpy (a5, s, 4);
43     x = p[-5];                          // { dg-warning "\\\[-Warray-bounds" }
44     x = p[-4];
45     x = p[-3];
46     x = p[-2];
47     x = p[-1];
48     x = p[ 0];
49     x = p[ 1];                          // { dg-warning "\\\[-Warray-bounds" }
50   }
51 
52   {
53     char *p = mempcpy (a5, s, 4);
54 
55     if (i > -1) i = -1;
56     x = p[i];
57 
58     if (i > -2) i = -2;
59     x = p[i];
60 
61     if (i > -3) i = -3;
62     x = p[i];
63 
64     if (i > -4) i = -4;
65     x = p[i];
66 
67     if (i > -5) i = -5;
68     x = p[i];                           // { dg-warning "\\\[-Warray-bounds" }
69   }
70 }
71 
72 /* Verify warnings for indexing into the result of mempcpy with a source
73    an array of size 5.  */
74 
test_mempcpy_from_a5(int i,int n,int n3_9)75 void test_mempcpy_from_a5 (int i, int n, int n3_9)
76 {
77   {
78     // The returned pointer is ax + 3 as specified by the bound.
79     char *p = mempcpy (ax, a5, 3);
80     x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
81     x = p[-3];
82     x = p[-2];
83     x = p[ 0];
84     x = p[ 1];
85     x = p[ 2];
86   }
87 
88   {
89     // The returned pointer is ax + 5.
90     char *p = mempcpy (ax, a5, 5);
91     x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
92     x = p[-5];
93     x = p[-1];
94     x = p[ 0];
95     x = p[ 9];
96   }
97 
98   {
99     //The returned pointer is in [ax, ax + 5] even though n is not known.
100     char *p = mempcpy (ax, a5, n);
101     x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
102     x = p[-5];
103     x = p[-1];
104     x = p[ 0];
105     x = p[ 9];
106   }
107 
108 
109   {
110     // The returned pointer is a3 + 3.
111     char *p = mempcpy (a3, a5, 3);
112     x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
113     x = p[-3];
114     x = p[-1];
115     x = p[ 0];                          // { dg-warning "\\\[-Warray-bounds" }
116     x = p[ 1];                          // { dg-warning "\\\[-Warray-bounds" }
117   }
118 
119   {
120     // The returned pointer is in [a3, a3 + 3].
121     char *p = mempcpy (a3, a5, n);
122     x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
123     x = p[-3];
124     x = p[-2];
125     x = p[-1];
126     x = p[ 0];
127     x = p[ 2];
128     x = p[ 3];                          // { dg-warning "\\\[-Warray-bounds" }
129   }
130 
131   {
132     if (n3_9 < 3 || 9 < n3_9)
133       n3_9 = 3;
134 
135     // The returned pointer is a3.
136     char *p = mempcpy (a3, a5, n3_9);
137     x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
138     x = p[-3];
139     x = p[-2];
140     x = p[-1];
141     x = p[ 0];                          // { dg-warning "\\\[-Warray-bounds" }
142   }
143 
144   {
145     char *p = mempcpy (a3, a5, 3);
146 
147     if (i > -1) i = -1;
148     x = p[i];
149 
150     if (i > -2) i = -2;
151     x = p[i];
152 
153     if (i > -3) i = -3;
154     x = p[i];
155 
156     if (i > -4) i = -4;
157     x = p[i];                           // { dg-warning "\\\[-Warray-bounds" }
158   }
159 }
160 
161 
162 /* Verify warnings for indexing into the result of mempcpy with a source
163    an array of size 7.  */
164 
test_mempcpy_from_a7(int i,int n,int n3_9)165 void test_mempcpy_from_a7 (int i, int n, int n3_9)
166 {
167   {
168     // The returned pointer is ax + 5.
169     char *p = mempcpy (ax, a7, 5);
170     x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
171     x = p[-5];
172     x = p[-1];
173     x = p[ 0];
174     x = p[ 9];
175   }
176 
177   {
178     //The returned pointer is in [ax, ax + 7] even though n is not known.
179     char *p = mempcpy (ax, a7, n);
180     x = p[-8];                          // { dg-warning "\\\[-Warray-bounds" }
181     x = p[-7];
182     x = p[-1];
183     x = p[ 0];
184     x = p[ 9];
185   }
186 
187 
188   {
189     // The returned pointer is a5 + 3 as specified by the bound.
190     char *p = mempcpy (a5, a7, 3);
191     x = p[-4];                          // { dg-warning "\\\[-Warray-bounds" }
192     x = p[-3];
193     x = p[-2];
194     x = p[ 0];
195     x = p[ 1];
196     x = p[ 2];                          // { dg-warning "\\\[-Warray-bounds" }
197   }
198 
199   {
200     // The returned pointer is a5 + 4.
201     char *p = mempcpy (a5, a7, 4);
202     x = p[-5];                          // { dg-warning "\\\[-Warray-bounds" }
203     x = p[-4];
204     x = p[-3];
205     x = p[-2];
206     x = p[-1];
207     x = p[ 0];
208     x = p[ 1];                          // { dg-warning "\\\[-Warray-bounds" }
209   }
210 
211   {
212     // The returned pointer is in [a5, a5 + 5].
213     char *p = mempcpy (a5, a7, n);
214     x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
215     x = p[-5];
216     x = p[-3];
217     x = p[-2];
218     x = p[-1];
219     x = p[ 0];
220     x = p[ 4];
221     x = p[ 5];                          // { dg-warning "\\\[-Warray-bounds" }
222   }
223 
224   {
225     if (n3_9 < 3 || 9 < n3_9)
226       n3_9 = 3;
227 
228     // The returned pointer is in [a5 + 3, a5 + 5].
229     char *p = mempcpy (a5, a7, n3_9);
230     x = p[-6];                          // { dg-warning "\\\[-Warray-bounds" }
231     x = p[-5];
232     x = p[-3];
233     x = p[-2];
234     x = p[-1];
235     x = p[ 0];
236     x = p[ 1];
237     x = p[ 2];                          // { dg-warning "\\\[-Warray-bounds" }
238   }
239 
240   {
241     char *p = mempcpy (a5, a7, 4);
242 
243     if (i > -1) i = -1;
244     x = p[i];
245 
246     if (i > -2) i = -2;
247     x = p[i];
248 
249     if (i > -3) i = -3;
250     x = p[i];
251 
252     if (i > -4) i = -4;
253     x = p[i];
254 
255     if (i > -5) i = -5;
256     x = p[i];                           // { dg-warning "\\\[-Warray-bounds" }
257   }
258 }
259