diff --git a/include/stdarg.h b/include/stdarg.h index 06d592b..9fff0c0 100644 --- a/include/stdarg.h +++ b/include/stdarg.h @@ -30,7 +30,8 @@ void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); #else /* _WIN64 */ typedef char *va_list; #define va_start(ap,last) __builtin_va_start(ap,last) -#define va_arg(ap,type) (ap += 8, sizeof(type)<=8 ? *(type*)ap : **(type**)ap) +#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ + ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) #define va_copy(dest, src) ((dest) = (src)) #define va_end(ap) #endif diff --git a/tccgen.c b/tccgen.c index d7f8c0d..5d92e5f 100644 --- a/tccgen.c +++ b/tccgen.c @@ -4033,6 +4033,7 @@ ST_FUNC void unary(void) tcc_error("__builtin_va_start expects a local variable"); vtop->r &= ~(VT_LVAL | VT_REF); vtop->type = char_pointer_type; + vtop->c.i += 8; vstore(); } break; diff --git a/tccpp.c b/tccpp.c index 024f9de..b8453da 100644 --- a/tccpp.c +++ b/tccpp.c @@ -464,9 +464,6 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) switch(v) { case TOK_CINT: case TOK_CUINT: - /* XXX: not quite exact, but only useful for testing */ - sprintf(p, "%llu", (unsigned long long)cv->i); - break; case TOK_CLLONG: case TOK_CULLONG: /* XXX: not quite exact, but only useful for testing */ diff --git a/tests/tcctest.c b/tests/tcctest.c index e5ec783..6ec23a1 100644 --- a/tests/tcctest.c +++ b/tests/tcctest.c @@ -2116,6 +2116,14 @@ void stdarg_for_struct(struct myspace bob, ...) va_end(ap); } +void stdarg_for_libc(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + void stdarg_test(void) { LONG_DOUBLE ld = 1234567891234LL; @@ -2162,6 +2170,7 @@ void stdarg_test(void) bob.profile = 42; stdarg_for_struct(bob, bob, bob, bob.profile); + stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456); } void whitespace_test(void) diff --git a/x86_64-gen.c b/x86_64-gen.c index e313a5f..5a122d0 100644 --- a/x86_64-gen.c +++ b/x86_64-gen.c @@ -2228,7 +2228,6 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { vpush_global_sym(&func_old_type, TOK_alloca); vswap(); /* Move alloca ref past allocation size */ gfunc_call(1); - vset(type, REG_IRET, 0); #else int r; r = gv(RC_INT); /* allocation size */