blob: 2d4dad186720f050c5a9aa16d895bf817660230e [file] [log] [blame]
/* 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" } } */