tcctest1-3 fail, but this appears to be due to bugs in GCC rather than TCC (from manual inspection of the output).
Showing the changes to tests (2 of 8 files). Show all
Unified · Split
| @@ -6,7 +6,7 @@ add_test(NAME abitest-cc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND abitest-c · 5 unmodified lines | ||
| 6 | 6 | |
| 7 | 7 | set(ABITEST_TCC abitest-tcc${CMAKE_EXECUTABLE_SUFFIX}) |
| 8 | 8 | get_property(LIBTCC_LIB TARGET libtcc PROPERTY LOCATION) |
| 9 | −add_custom_command(OUTPUT ${ABITEST_TCC} COMMAND tcc ${TCC_CFLAGS} -I${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c ${LIBTCC_LIB} -o ${ABITEST_TCC} DEPENDS abitest.c) | |
| 9 | +add_custom_command(OUTPUT ${ABITEST_TCC} COMMAND tcc ${TCC_CFLAGS} -g -I${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/abitest.c ${LIBTCC_LIB} -o ${ABITEST_TCC} DEPENDS abitest.c) | |
| 10 | 10 | add_custom_target(abitest-tcc-exe ALL DEPENDS ${ABITEST_TCC}) |
| 11 | 11 | |
| 12 | 12 | add_test(NAME abitest-tcc WORKING_DIRECTORY ${CMAKE_BINARY_DIR} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${ABITEST_TCC} lib_path=${CMAKE_BINARY_DIR} include=${CMAKE_SOURCE_DIR}/include) |
| @@ -20,7 +20,7 @@ if(WIN32) · 7 unmodified lines | ||
| 20 | 20 | set(TCC_TEST_CFLAGS ${TCC_TEST_CFLAGS} -I${CMAKE_SOURCE_DIR}/win32/include/winapi) |
| 21 | 21 | endif() |
| 22 | 22 | set(TCC_TEST_SOURCE ${TCC_TEST_CFLAGS} -run ${CMAKE_CURRENT_SOURCE_DIR}/tcctest.c) |
| 23 | −set(TCC_TEST_RUN ${TCC_TEST_CFLAGS} -DONE_SOURCE -run ${CMAKE_SOURCE_DIR}/tcc.c) | |
| 23 | +set(TCC_TEST_RUN ${TCC_TEST_CFLAGS} ${TCC_TARGET_FLAGS} -DONE_SOURCE -run ${CMAKE_SOURCE_DIR}/tcc.c) | |
| 24 | 24 | |
| 25 | 25 | add_custom_command(OUTPUT tcctest.ref COMMAND tcctest-cc > tcctest.ref) |
| 26 | 26 | add_custom_command(OUTPUT tcctest.1 COMMAND tcc ${TCC_TEST_SOURCE} > tcctest.1) |
| @@ -262,41 +262,133 @@ static int two_member_union_test(void) { · 261 unmodified lines | ||
| 262 | 262 | return run_callback(src, two_member_union_test_callback); |
| 263 | 263 | } |
| 264 | 264 | |
| 265 | +/* | |
| 266 | + * Win64 calling convetntion test. | |
| 267 | + */ | |
| 268 | + | |
| 269 | +typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type; | |
| 270 | +typedef many_struct_test_type (*many_struct_test_function_type) (many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type,many_struct_test_type); | |
| 271 | + | |
| 272 | +static int many_struct_test_callback(void *ptr) { | |
| 273 | + many_struct_test_function_type f = (many_struct_test_function_type)ptr; | |
| 274 | + many_struct_test_type v = {1, 2, 3}; | |
| 275 | + many_struct_test_type r = f(v,v,v,v,v,v); | |
| 276 | + return ((r.a == 6) && (r.b == 12) && (r.c == 18))?0:-1; | |
| 277 | +} | |
| 278 | + | |
| 279 | +static int many_struct_test(void) { | |
| 280 | + const char *src = | |
| 281 | + "typedef struct many_struct_test_type_s {long long a, b, c;} many_struct_test_type;\n" | |
| 282 | + "many_struct_test_type f(many_struct_test_type x1, many_struct_test_type x2, many_struct_test_type x3, many_struct_test_type x4, many_struct_test_type x5, many_struct_test_type x6) {\n" | |
| 283 | + " many_struct_test_type y;\n" | |
| 284 | + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" | |
| 285 | + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" | |
| 286 | + " y.c = x1.c + x2.c + x3.c + x4.c + x5.c + x6.c;\n" | |
| 287 | + " return y;\n" | |
| 288 | + "}\n"; | |
| 289 | + return run_callback(src, many_struct_test_callback); | |
| 290 | +} | |
| 291 | + | |
| 292 | +/* | |
| 293 | + * Win64 calling convention test. | |
| 294 | + */ | |
| 295 | + | |
| 296 | +typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type; | |
| 297 | +typedef many_struct_test_2_type (*many_struct_test_2_function_type) (many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type,many_struct_test_2_type); | |
| 298 | + | |
| 299 | +static int many_struct_test_2_callback(void *ptr) { | |
| 300 | + many_struct_test_2_function_type f = (many_struct_test_2_function_type)ptr; | |
| 301 | + many_struct_test_2_type v = {1,2}; | |
| 302 | + many_struct_test_2_type r = f(v,v,v,v,v,v); | |
| 303 | + return ((r.a == 6) && (r.b == 12))?0:-1; | |
| 304 | +} | |
| 305 | + | |
| 306 | +static int many_struct_test_2(void) { | |
| 307 | + const char *src = | |
| 308 | + "typedef struct many_struct_test_2_type_s {int a, b;} many_struct_test_2_type;\n" | |
| 309 | + "many_struct_test_2_type f(many_struct_test_2_type x1, many_struct_test_2_type x2, many_struct_test_2_type x3, many_struct_test_2_type x4, many_struct_test_2_type x5, many_struct_test_2_type x6) {\n" | |
| 310 | + " many_struct_test_2_type y;\n" | |
| 311 | + " y.a = x1.a + x2.a + x3.a + x4.a + x5.a + x6.a;\n" | |
| 312 | + " y.b = x1.b + x2.b + x3.b + x4.b + x5.b + x6.b;\n" | |
| 313 | + " return y;\n" | |
| 314 | + "}\n"; | |
| 315 | + return run_callback(src, many_struct_test_2_callback); | |
| 316 | +} | |
| 317 | + | |
| 265 | 318 | /* |
| 266 | 319 | * stdarg_test: Test variable argument list ABI |
| 267 | 320 | */ |
| 268 | 321 | |
| 269 | −typedef void (*stdarg_test_function_type) (int,int,...); | |
| 322 | +typedef struct {long long a, b, c;} stdarg_test_struct_type; | |
| 323 | +typedef void (*stdarg_test_function_type) (int,int,int,...); | |
| 270 | 324 | |
| 271 | 325 | static int stdarg_test_callback(void *ptr) { |
| 272 | 326 | stdarg_test_function_type f = (stdarg_test_function_type)ptr; |
| 273 | 327 | int x; |
| 274 | 328 | double y; |
| 275 | − f(10, 10, | |
| 329 | + stdarg_test_struct_type z = {1, 2, 3}, w; | |
| 330 | + f(10, 10, 5, | |
| 276 | 331 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, &x, |
| 277 | − 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y); | |
| 278 | − return ((x == 55) && (y == 55)) ? 0 : -1; | |
| 332 | + 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, &y, | |
| 333 | + z, z, z, z, z, &w); | |
| 334 | + return ((x == 55) && (y == 55) && (w.a == 5) && (w.b == 10) && (w.c == 15)) ? 0 : -1; | |
| 279 | 335 | } |
| 280 | 336 | |
| 281 | 337 | static int stdarg_test(void) { |
| 282 | 338 | const char *src = |
| 283 | 339 | "#include <stdarg.h>\n" |
| 284 | − "void f(int n_int, int n_float, ...) {\n" | |
| 340 | + "typedef struct {long long a, b, c;} stdarg_test_struct_type;\n" | |
| 341 | + "void f(int n_int, int n_float, int n_struct, ...) {\n" | |
| 285 | 342 | " int i, ti;\n" |
| 286 | 343 | " double td;\n" |
| 344 | + " stdarg_test_struct_type ts = {0,0,0}, tmp;\n" | |
| 287 | 345 | " va_list ap;\n" |
| 288 | − " va_start(ap, n_float);\n" | |
| 346 | + " va_start(ap, n_struct);\n" | |
| 289 | 347 | " for (i = 0, ti = 0; i < n_int; ++i)\n" |
| 290 | 348 | " ti += va_arg(ap, int);\n" |
| 291 | 349 | " *va_arg(ap, int*) = ti;\n" |
| 292 | 350 | " for (i = 0, td = 0; i < n_float; ++i)\n" |
| 293 | 351 | " td += va_arg(ap, double);\n" |
| 294 | 352 | " *va_arg(ap, double*) = td;\n" |
| 353 | + " for (i = 0; i < n_struct; ++i) {\n" | |
| 354 | + " tmp = va_arg(ap, stdarg_test_struct_type);\n" | |
| 355 | + " ts.a += tmp.a; ts.b += tmp.b; ts.c += tmp.c;" | |
| 356 | + " }\n" | |
| 357 | + " *va_arg(ap, stdarg_test_struct_type*) = ts;\n" | |
| 295 | 358 | " va_end(ap);" |
| 296 | 359 | "}\n"; |
| 297 | 360 | return run_callback(src, stdarg_test_callback); |
| 298 | 361 | } |
| 299 | 362 | |
| 363 | +/* | |
| 364 | + * Test Win32 stdarg handling, since the calling convention will pass a pointer | |
| 365 | + * to the struct and the stdarg pointer must point to that pointer initially. | |
| 366 | + */ | |
| 367 | + | |
| 368 | +typedef struct {long long a, b, c;} stdarg_struct_test_struct_type; | |
| 369 | +typedef int (*stdarg_struct_test_function_type) (stdarg_struct_test_struct_type a, ...); | |
| 370 | + | |
| 371 | +static int stdarg_struct_test_callback(void *ptr) { | |
| 372 | + stdarg_struct_test_function_type f = (stdarg_struct_test_function_type)ptr; | |
| 373 | + stdarg_struct_test_struct_type v = {10, 35, 99}; | |
| 374 | + int x = f(v, 234); | |
| 375 | + return (x == 378) ? 0 : -1; | |
| 376 | +} | |
| 377 | + | |
| 378 | +static int stdarg_struct_test(void) { | |
| 379 | + const char *src = | |
| 380 | + "#include <stdarg.h>\n" | |
| 381 | + "typedef struct {long long a, b, c;} stdarg_struct_test_struct_type;\n" | |
| 382 | + "int f(stdarg_struct_test_struct_type a, ...) {\n" | |
| 383 | + " va_list ap;\n" | |
| 384 | + " va_start(ap, a);\n" | |
| 385 | + " int z = va_arg(ap, int);\n" | |
| 386 | + " va_end(ap);\n" | |
| 387 | + " return z + a.a + a.b + a.c;\n" | |
| 388 | + "}\n"; | |
| 389 | + return run_callback(src, stdarg_struct_test_callback); | |
| 390 | +} | |
| 391 | + | |
| 300 | 392 | #define RUN_TEST(t) \ |
| 301 | 393 | if (!testname || (strcmp(#t, testname) == 0)) { \ |
| 302 | 394 | fputs(#t "... ", stdout); \ |
| @@ -336,6 +428,9 @@ int main(int argc, char **argv) { · 33 unmodified lines | ||
| 336 | 428 | RUN_TEST(sret_test); |
| 337 | 429 | RUN_TEST(one_member_union_test); |
| 338 | 430 | RUN_TEST(two_member_union_test); |
| 431 | + RUN_TEST(many_struct_test); | |
| 432 | + RUN_TEST(many_struct_test_2); | |
| 339 | 433 | RUN_TEST(stdarg_test); |
| 434 | + RUN_TEST(stdarg_struct_test); | |
| 340 | 435 | return retval; |
| 341 | 436 | } |