diff options
authorRich Felker <>2011-04-27 23:41:48 -0400
committerRich Felker <>2011-04-27 23:41:48 -0400
commitdef0af189871a499efdc9bc37438d8b20eb702ab (patch)
parente6bac87d0eaab116878a04874bc5b6a3496cb938 (diff)
use compiler builtins for variadic macros when available
this slightly cuts down on the degree musl "fights with" gcc, but more importantly, it fixes a critical bug when gcc inlines a variadic function and optimizes out the variadic arguments due to noticing that they were "not used" (by __builtin_va_arg). we leave the old code in place if __GNUC__ >= 3 is false; it seems like it might be necessary at least for tinycc support and perhaps if anyone ever gets around to fixing gcc 2.95.3 enough to make it work..
3 files changed, 12 insertions, 1 deletions
diff --git a/arch/i386/bits/ b/arch/i386/bits/
index 9d94c911..335c0957 100755
--- a/arch/i386/bits/
+++ b/arch/i386/bits/
@@ -19,7 +19,12 @@ union \1 \2;\
TYPEDEF unsigned size_t;
TYPEDEF int ssize_t;
TYPEDEF long ptrdiff_t;
+#if __GNUC__ >= 3
+TYPEDEF __builtin_va_list va_list;
TYPEDEF struct __va_list * va_list;
TYPEDEF long wchar_t;
TYPEDEF long wint_t;
diff --git a/arch/x86_64/bits/stdarg.h b/arch/x86_64/bits/stdarg.h
index 24b679c9..fde37814 100644
--- a/arch/x86_64/bits/stdarg.h
+++ b/arch/x86_64/bits/stdarg.h
@@ -2,4 +2,3 @@
#define va_end(v) __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)
#define va_copy(d,s) __builtin_va_copy(d,s)
-#define __va_copy(d,s) __builtin_va_copy(d,s)
diff --git a/include/stdarg.h b/include/stdarg.h
index 2e18e5f5..60d4e2af 100644
--- a/include/stdarg.h
+++ b/include/stdarg.h
@@ -9,7 +9,14 @@ extern "C" {
#include <bits/alltypes.h>
+#if __GNUC__ >= 3
+#define va_start(v,l) __builtin_va_start(v,l)
+#define va_end(v) __builtin_va_end(v)
+#define va_arg(v,l) __builtin_va_arg(v,l)
+#define va_copy(d,s) __builtin_va_copy(d,s)
#include <bits/stdarg.h>
#ifdef __cplusplus