1 /* { dg-do run } */
2 /* { dg-options "-O2 -fdump-tree-strlen -fdump-tree-optimized" } */
3 
4 #include "strlenopt.h"
5 
6 __attribute__((noinline, noclone)) size_t
fn1(char * p,char * q)7 fn1 (char *p, char *q)
8 {
9   size_t s = strlen (q);
10   strcpy (p, q);
11   return s - strlen (p);
12 }
13 
14 __attribute__((noinline, noclone)) size_t
fn2(char * p,char * q)15 fn2 (char *p, char *q)
16 {
17   size_t s = strlen (q);
18   memcpy (p, q, s + 1);
19   return s - strlen (p);
20 }
21 
22 __attribute__((noinline, noclone)) size_t
fn3(char * p)23 fn3 (char *p)
24 {
25   memcpy (p, "abcd", 5);
26   return strlen (p);
27 }
28 
29 __attribute__((noinline, noclone)) size_t
fn4(char * p)30 fn4 (char *p)
31 {
32   memcpy (p, "efg\0hij", 6);
33   return strlen (p);
34 }
35 
36 int
main()37 main ()
38 {
39   char buf[64];
40   char *volatile p = buf;
41   char *volatile q = "ABCDEF";
42   buf[7] = 'G';
43   if (fn1 (p, q) != 0 || memcmp (buf, "ABCDEF\0G", 8))
44     abort ();
45   q = "HIJ";
46   if (fn2 (p + 1, q) != 0 || memcmp (buf, "AHIJ\0F\0G", 8))
47     abort ();
48   buf[6] = 'K';
49   if (fn3 (p + 1) != 4 || memcmp (buf, "Aabcd\0KG", 8))
50     abort ();
51   if (fn4 (p) != 3 || memcmp (buf, "efg\0hiKG", 8))
52     abort ();
53   return 0;
54 }
55 
56 /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */
57 /* { dg-final { scan-tree-dump-times "memcpy \\(" 4 "strlen1" } } */
58 /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */
59 /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */
60 /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */
61 /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */
62 /* { dg-final { scan-tree-dump-times "return 0" 3 "optimized" } } */
63 /* { dg-final { scan-tree-dump-times "return 4" 1 "optimized" } } */
64 /* { dg-final { scan-tree-dump-times "return 3" 1 "optimized" } } */
65