struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / support / regression / tests / bitfields.c
blob29eebc00b8c7836766427e2fad8c9f90c1600ef8
1 /** Bitfield tests.
3 SDCC pic16 port currently does not support bitfields of size > 8,
4 so they are ifdefed out.
5 */
6 #include <testfwk.h>
8 struct {
9 char c0_3 : 3;
10 char c3_5 : 5;
11 } c_bf;
13 #ifndef __SDCC_pdk14 // Lack of memory
14 #if !defined(__SDCC_pic16)
15 struct {
16 int i0_7 : 7;
17 int i7_9 : 9;
18 } i_bf;
20 struct {
21 long l0_7 : 7;
22 long l7_10 : 10;
23 long l17_15 : 15;
24 } l_bf;
26 struct {
27 unsigned int b0 : 1;
28 unsigned int b1 : 1;
29 unsigned int b2 : 1;
30 unsigned int b3 : 1;
31 unsigned int b4 : 1;
32 unsigned int b5 : 1;
33 unsigned int b6 : 1;
34 unsigned int b7 : 1;
35 unsigned int b8 : 1;
36 unsigned int b9 : 1;
37 } sb_bf;
38 #endif /* !__SDCC_pic16 */
39 #endif
41 struct {
42 unsigned int b0 : 1;
43 unsigned int b2 : 1;
44 } size1a_bf;
46 struct {
47 unsigned int b0 : 1;
48 unsigned int b1 : 1;
49 unsigned int : 0;
50 } size1b_bf;
52 struct {
53 unsigned int b0 : 1;
54 unsigned int b1 : 1;
55 unsigned int b2 : 6;
56 } size1c_bf;
58 struct {
59 unsigned int b0 : 1;
60 unsigned int : 0;
61 unsigned int b1 : 1;
62 } size2a_bf;
64 #if !defined(__SDCC_pic16)
65 struct {
66 unsigned int b0 : 1;
67 unsigned int b1 : 1;
68 unsigned int b2 : 1;
69 unsigned int b3 : 1;
70 unsigned int b4 : 1;
71 unsigned int b5 : 1;
72 unsigned int b6 : 1;
73 unsigned int b7 : 1;
74 unsigned int b8 : 1;
75 unsigned int b9 : 1;
76 } size2b_bf;
78 struct {
79 unsigned int b0 : 4;
80 unsigned int b1 : 5;
81 } size2c_bf;
83 struct {
84 unsigned int b0 : 12;
85 unsigned int b1 : 3;
86 } size2d_bf;
88 struct { /* Bit-fields that end on byte boundary */
89 unsigned int b0 : 3;
90 unsigned int b1 : 5;
91 unsigned int b2 : 5;
92 unsigned int b3 : 3;
93 } size2e_bf;
95 struct {
96 unsigned int b0 : 3;
97 unsigned int b1 : 12;
98 } size3a_bf;
100 struct {
101 signed int s0_7 : 7;
102 signed int s7_1 : 1;
103 signed int s8_9 : 9;
104 } s_bf;
105 #endif /* !__SDCC_pic16 */
107 void
108 testBitfieldSizeof(void)
110 /* Although bitfields are extremely implementation dependent, these
111 assertions should hold for all implementations with storage units
112 of 8 bits or larger (nearly universal).
114 ASSERT( sizeof(size1a_bf) >= 1);
115 ASSERT( sizeof(size1b_bf) >= 1);
116 ASSERT( sizeof(size1c_bf) >= 1);
117 #if !defined(__SDCC_pic16)
118 ASSERT( sizeof(size2b_bf) >= 2);
119 ASSERT( sizeof(size2c_bf) >= 2);
120 ASSERT( sizeof(size2d_bf) >= 2);
121 ASSERT( sizeof(size3a_bf) >= 2);
122 ASSERT( sizeof(size1a_bf) <= sizeof(size1b_bf));
123 #endif /* !__SDCC_pic16 */
124 /* Some SDCC specific assertions. SDCC uses 8 bit storage units.
125 Bitfields that are less than 8 bits, but would (due to earlier
126 bitfield declarations) span a storage unit boundary are
127 realigned to the next storage unit boundary. Bitfields of
128 8 or greater bits are always aligned to start on a storage
129 unit boundary.
131 #ifdef __SDCC
132 ASSERT( sizeof(size1a_bf) == 1);
133 ASSERT( sizeof(size1b_bf) == 1);
134 ASSERT( sizeof(size1c_bf) == 1);
135 ASSERT( sizeof(size2a_bf) == 2);
136 #if !defined(__SDCC_pic16)
137 ASSERT( sizeof(size2b_bf) == 2);
138 ASSERT( sizeof(size2c_bf) == 2);
139 ASSERT( sizeof(size2d_bf) == 2);
140 ASSERT( sizeof(size3a_bf) == 3);
141 #endif /* !__SDCC_pic16 */
142 #endif
146 void
147 testBitfieldsSingleBitLiteral(void)
149 #ifndef __SDCC_pdk14 // Lack of memory
150 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
151 #if !defined(__SDCC_pic16)
152 size2b_bf.b0 = 0;
153 size2b_bf.b1 = 0;
154 size2b_bf.b2 = 0;
155 size2b_bf.b3 = 0;
156 size2b_bf.b4 = 0;
157 size2b_bf.b5 = 0;
158 size2b_bf.b6 = 0;
159 size2b_bf.b7 = 0;
160 size2b_bf.b8 = 0;
161 size2b_bf.b9 = 0;
163 /* make sure modulo 2 truncation works */
164 size2b_bf.b0 = 0x3fe;
165 ASSERT(size2b_bf.b0==0);
166 ASSERT(size2b_bf.b1==0);
167 ASSERT(size2b_bf.b2==0);
168 ASSERT(size2b_bf.b3==0);
169 ASSERT(size2b_bf.b4==0);
170 ASSERT(size2b_bf.b5==0);
171 ASSERT(size2b_bf.b6==0);
172 ASSERT(size2b_bf.b7==0);
173 ASSERT(size2b_bf.b8==0);
174 ASSERT(size2b_bf.b9==0);
175 size2b_bf.b0 = 0x3ff;
176 ASSERT(size2b_bf.b0==1);
177 ASSERT(size2b_bf.b1==0);
178 ASSERT(size2b_bf.b2==0);
179 ASSERT(size2b_bf.b3==0);
180 ASSERT(size2b_bf.b4==0);
181 ASSERT(size2b_bf.b5==0);
182 ASSERT(size2b_bf.b6==0);
183 ASSERT(size2b_bf.b7==0);
184 ASSERT(size2b_bf.b8==0);
185 ASSERT(size2b_bf.b9==0);
187 /* make sure both bytes work */
188 size2b_bf.b9 = 0x3ff;
189 ASSERT(size2b_bf.b0==1);
190 ASSERT(size2b_bf.b1==0);
191 ASSERT(size2b_bf.b2==0);
192 ASSERT(size2b_bf.b3==0);
193 ASSERT(size2b_bf.b4==0);
194 ASSERT(size2b_bf.b5==0);
195 ASSERT(size2b_bf.b6==0);
196 ASSERT(size2b_bf.b7==0);
197 ASSERT(size2b_bf.b8==0);
198 ASSERT(size2b_bf.b9==1);
199 #endif /* !__SDCC_pic16 */
200 #endif
201 #endif
204 void
205 testBitfieldsSingleBit(void)
207 #ifndef __SDCC_pdk14 // Lack of memory
208 #if !(defined (__SDCC_pdk15) && defined(__SDCC_STACK_AUTO)) // Lack of code memory
209 #if !defined(__SDCC_pic16)
210 volatile unsigned char c;
212 c = 0;
213 size2b_bf.b0 = c;
214 size2b_bf.b1 = c;
215 size2b_bf.b2 = c;
216 size2b_bf.b3 = c;
217 size2b_bf.b4 = c;
218 size2b_bf.b5 = c;
219 size2b_bf.b6 = c;
220 size2b_bf.b7 = c;
221 size2b_bf.b8 = c;
222 size2b_bf.b9 = c;
224 /* make sure modulo 2 truncation works */
225 c = 0xfe;
226 size2b_bf.b0 = c;
227 ASSERT(size2b_bf.b0==0);
228 ASSERT(size2b_bf.b1==0);
229 ASSERT(size2b_bf.b2==0);
230 ASSERT(size2b_bf.b3==0);
231 ASSERT(size2b_bf.b4==0);
232 ASSERT(size2b_bf.b5==0);
233 ASSERT(size2b_bf.b6==0);
234 ASSERT(size2b_bf.b7==0);
235 ASSERT(size2b_bf.b8==0);
236 ASSERT(size2b_bf.b9==0);
237 c++;
238 size2b_bf.b0 = c;
239 ASSERT(size2b_bf.b0==1);
240 ASSERT(size2b_bf.b1==0);
241 ASSERT(size2b_bf.b2==0);
242 ASSERT(size2b_bf.b3==0);
243 ASSERT(size2b_bf.b4==0);
244 ASSERT(size2b_bf.b5==0);
245 ASSERT(size2b_bf.b6==0);
246 ASSERT(size2b_bf.b7==0);
247 ASSERT(size2b_bf.b8==0);
248 ASSERT(size2b_bf.b9==0);
250 /* make sure both bytes work */
251 size2b_bf.b9 = c;
252 ASSERT(size2b_bf.b0==1);
253 ASSERT(size2b_bf.b1==0);
254 ASSERT(size2b_bf.b2==0);
255 ASSERT(size2b_bf.b3==0);
256 ASSERT(size2b_bf.b4==0);
257 ASSERT(size2b_bf.b5==0);
258 ASSERT(size2b_bf.b6==0);
259 ASSERT(size2b_bf.b7==0);
260 ASSERT(size2b_bf.b8==0);
261 ASSERT(size2b_bf.b9==1);
262 #endif /* !__SDCC_pic16 */
263 #endif
264 #endif
267 void
268 testBitfieldsMultibitLiteral(void)
270 #if !defined( __SDCC_pdk14) && !defined( __SDCC_pdk15) // Lack of memory
271 #if !defined(__SDCC_pic16)
272 size2c_bf.b0 = 0xff; /* should truncate to 0x0f */
273 size2c_bf.b1 = 0;
274 ASSERT(size2c_bf.b0==0x0f);
275 ASSERT(size2c_bf.b1==0);
277 size2c_bf.b1 = 0xff; /* should truncate to 0x1f */
278 size2c_bf.b0 = 0;
279 ASSERT(size2c_bf.b0==0);
280 ASSERT(size2c_bf.b1==0x1f);
282 size2c_bf.b0 = 0xff; /* should truncate to 0x0f */
283 size2c_bf.b1 = 0xff; /* should truncate to 0x1f */
284 ASSERT(size2c_bf.b0==0x0f);
285 ASSERT(size2c_bf.b1==0x1f);
287 size2d_bf.b0 = 0xffff; /* should truncate to 0x0fff */
288 size2d_bf.b1 = 0;
289 ASSERT(size2d_bf.b0==0x0fff);
290 ASSERT(size2d_bf.b1==0);
292 size2d_bf.b1 = 0xffff; /* should truncate to 0x07 */
293 size2d_bf.b0 = 0;
294 ASSERT(size2d_bf.b0==0);
295 ASSERT(size2d_bf.b1==0x07);
297 size2d_bf.b0 = 0xffff; /* should truncate to 0x0fff */
298 size2d_bf.b1 = 0xffff; /* should truncate to 0x07 */
299 ASSERT(size2d_bf.b0==0x0fff);
300 ASSERT(size2d_bf.b1==0x07);
302 size2d_bf.b0 = 0x0321;
303 size2d_bf.b1 = 1;
304 ASSERT(size2d_bf.b0==0x0321);
305 ASSERT(size2d_bf.b1==1);
307 size2d_bf.b0 = 0x0a46;
308 size2d_bf.b1 = 5;
309 ASSERT(size2d_bf.b0==0x0a46);
310 ASSERT(size2d_bf.b1==5);
312 size2e_bf.b0 = 2;
313 size2e_bf.b1 = 2;
314 size2e_bf.b2 = 2;
315 size2e_bf.b3 = 2;
317 ASSERT(size2e_bf.b0==2);
318 ASSERT(size2e_bf.b1==2);
319 ASSERT(size2e_bf.b2==2);
320 ASSERT(size2e_bf.b3==2);
321 #endif /* !__SDCC_pic16 */
322 #endif
325 void
326 testBitfieldsMultibit(void)
328 #if !defined( __SDCC_pdk14) && !defined( __SDCC_pdk15) // Lack of memory
329 #if !defined(__SDCC_pic16)
330 volatile int allones = 0xffff;
331 volatile int zero = 0;
332 volatile int x;
334 size2c_bf.b0 = allones; /* should truncate to 0x0f */
335 size2c_bf.b1 = zero;
336 ASSERT(size2c_bf.b0==0x0f);
337 ASSERT(size2c_bf.b1==0);
339 size2c_bf.b1 = allones; /* should truncate to 0x1f */
340 size2c_bf.b0 = zero;
341 ASSERT(size2c_bf.b0==0);
342 ASSERT(size2c_bf.b1==0x1f);
344 size2d_bf.b0 = allones; /* should truncate to 0x0fff */
345 size2d_bf.b1 = zero;
346 ASSERT(size2d_bf.b0==0x0fff);
347 ASSERT(size2d_bf.b1==0);
349 size2d_bf.b1 = allones; /* should truncate to 0x07 */
350 size2d_bf.b0 = zero;
351 ASSERT(size2d_bf.b0==0);
352 ASSERT(size2d_bf.b1==0x07);
354 x = 0x0321;
355 size2d_bf.b0 = x;
356 x = 1;
357 size2d_bf.b1 = x;
358 ASSERT(size2d_bf.b0==0x0321);
359 ASSERT(size2d_bf.b1==1);
361 x = 0x0a46;
362 size2d_bf.b0 = x;
363 x = 5;
364 size2d_bf.b1 = x;
365 ASSERT(size2d_bf.b0==0x0a46);
366 ASSERT(size2d_bf.b1==5);
368 x = 2;
369 size2e_bf.b0 = x;
370 size2e_bf.b1 = x;
371 size2e_bf.b2 = x;
372 size2e_bf.b3 = x;
374 ASSERT(size2e_bf.b0==2);
375 ASSERT(size2e_bf.b1==2);
376 ASSERT(size2e_bf.b2==2);
377 ASSERT(size2e_bf.b3==2);
378 #endif /* !__SDCC_pic16 */
379 #endif
382 void
383 testBitfields(void)
385 c_bf.c0_3 = 2;
386 c_bf.c3_5 = 3;
387 #if defined(PORT_HOST) && (defined(__ppc__) || defined(__PPC__) || defined(__sparc) || defined(__sparc64__))
388 /* bitfields on powerpc and sparc architectures are allocated from left to right */
389 ASSERT(*(char *)(&c_bf) == ((2<<(8-3)) + 3) );
390 #else
391 ASSERT(*(char *)(&c_bf) == (2 + (3<<3)) );
392 #endif
394 #if 0 // not yet
395 i_bf.i0_7 = 23;
396 i_bf.i7_9 = 234;
397 ASSERT(*(int *)(&i_bf) == (23 + (234<<7)) );
399 l_bitfield.l0_7 = 23;
400 l_bitfield.l7_10 = 234;
401 l_bitfield.l17_15 = 2345;
402 ASSERT(*(long *)(&l_bf) == (23 + (234<<7) + (2345<<17)) );
403 #endif
406 void
407 testSignedBitfields(void)
409 #if !defined( __SDCC_pdk14) && !defined( __SDCC_pdk15) // Lack of memory
410 #if !defined(__SDCC_pic16)
411 s_bf.s0_7 = 0xf0;
412 s_bf.s7_1 = 1;
413 s_bf.s8_9 = 0xfff8;
414 ASSERT(s_bf.s0_7 == -16);
415 ASSERT(s_bf.s7_1 == - 1);
416 ASSERT(s_bf.s8_9 == - 8);
417 ASSERT(s_bf.s0_7 < 0);
418 ASSERT(s_bf.s7_1 < 0);
419 ASSERT(s_bf.s8_9 < 0);
421 s_bf.s0_7 = 0x3f;
422 s_bf.s7_1 = 2;
423 s_bf.s8_9 = 0x00ff;
424 ASSERT(s_bf.s0_7 == 0x3f);
425 ASSERT(s_bf.s7_1 == 0);
426 ASSERT(s_bf.s8_9 == 0xff);
427 ASSERT(s_bf.s0_7 > 0);
428 ASSERT(s_bf.s8_9 > 0);
429 #endif /* !__SDCC_pic16 */
430 #endif
433 /* test case for enhancement request #2291335 : Unnamed bit-field initialization */
435 struct s2291335_1 {
436 int a : 2;
437 char : 2;
438 int b : 2;
441 struct s2291335_2 {
442 int a : 2;
443 char : 0;
444 int b : 2;
447 struct s2291335_1 gs2291335_1 = {1, 2};
448 struct s2291335_2 gs2291335_2 = {1, 2};
450 void
451 __test2291335(void)
453 struct s2291335_1 ls2291335_1 = {1, 2};
454 struct s2291335_2 ls2291335_2 = {1, 2};
456 ASSERT(gs2291335_1.a == 1);
457 ASSERT(gs2291335_1.b == 2);
458 ASSERT(gs2291335_2.a == 1);
459 ASSERT(gs2291335_2.b == 2);
461 ASSERT(ls2291335_1.a == 1);
462 ASSERT(ls2291335_1.b == 2);
463 ASSERT(ls2291335_2.a == 1);
464 ASSERT(ls2291335_2.b == 2);
467 /* test case for bug #2366757: segfault when initializing structure with bitfield */
469 struct
471 char a : 1;
472 char b : 1;
473 } s2366757 = {0};
475 /* test case for const struct with bitfields */
477 #if !defined( __SDCC_pdk14) && !defined( __SDCC_pdk15) // Lack of memory
478 #ifndef __SDCC_pic16 // TODO: enable when the pic16 ports supports bitfields of size greater than 8 bits!
479 const struct
481 unsigned int a : 4;
482 unsigned int b : 3;
483 unsigned int c : 12;
484 unsigned int d : 3;
485 unsigned int e : 2;
486 unsigned int : 4;
487 unsigned int f : 2;
488 unsigned int g;
489 } cs = { 1, 2, 345, 6, 2, 1, 54321};
490 #endif
491 #endif
493 #if defined(PORT_HOST) && (defined(__x86_64__) || defined(__i386__)) && defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 6)
494 /* Workaround to fix the (cs.f == 1) test failure, which appeared in svn build 6665, when -O2 gcc option was included.
495 * The failure only occurs on i386 and x86_64 host architectures with gcc 4.6 if -O2 is set.
496 * This seems like a gcc bug to me. (Borut)
498 #pragma GCC push_options
499 #pragma GCC optimize ("O0")
500 #endif
501 void
502 testCS(void)
504 #if !defined( __SDCC_pdk14) && !defined( __SDCC_pdk15) // Lack of memory
505 #ifndef __SDCC_pic16 // TODO: enable when the pic16 ports supports bitfields of size greater than 8 bits!
506 ASSERT(cs.a == 1);
507 ASSERT(cs.b == 2);
508 ASSERT(cs.c == 345);
509 ASSERT(cs.d == 6);
510 ASSERT(cs.e == 2);
511 ASSERT(cs.f == 1);
512 ASSERT(cs.g == 54321U);
513 #endif
514 #endif
516 #if defined(PORT_HOST) && defined(__sun) && defined(__i386__) && defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ == 6)
517 #pragma GCC pop_options
518 #endif