| /* PR tree-optimization/92226 - live nul char store to array eliminated |
| { dg-do compile } |
| { dg-options "-O2 -fdump-tree-strlen" } */ |
| |
| #include "strlenopt.h" |
| |
| #define NOIPA __attribute__ ((noipa)) |
| |
| #define T(MIN, MAX, SIZE, IDX) \ |
| NOIPA void \ |
| test_ ## MIN ## _ ## MAX ## _ ## SIZE ## _ ## IDX (const char *s) \ |
| { \ |
| extern char a ## SIZE[SIZE]; \ |
| char *d = a ## SIZE; \ |
| size_t len = strlen (s); \ |
| size_t idx = IDX; \ |
| if (MIN <= len && len <= MAX) \ |
| { \ |
| strcpy (d, s); \ |
| d[idx] = 0; \ |
| if (strlen (d) != idx) \ |
| abort (); \ |
| } \ |
| } typedef void dummy_type |
| |
| |
| /* The final nul store must be retained but the second strlen call should |
| be eliminated because the final length of the destination after the nul |
| store must be equal to the index of the store. */ |
| T (0, 2, 4, 0); |
| |
| /* Not handled yet (see below): |
| T (0, 2, 4, 1); */ |
| |
| /* Not handled yet: in addition to the cases above, the second strlen |
| call can also be eliminated in those below because in both the final |
| length of the destination after the nul store must be in the same |
| range as the length of the source. |
| T (0, 2, 4, 2); |
| T (0, 2, 4, 3); */ |
| |
| T (2, 3, 4, 0); |
| T (2, 3, 4, 1); |
| |
| /* Not handled yet (see above): |
| T (2, 3, 4, 2); |
| T (2, 3, 4, 3); */ |
| |
| T (3, 4, 5, 0); |
| T (3, 4, 5, 1); |
| T (3, 4, 5, 2); |
| |
| /* Not handled yet (see above): |
| T (3, 4, 5, 3); |
| T (3, 4, 5, 4); */ |
| |
| T (3, 4, 6, 0); |
| T (3, 4, 6, 1); |
| T (3, 4, 6, 2); |
| |
| /* Not handled yet (see above): |
| T (3, 4, 6, 3); |
| T (3, 4, 6, 4); |
| T (3, 4, 6, 5); */ |
| |
| |
| /* Verify that each function makes just one call to strlen to compute |
| the length of its argument (and not also to compute the length of |
| the copy): |
| { dg-final { scan-tree-dump-times "strlen \\(s_" 9 "strlen1" } } |
| { dg-final { scan-tree-dump-not "strlen \\(\\&a" "strlen1" } } |
| |
| Verify that nul stores into the destination have not been eliminated: |
| { dg-final { scan-tree-dump-times "a4\\\] = 0;" 2 "strlen1" } } |
| { dg-final { scan-tree-dump-times "a4 \\\+ 1B\\\] = 0;" 1 "strlen1" } } |
| |
| { dg-final { scan-tree-dump-times "a5\\\] = 0;" 1 "strlen1" } } |
| { dg-final { scan-tree-dump-times "a5 \\\+ 1B\\\] = 0;" 1 "strlen1" } } |
| { dg-final { scan-tree-dump-times "a5 \\\+ 2B\\\] = 0;" 1 "strlen1" } } |
| |
| { dg-final { scan-tree-dump-times "a6\\\] = 0;" 1 "strlen1" } } |
| { dg-final { scan-tree-dump-times "a6 \\\+ 1B\\\] = 0;" 1 "strlen1" } } |
| { dg-final { scan-tree-dump-times "a6 \\\+ 2B\\\] = 0;" 1 "strlen1" } } */ |