Index | Thread | Search

From:
Theo Buehler <tb@theobuehler.org>
Subject:
Re: [RFC PATCH] Use __builtin_va_list consistently for va_list without __GNUC__
To:
Michael Forney <mforney@mforney.org>
Cc:
tech@openbsd.org
Date:
Tue, 11 Aug 2026 19:27:39 +0200

Download raw body.

Thread
On Wed, Jun 24, 2026 at 10:49:31AM +0200, Theo Buehler wrote:
> On Mon, Jun 01, 2026 at 10:07:11AM -0700, Michael Forney wrote:
> > Since OpenBSD 6.7, stdarg.h unconditionally defines va_list as
> > __builtin_va_list and uses __builtin_va_* to implement the va_*
> > macros. However, compilers that don't define __GNUC__ now get
> > conflicting definitions for the va_list typedef and the va_list
> > type used in function prototypes like vprintf.
> 
> Thanks.
> 
> I do not know the detailed historical reasons for this, but I think the
> patch makes sense and should be committed. Others have reported this
> before, e.g., https://marc.info/?l=openbsd-tech&m=171861388512726&w=2
> 
> I believe we've had some issues with precompiled headers in openbsd
> ports that were related.
> 
> I've tested this in an amd64 bulk, not sure how much more testing would
> be needed.
> 
> Patch reinlined at the end for convenience.

I still think it would be a good idea to commit this. Any concerns or
objections?

> 
> > 
> > To fix this, adjust all definitions of __va_list to match va_list
> > defined in stdarg.h.
> > ---
> > Consider the following example program:
> > 
> > 	#include <stdarg.h>
> > 	#include <stdio.h>
> > 
> > 	void
> > 	f(const char *fmt, ...)
> > 	{
> > 	        va_list ap;
> > 
> > 	        va_start(ap, fmt);
> > 	        vprintf(fmt, ap);
> > 	        va_end(ap);
> > 	}
> > 
> > If compiled with -U __GNUC__, we currently end up with
> > 
> > 	typedef __builtin_va_list __gnuc_va_list;
> > 	typedef __gnuc_va_list va_list;
> > 	typedef char * __va_list;
> > 	int vprintf(const char * __restrict, __va_list);
> > 
> > which results in a warning when we try to call vprintf due to the
> > the conflicting va_list definition.
> > 
> > 	t.c:10:15: warning: incompatible pointer types passing 'va_list' (aka '__builtin_va_list') to parameter of type '__va_list' (aka 'char *') [-Wincompatible-pointer-types]
> > 	   10 |         vprintf(fmt, ap);
> > 	      |                      ^~
> > 	/usr/include/stdio.h:188:48: note: passing argument to parameter here
> > 	  188 | int      vprintf(const char * __restrict, __va_list);
> > 	      |                                                    ^
> > 	1 warning generated.
> > 

 sys/arch/alpha/include/_types.h     | 8 --------
 sys/arch/amd64/include/_types.h     | 4 ----
 sys/arch/arm/include/_types.h       | 4 ----
 sys/arch/arm64/include/_types.h     | 4 ----
 sys/arch/hppa/include/_types.h      | 4 ----
 sys/arch/i386/include/_types.h      | 4 ----
 sys/arch/m88k/include/_types.h      | 5 -----
 sys/arch/mips64/include/_types.h    | 4 ----
 sys/arch/powerpc/include/_types.h   | 5 -----
 sys/arch/powerpc64/include/_types.h | 4 ----
 sys/arch/riscv64/include/_types.h   | 4 ----
 sys/arch/sh/include/_types.h        | 5 -----
 sys/arch/sparc64/include/_types.h   | 4 ----
 13 files changed, 59 deletions(-)

diff --git a/sys/arch/alpha/include/_types.h b/sys/arch/alpha/include/_types.h
index a2ff372b4dc..9d457ec77c4 100644
--- a/sys/arch/alpha/include/_types.h
+++ b/sys/arch/alpha/include/_types.h
@@ -122,15 +122,7 @@ typedef float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef struct {
-	char *__base;
-	int __offset;
-	int __pad;
-} __va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/amd64/include/_types.h b/sys/arch/amd64/include/_types.h
index 9856177da81..9b2e8d3a430 100644
--- a/sys/arch/amd64/include/_types.h
+++ b/sys/arch/amd64/include/_types.h
@@ -122,11 +122,7 @@ typedef	float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/arm/include/_types.h b/sys/arch/arm/include/_types.h
index 71043162186..57dd3524285 100644
--- a/sys/arch/arm/include/_types.h
+++ b/sys/arch/arm/include/_types.h
@@ -122,11 +122,7 @@ typedef float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/arm64/include/_types.h b/sys/arch/arm64/include/_types.h
index 9661d1e2b20..8f8ab433ab3 100644
--- a/sys/arch/arm64/include/_types.h
+++ b/sys/arch/arm64/include/_types.h
@@ -123,11 +123,7 @@ typedef	float			__float_t;
 typedef	long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/hppa/include/_types.h b/sys/arch/hppa/include/_types.h
index 1a7a8799fdb..7c456a44cfb 100644
--- a/sys/arch/hppa/include/_types.h
+++ b/sys/arch/hppa/include/_types.h
@@ -126,11 +126,7 @@ typedef float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	double			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/i386/include/_types.h b/sys/arch/i386/include/_types.h
index d879b02fee2..c1cae2f0e29 100644
--- a/sys/arch/i386/include/_types.h
+++ b/sys/arch/i386/include/_types.h
@@ -122,11 +122,7 @@ typedef long double		__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/m88k/include/_types.h b/sys/arch/m88k/include/_types.h
index a8a53df0bf4..a637fe0b280 100644
--- a/sys/arch/m88k/include/_types.h
+++ b/sys/arch/m88k/include/_types.h
@@ -126,12 +126,7 @@ typedef long double		__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-struct __va_list_tag;
-typedef	struct __va_list_tag *	__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/mips64/include/_types.h b/sys/arch/mips64/include/_types.h
index 87e43ebeefe..50930c1e2da 100644
--- a/sys/arch/mips64/include/_types.h
+++ b/sys/arch/mips64/include/_types.h
@@ -127,11 +127,7 @@ typedef float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/powerpc/include/_types.h b/sys/arch/powerpc/include/_types.h
index 001c5c7d37e..62d4618299d 100644
--- a/sys/arch/powerpc/include/_types.h
+++ b/sys/arch/powerpc/include/_types.h
@@ -122,12 +122,7 @@ typedef float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-struct __va_list_tag;
-typedef	struct __va_list_tag *	__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/powerpc64/include/_types.h b/sys/arch/powerpc64/include/_types.h
index 7306803d303..8b15ef4591d 100644
--- a/sys/arch/powerpc64/include/_types.h
+++ b/sys/arch/powerpc64/include/_types.h
@@ -123,11 +123,7 @@ typedef	float			__float_t;
 typedef	long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/riscv64/include/_types.h b/sys/arch/riscv64/include/_types.h
index 6a106c61ffc..408f8760413 100644
--- a/sys/arch/riscv64/include/_types.h
+++ b/sys/arch/riscv64/include/_types.h
@@ -124,11 +124,7 @@ typedef	float			__float_t;
 typedef	long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/sh/include/_types.h b/sys/arch/sh/include/_types.h
index 9308f2f3a46..b8f247ff254 100644
--- a/sys/arch/sh/include/_types.h
+++ b/sys/arch/sh/include/_types.h
@@ -122,12 +122,7 @@ typedef float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-struct __va_list_tag;
-typedef	struct __va_list_tag *	__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
diff --git a/sys/arch/sparc64/include/_types.h b/sys/arch/sparc64/include/_types.h
index fbf0e66d46c..23aff34397c 100644
--- a/sys/arch/sparc64/include/_types.h
+++ b/sys/arch/sparc64/include/_types.h
@@ -122,11 +122,7 @@ typedef	float			__float_t;
 typedef long			__ptrdiff_t;
 typedef	unsigned long		__size_t;
 typedef	long			__ssize_t;
-#if defined(__GNUC__) && __GNUC__ >= 3
 typedef	__builtin_va_list	__va_list;
-#else
-typedef	char *			__va_list;
-#endif
 
 /* Wide character support types */
 #ifndef __cplusplus
-- 
2.54.0