1 /* { dg-do run } */
2 /* { dg-options "-O2 -fdump-tree-strlen" } */
3
4 #include "strlenopt.h"
5
6 struct S { char *p; size_t l; };
7
8 __attribute__((noinline, noclone)) struct S
foo(char * x,int n)9 foo (char *x, int n)
10 {
11 int i;
12 char a[64];
13 char *p = strchr (x, '\0');
14 struct S s;
15 /* strcpy here is optimized into memcpy, length computed as p - x + 1. */
16 strcpy (a, x);
17 /* strcat here is optimized into memcpy. */
18 strcat (p, "abcd");
19 for (i = 0; i < n; i++)
20 if ((i % 123) == 53)
21 /* strcat here is optimized into strlen and memcpy. */
22 strcat (a, "efg");
23 s.p = strdup (a);
24 /* The strlen should be optimized here into 4. */
25 s.l = strlen (p);
26 return s;
27 }
28
29 int
main()30 main ()
31 {
32 char buf[32];
33 struct S s;
34 buf[0] = 'z';
35 buf[1] = '\0';
36 s = foo (buf, 0);
37 if (s.l != 4 || memcmp (buf, "zabcd", 6) != 0)
38 abort ();
39 if (s.p == NULL)
40 return 0;
41 if (memcmp (s.p, "z", 2) != 0)
42 abort ();
43 s = foo (buf, 60);
44 if (s.l != 4 || memcmp (buf, "zabcdabcd", 10) != 0)
45 abort ();
46 if (s.p == NULL)
47 return 0;
48 if (memcmp (s.p, "zabcdefg", 9) != 0)
49 abort ();
50 s = foo (buf, 240);
51 if (s.l != 4 || memcmp (buf, "zabcdabcdabcd", 14) != 0)
52 abort ();
53 if (s.p == NULL)
54 return 0;
55 if (memcmp (s.p, "zabcdabcdefgefg", 16) != 0)
56 abort ();
57 return 0;
58 }
59
60 /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
61 /* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */
62 /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
63 /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
64 /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
65 /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
66