1 /* PR tree-optimization/91183 - strlen of a strcpy result with a conditional
2 source not folded
3 Runtime test to verify that multibyte stores are handled correctly.
4 { dg-do run }
5 { dg-options "-O2 -Wall" } */
6
7 #include "strlenopt.h"
8
9 #define CHAR_BIT __CHAR_BIT__
10
11 typedef __UINT16_TYPE__ uint16_t;
12 typedef __UINT32_TYPE__ uint32_t;
13
14 #define NOIPA __attribute__ ((noclone, noinline, noipa))
15
16 /* Prevent the optimizer from detemining invariants from prior tests. */
terminate(void)17 NOIPA void terminate (void)
18 {
19 __builtin_abort ();
20 }
21
22 #define VERIFY(expr, str) \
23 do { \
24 const unsigned expect = strlen (str); \
25 const unsigned len = strlen (expr); \
26 if (len != expect) \
27 { \
28 __builtin_printf ("line %i: strlen(%s) == %u failed: " \
29 "got %u with a = \"%.*s\"\n", \
30 __LINE__, #expr, expect, len, \
31 (int)sizeof a, a); \
32 terminate (); \
33 } \
34 if (memcmp (a, str, expect + 1)) \
35 { \
36 __builtin_printf ("line %i: expected string \"%s\", " \
37 "got a = \"%.*s\"\n", \
38 __LINE__, str, (int)sizeof a, a); \
39 terminate (); \
40 } \
41 } while (0)
42
43
44 #define ELT(s, i) ((s "\0\0\0\0")[i])
45
46 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
47 # define I16(s) (((uint16_t)ELT (s, 0) << 8) + (uint16_t)ELT (s, 1))
48 # define I32(s) \
49 (((uint32_t)ELT (s, 0) << 24) \
50 + ((uint32_t)ELT (s, 1) << 16) \
51 + ((uint32_t)ELT (s, 2) << 8) \
52 + (uint32_t)ELT (s, 3))
53 #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
54 # define I16(s) (((uint16_t)ELT (s, 1) << 8) + (uint16_t)ELT (s, 0))
55 # define I32(s) \
56 (((uint32_t)ELT (s, 3) << 24) \
57 + ((uint32_t)ELT (s, 2) << 16) \
58 + ((uint32_t)ELT (s, 1) << 8) \
59 + (uint32_t)ELT (s, 0))
60 #endif
61
62 char a[32];
63
64 NOIPA void
i16_1(void)65 i16_1 (void)
66 {
67 *(uint16_t*)a = I16 ("12");
68 *(uint16_t*)(a + 2) = I16 ("3");
69 VERIFY (a, "123");
70
71 *(uint16_t*)(a + 1) = I16 ("23");
72 VERIFY (a, "123");
73
74 *(uint16_t*)(a) = I16 ("12");
75 VERIFY (a, "123");
76
77 *(uint16_t*)(a + 1) = I16 ("2");
78 VERIFY (a, "12");
79
80 *(uint16_t*)(a + 3) = I16 ("45");
81 *(uint16_t*)(a + 2) = I16 ("34");
82 VERIFY (a, "12345");
83 }
84
85 NOIPA void
i16_2(void)86 i16_2 (void)
87 {
88 strcpy (a, "12");
89 strcat (a, "34");
90
91 *(uint16_t*)a = I16 ("12");
92 VERIFY (a, "1234");
93
94 *(uint16_t*)(a + 1) = I16 ("12");
95 VERIFY (a, "1124");
96
97 *(uint16_t*)(a + 2) = I16 ("12");
98 VERIFY (a, "1112");
99
100 *(uint16_t*)(a + 3) = I16 ("12");
101 VERIFY (a, "11112");
102
103 *(uint16_t*)(a + 4) = I16 ("12");
104 VERIFY (a, "111112");
105 }
106
107
108 NOIPA void
i32_1(void)109 i32_1 (void)
110 {
111 *(uint32_t*)a = I32 ("1234");
112 VERIFY (a, "1234");
113
114 *(uint32_t*)(a + 1) = I32 ("2345");
115 VERIFY (a, "12345");
116 }
117
118 NOIPA void
i32_2(void)119 i32_2 (void)
120 {
121 strcpy (a, "12");
122 strcat (a, "34");
123
124 *(uint32_t*)a = I32 ("1234");
125 VERIFY (a, "1234");
126
127 *(uint32_t*)(a + 4) = I32 ("567");
128 VERIFY (a, "1234567");
129
130 *(uint32_t*)(a + 7) = I32 ("89\0");
131 VERIFY (a, "123456789");
132
133 *(uint32_t*)(a + 3) = I32 ("4567");
134 VERIFY (a, "123456789");
135
136 *(uint32_t*)(a + 2) = I32 ("3456");
137 VERIFY (a, "123456789");
138
139 *(uint32_t*)(a + 1) = I32 ("2345");
140 VERIFY (a, "123456789");
141 }
142
143
144 NOIPA void
i32_3(void)145 i32_3 (void)
146 {
147 strcpy (a, "1234");
148 strcat (a, "5678");
149
150 *(uint32_t*)a = I32 ("1234");
151 VERIFY (a, "12345678");
152
153 *(uint32_t*)(a + 1) = I32 ("234");
154 VERIFY (a, "1234");
155
156 *(uint32_t*)(a + 2) = I32 ("3456");
157 VERIFY (a, "12345678");
158
159 *(uint32_t*)(a + 3) = I32 ("4567");
160 VERIFY (a, "12345678");
161
162 *(uint32_t*)(a + 4) = I32 ("5678");
163 VERIFY (a, "12345678");
164
165 *(uint32_t*)(a + 5) = I32 ("6789");
166 VERIFY (a, "123456789");
167
168 *(uint32_t*)(a + 6) = I32 ("789A");
169 VERIFY (a, "123456789A");
170 }
171
172 volatile int vzero = 0;
173
174 NOIPA void
i32_4(void)175 i32_4 (void)
176 {
177 strcpy (a, "1234");
178 strcat (a, "5678");
179
180 *(uint32_t*)a = vzero ? I32 ("1\0\0\0") : I32 ("1234");
181 VERIFY (a, "12345678");
182
183 *(uint32_t*)a = vzero ? I32 ("12\0\0") : I32 ("1234");
184 VERIFY (a, "12345678");
185
186 *(uint32_t*)a = vzero ? I32 ("123\0") : I32 ("1234");
187 VERIFY (a, "12345678");
188
189 *(uint32_t*)a = vzero ? I32 ("1234") : I32 ("1234");
190 VERIFY (a, "12345678");
191
192 *(uint32_t*)a = vzero ? I32 ("1235") : I32 ("1234");
193 VERIFY (a, "12345678");
194
195 *(uint32_t*)a = vzero ? I32 ("1234") : I32 ("123\0");
196 VERIFY (a, "123");
197
198 *(uint32_t*)(a + 3) = vzero ? I32 ("456\0") : I32 ("4567");
199 VERIFY (a, "12345678");
200 }
201
202
main()203 int main ()
204 {
205 memset (a, 0, sizeof a);
206 i16_1 ();
207
208 memset (a, 0, sizeof a);
209 i16_2 ();
210
211
212 memset (a, 0, sizeof a);
213 i32_1 ();
214
215 memset (a, 0, sizeof a);
216 i32_2 ();
217
218 memset (a, 0, sizeof a);
219 i32_3 ();
220
221 memset (a, 0, sizeof a);
222 i32_4 ();
223 }
224