PR tree-optimization/83369 - Missing diagnostics during inlining
[official-gcc.git] / gcc / testsuite / gcc.dg / strlenopt-40.c
blobf4577d69e1a40dd098aac553dc452825db85f507
1 /* PR tree-optimization/83671 - fix for false positive reported by
2 -Wstringop-overflow does not work with inlining
3 { dg-do compile }
4 { dg-options "-O1 -fdump-tree-optimized" } */
6 #include "strlenopt.h"
8 #define DIFF_MAX __PTRDIFF_MAX__
10 #define CAT(x, y) x ## y
11 #define CONCAT(x, y) CAT (x, y)
12 #define FAILNAME(name) CONCAT (call_ ## name ##_on_line_, __LINE__)
14 #define FAIL(name) do { \
15 extern void FAILNAME (name) (void); \
16 FAILNAME (name)(); \
17 } while (0)
19 /* Macros to emit a call to funcation named
20 call_in_{true,false}_branch_not_eliminated_on_line_NNN()
21 for each call that's expected to be eliminated. The dg-final
22 scan-tree-dump-time directive at the bottom of the test verifies
23 that no such call appears in output. */
24 #define ELIM_TRUE(expr) \
25 if (!(expr)) FAIL (in_true_branch_not_eliminated); else (void)0
27 #define ELIM_FALSE(expr) \
28 if (!!(expr)) FAIL (in_false_branch_not_eliminated); else (void)0
30 /* Macro to emit a call to a function named
31 call_made_in_{true,false}_branch_on_line_NNN()
32 for each call that's expected to be retained. The dg-final
33 scan-tree-dump-time directive at the bottom of the test verifies
34 that the expected number of both kinds of calls appears in output
35 (a pair for each line with the invocation of the KEEP() macro. */
36 #define KEEP(expr) \
37 if (expr) \
38 FAIL (made_in_true_branch); \
39 else \
40 FAIL (made_in_false_branch)
42 typedef char A3[3], A5[5], A7[7], AX[];
44 typedef A3 A7_3[7];
45 typedef A3 AX_3[];
46 typedef A5 A7_5[7];
47 typedef A7 A5_7[5];
49 extern A7_3 a7_3;
50 extern A5_7 a5_7;
51 extern AX_3 ax_3;
53 extern A3 a3;
54 extern A7 a5;
55 extern A7 a7;
56 extern AX ax;
58 extern A3 *pa3;
59 extern A5 *pa5;
60 extern A7 *pa7;
62 extern A7_3 *pa7_3;
63 extern AX_3 *pax_3;
64 extern A5_7 *pa5_7;
65 extern A7_5 *pa7_5;
67 extern char *ptr;
69 struct MemArrays0 {
70 A7_3 a7_3;
71 A5_7 a5_7;
72 char a3[3], a5[5], a0[0];
74 struct MemArraysX { char a3[3], a5[5], ax[]; };
75 struct MemArrays7 { char a3[3], a5[5], a7[7]; };
77 struct MemArrays0 ma0_3_5_7[3][5][7];
79 void elim_strings (int i)
81 ELIM_TRUE (strlen (i < 0 ? "123" : "321") == 3);
82 ELIM_FALSE (strlen (i < 0 ? "123" : "321") > 3);
83 ELIM_FALSE (strlen (i < 0 ? "123" : "321") < 3);
85 ELIM_TRUE (strlen (i < 0 ? "123" : "4321") >= 3);
86 ELIM_FALSE (strlen (i < 0 ? "123" : "4321") > 4);
87 ELIM_FALSE (strlen (i < 0 ? "123" : "4321") < 3);
89 ELIM_TRUE (strlen (i < 0 ? "1234" : "321") >= 3);
90 ELIM_FALSE (strlen (i < 0 ? "1234" : "321") < 3);
91 ELIM_FALSE (strlen (i < 0 ? "1234" : "321") > 4);
93 ELIM_TRUE (strlen (i < 0 ? "123" : "4321") <= 4);
94 ELIM_TRUE (strlen (i < 0 ? "1234" : "321") <= 4);
96 ELIM_TRUE (strlen (i < 0 ? "1" : "123456789") <= 9);
97 ELIM_TRUE (strlen (i < 0 ? "1" : "123456789") >= 1);
100 /* Verify that strlen calls involving uninitialized global arrays
101 of known size are eliminated when they appear in expressions
102 that test for results that must be true. */
103 void elim_global_arrays (int i)
105 /* Verify that the expression involving the strlen call as well
106 as whatever depends on it is eliminated from the test output.
107 All these expressions must be trivially true. */
108 ELIM_TRUE (strlen (a7_3[0]) < sizeof a7_3[0]);
109 ELIM_TRUE (strlen (a7_3[1]) < sizeof a7_3[1]);
110 ELIM_TRUE (strlen (a7_3[6]) < sizeof a7_3[6]);
111 ELIM_TRUE (strlen (a7_3[i]) < sizeof a7_3[i]);
113 ELIM_TRUE (strlen (a5_7[0]) < sizeof a5_7[0]);
114 ELIM_TRUE (strlen (a5_7[1]) < sizeof a5_7[1]);
115 ELIM_TRUE (strlen (a5_7[4]) < sizeof a5_7[4]);
116 ELIM_TRUE (strlen (a5_7[i]) < sizeof a5_7[0]);
118 ELIM_TRUE (strlen (ax_3[0]) < sizeof ax_3[0]);
119 ELIM_TRUE (strlen (ax_3[1]) < sizeof ax_3[1]);
120 ELIM_TRUE (strlen (ax_3[9]) < sizeof ax_3[9]);
121 ELIM_TRUE (strlen (ax_3[i]) < sizeof ax_3[i]);
123 ELIM_TRUE (strlen (a3) < sizeof a3);
124 ELIM_TRUE (strlen (a7) < sizeof a7);
126 ELIM_TRUE (strlen (ax) != DIFF_MAX);
127 ELIM_TRUE (strlen (ax) != DIFF_MAX - 1);
128 ELIM_TRUE (strlen (ax) < DIFF_MAX - 1);
131 void elim_pointer_to_arrays (void)
133 ELIM_TRUE (strlen (*pa7) < 7);
134 ELIM_TRUE (strlen (*pa5) < 5);
135 ELIM_TRUE (strlen (*pa3) < 3);
137 ELIM_TRUE (strlen ((*pa7_3)[0]) < 3);
138 ELIM_TRUE (strlen ((*pa7_3)[1]) < 3);
139 ELIM_TRUE (strlen ((*pa7_3)[6]) < 3);
141 ELIM_TRUE (strlen ((*pax_3)[0]) < 3);
142 ELIM_TRUE (strlen ((*pax_3)[1]) < 3);
143 ELIM_TRUE (strlen ((*pax_3)[9]) < 3);
145 ELIM_TRUE (strlen ((*pa5_7)[0]) < 7);
146 ELIM_TRUE (strlen ((*pa5_7)[1]) < 7);
147 ELIM_TRUE (strlen ((*pa5_7)[4]) < 7);
150 void elim_global_arrays_and_strings (int i)
152 ELIM_TRUE (strlen (i < 0 ? a3 : "") < 3);
153 ELIM_TRUE (strlen (i < 0 ? a3 : "1") < 3);
154 ELIM_TRUE (strlen (i < 0 ? a3 : "12") < 3);
155 ELIM_TRUE (strlen (i < 0 ? a3 : "123") < 4);
157 ELIM_FALSE (strlen (i < 0 ? a3 : "") > 3);
158 ELIM_FALSE (strlen (i < 0 ? a3 : "1") > 3);
159 ELIM_FALSE (strlen (i < 0 ? a3 : "12") > 3);
160 ELIM_FALSE (strlen (i < 0 ? a3 : "123") > 4);
162 ELIM_TRUE (strlen (i < 0 ? a7 : "") < 7);
163 ELIM_TRUE (strlen (i < 0 ? a7 : "1") < 7);
164 ELIM_TRUE (strlen (i < 0 ? a7 : "12") < 7);
165 ELIM_TRUE (strlen (i < 0 ? a7 : "123") < 7);
166 ELIM_TRUE (strlen (i < 0 ? a7 : "123456") < 7);
167 ELIM_TRUE (strlen (i < 0 ? a7 : "1234567") < 8);
169 ELIM_FALSE (strlen (i < 0 ? a7 : "") > 6);
170 ELIM_FALSE (strlen (i < 0 ? a7 : "1") > 6);
171 ELIM_FALSE (strlen (i < 0 ? a7 : "12") > 6);
172 ELIM_FALSE (strlen (i < 0 ? a7 : "123") > 6);
173 ELIM_FALSE (strlen (i < 0 ? a7 : "123456") > 7);
174 ELIM_FALSE (strlen (i < 0 ? a7 : "1234567") > 8);
177 void elim_member_arrays_obj (int i)
179 ELIM_TRUE (strlen (ma0_3_5_7[0][0][0].a3) < 3);
180 ELIM_TRUE (strlen (ma0_3_5_7[0][0][1].a3) < 3);
181 ELIM_TRUE (strlen (ma0_3_5_7[0][0][2].a3) < 3);
182 ELIM_TRUE (strlen (ma0_3_5_7[0][0][6].a3) < 3);
184 ELIM_TRUE (strlen (ma0_3_5_7[1][0][0].a3) < 3);
185 ELIM_TRUE (strlen (ma0_3_5_7[2][0][1].a3) < 3);
187 ELIM_TRUE (strlen (ma0_3_5_7[1][1][0].a3) < 3);
188 ELIM_TRUE (strlen (ma0_3_5_7[2][4][6].a3) < 3);
190 ELIM_TRUE (strlen (ma0_3_5_7[0][0][0].a5) < 5);
191 ELIM_TRUE (strlen (ma0_3_5_7[0][0][1].a5) < 5);
192 ELIM_TRUE (strlen (ma0_3_5_7[0][0][2].a5) < 5);
193 ELIM_TRUE (strlen (ma0_3_5_7[0][0][6].a5) < 5);
195 ELIM_TRUE (strlen (ma0_3_5_7[1][0][0].a5) < 5);
196 ELIM_TRUE (strlen (ma0_3_5_7[2][0][1].a5) < 5);
198 ELIM_TRUE (strlen (ma0_3_5_7[1][1][0].a5) < 5);
199 ELIM_TRUE (strlen (ma0_3_5_7[2][4][6].a5) < 5);
201 ELIM_TRUE (strlen (ma0_3_5_7[0][0][0].a7_3[0]) < 3);
202 ELIM_TRUE (strlen (ma0_3_5_7[2][4][6].a7_3[2]) < 3);
204 ELIM_TRUE (strlen (ma0_3_5_7[0][0][0].a5_7[0]) < 7);
205 ELIM_TRUE (strlen (ma0_3_5_7[2][4][6].a5_7[4]) < 7);
208 void elim_member_arrays_ptr (struct MemArrays0 *ma0,
209 struct MemArraysX *max,
210 struct MemArrays7 *ma7,
211 int i)
213 ELIM_TRUE (strlen (ma0->a7_3[0]) < 3);
214 ELIM_TRUE (strlen (ma0->a7_3[1]) < 3);
215 ELIM_TRUE (strlen (ma0->a7_3[6]) < 3);
216 ELIM_TRUE (strlen (ma0->a7_3[6]) < 3);
217 ELIM_TRUE (strlen (ma0->a7_3[i]) < 3);
218 ELIM_TRUE (strlen (ma0->a7_3[i]) < 3);
220 ELIM_TRUE (strlen (ma0->a5_7[0]) < 7);
221 ELIM_TRUE (strlen (ma0[0].a5_7[0]) < 7);
222 ELIM_TRUE (strlen (ma0[1].a5_7[0]) < 7);
223 ELIM_TRUE (strlen (ma0[1].a5_7[4]) < 7);
224 ELIM_TRUE (strlen (ma0[9].a5_7[0]) < 7);
225 ELIM_TRUE (strlen (ma0[9].a5_7[4]) < 7);
227 ELIM_TRUE (strlen (ma0->a3) < sizeof ma0->a3);
228 ELIM_TRUE (strlen (ma0->a5) < sizeof ma0->a5);
229 ELIM_TRUE (strlen (ma0->a0) < DIFF_MAX - 1);
231 ELIM_TRUE (strlen (max->a3) < sizeof max->a3);
232 ELIM_TRUE (strlen (max->a5) < sizeof max->a5);
233 ELIM_TRUE (strlen (max->ax) < DIFF_MAX - 1);
235 ELIM_TRUE (strlen (ma7->a3) < sizeof max->a3);
236 ELIM_TRUE (strlen (ma7->a5) < sizeof max->a5);
237 ELIM_TRUE (strlen (ma7->a7) < DIFF_MAX - 1);
241 #line 1000
243 /* Verify that strlen calls involving uninitialized global arrays
244 of unknown size are not eliminated when they appear in expressions
245 that test for results that need not be true. */
246 void keep_global_arrays (int i)
248 KEEP (strlen (a7_3[0]) < 2);
249 KEEP (strlen (a7_3[1]) < 2);
250 KEEP (strlen (a7_3[6]) < 2);
251 KEEP (strlen (a7_3[i]) < 2);
253 KEEP (strlen (a5_7[0]) < 6);
254 KEEP (strlen (a5_7[1]) < 6);
255 KEEP (strlen (a5_7[4]) < 6);
256 KEEP (strlen (a5_7[i]) < 6);
258 KEEP (strlen (ax_3[0]) < 2);
259 KEEP (strlen (ax_3[1]) < 2);
260 KEEP (strlen (ax_3[2]) < 2);
261 KEEP (strlen (ax_3[i]) < 2);
263 KEEP (strlen (a3) < 2);
264 KEEP (strlen (a7) < 6);
266 KEEP (strlen (a3 + i) < 2);
267 KEEP (strlen (a7 + i) < 2);
269 /* The length of an array of unknown size may be as large as
270 DIFF_MAX - 2. */
271 KEEP (strlen (ax) != DIFF_MAX - 2);
272 KEEP (strlen (ax) < DIFF_MAX - 2);
273 KEEP (strlen (ax) < 999);
274 KEEP (strlen (ax) < 1);
277 void keep_pointer_to_arrays (void)
279 KEEP (strlen (*pa7) < 6);
280 KEEP (strlen (*pa5) < 4);
281 KEEP (strlen (*pa3) < 2);
283 KEEP (strlen ((*pa7_3)[0]) < 2);
284 KEEP (strlen ((*pa7_3)[1]) < 2);
285 KEEP (strlen ((*pa7_3)[6]) < 2);
287 KEEP (strlen ((*pax_3)[0]) < 2);
288 KEEP (strlen ((*pax_3)[1]) < 2);
289 KEEP (strlen ((*pax_3)[9]) < 2);
291 KEEP (strlen ((*pa5_7)[0]) < 6);
292 KEEP (strlen ((*pa5_7)[1]) < 6);
293 KEEP (strlen ((*pa5_7)[4]) < 6);
296 void keep_global_arrays_and_strings (int i)
298 KEEP (strlen (i < 0 ? a3 : "") < 2);
299 KEEP (strlen (i < 0 ? a3 : "1") < 2);
300 KEEP (strlen (i < 0 ? a3 : "12") < 2);
301 KEEP (strlen (i < 0 ? a3 : "123") < 3);
303 KEEP (strlen (i < 0 ? a7 : "") < 5);
304 KEEP (strlen (i < 0 ? a7 : "1") < 5);
305 KEEP (strlen (i < 0 ? a7 : "12") < 5);
306 KEEP (strlen (i < 0 ? a7 : "123") < 5);
307 KEEP (strlen (i < 0 ? a7 : "123456") < 6);
308 KEEP (strlen (i < 0 ? a7 : "1234567") < 6);
311 void keep_member_arrays_obj (int i)
313 KEEP (strlen (ma0_3_5_7[0][0][0].a3) < 2);
314 KEEP (strlen (ma0_3_5_7[0][0][1].a3) < 2);
315 KEEP (strlen (ma0_3_5_7[0][0][2].a3) < 2);
316 KEEP (strlen (ma0_3_5_7[0][0][6].a3) < 2);
318 KEEP (strlen (ma0_3_5_7[1][0][0].a3) < 2);
319 KEEP (strlen (ma0_3_5_7[2][0][1].a3) < 2);
321 KEEP (strlen (ma0_3_5_7[1][1][0].a3) < 2);
322 KEEP (strlen (ma0_3_5_7[2][4][6].a3) < 2);
324 KEEP (strlen (ma0_3_5_7[0][0][0].a5) < 4);
325 KEEP (strlen (ma0_3_5_7[0][0][1].a5) < 4);
326 KEEP (strlen (ma0_3_5_7[0][0][2].a5) < 4);
327 KEEP (strlen (ma0_3_5_7[0][0][6].a5) < 4);
329 KEEP (strlen (ma0_3_5_7[1][0][0].a5) < 4);
330 KEEP (strlen (ma0_3_5_7[2][0][1].a5) < 4);
332 KEEP (strlen (ma0_3_5_7[1][1][0].a5) < 4);
333 KEEP (strlen (ma0_3_5_7[2][4][6].a5) < 4);
335 KEEP (strlen (ma0_3_5_7[0][0][0].a7_3[0]) < 2);
336 KEEP (strlen (ma0_3_5_7[2][4][6].a7_3[2]) < 2);
338 KEEP (strlen (ma0_3_5_7[0][0][0].a5_7[0]) < 6);
339 KEEP (strlen (ma0_3_5_7[2][4][6].a5_7[4]) < 6);
342 void keep_member_arrays_ptr (struct MemArrays0 *ma0,
343 struct MemArraysX *max,
344 struct MemArrays7 *ma7,
345 int i)
347 KEEP (strlen (ma0->a7_3[0]) > 0);
348 KEEP (strlen (ma0->a7_3[0]) < 2);
349 KEEP (strlen (ma0->a7_3[1]) < 2);
350 KEEP (strlen (ma0->a7_3[6]) < 2);
351 KEEP (strlen (ma0->a7_3[6]) < 2);
352 KEEP (strlen (ma0->a7_3[i]) > 0);
353 KEEP (strlen (ma0->a7_3[i]) < 2);
354 KEEP (strlen (ma0->a7_3[i]) < 2);
356 KEEP (strlen (ma0->a5_7[0]) < 5);
357 KEEP (strlen (ma0[0].a5_7[0]) < 5);
358 KEEP (strlen (ma0[1].a5_7[0]) < 5);
359 KEEP (strlen (ma0[9].a5_7[0]) < 5);
360 KEEP (strlen (ma0[9].a5_7[4]) < 5);
361 KEEP (strlen (ma0[i].a5_7[4]) < 5);
362 KEEP (strlen (ma0[i].a5_7[i]) < 5);
364 KEEP (strlen (ma0->a0) < DIFF_MAX - 2);
365 KEEP (strlen (ma0->a0) < 999);
366 KEEP (strlen (ma0->a0) < 1);
368 KEEP (strlen (max->ax) < DIFF_MAX - 2);
369 KEEP (strlen (max->ax) < 999);
370 KEEP (strlen (max->ax) < 1);
372 KEEP (strlen (ma7->a7) < DIFF_MAX - 2);
373 KEEP (strlen (ma7->a7) < 999);
374 KEEP (strlen (ma7->a7) < 1);
377 void keep_pointers (const char *s)
379 KEEP (strlen (ptr) < DIFF_MAX - 2);
380 KEEP (strlen (ptr) < 999);
381 KEEP (strlen (ptr) < 1);
383 KEEP (strlen (s) < DIFF_MAX - 2);
384 KEEP (strlen (s) < 999);
385 KEEP (strlen (s) < 1);
389 /* { dg-final { scan-tree-dump-times "call_in_true_branch_not_eliminated_" 0 "optimized" } }
390 { dg-final { scan-tree-dump-times "call_in_false_branch_not_eliminated_" 0 "optimized" } }
392 { dg-final { scan-tree-dump-times "call_made_in_true_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 92 "optimized" } }
393 { dg-final { scan-tree-dump-times "call_made_in_false_branch_on_line_1\[0-9\]\[0-9\]\[0-9\]" 92 "optimized" } } */