kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

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 }