c_frontback_amalgam.c (6020B)
1 #include <stdarg.h> 2 #include <stdint.h> 3 4 /* --- Front/back smoke amalgamation -------------------------------------- */ 5 6 #define FB_MUL2(X) ((X) * (X)) 7 8 _Static_assert(FB_MUL2(3u) == 9u, "macro expansion sanity"); 9 10 struct fb_small_struct { 11 int32_t a; 12 int16_t b; 13 }; 14 15 struct fb_large_struct { 16 uint64_t a; 17 uint64_t b; 18 uint64_t c; 19 uint64_t d; 20 }; 21 22 union fb_union_bits { 23 uint32_t raw; 24 struct { 25 uint32_t low:12; 26 uint32_t high:20; 27 } bits; 28 }; 29 30 static uint32_t fb_mutable_data = 7; 31 static const uint32_t fb_ro_data = 0xA55A3A11u; 32 static uint32_t fb_bss[4]; 33 34 static int fb_fail(const int rc) { 35 return rc; 36 } 37 38 static int fb_macro_and_static_assert(void) { 39 int x = FB_MUL2(2 + 1); 40 return x != 9 ? fb_fail(1) : 0; 41 } 42 43 static int fb_integer_promotions(void) { 44 int8_t s8 = -42; 45 uint8_t u8 = 17; 46 int32_t sum = (int32_t)s8 + (int32_t)u8; 47 return sum != -25 ? fb_fail(2) : 0; 48 } 49 50 static int fb_signed_unsigned(void) { 51 int32_t si = -20; 52 uint32_t ui = 5u; 53 uint32_t mixed = si + ui; 54 return mixed != 4294967281u ? fb_fail(3) : 0; 55 } 56 57 static int fb_shift_div_rem(void) { 58 uint32_t a = 0x10u; 59 uint32_t b = (a << 4) - 5u; 60 uint32_t c = b / 3u; 61 uint32_t d = b % 3u; 62 return (b != 0xFBu || c != 0x53u || d != 2u) ? fb_fail(4) : 0; 63 } 64 65 static int fb_pointer_arith(void) { 66 int32_t values[5] = { 1, 2, 3, 4, 5 }; 67 int32_t* p = values; 68 int32_t x = p[2] + *(p + 2); 69 return (p + 4) - p != 4 || x != 6 ? fb_fail(5) : 0; 70 } 71 72 static int fb_arrays_compound(void) { 73 int32_t arr[6] = { [0] = 1, [3] = 4, [5] = 9 }; 74 int32_t* tmp = (int32_t[]){ 10, 11, 12, 13 }; 75 if (arr[1] != 0 || arr[3] != 4 || arr[5] != 9) return fb_fail(6); 76 return (tmp[0] + tmp[3] == 23 && tmp[2] == 12) ? 0 : fb_fail(6); 77 } 78 79 static int fb_struct_union_bitfields(void) { 80 struct fb_small_struct s = { .a = 7, .b = -2 }; 81 union fb_union_bits u; 82 struct { 83 uint32_t a; 84 uint32_t b; 85 uint32_t c; 86 } t; 87 u.raw = 0x1234u; 88 t.a = s.a; 89 t.b = (uint32_t)u.bits.low; 90 t.c = (uint32_t)u.bits.high; 91 if (t.a != 7u || t.b != 0x234u || t.c != 0x1u) return fb_fail(7); 92 return 0; 93 } 94 95 static int fb_switches(void) { 96 int32_t dense = 0; 97 switch (2) { 98 case 0: dense = 1; break; 99 case 1: dense = 2; break; 100 case 2: dense = 3; break; 101 default: dense = 9; break; 102 } 103 if (dense != 3) return fb_fail(8); 104 105 int32_t sparse = 0; 106 switch (100) { 107 case 1: sparse = 1; break; 108 case 100: sparse = 2; break; 109 case 200: sparse = 3; break; 110 default: sparse = 4; break; 111 } 112 return sparse == 2 ? 0 : fb_fail(8); 113 } 114 115 static int fb_loops_goto(void) { 116 int32_t sum = 0; 117 int32_t i = 0; 118 while (i < 4) { 119 sum += i; 120 i += 1; 121 if (i == 3) goto fb_gate; 122 } 123 fb_gate: 124 return (sum == 3) ? 0 : fb_fail(9); 125 } 126 127 static int fb_recursion(int32_t n) { 128 return n <= 1 ? n : fb_recursion(n - 1) + fb_recursion(n - 2); 129 } 130 131 static int fb_many_args(int32_t a0, int32_t a1, int32_t a2, int32_t a3, int32_t a4, 132 int32_t a5, int32_t a6, int32_t a7, int32_t a8, int32_t a9, 133 int32_t a10) { 134 return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10; 135 } 136 137 static struct fb_small_struct fb_struct_by_value_small(struct fb_small_struct s) { 138 struct fb_small_struct out; 139 out.a = s.a + 1; 140 out.b = (int16_t)(s.b + 2); 141 return out; 142 } 143 144 static struct fb_large_struct fb_struct_by_value_large(uint32_t seed) { 145 struct fb_large_struct r; 146 r.a = (uint64_t)seed + 1u; 147 r.b = (uint64_t)seed + 2u; 148 r.c = (uint64_t)seed + 3u; 149 r.d = (uint64_t)seed + 4u; 150 return r; 151 } 152 153 static int fb_mixed_calls(int32_t i, float f, double d) { 154 int32_t mixed = (int32_t)d + (int32_t)f + i; 155 return mixed == 10 ? 0 : fb_fail(10); 156 } 157 158 static int fb_varargs(const int count, ...) { 159 va_list ap; 160 int32_t sum; 161 int i; 162 va_start(ap, count); 163 sum = 0; 164 for (i = 0; i < count; ++i) { 165 sum += va_arg(ap, int32_t); 166 } 167 va_end(ap); 168 return sum == 10 ? 0 : fb_fail(11); 169 } 170 171 static int fb_function_pointer(void) { 172 int32_t (*fp)(int32_t) = fb_recursion; 173 return (fp == 0) ? fb_fail(12) : (fp(2) != 1 ? fb_fail(12) : 0); 174 } 175 176 static int fb_storage_and_memory(void) { 177 static uint32_t local_static; 178 struct fb_small_struct s = { 1, 2 }; 179 struct fb_small_struct t = fb_struct_by_value_small(s); 180 local_static += 3u; 181 fb_mutable_data += 1u; 182 if (t.a != 2 || local_static != 3u || fb_mutable_data != 8u) return fb_fail(13); 183 184 if (fb_bss[0] != 0u || fb_bss[1] != 0u || fb_bss[2] != 0u || fb_bss[3] != 0u) { 185 return fb_fail(14); 186 } 187 fb_bss[2] = 0x1234u; 188 if (fb_bss[2] != 0x1234u || fb_ro_data != 0xA55A3A11u) return fb_fail(14); 189 return 0; 190 } 191 192 static int fb_float_double(void) { 193 float f = 3.0f; 194 double d = 4.5; 195 float f2 = 0.5f; 196 double a = (double)f * f2; 197 double b = d - 0.5; 198 if (!(a == 1.5 && b == 4.0)) return fb_fail(15); 199 return 0; 200 } 201 202 int main(void) { 203 int32_t rc; 204 205 rc = fb_macro_and_static_assert(); 206 if (rc) return rc; 207 rc = fb_integer_promotions(); 208 if (rc) return rc; 209 rc = fb_signed_unsigned(); 210 if (rc) return rc; 211 rc = fb_shift_div_rem(); 212 if (rc) return rc; 213 rc = fb_pointer_arith(); 214 if (rc) return rc; 215 rc = fb_arrays_compound(); 216 if (rc) return rc; 217 rc = fb_struct_union_bitfields(); 218 if (rc) return rc; 219 rc = fb_switches(); 220 if (rc) return rc; 221 rc = fb_loops_goto(); 222 if (rc) return rc; 223 rc = fb_recursion(6) == 8 ? 0 : fb_fail(16); 224 if (rc) return rc; 225 rc = (fb_many_args(1,2,3,4,5,6,7,8,9,10,10) == 65) ? 0 : fb_fail(17); 226 if (rc) return rc; 227 { 228 struct fb_small_struct s = { 10, 20 }; 229 struct fb_small_struct p = fb_struct_by_value_small(s); 230 if (p.a != 11 || p.b != 22) return fb_fail(18); 231 } 232 { 233 struct fb_large_struct r = fb_struct_by_value_large(5); 234 uint64_t sum = r.a + r.b + r.c + r.d; 235 if (sum != 30u) return fb_fail(19); 236 } 237 rc = fb_mixed_calls(2, 3.0f, 5.0); 238 if (rc) return rc; 239 rc = fb_varargs(4, 1, 2, 3, 4); 240 if (rc) return rc; 241 rc = fb_function_pointer(); 242 if (rc) return rc; 243 rc = fb_storage_and_memory(); 244 if (rc) return rc; 245 rc = fb_float_double(); 246 if (rc) return rc; 247 248 return 0; 249 }