111
|
1 /* This test needs runtime that provides stpcpy function. */
|
|
2 /* { dg-do run { target *-*-linux* *-*-gnu* } } */
|
|
3 /* { dg-options "-O2 -fdump-tree-strlen" } */
|
|
4
|
|
5 #define USE_GNU
|
|
6 #include "strlenopt.h"
|
|
7
|
|
8 __attribute__((noinline, noclone)) int
|
|
9 foo (const char *p)
|
|
10 {
|
|
11 static int c;
|
|
12 const char *q[] = { "123498765abcde", "123498765..", "129abcde", "129abcde" };
|
|
13 if (strcmp (p, q[c]) != 0)
|
|
14 abort ();
|
|
15 return c++;
|
|
16 }
|
|
17
|
|
18 __attribute__((noinline, noclone)) void
|
|
19 bar (const char *p, const char *q)
|
|
20 {
|
|
21 size_t l;
|
|
22 /* This strlen stays. */
|
|
23 char *a = __builtin_alloca (strlen (p) + 50);
|
|
24 /* strcpy can be optimized into memcpy. */
|
|
25 strcpy (a, p);
|
|
26 /* strcat into stpcpy. */
|
|
27 strcat (a, q);
|
|
28 /* This strlen can be optimized away. */
|
|
29 l = strlen (a);
|
|
30 /* This becomes memcpy. */
|
|
31 strcat (a, "abcde");
|
|
32 if (!foo (a))
|
|
33 /* And this one too. */
|
|
34 strcpy (a + l, "..");
|
|
35 foo (a);
|
|
36 }
|
|
37
|
|
38 int
|
|
39 main ()
|
|
40 {
|
|
41 const char *volatile s1 = "1234";
|
|
42 const char *volatile s2 = "98765";
|
|
43 const char *volatile s3 = "12";
|
|
44 const char *volatile s4 = "9";
|
|
45 bar (s1, s2);
|
|
46 bar (s3, s4);
|
|
47 return 0;
|
|
48 }
|
|
49
|
|
50 /* { dg-final { scan-tree-dump-times "strlen \\(" 1 "strlen" } } */
|
|
51 /* { dg-final { scan-tree-dump-times "memcpy \\(" 3 "strlen" } } */
|
|
52 /* { dg-final { scan-tree-dump-times "mempcpy \\(" 0 "strlen" } } */
|
|
53 /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
|
|
54 /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
|
|
55 /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
|
|
56 /* { dg-final { scan-tree-dump-times "stpcpy \\(" 1 "strlen" } } */
|