1 /* PR tree-optimization/86204 - wrong strlen result after prior strnlen
2    { dg-do run }
3    { dg-options "-O2 -Wall -fdump-tree-optimized" } */
4 
5 #include "strlenopt.h"
6 
7 #define NOIPA   __attribute__ ((noipa))
8 
9 char a[] = "12345";
10 
f0(void)11 NOIPA void f0 (void)
12 {
13   unsigned n0 = strnlen (a, 0);
14   unsigned n1 = strlen (a);
15 
16   if (n0 != 0 || n1 != 5)
17     abort ();
18 }
19 
f1(void)20 NOIPA void f1 (void)
21 {
22   unsigned n0 = strnlen (a, 1);
23   unsigned n1 = strlen (a);
24 
25   if (n0 != 1 || n1 != 5)
26     abort ();
27 }
28 
f2(void)29 NOIPA void f2 (void)
30 {
31   unsigned n0 = strnlen (a, 2);
32   unsigned n1 = strlen (a);
33 
34   if (n0 != 2 || n1 != 5)
35     abort ();
36 }
37 
f3(void)38 NOIPA void f3 (void)
39 {
40   unsigned n0 = strnlen (a, 3);
41   unsigned n1 = strlen (a);
42 
43   if (n0 != 3 || n1 != 5)
44     abort ();
45 }
46 
f4(void)47 NOIPA void f4 (void)
48 {
49   unsigned n0 = strnlen (a, 4);
50   unsigned n1 = strlen (a);
51 
52   if (n0 != 4 || n1 != 5)
53     abort ();
54 }
55 
f5(void)56 NOIPA void f5 (void)
57 {
58   unsigned n0 = strnlen (a, 5);
59   unsigned n1 = strlen (a);
60 
61   if (n0 != 5 || n1 != 5)
62     abort ();
63 }
64 
f6(void)65 NOIPA void f6 (void)
66 {
67   unsigned n0 = strnlen (a, 6);
68   unsigned n1 = strlen (a);
69 
70   if (n0 != 5 || n1 != 5)
71     abort ();
72 }
73 
fx(unsigned n)74 NOIPA void fx (unsigned n)
75 {
76   unsigned n0 = strnlen (a, n);
77   unsigned n1 = strlen (a);
78 
79   unsigned min = n < 5 ? n : 5;
80   if (n0 != min || n1 != 5)
81     abort ();
82 }
83 
g2(void)84 NOIPA void g2 (void)
85 {
86   strcpy (a, "123");
87   unsigned n0 = strnlen (a, 2);
88   unsigned n1 = strlen (a);
89 
90   if (n0 != 2 || n1 != 3)
91     abort ();
92 }
93 
g7(void)94 NOIPA void g7 (void)
95 {
96   strcpy (a, "123");
97   unsigned n0 = strnlen (a, 7);
98   unsigned n1 = strlen (a);
99 
100   if (n0 != 3 || n1 != 3)
101     abort ();
102 }
103 
gx(unsigned n)104 NOIPA void gx (unsigned n)
105 {
106   strcpy (a, "123");
107   unsigned n0 = strnlen (a, n);
108   unsigned n1 = strlen (a);
109 
110   unsigned min = n < 3 ? n : 3;
111   if (n0 != min || n1 != 3)
112     abort ();
113 }
114 
main(void)115 int main (void)
116 {
117   f0 ();
118   f1 ();
119   f2 ();
120   f3 ();
121   f4 ();
122   f5 ();
123   f6 ();
124   fx (2);
125   fx (7);
126 
127   g2 ();
128   g7 ();
129   gx (2);
130   gx (7);
131 }
132 
133 
134 /* For targets like Solaris 10 that don't define strnlen().  */
135 
136 NOIPA size_t
strnlen(const char * s,size_t n)137 strnlen (const char *s, size_t n)
138 {
139   size_t len = 0;
140   while (*s++ && n--)
141     ++len;
142   return len;
143 }
144 
145 /* Verify that at least some of the 11 calls to strnlen have been
146    folded (this number of folded calls may need to be adjusted up
147    if the strnlen optimization improves, but it should not go down.
148   { dg-final { scan-tree-dump-times "= strnlen" 7 "optimized" } } */
149