[15/25] Don’t rely on stddef.h or stdarg.h for individual type definitions.
diff mbox series

Message ID 20190626175029.4699-6-zackw@panix.com
State New
Headers show
Series
  • Public header file hygiene improvements for 2.30
Related show

Commit Message

Zack Weinberg June 26, 2019, 5:50 p.m. UTC
In the course of developing earlier patches in this series I
discovered that clang’s stddef.h does not implement the __need_*
convention correctly: in C++, under some circumstances __need_NULL
will also cause a definition of nullptr_t, and when the “modules”
feature is enabled, all of the __need macros are ignored and all of
stddef.h is exposed.  (I’m not sure how to actually make either of
these things happen, I discovered the problem by reading the file.)

Worse, clang’s stdarg.h does not implement __need___va_list *at all*;
including its stdarg.h will always expose all of its definitions.

These are bugs in clang but it seems prudent to work around them, and
the simplest way to do so is to have the bits/types/ headers
introduced in the previous patch make definitions themselves, when
possible.  For size_t, ptrdiff_t, and wchar_t, we can use the
predefined macros __SIZE_TYPE__, __PTRDIFF_TYPE__, and __WCHAR_TYPE__,
when available, falling back to the old approach.  For __gnuc_va_list,
we have a whitelist of compilers known to provide __builtin_va_list,
falling back to the old approach.  NULL and va_list are defined
ab initio.

An additional complication is that we must be able to tell stddef.h
and stdarg.h _not_ to define again things we have already defined.  It
appears to me, based on inspection of clang, GCC, and icc stddef.h and
stdarg.h, that we can use the macros _SIZE_T, _PTRDIFF_T, _WCHAR_T,
_VA_LIST, and __GNUC_VA_LIST to accomplish this.

Since we are no longer relying on stdarg.h to define an
implementation-namespace alias for us, I thought it would make sense
also to stop calling it __gnuc_va_list.  The bulk of this patch is
a mechanical substitution of __va_list for __gnuc_va_list throughout
our headers.

Copyright boilerplate is added to stdlib/bits/NULL.h and stdlib/bits/types/*.h
because they now contain enough commentary and code that they could
plausibly be copyrightable.

	* stdlib/bits/NULL.h: Do not use stddef.h to define NULL.
	Define NULL ab initio if not already defined, as `((void *)0)` for C,
	and either `__null` or 0 for C++, depending on compiler support.

	* stdlib/bits/types/__va_list.h: If __builtin_va_list is known to
	be available, use it to define __va_list without including
	stdarg.h.  Otherwise use __need___va_list to request a definition
	of __gnuc_va_list and nothing else from stdarg.h, then use that to
	define __va_list.
	* stdlib/bits/types/va_list.h: Use __va_list, not __gnuc_va_list,
	to define va_list.  Improve commentary.

	* stdlib/bits/types/ptrdiff_t.h: If __PTRDIFF_TYPE__ is defined,
	use it to define ptrdiff_t without including stddef.h.  Otherwise
	use __need_ptrdiff_t to request a definition of ptrdiff_t and
	nothing else from stddef.h.  Use _PTRDIFF_T as guard macro to
	match behavior of common stddef.h implementations.
	* stdlib/bits/types/size_t.h: Similarly for size_t, with
	__SIZE_TYPE__, __need_size_t, and _SIZE_T.
	* stdlib/bits/types/wchar_t.h: Similarly for wchar_t, with
	__WCHAR_TYPE__, __need_wchar_t, and _WCHAR_T.  If __cplusplus
	is defined, do nothing; wchar_t is built-in in C++.

	* conform/data/stdio.h-data, conform/data/wchar.h-data
	* include/err.h, include/stdio.h, include/syslog.h, include/wchar.h
	* libio/bits/stdio.h, libio/bits/stdio2.h, libio/iolibio.h
	* libio/libio.h, libio/stdio.h, libio/vwprintf.c, misc/bits/syslog.h
	* misc/err.c, misc/err.h, misc/syslog.h, stdio-common/printf.h
	* sysdeps/ieee754/ldbl-opt/nldbl-compat.c
	* sysdeps/ieee754/ldbl-opt/nldbl-compat.h
	* wcsmbs/bits/wchar2.h, wcsmbs/wchar.h:
	Replace all uses of __gnuc_va_list with __va_list.

        * scripts/check-obsolete-constructs.py (HEADER_ALLOWED_INCLUDES):
        bits/NULL.h is no longer allowed to include stddef.h.
---
 conform/data/stdio.h-data               |  2 +-
 conform/data/wchar.h-data               | 12 ++---
 include/err.h                           |  6 +--
 include/stdio.h                         | 30 ++++++-------
 include/syslog.h                        |  2 +-
 include/wchar.h                         | 14 +++---
 libio/bits/stdio.h                      |  2 +-
 libio/bits/stdio2.h                     | 28 ++++++------
 libio/iolibio.h                         |  2 +-
 libio/libio.h                           |  4 +-
 libio/stdio.h                           | 33 +++++++-------
 libio/vwprintf.c                        |  2 +-
 misc/bits/syslog.h                      |  4 +-
 misc/err.c                              | 12 ++---
 misc/err.h                              |  8 ++--
 misc/syslog.h                           |  2 +-
 scripts/check-obsolete-constructs.py    |  1 -
 stdio-common/printf.h                   |  2 +-
 stdlib/bits/NULL.h                      | 55 +++++++++++++++++++----
 stdlib/bits/types/__va_list.h           | 48 +++++++++++++++++---
 stdlib/bits/types/ptrdiff_t.h           | 54 ++++++++++++++++++----
 stdlib/bits/types/size_t.h              | 54 ++++++++++++++++++----
 stdlib/bits/types/va_list.h             | 31 ++++++++++---
 stdlib/bits/types/wchar_t.h             | 59 +++++++++++++++++++++----
 sysdeps/ieee754/ldbl-opt/nldbl-compat.c |  8 ++--
 sysdeps/ieee754/ldbl-opt/nldbl-compat.h | 16 +++----
 wcsmbs/bits/wchar2.h                    | 14 +++---
 wcsmbs/wchar.h                          | 24 +++++-----
 28 files changed, 367 insertions(+), 162 deletions(-)
 rewrite stdlib/bits/NULL.h (93%)
 rewrite stdlib/bits/types/ptrdiff_t.h (92%)
 rewrite stdlib/bits/types/size_t.h (93%)
 rewrite stdlib/bits/types/wchar_t.h (93%)

Patch
diff mbox series

diff --git a/conform/data/stdio.h-data b/conform/data/stdio.h-data
index 3ef2460661..60ebea4ee4 100644
--- a/conform/data/stdio.h-data
+++ b/conform/data/stdio.h-data
@@ -41,7 +41,7 @@  type fpos_t
 #if !defined ISO && !defined ISO99 && !defined ISO11 && !defined POSIX
 type va_list
 #else
-#define va_list __gnuc_va_list
+#define va_list __va_list
 #endif
 type size_t
 #if defined XOPEN2K8 || defined POSIX2008
diff --git a/conform/data/wchar.h-data b/conform/data/wchar.h-data
index e414651a33..424c59c819 100644
--- a/conform/data/wchar.h-data
+++ b/conform/data/wchar.h-data
@@ -59,17 +59,17 @@  function wint_t towlower (wint_t)
 function wint_t towupper (wint_t)
 # endif
 function wint_t ungetwc (wint_t, FILE*)
-function int vfwprintf (FILE*, const wchar_t*, __gnuc_va_list)
+function int vfwprintf (FILE*, const wchar_t*, __va_list)
 # ifndef UNIX98
-function int vfwscanf (FILE*, const wchar_t*, __gnuc_va_list)
+function int vfwscanf (FILE*, const wchar_t*, __va_list)
 # endif
-function int vwprintf (const wchar_t*, __gnuc_va_list)
+function int vwprintf (const wchar_t*, __va_list)
 # ifndef UNIX98
-function int vwscanf (const wchar_t*, __gnuc_va_list)
+function int vwscanf (const wchar_t*, __va_list)
 # endif
-function int vswprintf (wchar_t*, size_t, const wchar_t*, __gnuc_va_list)
+function int vswprintf (wchar_t*, size_t, const wchar_t*, __va_list)
 # ifndef UNIX98
-function int vswscanf (const wchar_t*, const wchar_t*, __gnuc_va_list)
+function int vswscanf (const wchar_t*, const wchar_t*, __va_list)
 # endif
 # if defined XOPEN2K8 || defined POSIX2008
 function {wchar_t*} wcpcpy (wchar_t*, const wchar_t*)
diff --git a/include/err.h b/include/err.h
index 7c05cd1dbb..573a0f8ef2 100644
--- a/include/err.h
+++ b/include/err.h
@@ -3,12 +3,10 @@ 
 
 /* Prototypes for internal err.h functions.  */
 void
-__vwarnx_internal (const char *format, __gnuc_va_list ap,
-		   unsigned int mode_flags);
+__vwarnx_internal (const char *format, __va_list ap, unsigned int mode_flags);
 
 void
-__vwarn_internal (const char *format, __gnuc_va_list ap,
-		   unsigned int mode_flags);
+__vwarn_internal (const char *format, __va_list ap, unsigned int mode_flags);
 
 # ifndef _ISOMAC
 
diff --git a/include/stdio.h b/include/stdio.h
index c72d410013..b25ab6293a 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -16,40 +16,39 @@  extern int __snprintf (char *__restrict __s, size_t __maxlen,
 libc_hidden_proto (__snprintf)
 extern int __vfscanf (FILE *__restrict __s,
 		      const char *__restrict __format,
-		      __gnuc_va_list __arg)
+		      __va_list __arg)
      __attribute__ ((__format__ (__scanf__, 2, 0)));
 libc_hidden_proto (__vfscanf)
-extern int __vscanf (const char *__restrict __format,
-		     __gnuc_va_list __arg)
+extern int __vscanf (const char *__restrict __format, __va_list __arg)
      __attribute__ ((__format__ (__scanf__, 1, 0)));
 extern __ssize_t __getline (char **__lineptr, size_t *__n,
                             FILE *__stream) attribute_hidden;
 extern int __vsscanf (const char *__restrict __s,
 		      const char *__restrict __format,
-		      __gnuc_va_list __arg)
+		      __va_list __arg)
      __attribute__ ((__format__ (__scanf__, 2, 0)));
 
 extern int __sprintf_chk (char *, int, size_t, const char *, ...) __THROW;
 extern int __snprintf_chk (char *, size_t, int, size_t, const char *, ...)
      __THROW;
 extern int __vsprintf_chk (char *, int, size_t, const char *,
-			   __gnuc_va_list) __THROW;
+			   __va_list) __THROW;
 extern int __vsnprintf_chk (char *, size_t, int, size_t, const char *,
-			    __gnuc_va_list) __THROW;
+			    __va_list) __THROW;
 extern int __printf_chk (int, const char *, ...);
 extern int __fprintf_chk (FILE *, int, const char *, ...);
-extern int __vprintf_chk (int, const char *, __gnuc_va_list);
-extern int __vfprintf_chk (FILE *, int, const char *, __gnuc_va_list);
+extern int __vprintf_chk (int, const char *, __va_list);
+extern int __vfprintf_chk (FILE *, int, const char *, __va_list);
 extern char *__fgets_unlocked_chk (char *buf, size_t size, int n, FILE *fp);
 extern char *__fgets_chk (char *buf, size_t size, int n, FILE *fp);
 extern int __asprintf_chk (char **, int, const char *, ...) __THROW;
-extern int __vasprintf_chk (char **, int, const char *, __gnuc_va_list) __THROW;
+extern int __vasprintf_chk (char **, int, const char *, __va_list) __THROW;
 extern int __dprintf_chk (int, int, const char *, ...);
-extern int __vdprintf_chk (int, int, const char *, __gnuc_va_list);
+extern int __vdprintf_chk (int, int, const char *, __va_list);
 extern int __obstack_printf_chk (struct obstack *, int, const char *, ...)
      __THROW;
 extern int __obstack_vprintf_chk (struct obstack *, int, const char *,
-				  __gnuc_va_list) __THROW;
+				  __va_list) __THROW;
 
 extern int __isoc99_fscanf (FILE *__restrict __stream,
 			    const char *__restrict __format, ...) __wur;
@@ -58,12 +57,12 @@  extern int __isoc99_sscanf (const char *__restrict __s,
 			    const char *__restrict __format, ...) __THROW;
 extern int __isoc99_vfscanf (FILE *__restrict __s,
 			     const char *__restrict __format,
-			     __gnuc_va_list __arg) __wur;
+			     __va_list __arg) __wur;
 extern int __isoc99_vscanf (const char *__restrict __format,
-			    __gnuc_va_list __arg) __wur;
+			    __va_list __arg) __wur;
 extern int __isoc99_vsscanf (const char *__restrict __s,
 			     const char *__restrict __format,
-			     __gnuc_va_list __arg) __THROW;
+			     __va_list __arg) __THROW;
 libc_hidden_proto (__isoc99_sscanf)
 libc_hidden_proto (__isoc99_vsscanf)
 libc_hidden_proto (__isoc99_vfscanf)
@@ -132,8 +131,7 @@  extern int __fxprintf (FILE *__fp, const char *__fmt, ...)
      __attribute__ ((__format__ (__printf__, 2, 3))) attribute_hidden;
 extern int __fxprintf_nocancel (FILE *__fp, const char *__fmt, ...)
      __attribute__ ((__format__ (__printf__, 2, 3))) attribute_hidden;
-int __vfxprintf (FILE *__fp, const char *__fmt, __gnuc_va_list,
-		 unsigned int)
+int __vfxprintf (FILE *__fp, const char *__fmt, __va_list, unsigned int)
   attribute_hidden;
 
 /* Read the next line from FP into BUFFER, of LENGTH bytes.  LINE will
diff --git a/include/syslog.h b/include/syslog.h
index 5dc6e76b7e..cd8b6b876b 100644
--- a/include/syslog.h
+++ b/include/syslog.h
@@ -6,7 +6,7 @@  libc_hidden_proto (syslog)
 
 /* __vsyslog_internal uses the same mode_flags bits as
    __v*printf_internal; see libio/libioP.h.  */
-extern void __vsyslog_internal (int pri, const char *fmt, __gnuc_va_list ap,
+extern void __vsyslog_internal (int pri, const char *fmt, __va_list ap,
 				unsigned int mode_flags)
      attribute_hidden
      __attribute__ ((__format__ (__printf__, 2, 0)));
diff --git a/include/wchar.h b/include/wchar.h
index 2cb44954fc..823685326e 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -206,7 +206,7 @@  extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
 
 extern int __vfwscanf (__FILE *__restrict __s,
 		       const wchar_t *__restrict __format,
-		       __gnuc_va_list __arg)
+		       __va_list __arg)
      attribute_hidden
      /* __attribute__ ((__format__ (__wscanf__, 2, 0)) */;
 extern int __fwprintf (__FILE *__restrict __s,
@@ -215,12 +215,12 @@  extern int __fwprintf (__FILE *__restrict __s,
      /* __attribute__ ((__format__ (__wprintf__, 2, 3))) */;
 extern int __vfwprintf_chk (FILE *__restrict __s, int __flag,
 			    const wchar_t *__restrict __format,
-			    __gnuc_va_list __arg)
+			    __va_list __arg)
      /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
 extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
 			    int __flag, size_t __s_len,
 			    const wchar_t *__restrict __format,
-			    __gnuc_va_list __arg)
+			    __va_list __arg)
      /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
 
 extern int __isoc99_fwscanf (__FILE *__restrict __stream,
@@ -231,15 +231,15 @@  extern int __isoc99_swscanf (const wchar_t *__restrict __s,
      __THROW;
 extern int __isoc99_vfwscanf (__FILE *__restrict __s,
 			      const wchar_t *__restrict __format,
-			      __gnuc_va_list __arg);
+			      __va_list __arg);
 extern int __isoc99_vwscanf (const wchar_t *__restrict __format,
-			     __gnuc_va_list __arg);
+			     __va_list __arg);
 extern int __isoc99_vswscanf (const wchar_t *__restrict __s,
 			      const wchar_t *__restrict __format,
-			      __gnuc_va_list __arg) __THROW;
+			      __va_list __arg) __THROW;
 extern int __vswscanf (const wchar_t *__restrict __s,
 		       const wchar_t *__restrict __format,
-		       __gnuc_va_list __arg) __THROW;
+		       __va_list __arg) __THROW;
 libc_hidden_proto (__isoc99_vswscanf)
 libc_hidden_proto (__vswscanf)
 libc_hidden_proto (__isoc99_vfwscanf)
diff --git a/libio/bits/stdio.h b/libio/bits/stdio.h
index 2efa0c5c6b..cdefaf9804 100644
--- a/libio/bits/stdio.h
+++ b/libio/bits/stdio.h
@@ -36,7 +36,7 @@ 
 # if !(__USE_FORTIFY_LEVEL > 0 && defined __fortify_function)
 /* Write formatted output to stdout from argument list ARG.  */
 __STDIO_INLINE int
-vprintf (const char *__restrict __fmt, __gnuc_va_list __arg)
+vprintf (const char *__restrict __fmt, __va_list __arg)
 {
   return vfprintf (stdout, __fmt, __arg);
 }
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index d1456f9927..6068f67f5c 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -27,7 +27,7 @@  extern int __sprintf_chk (char *__restrict __s, int __flag, size_t __slen,
 			  const char *__restrict __format, ...) __THROW;
 extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
 			   const char *__restrict __format,
-			   __gnuc_va_list __ap) __THROW;
+			   __va_list __ap) __THROW;
 
 #ifdef __va_arg_pack
 __fortify_function int
@@ -44,7 +44,7 @@  __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...))
 
 __fortify_function int
 __NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt,
-		 __gnuc_va_list __ap))
+		 __va_list __ap))
 {
   return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
 				   __bos (__s), __fmt, __ap);
@@ -57,7 +57,7 @@  extern int __snprintf_chk (char *__restrict __s, size_t __n, int __flag,
 			   ...) __THROW;
 extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
 			    size_t __slen, const char *__restrict __format,
-			    __gnuc_va_list __ap) __THROW;
+			    __va_list __ap) __THROW;
 
 # ifdef __va_arg_pack
 __fortify_function int
@@ -75,7 +75,7 @@  __NTH (snprintf (char *__restrict __s, size_t __n,
 
 __fortify_function int
 __NTH (vsnprintf (char *__restrict __s, size_t __n,
-		  const char *__restrict __fmt, __gnuc_va_list __ap))
+		  const char *__restrict __fmt, __va_list __ap))
 {
   return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
 				    __bos (__s), __fmt, __ap);
@@ -89,9 +89,9 @@  extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
 			  const char *__restrict __format, ...);
 extern int __printf_chk (int __flag, const char *__restrict __format, ...);
 extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
-			   const char *__restrict __format, __gnuc_va_list __ap);
+			   const char *__restrict __format, __va_list __ap);
 extern int __vprintf_chk (int __flag, const char *__restrict __format,
-			  __gnuc_va_list __ap);
+			  __va_list __ap);
 
 # ifdef __va_arg_pack
 __fortify_function int
@@ -114,7 +114,7 @@  printf (const char *__restrict __fmt, ...)
 # endif
 
 __fortify_function int
-vprintf (const char *__restrict __fmt, __gnuc_va_list __ap)
+vprintf (const char *__restrict __fmt, __va_list __ap)
 {
 #ifdef __USE_EXTERN_INLINES
   return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
@@ -125,7 +125,7 @@  vprintf (const char *__restrict __fmt, __gnuc_va_list __ap)
 
 __fortify_function int
 vfprintf (FILE *__restrict __stream,
-	  const char *__restrict __fmt, __gnuc_va_list __ap)
+	  const char *__restrict __fmt, __va_list __ap)
 {
   return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
 }
@@ -134,7 +134,7 @@  vfprintf (FILE *__restrict __stream,
 extern int __dprintf_chk (int __fd, int __flag, const char *__restrict __fmt,
 			  ...) __attribute__ ((__format__ (__printf__, 3, 4)));
 extern int __vdprintf_chk (int __fd, int __flag,
-			   const char *__restrict __fmt, __gnuc_va_list __arg)
+			   const char *__restrict __fmt, __va_list __arg)
      __attribute__ ((__format__ (__printf__, 3, 0)));
 
 #  ifdef __va_arg_pack
@@ -150,7 +150,7 @@  dprintf (int __fd, const char *__restrict __fmt, ...)
 #  endif
 
 __fortify_function int
-vdprintf (int __fd, const char *__restrict __fmt, __gnuc_va_list __ap)
+vdprintf (int __fd, const char *__restrict __fmt, __va_list __ap)
 {
   return __vdprintf_chk (__fd, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
 }
@@ -162,7 +162,7 @@  extern int __asprintf_chk (char **__restrict __ptr, int __flag,
 			   const char *__restrict __fmt, ...)
      __THROW __attribute__ ((__format__ (__printf__, 3, 4))) __wur;
 extern int __vasprintf_chk (char **__restrict __ptr, int __flag,
-			    const char *__restrict __fmt, __gnuc_va_list __arg)
+			    const char *__restrict __fmt, __va_list __arg)
      __THROW __attribute__ ((__format__ (__printf__, 3, 0))) __wur;
 extern int __obstack_printf_chk (struct obstack *__restrict __obstack,
 				 int __flag, const char *__restrict __format,
@@ -171,7 +171,7 @@  extern int __obstack_printf_chk (struct obstack *__restrict __obstack,
 extern int __obstack_vprintf_chk (struct obstack *__restrict __obstack,
 				  int __flag,
 				  const char *__restrict __format,
-				  __gnuc_va_list __args)
+				  __va_list __args)
      __THROW __attribute__ ((__format__ (__printf__, 3, 0)));
 
 #  ifdef __va_arg_pack
@@ -208,14 +208,14 @@  __NTH (obstack_printf (struct obstack *__restrict __obstack,
 
 __fortify_function int
 __NTH (vasprintf (char **__restrict __ptr, const char *__restrict __fmt,
-		  __gnuc_va_list __ap))
+		  __va_list __ap))
 {
   return __vasprintf_chk (__ptr, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
 }
 
 __fortify_function int
 __NTH (obstack_vprintf (struct obstack *__restrict __obstack,
-			const char *__restrict __fmt, __gnuc_va_list __ap))
+			const char *__restrict __fmt, __va_list __ap))
 {
   return __obstack_vprintf_chk (__obstack, __USE_FORTIFY_LEVEL - 1, __fmt,
 				__ap);
diff --git a/libio/iolibio.h b/libio/iolibio.h
index 9561833655..d956c01630 100644
--- a/libio/iolibio.h
+++ b/libio/iolibio.h
@@ -50,7 +50,7 @@  libc_hidden_proto (_IO_setvbuf)
 extern int _IO_sscanf (const char*, const char*, ...) __THROW;
 extern int _IO_sprintf (char *, const char*, ...) __THROW;
 extern int _IO_ungetc (int, FILE*) __THROW;
-extern int _IO_vsscanf (const char *, const char *, __gnuc_va_list) __THROW;
+extern int _IO_vsscanf (const char *, const char *, __va_list) __THROW;
 
 #define _IO_clearerr(FP) ((FP)->_flags &= ~(_IO_ERR_SEEN|_IO_EOF_SEEN))
 #define _IO_fseek(__fp, __offset, __whence) \
diff --git a/libio/libio.h b/libio/libio.h
index 96fa1062f2..3903097448 100644
--- a/libio/libio.h
+++ b/libio/libio.h
@@ -216,7 +216,7 @@  extern int _IO_ftrylockfile (FILE *) __THROW;
   (((_fp)->_flags2 & _IO_FLAGS2_NEED_LOCK) != 0)
 
 extern int _IO_vfscanf (FILE * __restrict, const char * __restrict,
-			__gnuc_va_list, int *__restrict);
+			__va_list, int *__restrict);
 extern __ssize_t _IO_padn (FILE *, int, __ssize_t);
 extern size_t _IO_sgetn (FILE *, void *, size_t);
 
@@ -257,7 +257,7 @@  weak_extern (_IO_stdin_used);
      __result; })
 
 extern int _IO_vfwscanf (FILE * __restrict, const wchar_t * __restrict,
-			 __gnuc_va_list, int *__restrict);
+			 __va_list, int *__restrict);
 extern __ssize_t _IO_wpadn (FILE *, wint_t, __ssize_t);
 extern void _IO_free_wbackup_area (FILE *) __THROW;
 
diff --git a/libio/stdio.h b/libio/stdio.h
index 275091e416..734fa07008 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -317,15 +317,15 @@  extern int sprintf (char *__restrict __s,
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,
-		     __gnuc_va_list __arg);
+		     __va_list __arg);
 /* Write formatted output to stdout from argument list ARG.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg);
+extern int vprintf (const char *__restrict __format, __va_list __arg);
 /* Write formatted output to S from argument list ARG.  */
 extern int vsprintf (char *__restrict __s, const char *__restrict __format,
-		     __gnuc_va_list __arg) __THROWNL;
+		     __va_list __arg) __THROWNL;
 
 #if defined __USE_ISOC99 || defined __USE_UNIX98
 /* Maximum chars of output to write in MAXLEN.  */
@@ -334,7 +334,7 @@  extern int snprintf (char *__restrict __s, size_t __maxlen,
      __THROWNL __attribute__ ((__format__ (__printf__, 3, 4)));
 
 extern int vsnprintf (char *__restrict __s, size_t __maxlen,
-		      const char *__restrict __format, __gnuc_va_list __arg)
+		      const char *__restrict __format, __va_list __arg)
      __THROWNL __attribute__ ((__format__ (__printf__, 3, 0)));
 #endif
 
@@ -342,7 +342,7 @@  extern int vsnprintf (char *__restrict __s, size_t __maxlen,
 /* Write formatted output to a string dynamically allocated with `malloc'.
    Store the address of the string in *PTR.  */
 extern int vasprintf (char **__restrict __ptr, const char *__restrict __f,
-		      __gnuc_va_list __arg)
+		      __va_list __arg)
      __THROWNL __attribute__ ((__format__ (__printf__, 2, 0))) __wur;
 extern int __asprintf (char **__restrict __ptr,
 		       const char *__restrict __fmt, ...)
@@ -354,8 +354,7 @@  extern int asprintf (char **__restrict __ptr,
 
 #ifdef __USE_XOPEN2K8
 /* Write formatted output to a file descriptor.  */
-extern int vdprintf (int __fd, const char *__restrict __fmt,
-		     __gnuc_va_list __arg)
+extern int vdprintf (int __fd, const char *__restrict __fmt, __va_list __arg)
      __attribute__ ((__format__ (__printf__, 2, 0)));
 extern int dprintf (int __fd, const char *__restrict __fmt, ...)
      __attribute__ ((__format__ (__printf__, 2, 3)));
@@ -408,19 +407,19 @@  extern int __isoc99_sscanf (const char *__restrict __s,
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,
-		    __gnuc_va_list __arg)
+		    __va_list __arg)
      __attribute__ ((__format__ (__scanf__, 2, 0))) __wur;
 
 /* Read formatted input from stdin into argument list ARG.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
-extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)
+extern int vscanf (const char *__restrict __format, __va_list __arg)
      __attribute__ ((__format__ (__scanf__, 1, 0))) __wur;
 
 /* Read formatted input from S into argument list ARG.  */
 extern int vsscanf (const char *__restrict __s,
-		    const char *__restrict __format, __gnuc_va_list __arg)
+		    const char *__restrict __format, __va_list __arg)
      __THROW __attribute__ ((__format__ (__scanf__, 2, 0)));
 
 /* Same redirection as above for the v*scanf family.  */
@@ -428,26 +427,26 @@  extern int vsscanf (const char *__restrict __s,
 #  if defined __REDIRECT && !defined __LDBL_COMPAT
 extern int __REDIRECT (vfscanf,
 		       (FILE *__restrict __s,
-			const char *__restrict __format, __gnuc_va_list __arg),
+			const char *__restrict __format, __va_list __arg),
 		       __isoc99_vfscanf)
      __attribute__ ((__format__ (__scanf__, 2, 0))) __wur;
 extern int __REDIRECT (vscanf, (const char *__restrict __format,
-				__gnuc_va_list __arg), __isoc99_vscanf)
+				__va_list __arg), __isoc99_vscanf)
      __attribute__ ((__format__ (__scanf__, 1, 0))) __wur;
 extern int __REDIRECT_NTH (vsscanf,
 			   (const char *__restrict __s,
 			    const char *__restrict __format,
-			    __gnuc_va_list __arg), __isoc99_vsscanf)
+			    __va_list __arg), __isoc99_vsscanf)
      __attribute__ ((__format__ (__scanf__, 2, 0)));
 #  elif !defined __REDIRECT
 extern int __isoc99_vfscanf (FILE *__restrict __s,
 			     const char *__restrict __format,
-			     __gnuc_va_list __arg) __wur;
+			     __va_list __arg) __wur;
 extern int __isoc99_vscanf (const char *__restrict __format,
-			    __gnuc_va_list __arg) __wur;
+			    __va_list __arg) __wur;
 extern int __isoc99_vsscanf (const char *__restrict __s,
 			     const char *__restrict __format,
-			     __gnuc_va_list __arg) __THROW;
+			     __va_list __arg) __THROW;
 #   define vfscanf __isoc99_vfscanf
 #   define vscanf __isoc99_vscanf
 #   define vsscanf __isoc99_vsscanf
@@ -806,7 +805,7 @@  extern int obstack_printf (struct obstack *__restrict __obstack,
      __THROWNL __attribute__ ((__format__ (__printf__, 2, 3)));
 extern int obstack_vprintf (struct obstack *__restrict __obstack,
 			    const char *__restrict __format,
-			    __gnuc_va_list __args)
+			    __va_list __args)
      __THROWNL __attribute__ ((__format__ (__printf__, 2, 0)));
 #endif /* Use GNU.  */
 
diff --git a/libio/vwprintf.c b/libio/vwprintf.c
index 96c597de02..35e5ca6a23 100644
--- a/libio/vwprintf.c
+++ b/libio/vwprintf.c
@@ -23,7 +23,7 @@ 
 /* Write formatted output to stdout according to the
    format string FORMAT, using the argument list in ARG.  */
 int
-__vwprintf (const wchar_t *format, __gnuc_va_list arg)
+__vwprintf (const wchar_t *format, __va_list arg)
 {
   return __vfwprintf_internal (stdout, format, arg, 0);
 }
diff --git a/misc/bits/syslog.h b/misc/bits/syslog.h
index e796955c1c..67e50cd4d0 100644
--- a/misc/bits/syslog.h
+++ b/misc/bits/syslog.h
@@ -41,11 +41,11 @@  syslog (int __pri, const char *__fmt, ...)
 
 #ifdef __USE_MISC
 extern void __vsyslog_chk (int __pri, int __flag, const char *__fmt,
-			   __gnuc_va_list __ap)
+			   __va_list __ap)
      __attribute__ ((__format__ (__printf__, 3, 0)));
 
 __fortify_function void
-vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
+vsyslog (int __pri, const char *__fmt, __va_list __ap)
 {
   __vsyslog_chk (__pri,  __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
 }
diff --git a/misc/err.c b/misc/err.c
index 988ec8f3ee..b9eabb7285 100644
--- a/misc/err.c
+++ b/misc/err.c
@@ -38,7 +38,7 @@  extern char *__progname;
 }
 
 void
-__vwarnx_internal (const char *format, __gnuc_va_list ap,
+__vwarnx_internal (const char *format, __va_list ap,
 		   unsigned int mode_flags)
 {
   flockfile (stderr);
@@ -50,7 +50,7 @@  __vwarnx_internal (const char *format, __gnuc_va_list ap,
 }
 
 void
-__vwarn_internal (const char *format, __gnuc_va_list ap,
+__vwarn_internal (const char *format, __va_list ap,
 		   unsigned int mode_flags)
 {
   int error = errno;
@@ -72,14 +72,14 @@  __vwarn_internal (const char *format, __gnuc_va_list ap,
 }
 
 void
-vwarn (const char *format, __gnuc_va_list ap)
+vwarn (const char *format, __va_list ap)
 {
   __vwarn_internal (format, ap, 0);
 }
 libc_hidden_def (vwarn)
 
 void
-vwarnx (const char *format, __gnuc_va_list ap)
+vwarnx (const char *format, __va_list ap)
 {
   __vwarnx_internal (format, ap, 0);
 }
@@ -100,7 +100,7 @@  warnx (const char *format, ...)
 libc_hidden_def (warnx)
 
 void
-verr (int status, const char *format, __gnuc_va_list ap)
+verr (int status, const char *format, __va_list ap)
 {
   vwarn (format, ap);
   exit (status);
@@ -108,7 +108,7 @@  verr (int status, const char *format, __gnuc_va_list ap)
 libc_hidden_def (verr)
 
 void
-verrx (int status, const char *format, __gnuc_va_list ap)
+verrx (int status, const char *format, __va_list ap)
 {
   vwarnx (format, ap);
   exit (status);
diff --git a/misc/err.h b/misc/err.h
index 2d12cbe68c..153bc112d9 100644
--- a/misc/err.h
+++ b/misc/err.h
@@ -29,23 +29,23 @@  __BEGIN_DECLS
    and a newline, on stderr.  */
 extern void warn (const char *__format, ...)
      __attribute__ ((__format__ (__printf__, 1, 2)));
-extern void vwarn (const char *__format, __gnuc_va_list)
+extern void vwarn (const char *__format, __va_list)
      __attribute__ ((__format__ (__printf__, 1, 0)));
 
 /* Likewise, but without ": " and the standard error string.  */
 extern void warnx (const char *__format, ...)
      __attribute__ ((__format__ (__printf__, 1, 2)));
-extern void vwarnx (const char *__format, __gnuc_va_list)
+extern void vwarnx (const char *__format, __va_list)
      __attribute__ ((__format__ (__printf__, 1, 0)));
 
 /* Likewise, and then exit with STATUS.  */
 extern void err (int __status, const char *__format, ...)
      __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
-extern void verr (int __status, const char *__format, __gnuc_va_list)
+extern void verr (int __status, const char *__format, __va_list)
      __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0)));
 extern void errx (int __status, const char *__format, ...)
      __attribute__ ((__noreturn__, __format__ (__printf__, 2, 3)));
-extern void verrx (int __status, const char *, __gnuc_va_list)
+extern void verrx (int __status, const char *, __va_list)
      __attribute__ ((__noreturn__, __format__ (__printf__, 2, 0)));
 
 #ifdef __LDBL_COMPAT
diff --git a/misc/syslog.h b/misc/syslog.h
index f7b7a6743f..f7a980bd74 100644
--- a/misc/syslog.h
+++ b/misc/syslog.h
@@ -196,7 +196,7 @@  extern void syslog (int __pri, const char *__fmt, ...)
    cancellation point.  But due to similarity with an POSIX interface
    or due to the implementation it is a cancellation point and
    therefore not marked with __THROW.  */
-extern void vsyslog (int __pri, const char *__fmt, __gnuc_va_list __ap)
+extern void vsyslog (int __pri, const char *__fmt, __va_list __ap)
      __attribute__ ((__format__ (__printf__, 2, 0)));
 #endif
 
diff --git a/scripts/check-obsolete-constructs.py b/scripts/check-obsolete-constructs.py
index 5cd3867be1..e95e587d3e 100755
--- a/scripts/check-obsolete-constructs.py
+++ b/scripts/check-obsolete-constructs.py
@@ -692,7 +692,6 @@  HEADER_ALLOWED_INCLUDES = {
     "bits/types/ptrdiff_t.h":      [ "stddef.h" ],
     "bits/types/size_t.h":         [ "stddef.h" ],
     "bits/types/wchar_t.h":        [ "stddef.h" ],
-    "bits/NULL.h":                 [ "stddef.h" ],
 }
 
 # As above, but each group of whitelist entries is only used for
diff --git a/stdio-common/printf.h b/stdio-common/printf.h
index 69c9691720..5e0d30dee9 100644
--- a/stdio-common/printf.h
+++ b/stdio-common/printf.h
@@ -86,7 +86,7 @@  typedef int printf_arginfo_function (const struct printf_info *__info,
 
 /* Type of a function to get a value of a user-defined from the
    variable argument list.  */
-typedef void printf_va_arg_function (void *__mem, __gnuc_va_list *__ap);
+typedef void printf_va_arg_function (void *__mem, __va_list *__ap);
 
 
 /* Register FUNC to be called to format SPEC specifiers; ARGINFO must be
diff --git a/stdlib/bits/NULL.h b/stdlib/bits/NULL.h
dissimilarity index 93%
index 79285bd7b2..96b75565a1 100644
--- a/stdlib/bits/NULL.h
+++ b/stdlib/bits/NULL.h
@@ -?,? +1,47 @@
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* There is no consensus among compilers as to the proper guard macro
+   for having defined NULL specifically ... except NULL itself.  */
+#ifndef NULL
+
+/* In C, ((void *)0) is the preferred choice for the expansion of
+   NULL, as it cannot be misinterpreted as an integer zero.  */
+#ifndef __cplusplus
+# define NULL ((void *)0)
+
+/* ((void *)0) cannot be used in C++.  In C++2011 and later, nullptr
+   is the preferred alternative, but programs are to be encouraged to
+   migrate away from both bare 0 and NULL to nullptr, so we do not
+   define NULL as nullptr.  Some compilers support an extension
+   keyword __null that will trigger diagnostics when used in a context
+   that expects an integer, but will also be treated as 0 for purposes
+   of diagnostics encouraging migration to nullptr.
+
+   The complexity of this #if is because clang++ always pretends to be
+   G++ and may also pretend to be one of several different Windows
+   compilers.  */
+#elif (defined __GNUG__ || defined __clang__) \
+  && !defined _MSC_VER && !defined __MINGW32__
+# define NULL __null
+
+/* Otherwise a bare 0 will have to do.  */
+#else
+# define NULL 0
+#endif
+
+#endif
diff --git a/stdlib/bits/types/__va_list.h b/stdlib/bits/types/__va_list.h
index e3c53c3e05..ac5ab40fd3 100644
--- a/stdlib/bits/types/__va_list.h
+++ b/stdlib/bits/types/__va_list.h
@@ -1,9 +1,47 @@ 
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
 #ifndef ____va_list_defined
-#define ____va_list_defined 1
 
-/* We rely on the compiler's stdarg.h to define __gnuc_va_list for us.  */
-#define __need___va_list
-#include <stdarg.h>
-#undef __need___va_list
+/* If __builtin_va_list is available, use it.  There is no predefined
+   macro advertising the availability of this type.  It is known to be
+   available in GCC 3.0 and later.  It is also known to be available
+   in all released versions of clang.  */
+#if defined __clang__ || (defined __GNUC__ && __GNUC__ >= 3)
 
+typedef __builtin_va_list __va_list;
+
+#else
+
+/* Depending on the compiler, we may be able to persuade its stdarg.h
+   to define an implementation-namespace alias for va_list and nothing
+   else.  If this feature is not available, exposing everything
+   defined by stdarg.h is better than not defining __va_list at all.  */
+# define __need___va_list
+# include <stdarg.h>
+# undef __need___va_list
+
+# ifdef __GNUC_VA_LIST
+typedef __gnuc_va_list __va_list;
+# else
+typedef va_list __va_list;
+# endif
+#endif
+
+/* This must not be defined until _after_ possibly including stdarg.h.  */
+#define ____va_list_defined 1
 #endif
diff --git a/stdlib/bits/types/ptrdiff_t.h b/stdlib/bits/types/ptrdiff_t.h
dissimilarity index 92%
index 23a8b986d5..a1cb9d985a 100644
--- a/stdlib/bits/types/ptrdiff_t.h
+++ b/stdlib/bits/types/ptrdiff_t.h
@@ -?,? +1,45 @@
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* The guard macro for this header must match the guard macro used by
+   the compiler's stddef.h for ptrdiff_t specifically.
+   GCC's stddef.h checks a long list of other macros as well as this
+   one, in order to accommodate many different C libraries, but clang's
+   stddef.h only looks for this macro.  Other compilers can reasonably
+   be expected to look for this macro as well.  */
+#ifndef _PTRDIFF_T
+
+#ifdef __PTRDIFF_TYPE__
+
+/* If the predefined macro __PTRDIFF_TYPE__ is available, use it.  */
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
+#else
+
+/* Depending on the compiler, we may be able to persuade its stddef.h
+   to define ptrdiff_t and nothing else.  If this feature is not
+   available, exposing everything defined by stddef.h is better than
+   not defining ptrdiff_t at all.  */
+# define __need_ptrdiff_t
+# include <stddef.h>
+# undef __need_ptrdiff_t
+
+#endif
+
+/* This must not be defined until _after_ possibly including stddef.h.  */
+#define _PTRDIFF_T
+#endif
diff --git a/stdlib/bits/types/size_t.h b/stdlib/bits/types/size_t.h
dissimilarity index 93%
index e151458eb3..827ede397c 100644
--- a/stdlib/bits/types/size_t.h
+++ b/stdlib/bits/types/size_t.h
@@ -?,? +1,45 @@
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* The guard macro for this header must match the guard macro used by
+   the compiler's stddef.h for size_t specifically.
+   GCC's stddef.h checks a long list of other macros as well as this
+   one, in order to accommodate many different C libraries, but clang's
+   stddef.h only looks for this macro.  Other compilers can reasonably
+   be expected to look for this macro as well.  */
+#ifndef _SIZE_T
+
+#ifdef __SIZE_TYPE__
+
+/* If the predefined macro __SIZE_TYPE__ is available, use it.  */
+typedef __SIZE_TYPE__ size_t;
+
+#else
+
+/* Depending on the compiler, we may be able to persuade its stddef.h
+   to define size_t and nothing else.  If this feature is not
+   available, exposing everything defined by stddef.h is better than
+   not defining size_t at all.  */
+# define __need_size_t
+# include <stddef.h>
+# undef __need_size_t
+
+#endif
+
+/* This must not be defined until _after_ possibly including stddef.h.  */
+#define _SIZE_T
+#endif
diff --git a/stdlib/bits/types/va_list.h b/stdlib/bits/types/va_list.h
index 6f3acac379..6e1db79280 100644
--- a/stdlib/bits/types/va_list.h
+++ b/stdlib/bits/types/va_list.h
@@ -1,6 +1,26 @@ 
-/* This guard macro needs to match the one used by at least gcc and
-   clang's stdarg.h to indicate that va_list, specifically, has been
-   defined.  */
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* The guard macro for this header must match the guard macro used by
+   the compiler's stdarg.h for va_list specifically.
+   GCC's stdarg.h checks several other macros as well as this one, in
+   order to accommodate many different C libraries, but clang's
+   stdarg.h only looks for this macro.  Other compilers can reasonably
+   be expected to look for this macro as well.  */
 #ifndef _VA_LIST
 
 #include <bits/types/__va_list.h>
@@ -8,8 +28,9 @@ 
 /* Check again, __va_list.h may not have been able to avoid including
    all of stdarg.h.  */
 # ifndef _VA_LIST
-typedef __gnuc_va_list va_list;
+typedef __va_list va_list;
 # endif
-# define _VA_LIST
 
+/* This must not be defined until _after_ possibly including stdarg.h.  */
+# define _VA_LIST
 #endif
diff --git a/stdlib/bits/types/wchar_t.h b/stdlib/bits/types/wchar_t.h
dissimilarity index 93%
index 1e44e157cc..ba0f94f803 100644
--- a/stdlib/bits/types/wchar_t.h
+++ b/stdlib/bits/types/wchar_t.h
@@ -?,? +1,50 @@
+/* Copyright (C) 2019 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* The guard macro for this header must match the guard macro used by
+   the compiler's stddef.h for wchar_t specifically.
+   GCC's stddef.h checks a long list of other macros as well as this
+   one, in order to accommodate many different C libraries, but clang's
+   stddef.h only looks for this macro.  Other compilers can reasonably
+   be expected to look for this macro as well.  */
+#ifndef _WCHAR_T
+
+#ifdef __cplusplus
+/* Do nothing; wchar_t is a built-in type and reserved word in C++.  */
+#else
+
+# ifdef __WCHAR_TYPE__
+
+/* If the predefined macro __WCHAR_TYPE__ is available, use it.  */
+typedef __WCHAR_TYPE__ wchar_t;
+
+# else
+
+/* Depending on the compiler, we may be able to persuade its stddef.h
+   to define wchar_t and nothing else.  If this feature is not
+   available, exposing everything defined by stddef.h is better than
+   not defining wchar_t at all.  */
+#  define __need_wchar_t
+#  include <stddef.h>
+#  undef __need_wchar_t
+
+# endif /* not __WCHAR_TYPE__ */
+#endif /* not __cplusplus */
+
+/* This must not be defined until _after_ possibly including stddef.h.  */
+#define _WCHAR_T
+#endif
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
index 86ac418007..cbe533a685 100644
--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.c
@@ -1036,14 +1036,14 @@  __nldbl_errx (int status, const char *format, ...)
 }
 
 void
-__nldbl_verr (int status, const char *format, __gnuc_va_list ap)
+__nldbl_verr (int status, const char *format, __va_list ap)
 {
   __vwarn_internal (format, ap, PRINTF_LDBL_IS_DBL);
   exit (status);
 }
 
 void
-__nldbl_verrx (int status, const char *format, __gnuc_va_list ap)
+__nldbl_verrx (int status, const char *format, __va_list ap)
 {
   __vwarnx_internal (format, ap, PRINTF_LDBL_IS_DBL);
   exit (status);
@@ -1062,13 +1062,13 @@  __nldbl_warnx (const char *format, ...)
 }
 
 void
-__nldbl_vwarn (const char *format, __gnuc_va_list ap)
+__nldbl_vwarn (const char *format, __va_list ap)
 {
   __vwarn_internal (format, ap, PRINTF_LDBL_IS_DBL);
 }
 
 void
-__nldbl_vwarnx (const char *format, __gnuc_va_list ap)
+__nldbl_vwarnx (const char *format, __va_list ap)
 {
   __vwarnx_internal (format, ap, PRINTF_LDBL_IS_DBL);
 }
diff --git a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
index aed1cc1497..3413c4287a 100644
--- a/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
+++ b/sysdeps/ieee754/ldbl-opt/nldbl-compat.h
@@ -103,23 +103,23 @@  extern ssize_t __nldbl___vstrfmon_l (char *, size_t, locale_t, const char *,
 /* These don't use __typeof because they were not declared by the headers,
    since we don't compile with _FORTIFY_SOURCE.  */
 extern int __nldbl___vfprintf_chk (FILE *__restrict, int,
-				   const char *__restrict, __gnuc_va_list);
+				   const char *__restrict, __va_list);
 extern int __nldbl___vfwprintf_chk (FILE *__restrict, int,
-				    const wchar_t *__restrict, __gnuc_va_list);
+				    const wchar_t *__restrict, __va_list);
 extern int __nldbl___vsprintf_chk (char *__restrict, int, size_t,
-				   const char *__restrict, __gnuc_va_list)
+				   const char *__restrict, __va_list)
   __THROW;
 extern int __nldbl___vsnprintf_chk (char *__restrict, size_t, int, size_t,
-				    const char *__restrict, __gnuc_va_list)
+				    const char *__restrict, __va_list)
   __THROW;
 extern int __nldbl___vswprintf_chk (wchar_t *__restrict, size_t, int, size_t,
-				    const wchar_t *__restrict, __gnuc_va_list)
+				    const wchar_t *__restrict, __va_list)
   __THROW;
-extern int __nldbl___vasprintf_chk (char **, int, const char *, __gnuc_va_list)
+extern int __nldbl___vasprintf_chk (char **, int, const char *, __va_list)
   __THROW;
-extern int __nldbl___vdprintf_chk (int, int, const char *, __gnuc_va_list);
+extern int __nldbl___vdprintf_chk (int, int, const char *, __va_list);
 extern int __nldbl___obstack_vprintf_chk (struct obstack *, int, const char *,
-					  __gnuc_va_list) __THROW;
+					  __va_list) __THROW;
 extern void __nldbl___vsyslog_chk (int, int, const char *, va_list);
 
 /* The original declarations of these were hidden by the including
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
index 81603d560b..4b6b614481 100644
--- a/wcsmbs/bits/wchar2.h
+++ b/wcsmbs/bits/wchar2.h
@@ -303,17 +303,17 @@  __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
 extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
 			    int __flag, size_t __s_len,
 			    const wchar_t *__restrict __format,
-			    __gnuc_va_list __arg)
+			    __va_list __arg)
      __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
 
 extern int __REDIRECT_NTH_LDBL (__vswprintf_alias,
 				(wchar_t *__restrict __s, size_t __n,
 				 const wchar_t *__restrict __fmt,
-				 __gnuc_va_list __ap), vswprintf);
+				 __va_list __ap), vswprintf);
 
 __fortify_function int
 __NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
-		  const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
+		  const wchar_t *__restrict __fmt, __va_list __ap))
 {
   if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
     return __vswprintf_chk (__s, __n,  __USE_FORTIFY_LEVEL - 1,
@@ -330,9 +330,9 @@  extern int __wprintf_chk (int __flag, const wchar_t *__restrict __format,
 			  ...);
 extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag,
 			    const wchar_t *__restrict __format,
-			    __gnuc_va_list __ap);
+			    __va_list __ap);
 extern int __vwprintf_chk (int __flag, const wchar_t *__restrict __format,
-			   __gnuc_va_list __ap);
+			   __va_list __ap);
 
 # ifdef __va_arg_pack
 __fortify_function int
@@ -355,14 +355,14 @@  fwprintf (__FILE *__restrict __stream, const wchar_t *__restrict __fmt, ...)
 # endif
 
 __fortify_function int
-vwprintf (const wchar_t *__restrict __fmt, __gnuc_va_list __ap)
+vwprintf (const wchar_t *__restrict __fmt, __va_list __ap)
 {
   return __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap);
 }
 
 __fortify_function int
 vfwprintf (__FILE *__restrict __stream,
-	   const wchar_t *__restrict __fmt, __gnuc_va_list __ap)
+	   const wchar_t *__restrict __fmt, __va_list __ap)
 {
   return __vfwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
 }
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index ceb72b340c..75d0dde675 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -593,20 +593,20 @@  extern int swprintf (wchar_t *__restrict __s, size_t __n,
    marked with __THROW.  */
 extern int vfwprintf (__FILE *__restrict __s,
 		      const wchar_t *__restrict __format,
-		      __gnuc_va_list __arg)
+		      __va_list __arg)
      /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */;
 /* Write formatted output to stdout from argument list ARG.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern int vwprintf (const wchar_t *__restrict __format,
-		     __gnuc_va_list __arg)
+		     __va_list __arg)
      /* __attribute__ ((__format__ (__wprintf__, 1, 0))) */;
 /* Write formatted output of at most N character to S from argument
    list ARG.  */
 extern int vswprintf (wchar_t *__restrict __s, size_t __n,
 		      const wchar_t *__restrict __format,
-		      __gnuc_va_list __arg)
+		      __va_list __arg)
      __THROW /* __attribute__ ((__format__ (__wprintf__, 3, 0))) */;
 
 
@@ -666,19 +666,19 @@  extern int __isoc99_swscanf (const wchar_t *__restrict __s,
    marked with __THROW.  */
 extern int vfwscanf (__FILE *__restrict __s,
 		     const wchar_t *__restrict __format,
-		     __gnuc_va_list __arg)
+		     __va_list __arg)
      /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */;
 /* Read formatted input from stdin into argument list ARG.
 
    This function is a possible cancellation point and therefore not
    marked with __THROW.  */
 extern int vwscanf (const wchar_t *__restrict __format,
-		    __gnuc_va_list __arg)
+		    __va_list __arg)
      /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */;
 /* Read formatted input from S into argument list ARG.  */
 extern int vswscanf (const wchar_t *__restrict __s,
 		     const wchar_t *__restrict __format,
-		     __gnuc_va_list __arg)
+		     __va_list __arg)
      __THROW /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */;
 
 # if !defined __USE_GNU \
@@ -687,24 +687,24 @@  extern int vswscanf (const wchar_t *__restrict __s,
 #  ifdef __REDIRECT
 extern int __REDIRECT (vfwscanf, (__FILE *__restrict __s,
 				  const wchar_t *__restrict __format,
-				  __gnuc_va_list __arg), __isoc99_vfwscanf)
+				  __va_list __arg), __isoc99_vfwscanf)
      /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */;
 extern int __REDIRECT (vwscanf, (const wchar_t *__restrict __format,
-				 __gnuc_va_list __arg), __isoc99_vwscanf)
+				 __va_list __arg), __isoc99_vwscanf)
      /* __attribute__ ((__format__ (__wscanf__, 1, 0))) */;
 extern int __REDIRECT_NTH (vswscanf, (const wchar_t *__restrict __s,
 				      const wchar_t *__restrict __format,
-				      __gnuc_va_list __arg), __isoc99_vswscanf)
+				      __va_list __arg), __isoc99_vswscanf)
      /* __attribute__ ((__format__ (__wscanf__, 2, 0))) */;
 #  else
 extern int __isoc99_vfwscanf (__FILE *__restrict __s,
 			      const wchar_t *__restrict __format,
-			      __gnuc_va_list __arg);
+			      __va_list __arg);
 extern int __isoc99_vwscanf (const wchar_t *__restrict __format,
-			     __gnuc_va_list __arg);
+			     __va_list __arg);
 extern int __isoc99_vswscanf (const wchar_t *__restrict __s,
 			      const wchar_t *__restrict __format,
-			      __gnuc_va_list __arg) __THROW;
+			      __va_list __arg) __THROW;
 #   define vfwscanf __isoc99_vfwscanf
 #   define vwscanf __isoc99_vwscanf
 #   define vswscanf __isoc99_vswscanf