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