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