PR tree-optimization/81384 - built-in form of strnlen missing
[official-gcc.git] / gcc / testsuite / gcc.dg / strlenopt-45.c
blobbd9b197a75d6913407ead49dc303903a81c7b5ad
1 /* PR tree-optimization/81384 - built-in form of strnlen missing
2 Test to verify that strnlen built-in expansion works correctly
3 in the absence of tree strlen optimization.
4 { dg-do compile }
5 { dg-options "-O2 -Wall -fdump-tree-optimized" } */
7 #include "strlenopt.h"
9 #define PTRDIFF_MAX __PTRDIFF_MAX__
10 #define SIZE_MAX __SIZE_MAX__
12 typedef __SIZE_TYPE__ size_t;
14 extern void abort (void);
15 extern size_t strnlen (const char *, size_t);
17 #define CAT(x, y) x ## y
18 #define CONCAT(x, y) CAT (x, y)
19 #define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
21 #define FAIL(name) do { \
22 extern void FAILNAME (name) (void); \
23 FAILNAME (name)(); \
24 } while (0)
26 /* Macro to emit a call to funcation named
27 call_in_true_branch_not_eliminated_on_line_NNN()
28 for each call that's expected to be eliminated. The dg-final
29 scan-tree-dump-time directive at the bottom of the test verifies
30 that no such call appears in output. */
31 #define ELIM(expr) \
32 if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0
34 /* Macro to emit a call to a function named
35 call_made_in_{true,false}_branch_on_line_NNN()
36 for each call that's expected to be retained. The dg-final
37 scan-tree-dump-time directive at the bottom of the test verifies
38 that the expected number of both kinds of calls appears in output
39 (a pair for each line with the invocation of the KEEP() macro. */
40 #define KEEP(expr) \
41 if (expr) \
42 FAIL (made_in_true_branch); \
43 else \
44 FAIL (made_in_false_branch)
46 extern char c;
47 extern char a1[1];
48 extern char a3[3];
49 extern char a5[5];
50 extern char a3_7[3][7];
51 extern char ax[];
53 void elim_strnlen_arr_cst (void)
55 /* The length of a string stored in a one-element array must be zero.
56 The result reported by strnlen() for such an array can be non-zero
57 only when the bound is equal to 1 (in which case the result must
58 be one). */
59 ELIM (strnlen (&c, 0) == 0);
60 ELIM (strnlen (&c, 1) < 2);
61 ELIM (strnlen (&c, 2) == 0);
62 ELIM (strnlen (&c, 9) == 0);
63 ELIM (strnlen (&c, PTRDIFF_MAX) == 0);
64 ELIM (strnlen (&c, SIZE_MAX) == 0);
65 ELIM (strnlen (&c, -1) == 0);
67 ELIM (strnlen (a1, 0) == 0);
68 ELIM (strnlen (a1, 1) < 2);
69 ELIM (strnlen (a1, 2) == 0);
70 ELIM (strnlen (a1, 9) == 0);
71 ELIM (strnlen (a1, PTRDIFF_MAX) == 0);
72 ELIM (strnlen (a1, SIZE_MAX) == 0);
73 ELIM (strnlen (a1, -1) == 0);
75 ELIM (strnlen (a3, 0) == 0);
76 ELIM (strnlen (a3, 1) < 2);
77 ELIM (strnlen (a3, 2) < 3);
78 ELIM (strnlen (a3, 3) < 4);
79 ELIM (strnlen (a3, 9) < 4);
80 ELIM (strnlen (a3, PTRDIFF_MAX) < 4);
81 ELIM (strnlen (a3, SIZE_MAX) < 4);
82 ELIM (strnlen (a3, -1) < 4);
84 ELIM (strnlen (a3_7[0], 0) == 0);
85 ELIM (strnlen (a3_7[0], 1) < 2);
86 ELIM (strnlen (a3_7[0], 2) < 3);
87 ELIM (strnlen (a3_7[0], 3) < 4);
88 ELIM (strnlen (a3_7[0], 9) < 8);
89 ELIM (strnlen (a3_7[0], PTRDIFF_MAX) < 8);
90 ELIM (strnlen (a3_7[0], SIZE_MAX) < 8);
91 ELIM (strnlen (a3_7[0], -1) < 8);
93 ELIM (strnlen (a3_7[2], 0) == 0);
94 ELIM (strnlen (a3_7[2], 1) < 2);
95 ELIM (strnlen (a3_7[2], 2) < 3);
96 ELIM (strnlen (a3_7[2], 3) < 4);
97 ELIM (strnlen (a3_7[2], 9) < 8);
98 ELIM (strnlen (a3_7[2], PTRDIFF_MAX) < 8);
99 ELIM (strnlen (a3_7[2], SIZE_MAX) < 8);
100 ELIM (strnlen (a3_7[2], -1) < 8);
102 ELIM (strnlen ((char*)a3_7, 0) == 0);
103 ELIM (strnlen ((char*)a3_7, 1) < 2);
104 ELIM (strnlen ((char*)a3_7, 2) < 3);
105 ELIM (strnlen ((char*)a3_7, 3) < 4);
106 ELIM (strnlen ((char*)a3_7, 9) < 10);
107 ELIM (strnlen ((char*)a3_7, 19) < 20);
108 ELIM (strnlen ((char*)a3_7, 21) < 22);
109 ELIM (strnlen ((char*)a3_7, 23) < 22);
110 ELIM (strnlen ((char*)a3_7, PTRDIFF_MAX) < 22);
111 ELIM (strnlen ((char*)a3_7, SIZE_MAX) < 22);
112 ELIM (strnlen ((char*)a3_7, -1) < 22);
114 ELIM (strnlen (ax, 0) == 0);
115 ELIM (strnlen (ax, 1) < 2);
116 ELIM (strnlen (ax, 2) < 3);
117 ELIM (strnlen (ax, 9) < 10);
118 ELIM (strnlen (a3, PTRDIFF_MAX) <= PTRDIFF_MAX);
119 ELIM (strnlen (a3, SIZE_MAX) < PTRDIFF_MAX);
120 ELIM (strnlen (a3, -1) < PTRDIFF_MAX);
123 struct MemArrays
125 char c;
126 char a0[0];
127 char a1[1];
128 char a3[3];
129 char a5[5];
130 char a3_7[3][7];
131 char ax[1];
134 void elim_strnlen_memarr_cst (struct MemArrays *p, int i)
136 ELIM (strnlen (&p->c, 0) == 0);
137 ELIM (strnlen (&p->c, 1) < 2);
138 ELIM (strnlen (&p->c, 9) == 0);
139 ELIM (strnlen (&p->c, PTRDIFF_MAX) == 0);
140 ELIM (strnlen (&p->c, SIZE_MAX) == 0);
141 ELIM (strnlen (&p->c, -1) == 0);
143 /* Other accesses to internal zero-length arrays are undefined. */
144 ELIM (strnlen (p->a0, 0) == 0);
146 ELIM (strnlen (p->a1, 0) == 0);
147 ELIM (strnlen (p->a1, 1) < 2);
148 ELIM (strnlen (p->a1, 9) == 0);
149 ELIM (strnlen (p->a1, PTRDIFF_MAX) == 0);
150 ELIM (strnlen (p->a1, SIZE_MAX) == 0);
151 ELIM (strnlen (p->a1, -1) == 0);
153 ELIM (strnlen (p->a3, 0) == 0);
154 ELIM (strnlen (p->a3, 1) < 2);
155 ELIM (strnlen (p->a3, 2) < 3);
156 ELIM (strnlen (p->a3, 3) < 4);
157 ELIM (strnlen (p->a3, 9) < 4);
158 ELIM (strnlen (p->a3, PTRDIFF_MAX) < 4);
159 ELIM (strnlen (p->a3, SIZE_MAX) < 4);
160 ELIM (strnlen (p->a3, -1) < 4);
162 ELIM (strnlen (p[i].a3, 0) == 0);
163 ELIM (strnlen (p[i].a3, 1) < 2);
164 ELIM (strnlen (p[i].a3, 2) < 3);
165 ELIM (strnlen (p[i].a3, 3) < 4);
166 ELIM (strnlen (p[i].a3, 9) < 4);
167 ELIM (strnlen (p[i].a3, PTRDIFF_MAX) < 4);
168 ELIM (strnlen (p[i].a3, SIZE_MAX) < 4);
169 ELIM (strnlen (p[i].a3, -1) < 4);
171 ELIM (strnlen (p->a3_7[0], 0) == 0);
172 ELIM (strnlen (p->a3_7[0], 1) < 2);
173 ELIM (strnlen (p->a3_7[0], 2) < 3);
174 ELIM (strnlen (p->a3_7[0], 3) < 4);
175 ELIM (strnlen (p->a3_7[0], 9) < 8);
176 ELIM (strnlen (p->a3_7[0], PTRDIFF_MAX) < 8);
177 ELIM (strnlen (p->a3_7[0], SIZE_MAX) < 8);
178 ELIM (strnlen (p->a3_7[0], -1) < 8);
180 ELIM (strnlen (p->a3_7[2], 0) == 0);
181 ELIM (strnlen (p->a3_7[2], 1) < 2);
182 ELIM (strnlen (p->a3_7[2], 2) < 3);
183 ELIM (strnlen (p->a3_7[2], 3) < 4);
184 ELIM (strnlen (p->a3_7[2], 9) < 8);
185 ELIM (strnlen (p->a3_7[2], PTRDIFF_MAX) < 8);
186 ELIM (strnlen (p->a3_7[2], SIZE_MAX) < 8);
187 ELIM (strnlen (p->a3_7[2], -1) < 8);
189 ELIM (strnlen (p->a3_7[i], 0) == 0);
190 ELIM (strnlen (p->a3_7[i], 1) < 2);
191 ELIM (strnlen (p->a3_7[i], 2) < 3);
192 ELIM (strnlen (p->a3_7[i], 3) < 4);
194 #if 0
195 /* This is tranformed into strnlen ((char*)p + offsetof (a3_7[i]), N)
196 which makes it impssible to determine the size of the array. */
197 ELIM (strnlen (p->a3_7[i], 9) < 8);
198 ELIM (strnlen (p->a3_7[i], PTRDIFF_MAX) < 8);
199 ELIM (strnlen (p->a3_7[i], SIZE_MAX) < 8);
200 ELIM (strnlen (p->a3_7[i], -1) < 8);
201 #else
202 ELIM (strnlen (p->a3_7[i], 9) < 10);
203 ELIM (strnlen (p->a3_7[i], 19) < 20);
204 #endif
206 ELIM (strnlen ((char*)p->a3_7, 0) == 0);
207 ELIM (strnlen ((char*)p->a3_7, 1) < 2);
208 ELIM (strnlen ((char*)p->a3_7, 2) < 3);
209 ELIM (strnlen ((char*)p->a3_7, 3) < 4);
210 ELIM (strnlen ((char*)p->a3_7, 9) < 10);
211 ELIM (strnlen ((char*)p->a3_7, 19) < 20);
212 ELIM (strnlen ((char*)p->a3_7, 21) < 22);
213 ELIM (strnlen ((char*)p->a3_7, 23) < 22);
214 ELIM (strnlen ((char*)p->a3_7, PTRDIFF_MAX) < 22);
215 ELIM (strnlen ((char*)p->a3_7, SIZE_MAX) < 22);
216 ELIM (strnlen ((char*)p->a3_7, -1) < 22);
218 ELIM (strnlen (p->ax, 0) == 0);
219 ELIM (strnlen (p->ax, 1) < 2);
220 ELIM (strnlen (p->ax, 2) < 3);
221 ELIM (strnlen (p->ax, 9) < 10);
222 ELIM (strnlen (p->a3, PTRDIFF_MAX) <= PTRDIFF_MAX);
223 ELIM (strnlen (p->a3, SIZE_MAX) < PTRDIFF_MAX);
224 ELIM (strnlen (p->a3, -1) < PTRDIFF_MAX);
228 void elim_strnlen_str_cst (void)
230 const char *s0 = "";
231 const char *s1 = "1";
232 const char *s3 = "123";
234 ELIM (strnlen (s0, 0) == 0);
235 ELIM (strnlen (s0, 1) == 0);
236 ELIM (strnlen (s0, 9) == 0);
237 ELIM (strnlen (s0, PTRDIFF_MAX) == 0);
238 ELIM (strnlen (s0, SIZE_MAX) == 0);
239 ELIM (strnlen (s0, -1) == 0);
241 ELIM (strnlen (s1, 0) == 0);
242 ELIM (strnlen (s1, 1) == 1);
243 ELIM (strnlen (s1, 9) == 1);
244 ELIM (strnlen (s1, PTRDIFF_MAX) == 1);
245 ELIM (strnlen (s1, SIZE_MAX) == 1);
246 ELIM (strnlen (s1, -2) == 1);
248 ELIM (strnlen (s3, 0) == 0);
249 ELIM (strnlen (s3, 1) == 1);
250 ELIM (strnlen (s3, 2) == 2);
251 ELIM (strnlen (s3, 3) == 3);
252 ELIM (strnlen (s3, 9) == 3);
253 ELIM (strnlen (s3, PTRDIFF_MAX) == 3);
254 ELIM (strnlen (s3, SIZE_MAX) == 3);
255 ELIM (strnlen (s3, -2) == 3);
258 void elim_strnlen_range (char *s)
260 const char *s0 = "";
261 const char *s1 = "1";
262 const char *s3 = "123";
264 size_t n_0_1 = (size_t)s & 1;
265 size_t n_0_2 = ((size_t)s & 3) < 3 ? ((size_t)s & 3) : 2;
266 size_t n_0_3 = (size_t)s & 3;
267 size_t n_1_2 = n_0_1 + 1;
269 ELIM (strnlen (s0, n_0_1) == 0);
270 ELIM (strnlen (s0, n_0_2) == 0);
271 ELIM (strnlen (s0, n_1_2) == 0);
273 ELIM (strnlen (s1, n_0_1) < 2);
274 ELIM (strnlen (s1, n_0_2) < 2);
275 ELIM (strnlen (s1, n_0_3) < 2);
277 ELIM (strnlen (s1, n_1_2) > 0);
278 ELIM (strnlen (s1, n_1_2) < 2);
280 ELIM (strnlen (s3, n_0_1) < 2);
281 ELIM (strnlen (s3, n_0_2) < 3);
282 ELIM (strnlen (s3, n_0_3) < 4);
284 ELIM (strnlen (s3, n_1_2) > 0);
285 ELIM (strnlen (s3, n_1_2) < 4);
289 #line 1000
291 void keep_strnlen_arr_cst (void)
293 KEEP (strnlen (&c, 1) == 0);
294 KEEP (strnlen (&c, 1) == 1);
296 KEEP (strnlen (a1, 1) == 0);
297 KEEP (strnlen (a1, 1) == 1);
299 KEEP (strnlen (ax, 9) < 9);
302 struct FlexArrays
304 char c;
305 char a0[0]; /* Access to internal zero-length arrays are undefined. */
306 char a1[1];
309 void keep_strnlen_memarr_cst (struct FlexArrays *p)
311 KEEP (strnlen (&p->c, 1) == 0);
312 KEEP (strnlen (&p->c, 1) == 1);
314 #if 0
315 /* Accesses to internal zero-length arrays are undefined so avoid
316 exercising them. */
317 KEEP (strnlen (p->a0, 1) == 0);
318 KEEP (strnlen (p->a0, 1) == 1);
319 KEEP (strnlen (p->a0, 9) < 9);
320 #endif
322 KEEP (strnlen (p->a1, 1) == 0);
323 KEEP (strnlen (p->a1, 1) == 1);
325 KEEP (strnlen (p->a1, 2) == 0);
326 KEEP (strnlen (p->a1, 2) == 1);
327 KEEP (strnlen (p->a1, 2) == 2);
329 KEEP (strnlen (p->a1, 9) < 9);
332 /* { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated_" 0 "optimized" } }
334 { dg-final { scan-tree-dump-times "call_made_in_true_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 13 "optimized" } }
335 { dg-final { scan-tree-dump-times "call_made_in_false_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 13 "optimized" } } */