1 /* PR middle-end/91490 - bogus argument missing terminating nul warning
2    on strlen of a flexible array member
3    Verify that strlen calls with a flexible array member (and its common
4    forms) of declaraed objects are folded.
5    { dg-do compile }
6    { dg-options "-Wall -fdump-tree-gimple" } */
7 
8 #include "strlenopt.h"
9 
10 extern void* memchr (const void*, int, size_t);
11 
12 struct A1 { char n, a[1]; };
13 struct A2 { char n, a[2]; };
14 struct A3 { char n, a[3]; };
15 struct Ax { char n, a[]; };
16 
17 const struct A1 a1_0 = { 0 };
18 const struct A1 a1_0_ = { 0, { } };
19 const struct A1 a1_0_0 = { 0, { 0 } };
20 
21 const struct A2 a2_1_ = { 1, { } };
22 const struct A2 a2_1_1 = { 1, { 1 } };
23 const struct A2 a2_1_1_0 = { 1, { 1, 0 } };
24 
25 const struct A3 aa3_1_[2] = { { 1 } };
26 
27 const struct Ax ax = { 3, { 3, 2, 1, 0 } };
28 
29 struct BxA1 { int n; struct A1 a[]; };
30 struct BxA2 { int n; struct A2 a[]; };
31 
32 const struct BxA2 bx = { 2, { { 2, { 2, 1 } }, { 2, { 1, 0 } } } };
33 
34 #if 0
35 
36 // Not implemented yet.
37 
38 int mchr1, mchr1__, mchr1_0, mchr2_1, mchr2, mchr2_1_0, mchrax, mchrbx;
39 
40 void test_memchr_flexarray (void)
41 {
42   mchr1 = 0 != memchr (&a1_0, '1', sizeof a1_0);
43   mchr1__ = 0 != memchr (&a1_0_, '2', sizeof a1_0_);
44   mchr1_0 = 0 != memchr (&a1_0_0, '3', sizeof a1_0_0);
45 
46   mchr2 = 0 != memchr (&a2_1_, '4', sizeof a2_1_);
47   mchr2_1 = 0 != memchr (&a2_1_1, '\001', sizeof a2_1_1);
48   mchr2_1_0 = 0 != memchr (&a2_1_1_0, '\001', sizeof a2_1_1_0);
49 
50   mchrax = (const char*)&ax + sizeof ax - 1 == memchr (&ax, '\001', sizeof ax);
51   mchrbx = (const char*)&bx + sizeof bx - 1 == memchr (&bx, '\001', sizeof bx);
52 }
53 
54 #endif
55 
56 
57 int schr1, schr1__, schr1_0, schr2_1, schr2, schr2_1_0, schrax, schrbx;
58 
test_strchr_flexarray(void)59 void test_strchr_flexarray (void)
60 {
61   schr1 = 0 != strchr (a1_0.a, '1');
62   schr1__ = 0 != strchr (a1_0_.a, '2');
63   schr1_0 = 0 != strchr (a1_0_0.a, '3');
64 
65   schr2 = 0 != strchr (a2_1_.a, '4');
66   schr2_1 = 0 != strchr (a2_1_1.a, '\001');
67   schr2_1_0 = 0 != strchr (a2_1_1_0.a, '\001');
68 
69   schrax = 0 != strchr (ax.a, '\001');
70   schrbx = 0 != strchr (bx.a[1].a, '\0');
71 
72   /* { dg-final { scan-tree-dump "schr1 = 0;" "gimple" } }
73      { dg-final { scan-tree-dump "schr1__ = 0;" "gimple" } }
74      { dg-final { scan-tree-dump "schr1_0 = 0;" "gimple" } }
75      { dg-final { scan-tree-dump "schr2 = 0;" "gimple" } }
76      { dg-final { scan-tree-dump "schr2_1 = 1;" "gimple" } }
77      { dg-final { scan-tree-dump "schr2_1_0 = 1;" "gimple" } }
78      { dg-final { scan-tree-dump "schrax = 1;" "gimple" } }
79      { dg-final { scan-tree-dump "schrbx = 1;" "gimple" } } */
80 }
81 
82 
83 int scmp1, scmp1__, scmp1_0, scmp2_1, scmp2, scmp2_1_0, scmpax, scmpbx;
84 
test_strcmp_flexarray(void)85 void test_strcmp_flexarray (void)
86 {
87   scmp1 = 0 == strcmp (a1_0.a, "1");
88   scmp1__ = 0 == strcmp (a1_0_.a, "2");
89   scmp1_0 = 0 == strcmp (a1_0_0.a, "3");
90 
91   scmp2 = 0 == strcmp (a2_1_.a, "4");
92   scmp2_1 = 0 == strcmp (a2_1_1.a, "\001");
93   scmp2_1_0 = 0 == strcmp (a2_1_1_0.a, "\001");
94 
95   scmpax = 0 == strcmp (ax.a, "\003\002\001");
96   scmpbx = 0 == strcmp (bx.a[1].a, "\001");
97 
98   /* { dg-final { scan-tree-dump "scmp1 = 0;" "gimple" } }
99      { dg-final { scan-tree-dump "scmp1__ = 0;" "gimple" } }
100      { dg-final { scan-tree-dump "scmp1_0 = 0;" "gimple" } }
101      { dg-final { scan-tree-dump "scmp2 = 0;" "gimple" } }
102      { dg-final { scan-tree-dump "scmp2_1 = 1;" "gimple" } }
103      { dg-final { scan-tree-dump "scmp2_1_0 = 1;" "gimple" } }
104      { dg-final { scan-tree-dump "scmpax = 1;" "gimple" } }
105      { dg-final { scan-tree-dump "scmpbx = 1;" "gimple" } } */
106 }
107 
108 
109 int len1, len1__, len1_0, len2_1, len2, len2_1_0, lenax, lenbx;
110 
test_strlen_flexarray(void)111 void test_strlen_flexarray (void)
112 {
113   len1 = strlen (a1_0.a);
114   len1__ = strlen (a1_0_.a);
115   len1_0 = strlen (a1_0_0.a);
116 
117   len2 = strlen (a2_1_.a);
118   len2_1 = strlen (a2_1_1.a);
119   len2_1_0 = strlen (a2_1_1_0.a);
120 
121   lenax = strlen (ax.a);
122   lenbx = strlen (bx.a[1].a);
123 
124   /* { dg-final { scan-tree-dump "len1 = 0;" "gimple" } }
125      { dg-final { scan-tree-dump "len1__ = 0;" "gimple" } }
126      { dg-final { scan-tree-dump "len1_0 = 0;" "gimple" } }
127      { dg-final { scan-tree-dump "len2 = 0;" "gimple" } }
128      { dg-final { scan-tree-dump "len2_1 = 1;" "gimple" } }
129      { dg-final { scan-tree-dump "len2_1_0 = 1;" "gimple" } }
130      { dg-final { scan-tree-dump "lenax = 3;" "gimple" } }
131      { dg-final { scan-tree-dump "lenbx = 1;" "gimple" } } */
132 }
133 
134 
135 int schraa3, scmpaa3, lenaa3;
136 
test_trailing_array_empty_init(void)137 void test_trailing_array_empty_init (void)
138 {
139   schraa3 = ((aa3_1_[0].a == strchr (aa3_1_[0].a, 0))
140 	     + (aa3_1_[1].a == strchr (aa3_1_[1].a, 0)));
141 
142   scmpaa3 = strcmp (aa3_1_[0].a, aa3_1_[1].a);
143   lenaa3 = strlen (aa3_1_[0].a) + strlen (aa3_1_[1].a);
144 
145   /* { dg-final { scan-tree-dump "schraa3 = 2;" "gimple" } }
146      { dg-final { scan-tree-dump "scmpaa3 = 0;" "gimple" } }
147      { dg-final { scan-tree-dump "lenaa3 = 0;" "gimple" } }  */
148 }
149 
150 union U4 { char a[4]; int i; };
151 const union U4 u4[2] = { { "123" } };
152 
153 int ulen0, ulen1;
154 
test_union_init(void)155 void test_union_init (void)
156 {
157   ulen0 = strlen (u4[0].a);
158   ulen1 = strlen (u4[1].a);
159 
160   /* { dg-final { scan-tree-dump "ulen0 = 3;" "gimple" } }
161      { dg-final { scan-tree-dump "ulen1 = 0;" "gimple" } } */
162 }
163 
164 /* { dg-final { scan-tree-dump-not "strchr *\\(" "gimple" } }
165    { dg-final { scan-tree-dump-not "strcmp *\\(" "gimple" } }
166    { dg-final { scan-tree-dump-not "strlen *\\(" "gimple" } } */
167