If there were more than 6 integer arguments before the ellipsis, or there were used more than 8 slots used until the ellipsis (e.g. by a large intermediate struct) we generated wrong code. See testcase.
Showing the changes to tests (1 of 2 files). Show all
Unified · Split
| @@ -558,6 +558,36 @@ static int stdarg_test(void) { · 557 unmodified lines | ||
| 558 | 558 | return run_callback(src, stdarg_test_callback); |
| 559 | 559 | } |
| 560 | 560 | |
| 561 | +typedef struct {long long a, b;} stdarg_many_test_struct_type; | |
| 562 | +typedef void (*stdarg_many_test_function_type) (int, int, int, int, int, | |
| 563 | + stdarg_many_test_struct_type, | |
| 564 | + int, int, ...); | |
| 565 | + | |
| 566 | +static int stdarg_many_test_callback(void *ptr) | |
| 567 | +{ | |
| 568 | + stdarg_many_test_function_type f = (stdarg_many_test_function_type)ptr; | |
| 569 | + int x; | |
| 570 | + stdarg_many_test_struct_type l = {10, 11}; | |
| 571 | + f(1, 2, 3, 4, 5, l, 6, 7, &x, 44); | |
| 572 | + return x == 44 ? 0 : -1; | |
| 573 | +} | |
| 574 | + | |
| 575 | +static int stdarg_many_test(void) | |
| 576 | +{ | |
| 577 | + const char *src = | |
| 578 | + "#include <stdarg.h>\n" | |
| 579 | + "typedef struct {long long a, b;} stdarg_many_test_struct_type;\n" | |
| 580 | + "void f (int a, int b, int c, int d, int e, stdarg_many_test_struct_type l, int f, int g, ...){\n" | |
| 581 | + " va_list ap;\n" | |
| 582 | + " int *p;\n" | |
| 583 | + " va_start (ap, g);\n" | |
| 584 | + " p = va_arg(ap, int*);\n" | |
| 585 | + " *p = va_arg(ap, int);\n" | |
| 586 | + " va_end (ap);\n" | |
| 587 | + "}\n"; | |
| 588 | + return run_callback(src, stdarg_many_test_callback); | |
| 589 | +} | |
| 590 | + | |
| 561 | 591 | /* |
| 562 | 592 | * Test Win32 stdarg handling, since the calling convention will pass a pointer |
| 563 | 593 | * to the struct and the stdarg pointer must point to that pointer initially. |
| @@ -654,6 +684,7 @@ int main(int argc, char **argv) { · 90 unmodified lines | ||
| 654 | 684 | RUN_TEST(many_struct_test_2); |
| 655 | 685 | RUN_TEST(many_struct_test_3); |
| 656 | 686 | RUN_TEST(stdarg_test); |
| 687 | + RUN_TEST(stdarg_many_test); | |
| 657 | 688 | RUN_TEST(stdarg_struct_test); |
| 658 | 689 | RUN_TEST(arg_align_test); |
| 659 | 690 | return retval; |