tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] win64: stdarg va_start and va_arg fails


From: Feng Nauh
Subject: [Tinycc-devel] win64: stdarg va_start and va_arg fails
Date: Fri, 24 Oct 2014 12:20:28 +0800

Self-compiled tcc output error like this on win64:
tcc -c file-not-exits.c
tcc: error: file 'file '%s' not found' not found

The output backtrace:
  libtcc.c:626: tcc_error
    libtcc.c:569: error1
      libtcc.c:561: strcat_printf
        libtcc.c:564: va_start(ap, fmt);
It seems ap get wrong address of fmt.

In stdarg.h:
#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)

I notice va_arg not like the one in Windows SDK:
#define _crt_va_arg(ap, t)   \
    ( ( sizeof(t) > sizeof(__int64) || ( sizeof(t) & (sizeof(t) - 1) ) != 0 ) \
        ? **(t **)( ( ap += sizeof(__int64) ) - sizeof(__int64) ) \
        :  *(t  *)( ( ap += sizeof(__int64) ) - sizeof(__int64) ) )

It has 8 bytes offset.

Patch followed:
diff --git a/include/stdarg.h b/include/stdarg.h
index 5aa9d57..23f820f 100644
--- a/include/stdarg.h
+++ b/include/stdarg.h
@@ -29,8 +29,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_start(ap,last) (__builtin_va_start(ap,last), ap += 8)
+#define va_arg(ap,type) (ap += 8, (sizeof(type)>8 || (sizeof(type)&(sizeof(type)-1))!=0) ? **(type**)(ap-8) : *(type*)(ap-8))
 #define va_copy(dest, src) ((dest) = (src))
 #define va_end(ap)
 #endif


Or someone can fix __builtin_va_start.

tests/abitest.c also works.

This problem does not happened with x86_64-w64-mingw-tcc or tcc-win32.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]