01-kitchen-sink.c (9782B)
1 /* tests/cc-e2e/01-kitchen-sink.c — single-TU integration test. 2 * 3 * Single-file end-to-end exercise of the codegen surface that the 4 * parser drives today. Each numbered test computes a value; main 5 * checks each against an expected literal and exits with the test 6 * number (1..N) on first mismatch, 0 on full pass. 7 * 8 * Designed to stress *interactions* between features (e.g., struct 9 * members through fn-ptr-returned pointer, variadic + recursion + 10 * pointer arith, etc.) that the per-feature cc-cg fixtures don't. 11 */ 12 13 typedef char *va_list; 14 15 /* -------- Globals: scalar, bss, array, string, struct, designated, fn-ptr table -- */ 16 17 int g_scalar = 42; 18 int g_zero; /* bss */ 19 int g_arr[3] = { 10, 20, 30 }; 20 char g_msg[] = "hello"; 21 struct Point { int x; int y; }; 22 struct Point g_pt = { 100, 200 }; /* positional */ 23 struct Point g_pt2 = { .y = 5, .x = 7 }; /* designated */ 24 25 typedef int (*op2_t)(int, int); 26 int op_add(int a, int b) { return a + b; } 27 int op_mul(int a, int b) { return a * b; } 28 op2_t g_ops[2] = { op_add, op_mul }; 29 30 enum Color { RED, GREEN = 5, BLUE }; 31 32 /* -------- Tests ----------------------------------------------------------- */ 33 34 int test_arith(void) { 35 int a = 5; 36 int b = 3; 37 int r = 0; 38 r = r + (a + b); /* 8 */ 39 r = r + (a - b); /* 2 */ 40 r = r + (a * b); /* 15 */ 41 r = r + (10 / 3); /* 3 */ 42 r = r + (10 % 3); /* 1 */ 43 r = r + (1 << 4); /* 16 */ 44 r = r + (64 >> 2); /* 16 */ 45 r = r + (12 & 10); /* 8 */ 46 r = r + (12 | 10); /* 14 */ 47 r = r + (12 ^ 10); /* 6 */ 48 r = r + !0; /* 1 */ 49 r = r + ~0; /* -1 */ 50 r = r + (-1); /* -1 */ 51 return r; /* 88 */ 52 } 53 54 int test_compound(void) { 55 int x = 10; 56 x += 5; /* 15 */ 57 x -= 3; /* 12 */ 58 x *= 2; /* 24 */ 59 x /= 4; /* 6 */ 60 x %= 4; /* 2 */ 61 x <<= 3; /* 16 */ 62 x >>= 1; /* 8 */ 63 x &= 12; /* 8 */ 64 x |= 1; /* 9 */ 65 x ^= 6; /* 15 */ 66 return x; 67 } 68 69 int test_inc_dec(void) { 70 int x = 5; 71 int a = x++; /* a=5, x=6 */ 72 int b = ++x; /* b=7, x=7 */ 73 int c = x--; /* c=7, x=6 */ 74 int d = --x; /* d=5, x=5 */ 75 return a + b + c + d + x; /* 5+7+7+5+5 = 29 */ 76 } 77 78 int test_logical(void) { 79 int r = 0; 80 if (1 && 1) r = r + 1; 81 if (0 && 1) r = r + 100; 82 if (1 || 0) r = r + 2; 83 if (0 || 0) r = r + 100; 84 int side = 0; 85 if (1 || (side = 100)) r = r + 4; /* short-circuit; side stays 0 */ 86 if (0 && (side = 100)) r = r + 100; 87 return r + side; /* 1+2+4+0 = 7 */ 88 } 89 90 int test_ternary(void) { 91 int x = 5; 92 int y = (x > 3) ? 10 : 20; /* 10 */ 93 int z = (x < 3) ? 100 : 200; /* 200 */ 94 return y + z; /* 210 */ 95 } 96 97 int test_compare(void) { 98 int r = 0; 99 if (5 == 5) r = r + 1; 100 if (5 != 6) r = r + 2; 101 if (5 < 6) r = r + 4; 102 if (6 > 5) r = r + 8; 103 if (5 <= 5) r = r + 16; 104 if (5 >= 5) r = r + 32; 105 return r; /* 63 */ 106 } 107 108 int test_pointer(void) { 109 int x = 7; 110 int *p = &x; 111 *p = *p + 3; /* x = 10 */ 112 int **pp = &p; 113 int v = **pp; /* 10 */ 114 return *p + v; /* 20 */ 115 } 116 117 int test_array(void) { 118 int a[5] = { 1, 2, 3, 4, 5 }; 119 int sum = 0; 120 int i; 121 for (i = 0; i < 5; i = i + 1) sum = sum + a[i]; 122 return sum; /* 15 */ 123 } 124 125 int test_array_2d(void) { 126 int m[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; 127 int sum = 0; 128 int i; int j; 129 for (i = 0; i < 2; i = i + 1) 130 for (j = 0; j < 3; j = j + 1) 131 sum = sum + m[i][j]; 132 return sum; /* 21 */ 133 } 134 135 int test_struct(void) { 136 struct Point local = { 3, 4 }; 137 return local.x + local.y; /* 7 */ 138 } 139 140 int f_struct_arg(struct Point *p) { return p->x + p->y; } 141 142 int test_struct_ptr(void) { 143 return f_struct_arg(&g_pt) + g_pt2.x + g_pt2.y; /* 300 + 7 + 5 = 312 */ 144 } 145 146 int f_basic(int a, int b) { return a + b; } 147 148 int test_call(void) { 149 int x = f_basic(3, 4); /* 7 */ 150 int y = f_basic(10, -2); /* 8 */ 151 return x + y; /* 15 */ 152 } 153 154 int factorial(int n) { 155 if (n <= 1) return 1; 156 return n * factorial(n - 1); 157 } 158 159 int test_recursion(void) { return factorial(5); } /* 120 */ 160 161 int f_variadic(int n, ...) { 162 va_list ap; 163 int total; 164 int i; 165 __builtin_va_start(ap, n); 166 total = 0; 167 i = 0; 168 while (i < n) { 169 total = total + __builtin_va_arg(ap, int); 170 i = i + 1; 171 } 172 __builtin_va_end(ap); 173 return total; 174 } 175 176 int test_variadic(void) { return f_variadic(4, 1, 2, 3, 4); } /* 10 */ 177 178 int test_fn_ptr(void) { 179 op2_t add = g_ops[0]; 180 op2_t mul = g_ops[1]; 181 return add(3, 4) + mul(5, 6); /* 7 + 30 = 37 */ 182 } 183 184 /* Interaction: fn-ptr param + struct-ptr param + member access via -> */ 185 int apply2(op2_t f, struct Point *p) { return f(p->x, p->y); } 186 187 int test_apply(void) { 188 return apply2(op_add, &g_pt) + apply2(op_mul, &g_pt2); /* 300 + 35 = 335 */ 189 } 190 191 /* Interaction: pointer arith + deref + recursion + global-array decay */ 192 int sum_arr(int *p, int n) { 193 if (n == 0) return 0; 194 return *p + sum_arr(p + 1, n - 1); 195 } 196 197 int test_ptr_recursion(void) { return sum_arr(g_arr, 3); } /* 60 */ 198 199 int counter(void) { 200 static int n = 0; 201 n = n + 1; 202 return n; 203 } 204 205 int test_static(void) { 206 int a = counter(); /* 1 */ 207 int b = counter(); /* 2 */ 208 int c = counter(); /* 3 */ 209 return a + b + c; /* 6 */ 210 } 211 212 int test_switch(void) { 213 int r = 0; 214 int i; 215 for (i = 0; i < 4; i = i + 1) { 216 switch (i) { 217 case 0: r = r + 1; break; 218 case 1: r = r + 2; break; 219 case 2: 220 case 3: r = r + 10; break; 221 default: r = r + 100; break; 222 } 223 } 224 return r; /* 1 + 2 + 10 + 10 = 23 */ 225 } 226 227 int test_goto(void) { 228 int n = 0; 229 loop: 230 n = n + 1; 231 if (n < 5) goto loop; 232 return n; /* 5 */ 233 } 234 235 int test_loops(void) { 236 int x = 0; 237 do { x = x + 1; } while (x < 3); /* x = 3 */ 238 int y = 0; 239 while (y < 10) { 240 y = y + 1; 241 if (y == 5) continue; 242 x = x + 1; 243 } /* x = 3 + 9 = 12 */ 244 return x; /* 12 */ 245 } 246 247 int test_strings(void) { 248 char *s = "world"; 249 int sum = 0; 250 while (*s) { 251 sum = sum + *s; 252 s = s + 1; 253 } 254 return sum; /* w+o+r+l+d = 119+111+114+108+100 = 552 */ 255 } 256 257 int test_globals(void) { 258 g_zero = g_zero + 1; /* now 1 */ 259 return g_scalar + g_zero + g_arr[1] + g_msg[0]; /* 42+1+20+'h'(104) = 167 */ 260 } 261 262 int test_sizeof(void) { 263 return sizeof(int) + sizeof(char) + sizeof(struct Point) + sizeof(g_arr); 264 /* 4 + 1 + 8 + 12 = 25 */ 265 } 266 267 int test_enum(void) { 268 return RED + GREEN + BLUE; /* 0 + 5 + 6 = 11 */ 269 } 270 271 void f_void(int *out, int v) { *out = v; } 272 273 int test_void_call(void) { 274 int x = 0; 275 f_void(&x, 42); 276 return x; /* 42 */ 277 } 278 279 int test_cast(void) { 280 int a = 300; 281 int b = (int)(char)a; /* (char)300 = 44 (sign-extends back to int) */ 282 int c = (int)(short)a; /* (short)300 = 300 (fits in 16 bits) */ 283 return b + c; /* 344 */ 284 } 285 286 int test_void_ptr(void) { 287 int x = 99; 288 void *p = &x; 289 int *q = (int *)p; 290 return *q; /* 99 */ 291 } 292 293 int test_comma(void) { 294 int a = 0; int b = 0; 295 int x = (a = 5, b = 10, a + b); /* 15 */ 296 return x; 297 } 298 299 int test_addr_array(void) { 300 int (*p)[3] = &g_arr; 301 return (*p)[0] + (*p)[1] + (*p)[2]; /* 60 */ 302 } 303 304 /* -------- main ------------------------------------------------------------ */ 305 306 int main(int argc, char **argv) { 307 if (test_arith() != 88) return 1; 308 if (test_compound() != 15) return 2; 309 if (test_inc_dec() != 29) return 3; 310 if (test_logical() != 7) return 4; 311 if (test_ternary() != 210) return 5; 312 if (test_compare() != 63) return 6; 313 if (test_pointer() != 20) return 7; 314 if (test_array() != 15) return 8; 315 if (test_array_2d() != 21) return 9; 316 if (test_struct() != 7) return 10; 317 if (test_struct_ptr() != 312) return 11; 318 if (test_call() != 15) return 12; 319 if (test_recursion() != 120) return 13; 320 if (test_variadic() != 10) return 14; 321 if (test_fn_ptr() != 37) return 15; 322 if (test_apply() != 335) return 16; 323 if (test_ptr_recursion() != 60) return 17; 324 if (test_static() != 6) return 18; 325 if (test_switch() != 23) return 19; 326 if (test_goto() != 5) return 20; 327 if (test_loops() != 12) return 21; 328 if (test_strings() != 552) return 22; 329 if (test_globals() != 167) return 23; 330 if (test_sizeof() != 25) return 24; 331 if (test_enum() != 11) return 25; 332 if (test_void_call() != 42) return 26; 333 if (test_cast() != 344) return 27; 334 if (test_void_ptr() != 99) return 28; 335 if (test_comma() != 15) return 29; 336 if (test_addr_array() != 60) return 30; 337 return 0; 338 }