struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / support / regression / tests / bitint.c.in
blob2718d226ad5fffae2512b5a71b5605e9d80ae71f
1 /** bit-precise integers
3 width: 2, 4, 6, 7, 8, 9, 15, 16, 17, 24, 32, 33, 40, 48, 63, 64, 65
4 sign: unsigned, signed
5 */
7 #include <testfwk.h>
9 #include <limits.h>
11 // clang 11 supports bit-precise types, but deviates a bit from C23.
12 #if __clang_major__ == 11
13 #define __SDCC_BITINT_MAXWIDTH 128
14 #define _BitInt _ExtInt
15 #endif
17 #if __SDCC_BITINT_MAXWIDTH >= {width} // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
19 typedef {sign} _BitInt({width}) bitinttype;
21 bitinttype f(void) // The backend needs to support returning types of arbitrary width, not just powers of two.
23 return 42;
26 bitinttype g(bitinttype a) // The backend needs to support parameters of arbitrary width, not just powers of two.
28 return ++a;
31 #endif
33 volatile int i = 42;
34 volatile long long ll = 42;
36 void testBitInt(void)
38 #if __SDCC_BITINT_MAXWIDTH >= {width} // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
39 ASSERT(f() == (bitinttype)42);
40 ASSERT(g(0) == (bitinttype)1);
42 #ifndef __clang_major__ // clang 11 does not yet support addition of _BitInt of different width
43 #if __SDCC_BITINT_MAXWIDTH >= 4 // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
44 ASSERT(_Generic((_BitInt(4))(4) + (_BitInt(6))(6), default: 1, _BitInt(6): 0) == 0); // _BitInt does not promote to int, even when narrower than int.
45 //BUG! SDCC makes 6 char instead of int! ASSERT(_Generic((_BitInt(4))(4) + 6, default: 1, int: 0) == 0); // But it does promote to int when the other operand is int.
46 //BUG! SDCC makes 6 char instead of int! ASSERT(_Generic((_BitInt(CHAR_BIT * sizeof(int)))(4) + 6, default: 1, int: 0) == 0); // Even when both are the same size.
48 ASSERT(_Generic((_BitInt(4))(4) + (_BitInt(6))(300), default: 1, _BitInt(6): 0) == 0); // _BitInt does not promote to int, even when narrower than int.
49 ASSERT(_Generic((_BitInt(4))(4) + 300, default: 1, int: 0) == 0); // But it does promote to int when the other operand is int.
50 #if __SDCC_BITINT_MAXWIDTH >= 32 // 32 should work on most platforms, including hosts with 32-bit int // TODO: When we can regression-test in --std-c23 mode, use the standard macro from limits.h instead!
51 ASSERT(_Generic((_BitInt(CHAR_BIT * sizeof(int)))(4) + 300, default: 1, int: 0) == 0); // Even when both are the same size.
52 #endif
53 #endif
54 #endif
56 bitinttype b = 1;
57 ASSERT(_Generic(++b, default: 1, bitinttype: 0) == 0); // ++a is not the same a += 1, but a += (bitinttype)1.
59 // Cast from int
60 ASSERT((bitinttype)i == (bitinttype)42); // Explicit cast
61 b = i; // Implicit cast
62 ASSERT(b == (bitinttype)42);
63 i = -23;
64 b = i; // Implicit cast
65 ASSERT(b == (bitinttype)-23);
67 // Cast from long long
68 ASSERT((bitinttype)ll == (bitinttype)42); // Explicit cast
69 b = ll; // Implicit cast
70 ASSERT(b == (bitinttype)42);
72 // Casts between bit-precise types
73 #if {width} >= 6
74 b = 0x5aff;
75 unsigned _BitInt(6) b6 = b;
76 ASSERT((unsigned _BitInt(6))((bitinttype)0x5aff) == b6); // Bug #3371 - both casts are done at compile time, results were different - left cast done on ast (ok), right on iCode (wrong on FreeBSD13 on aarch64).
77 b = b6;
78 ASSERT((bitinttype)b6 == (bitinttype)(unsigned _BitInt(6))0x5aff);
79 #endif
80 #endif