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