fixes 5c35ba66c5ade4713bbd9c005e66889f6d7db293 Implementation was consistent within tcc but incompatible with the ABI (for example library functions vprintf etc) Also: - tccpp.c/get_tok_str() : avoid "unknown format "%llu" warning - x86_64_gen.c/gen_vla_alloc() : fix vstack leak
Unified · Split
| @@ -30,7 +30,8 @@ void *__va_arg(__va_list_struct *ap, int arg_type, int size, int align); · 29 unmodified lines | ||
| 30 | 30 | #else /* _WIN64 */ |
| 31 | 31 | typedef char *va_list; |
| 32 | 32 | #define va_start(ap,last) __builtin_va_start(ap,last) |
| 33 | −#define va_arg(ap,type) (ap += 8, sizeof(type)<=8 ? *(type*)ap : **(type**)ap) | |
| 33 | +#define va_arg(ap, t) ((sizeof(t) > 8 || (sizeof(t) & (sizeof(t) - 1))) \ | |
| 34 | + ? **(t **)((ap += 8) - 8) : *(t *)((ap += 8) - 8)) | |
| 34 | 35 | #define va_copy(dest, src) ((dest) = (src)) |
| 35 | 36 | #define va_end(ap) |
| 36 | 37 | #endif |
| @@ -4033,6 +4033,7 @@ ST_FUNC void unary(void) · 4032 unmodified lines | ||
| 4033 | 4033 | tcc_error("__builtin_va_start expects a local variable"); |
| 4034 | 4034 | vtop->r &= ~(VT_LVAL | VT_REF); |
| 4035 | 4035 | vtop->type = char_pointer_type; |
| 4036 | + vtop->c.i += 8; | |
| 4036 | 4037 | vstore(); |
| 4037 | 4038 | } |
| 4038 | 4039 | break; |
| @@ -464,9 +464,6 @@ ST_FUNC const char *get_tok_str(int v, CValue *cv) · 463 unmodified lines | ||
| 464 | 464 | switch(v) { |
| 465 | 465 | case TOK_CINT: |
| 466 | 466 | case TOK_CUINT: |
| 467 | − /* XXX: not quite exact, but only useful for testing */ | |
| 468 | − sprintf(p, "%llu", (unsigned long long)cv->i); | |
| 469 | − break; | |
| 470 | 467 | case TOK_CLLONG: |
| 471 | 468 | case TOK_CULLONG: |
| 472 | 469 | /* XXX: not quite exact, but only useful for testing */ |
| @@ -2116,6 +2116,14 @@ void stdarg_for_struct(struct myspace bob, ...) · 2115 unmodified lines | ||
| 2116 | 2116 | va_end(ap); |
| 2117 | 2117 | } |
| 2118 | 2118 | |
| 2119 | +void stdarg_for_libc(const char *fmt, ...) | |
| 2120 | +{ | |
| 2121 | + va_list args; | |
| 2122 | + va_start(args, fmt); | |
| 2123 | + vprintf(fmt, args); | |
| 2124 | + va_end(args); | |
| 2125 | +} | |
| 2126 | + | |
| 2119 | 2127 | void stdarg_test(void) |
| 2120 | 2128 | { |
| 2121 | 2129 | LONG_DOUBLE ld = 1234567891234LL; |
| @@ -2162,6 +2170,7 @@ void stdarg_test(void) · 40 unmodified lines | ||
| 2162 | 2170 | |
| 2163 | 2171 | bob.profile = 42; |
| 2164 | 2172 | stdarg_for_struct(bob, bob, bob, bob.profile); |
| 2173 | + stdarg_for_libc("stdarg_for_libc: %s %.2f %d\n", "string", 1.23, 456); | |
| 2165 | 2174 | } |
| 2166 | 2175 | |
| 2167 | 2176 | void whitespace_test(void) |
| @@ -2228,7 +2228,6 @@ ST_FUNC void gen_vla_alloc(CType *type, int align) { · 2227 unmodified lines | ||
| 2228 | 2228 | vpush_global_sym(&func_old_type, TOK_alloca); |
| 2229 | 2229 | vswap(); /* Move alloca ref past allocation size */ |
| 2230 | 2230 | gfunc_call(1); |
| 2231 | − vset(type, REG_IRET, 0); | |
| 2232 | 2231 | #else |
| 2233 | 2232 | int r; |
| 2234 | 2233 | r = gv(RC_INT); /* allocation size */ |