about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog104
-rw-r--r--debug/Makefile24
-rw-r--r--debug/tst-chk1.c42
-rw-r--r--debug/tst-chk4.cc1
-rw-r--r--debug/tst-chk5.cc2
-rw-r--r--debug/tst-chk6.cc2
-rw-r--r--debug/tst-lfschk4.cc2
-rw-r--r--debug/tst-lfschk5.cc2
-rw-r--r--debug/tst-lfschk6.cc2
-rw-r--r--include/features.h3
-rw-r--r--include/stdio.h2
-rw-r--r--include/wchar.h2
-rw-r--r--io/fcntl.h3
-rw-r--r--io/sys/stat.h2
-rw-r--r--libio/bits/stdio-ldbl.h4
-rw-r--r--libio/bits/stdio.h9
-rw-r--r--libio/bits/stdio2.h84
-rw-r--r--libio/stdio.h2
-rw-r--r--math/bits/cmathcalls.h3
-rw-r--r--misc/bits/syslog-ldbl.h2
-rw-r--r--misc/bits/syslog.h19
-rw-r--r--misc/sys/cdefs.h20
-rw-r--r--misc/sys/syslog.h2
-rw-r--r--posix/unistd.h2
-rw-r--r--socket/sys/socket.h5
-rw-r--r--stdlib/stdlib.h2
-rw-r--r--string/bits/string3.h158
-rw-r--r--string/string.h2
-rw-r--r--sysdeps/alpha/fpu/bits/mathinline.h2
-rw-r--r--sysdeps/i386/fpu/bits/mathinline.h2
-rw-r--r--sysdeps/i386/i486/bits/string.h2
-rw-r--r--sysdeps/ia64/fpu/bits/mathinline.h2
-rw-r--r--sysdeps/powerpc/fpu/bits/mathinline.h2
-rw-r--r--sysdeps/s390/bits/string.h2
-rw-r--r--sysdeps/s390/fpu/bits/mathinline.h2
-rw-r--r--sysdeps/sparc/fpu/bits/mathinline.h2
-rw-r--r--sysdeps/unix/sysv/linux/sys/sysmacros.h10
-rw-r--r--sysdeps/x86_64/fpu/bits/mathinline.h2
-rw-r--r--wcsmbs/bits/wchar-ldbl.h2
-rw-r--r--wcsmbs/bits/wchar2.h76
-rw-r--r--wcsmbs/wchar.h4
41 files changed, 499 insertions, 118 deletions
diff --git a/ChangeLog b/ChangeLog
index 85b435ae74..94c7bdf58c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,107 @@
+2007-09-07  Jakub Jelinek  <jakub@redhat.com>
+
+	* misc/sys/cdefs.h (__va_arg_pack): Define for GCC 4.3+.
+	* misc/bits/syslog.h (syslog): When __va_arg_pack is defined,
+	implement as __extern_always_inline function.
+	(vsyslog): Define as __extern_always_inline function unconditionally.
+	* libio/bits/stdio2.h (sprintf, snprintf, printf, fprintf):
+	When __va_arg_pack is defined, implement as __extern_always_inline
+	functions.
+	(vsprintf, vsnprintf, vprintf, vfprintf): Define as
+	__extern_always_inline functions unconditionally.
+	* libio/bits/stdio.h (vprintf): Ifdef out the inline when
+	bits/stdio2.h will be included.
+	* wcsmbs/bits/wchar2.h (__swprintf_alias): New redirect.
+	(swprintf, wprintf, fwprintf): When __va_arg_pack is defined,
+	implement as __extern_always_inline functions.
+	(vswprintf, vwprintf, vfwprintf): Define as
+	__extern_always_inline functions unconditionally.
+	* debug/tst-chk1.c (do_test): Enable remaining tests for C++.
+
+2007-09-03  Jakub Jelinek  <jakub@redhat.com>
+
+	* misc/sys/cdefs.h (__extern_inline, __extern_always_inline): Only
+	define in C++ for GCC 4.3+, in C++ always use __gnu_inline__
+	attribute.
+	* include/features.h (__USE_EXTERN_INLINES): Define only when
+	__extern_inline is defined.
+	* stdlib/stdlib.h: Include bits/stdlib.h when __extern_always_inline
+	is defined instead of when not __cplusplus.
+	* misc/sys/syslog.h: Include bits/syslog.h when __extern_always_inline
+	is defined instead of when not __cplusplus.
+	* socket/sys/socket.h: Include bits/socket2.h when
+	__extern_always_inline is defined instead of when not __cplusplus.
+	* libio/stdio.h: Include bits/stdio2.h when __extern_always_inline
+	is defined instead of when not __cplusplus.
+	* posix/unistd.h: Include bits/unistd.h when __extern_always_inline
+	is defined instead of when not __cplusplus.
+	* string/string.h: Include bits/string3.h when __extern_always_inline
+	is defined instead of when not __cplusplus.
+	* wcsmbs/wchar.h: Include bits/wchar2.h when __extern_always_inline
+	is defined instead of when not __cplusplus.
+	(btowc, wctob): Don't guard the inlines with ifndef __cplusplus.
+	* io/fcntl.h: Don't include bits/fcntl2.h if __extern_always_inline
+	is not defined.
+	* misc/bits/syslog-ldbl.h: Guard *_chk stuff with
+	defined __extern_always_inline instead of !defined __cplusplus.
+	* libio/bits/stdio-ldbl.h: Likewise.
+	* wcsmbs/bits/wchar-ldbl.h: Likewise.
+	* misc/bits/syslog.h (syslog): Don't define for C++.
+	(vsyslog): Use __extern_always_inline function for C++ instead of
+	a macro.
+	* libio/bits/stdio.h (__STDIO_INLINE): Define to __extern_inline
+	whenever that macro is defined.
+	(vprintf): Don't provide the inline for C++.
+	(fread_unlocked, fwrite_unlocked): Don't define the macros for C++.
+	* libio/bits/stdio2.h (sprintf, snprintf, printf, fprintf): Don't
+	define the macros for C++.
+	(vsprintf, vsnprintf, vprintf, vfprintf): Define as
+	__extern_always_inline functions for C++.
+	* io/sys/stat.h (stat, lstat, fstat, fstatat, mknod, mknodat,
+	stat64, lstat64, fstat64, fstatat64): Don't define if not
+	__USE_EXTERN_INLINES.
+	* wcsmbs/bits/wchar2.h: Fix #error message.
+	(swprintf, wprintf, fwprintf): Don't define the macros for C++.
+	(vswprintf, vwprintf, vfwprintf): Define using
+	__extern_always_inline functions for C++.
+	* string/bits/string3.h: Don't #undef macros if __cplusplus.
+	(memcpy, memmove, mempcpy, memset, bcopy, bzero, strcpy, stpcpy,
+	strncpy, strcat, strncat): Define as __extern_always_inline
+	functions instead of macros for C++.
+	* math/bits/cmathcalls.h: Guard __extern_inline routines with
+	defined __extern_inline.
+	* sysdeps/alpha/fpu/bits/mathinline.h (__MATH_INLINE): Define
+	to __extern_inline whenever that macro is defined.
+	* sysdeps/ia64/fpu/bits/mathinline.h (__MATH_INLINE): Likewise.
+	* sysdeps/i386/fpu/bits/mathinline.h (__MATH_INLINE): Likewise.
+	* sysdeps/i386/i486/bits/string.h (__STRING_INLINE): Likewise.
+	* sysdeps/s390/bits/string.h (__STRING_INLINE): Likewise.
+	* sysdeps/s390/fpu/bits/mathinline.h (__MATH_INLINE): Likewise.
+	* sysdeps/powerpc/fpu/bits/mathinline.h (__MATH_INLINE): Likewise.
+	* sysdeps/x86_64/fpu/bits/mathinline.h (__MATH_INLINE): Likewise.
+	* sysdeps/sparc/fpu/bits/mathinline.h (__MATH_INLINE): Likewise.
+	* sysdeps/unix/sysv/linux/sys/sysmacros.h (gnu_dev_major,
+	gnu_dev_minor, gnu_dev_makedev): Remove __extern_inline from
+	prototypes.  Only provide __extern_inline routines if
+	__USE_EXTERN_INLINES.
+	* debug/Makefile: Add rules to build and run tst-{,lfs}chk{4,5,6}
+	tests.
+	* debug/tst-chk1.c (do_prepare, do_test): Allow compilation as C++.
+	For now avoid some *printf tests in C++.  Skip all testing
+	if __USE_FORTIFY_LEVEL is defined, but __extern_always_inline macro
+	is not.
+	* debug/tst-chk4.cc: New file.
+	* debug/tst-chk5.cc: New file.
+	* debug/tst-chk6.cc: New file.
+	* debug/tst-lfschk4.cc: New file.
+	* debug/tst-lfschk5.cc: New file.
+	* debug/tst-lfschk6.cc: New file.
+	* include/wchar.h (__vfwprintf_chk, __vswprintf_chk): Avoid
+	prototypes in C++.
+	* include/stdio.h (__sprintf_chk, __snprintf_chk, __vsprintf_chk,
+	__vsnprintf_chk, __printf_chk, __fprintf_chk, __vprintf_chk,
+	__vfprintf_chk, __fgets_unlocked_chk, __fgets_chk): Likewise.
+
 2007-09-13  Ulrich Drepper  <drepper@redhat.com>
 
 	* po/cs.po: Update from translation team.
diff --git a/debug/Makefile b/debug/Makefile
index 18905c366f..a2c28f9737 100644
--- a/debug/Makefile
+++ b/debug/Makefile
@@ -79,15 +79,37 @@ CFLAGS-recvfrom_chk.c = -fexceptions -fasynchronous-unwind-tables
 CFLAGS-tst-chk1.c = -Wno-format
 CFLAGS-tst-chk2.c = -Wno-format
 CFLAGS-tst-chk3.c = -Wno-format
+CFLAGS-tst-chk4.cc = -Wno-format
+CFLAGS-tst-chk5.cc = -Wno-format
+CFLAGS-tst-chk6.cc = -Wno-format
+CFLAGS-tst-lfschk1.c = -Wno-format
+CFLAGS-tst-lfschk2.c = -Wno-format
+CFLAGS-tst-lfschk3.c = -Wno-format
+CFLAGS-tst-lfschk4.cc = -Wno-format
+CFLAGS-tst-lfschk5.cc = -Wno-format
+CFLAGS-tst-lfschk6.cc = -Wno-format
 tst-chk1-ENV = LOCPATH=$(common-objpfx)localedata
 tst-chk2-ENV = LOCPATH=$(common-objpfx)localedata
 tst-chk3-ENV = LOCPATH=$(common-objpfx)localedata
+tst-chk4-ENV = LOCPATH=$(common-objpfx)localedata
+tst-chk5-ENV = LOCPATH=$(common-objpfx)localedata
+tst-chk6-ENV = LOCPATH=$(common-objpfx)localedata
 tst-lfschk1-ENV = LOCPATH=$(common-objpfx)localedata
 tst-lfschk2-ENV = LOCPATH=$(common-objpfx)localedata
 tst-lfschk3-ENV = LOCPATH=$(common-objpfx)localedata
+tst-lfschk4-ENV = LOCPATH=$(common-objpfx)localedata
+tst-lfschk5-ENV = LOCPATH=$(common-objpfx)localedata
+tst-lfschk6-ENV = LOCPATH=$(common-objpfx)localedata
+LDFLAGS-tst-chk4 = -lstdc++
+LDFLAGS-tst-chk5 = -lstdc++
+LDFLAGS-tst-chk6 = -lstdc++
+LDFLAGS-tst-lfschk4 = -lstdc++
+LDFLAGS-tst-lfschk5 = -lstdc++
+LDFLAGS-tst-lfschk6 = -lstdc++
 
 tests = backtrace-tst tst-chk1 tst-chk2 tst-chk3 \
-	tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk
+	tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \
+	tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6
 
 extra-libs = libSegFault libpcprofile
 extra-libs-others = $(extra-libs)
diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c
index 26ace28970..78a61be53b 100644
--- a/debug/tst-chk1.c
+++ b/debug/tst-chk1.c
@@ -49,7 +49,7 @@ do_prepare (void)
     }
 
   const char *strs = "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ";
-  if (write (temp_fd, strs, strlen (strs)) != strlen (strs))
+  if ((size_t) write (temp_fd, strs, strlen (strs)) != strlen (strs))
     {
       puts ("could not write test strings into file");
       unlink (temp_filename);
@@ -102,7 +102,7 @@ int num2 = 987654;
       chk_fail_ok = 0;				\
       FAIL ();					\
     }
-#if __USE_FORTIFY_LEVEL >= 2
+#if __USE_FORTIFY_LEVEL >= 2 && (!defined __cplusplus || defined __va_arg_pack)
 #define CHK_FAIL2_START CHK_FAIL_START
 #define CHK_FAIL2_END CHK_FAIL_END
 #else
@@ -142,6 +142,12 @@ do_test (void)
 #endif
 	  );
 
+#if defined __USE_FORTIFY_LEVEL && !defined __extern_always_inline
+  printf ("Test skipped");
+  if (l0 == 0)
+    return 0;
+#endif
+
   /* These ops can be done without runtime checking of object size.  */
   memcpy (buf, "abcdefghij", 10);
   memmove (buf + 1, buf, 9);
@@ -280,7 +286,7 @@ do_test (void)
   CHK_FAIL_END
 
   CHK_FAIL_START
-  p = mempcpy (buf + 6, "abcde", l0 + 5);
+  p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
   CHK_FAIL_END
 
   CHK_FAIL_START
@@ -303,6 +309,7 @@ do_test (void)
   stpncpy (buf + 6, "cd", l0 + 5);
   CHK_FAIL_END
 
+# if !defined __cplusplus || defined __va_arg_pack
   CHK_FAIL_START
   sprintf (buf + 8, "%d", num1);
   CHK_FAIL_END
@@ -310,6 +317,7 @@ do_test (void)
   CHK_FAIL_START
   snprintf (buf + 8, l0 + 3, "%d", num2);
   CHK_FAIL_END
+# endif
 
   memcpy (buf, str1 + 2, l0 + 9);
   CHK_FAIL_START
@@ -330,18 +338,18 @@ do_test (void)
   CHK_FAIL_END
 
   CHK_FAIL_START
-  p = mempcpy (a.buf1 + 6, "abcde", l0 + 5);
+  p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
   CHK_FAIL_END
 
   CHK_FAIL_START
   memset (a.buf1 + 9, 'j', l0 + 2);
   CHK_FAIL_END
 
-#if __USE_FORTIFY_LEVEL >= 2
-# define O 0
-#else
-# define O 1
-#endif
+# if __USE_FORTIFY_LEVEL >= 2
+#  define O 0
+# else
+#  define O 1
+# endif
 
   CHK_FAIL_START
   strcpy (a.buf1 + (O + 4), str1 + 5);
@@ -355,6 +363,7 @@ do_test (void)
   strncpy (a.buf1 + (O + 6), "X", l0 + 4);
   CHK_FAIL_END
 
+# if !defined __cplusplus || defined __va_arg_pack
   CHK_FAIL_START
   sprintf (a.buf1 + (O + 7), "%d", num1);
   CHK_FAIL_END
@@ -362,6 +371,7 @@ do_test (void)
   CHK_FAIL_START
   snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
   CHK_FAIL_END
+# endif
 
   memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O);
   CHK_FAIL_START
@@ -919,7 +929,8 @@ do_test (void)
   else
     {
       const char *sendstr = "abcdefgh\nABCDEFGH\n0123456789\n";
-      if (send (sp[0], sendstr, strlen (sendstr), 0) != strlen (sendstr))
+      if ((size_t) send (sp[0], sendstr, strlen (sendstr), 0)
+	  != strlen (sendstr))
 	FAIL ();
 
       char recvbuf[12];
@@ -951,29 +962,30 @@ do_test (void)
       struct sockaddr_un sa_un;
 
       sl = sizeof (sa_un);
-      if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
+      if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK,
+		    (struct sockaddr *) &sa_un, &sl)
 	  != sizeof recvbuf
 	  || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
 	FAIL ();
 
       sl = sizeof (sa_un);
       if (recvfrom (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK,
-	  &sa_un, &sl) != sizeof recvbuf - 7
+		    (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf - 7
 	  || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
 	FAIL ();
 
 #if __USE_FORTIFY_LEVEL >= 1
       CHK_FAIL_START
       sl = sizeof (sa_un);
-      if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
-	  != sizeof recvbuf)
+      if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK,
+		    (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf)
 	FAIL ();
       CHK_FAIL_END
 
       CHK_FAIL_START
       sl = sizeof (sa_un);
       if (recvfrom (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK,
-	  &sa_un, &sl) != sizeof recvbuf - 3)
+		    (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf - 3)
 	FAIL ();
       CHK_FAIL_END
 #endif
diff --git a/debug/tst-chk4.cc b/debug/tst-chk4.cc
new file mode 100644
index 0000000000..c82e6aac86
--- /dev/null
+++ b/debug/tst-chk4.cc
@@ -0,0 +1 @@
+#include "tst-chk1.c"
diff --git a/debug/tst-chk5.cc b/debug/tst-chk5.cc
new file mode 100644
index 0000000000..be37ce2d22
--- /dev/null
+++ b/debug/tst-chk5.cc
@@ -0,0 +1,2 @@
+#define _FORTIFY_SOURCE 1
+#include "tst-chk1.c"
diff --git a/debug/tst-chk6.cc b/debug/tst-chk6.cc
new file mode 100644
index 0000000000..38b8e4fb36
--- /dev/null
+++ b/debug/tst-chk6.cc
@@ -0,0 +1,2 @@
+#define _FORTIFY_SOURCE 2
+#include "tst-chk1.c"
diff --git a/debug/tst-lfschk4.cc b/debug/tst-lfschk4.cc
new file mode 100644
index 0000000000..f3e6d47d5e
--- /dev/null
+++ b/debug/tst-lfschk4.cc
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-chk1.c"
diff --git a/debug/tst-lfschk5.cc b/debug/tst-lfschk5.cc
new file mode 100644
index 0000000000..95d4db1d32
--- /dev/null
+++ b/debug/tst-lfschk5.cc
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-chk2.c"
diff --git a/debug/tst-lfschk6.cc b/debug/tst-lfschk6.cc
new file mode 100644
index 0000000000..50a1ae1258
--- /dev/null
+++ b/debug/tst-lfschk6.cc
@@ -0,0 +1,2 @@
+#define _FILE_OFFSET_BITS 64
+#include "tst-chk3.c"
diff --git a/include/features.h b/include/features.h
index 7f99741a95..18f743cb75 100644
--- a/include/features.h
+++ b/include/features.h
@@ -341,7 +341,8 @@
 
 /* Decide whether we can define 'extern inline' functions in headers.  */
 #if __GNUC_PREREQ (2, 7) && defined __OPTIMIZE__ \
-    && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__
+    && !defined __OPTIMIZE_SIZE__ && !defined __NO_INLINE__ \
+    && defined __extern_inline
 # define __USE_EXTERN_INLINES	1
 #endif
 
diff --git a/include/stdio.h b/include/stdio.h
index 748523d4d1..84b8af9da1 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -27,6 +27,7 @@ extern int __vsscanf (__const char *__restrict __s,
 		      _G_va_list __arg)
      __attribute__ ((__format__ (__scanf__, 2, 0)));
 
+#ifndef __cplusplus
 extern int __sprintf_chk (char *, int, size_t, const char *, ...) __THROW;
 extern int __snprintf_chk (char *, size_t, int, size_t, const char *, ...)
      __THROW;
@@ -40,6 +41,7 @@ extern int __vprintf_chk (int, const char *, _G_va_list);
 extern int __vfprintf_chk (FILE *, int, const char *, _G_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);
+#endif
 
 /* Prototypes for compatibility functions.  */
 extern FILE *__new_tmpfile (void);
diff --git a/include/wchar.h b/include/wchar.h
index b5f74da0f0..7651f6de29 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -152,6 +152,7 @@ extern int __vfwprintf (__FILE *__restrict __s,
 			__const wchar_t *__restrict __format,
 			__gnuc_va_list __arg)
      /* __attribute__ ((__format__ (__wprintf__, 2, 0))) */;
+#ifndef __cplusplus
 extern int __vfwprintf_chk (FILE *__restrict __s, int __flag,
 			    const wchar_t *__restrict __format,
 			    __gnuc_va_list __arg)
@@ -163,6 +164,7 @@ extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
      /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
 libc_hidden_proto (__vfwprintf_chk)
 libc_hidden_proto (__vswprintf_chk)
+#endif
 
 /* Internal functions.  */
 extern size_t __mbsrtowcs_l (wchar_t *dst, const char **src, size_t len,
diff --git a/io/fcntl.h b/io/fcntl.h
index c89bf625bf..6bfa9fd6cf 100644
--- a/io/fcntl.h
+++ b/io/fcntl.h
@@ -212,7 +212,8 @@ extern int posix_fallocate64 (int __fd, __off64_t __offset, __off64_t __len);
 
 
 /* Define some macros helping to catch common problems.  */
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline \
+    && !defined __cplusplus
 # include <bits/fcntl2.h>
 #endif
 
diff --git a/io/sys/stat.h b/io/sys/stat.h
index 15ae35b199..364c43f8f4 100644
--- a/io/sys/stat.h
+++ b/io/sys/stat.h
@@ -444,7 +444,7 @@ extern int __xmknodat (int __ver, int __fd, __const char *__path,
 		       __mode_t __mode, __dev_t *__dev)
      __THROW __nonnull ((3, 5));
 
-#if defined __GNUC__ && __GNUC__ >= 2
+#if defined __GNUC__ && __GNUC__ >= 2 && defined __USE_EXTERN_INLINES
 /* Inlined versions of the real stat and mknod functions.  */
 
 __extern_inline int
diff --git a/libio/bits/stdio-ldbl.h b/libio/bits/stdio-ldbl.h
index 7a4291225e..b6ec7f3c92 100644
--- a/libio/bits/stdio-ldbl.h
+++ b/libio/bits/stdio-ldbl.h
@@ -1,5 +1,5 @@
 /* -mlong-double-64 compatibility mode for stdio functions.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007 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
@@ -58,7 +58,7 @@ __LDBL_REDIR_DECL (obstack_printf)
 __LDBL_REDIR_DECL (obstack_vprintf)
 #endif
 
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 __LDBL_REDIR_DECL (__sprintf_chk)
 __LDBL_REDIR_DECL (__vsprintf_chk)
 # if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
diff --git a/libio/bits/stdio.h b/libio/bits/stdio.h
index 4d23f28db0..49303c6900 100644
--- a/libio/bits/stdio.h
+++ b/libio/bits/stdio.h
@@ -21,7 +21,7 @@
 # error "Never include <bits/stdio.h> directly; use <stdio.h> instead."
 #endif
 
-#ifdef __cplusplus
+#ifndef __extern_inline
 # define __STDIO_INLINE inline
 #else
 # define __STDIO_INLINE __extern_inline
@@ -29,12 +29,16 @@
 
 
 #ifdef __USE_EXTERN_INLINES
+/* For -D_FORTIFY_SOURCE{,=2} bits/stdio2.h will define a different
+   inline.  */
+# if !(__USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline)
 /* Write formatted output to stdout from argument list ARG.  */
 __STDIO_INLINE int
 vprintf (__const char *__restrict __fmt, _G_va_list __arg)
 {
   return vfprintf (stdout, __fmt, __arg);
 }
+# endif
 
 /* Read a character from stdin.  */
 __STDIO_INLINE int
@@ -135,7 +139,8 @@ __NTH (ferror_unlocked (FILE *__stream))
 #endif /* Use extern inlines.  */
 
 
-#if defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__
+#if defined __USE_MISC && defined __GNUC__ && defined __OPTIMIZE__ \
+    && !defined __cplusplus
 /* Perform some simple optimizations.  */
 # define fread_unlocked(ptr, size, n, stream) \
   (__extension__ ((__builtin_constant_p (size) && __builtin_constant_p (n)    \
diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h
index 89f5770ee3..841a0ff6aa 100644
--- a/libio/bits/stdio2.h
+++ b/libio/bits/stdio2.h
@@ -27,11 +27,26 @@ extern int __vsprintf_chk (char *__restrict __s, int __flag, size_t __slen,
 			   __const char *__restrict __format,
 			   _G_va_list __ap) __THROW;
 
-#define sprintf(str, ...) \
+#ifdef __va_arg_pack
+__extern_always_inline int
+__NTH (sprintf (char *__restrict __s, __const char *__restrict __fmt, ...))
+{
+  return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
+				  __bos (__s), __fmt, __va_arg_pack ());
+}
+#elif !defined __cplusplus
+# define sprintf(str, ...) \
   __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \
 			   __VA_ARGS__)
-#define vsprintf(str, fmt, ap) \
-  __builtin___vsprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), fmt, ap)
+#endif
+
+__extern_always_inline int
+__NTH (vsprintf (char *__restrict __s, __const char *__restrict __fmt,
+		 _G_va_list __ap))
+{
+  return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1,
+				   __bos (__s), __fmt, __ap);
+}
 
 #if defined __USE_BSD || defined __USE_ISOC99 || defined __USE_UNIX98
 
@@ -42,12 +57,27 @@ extern int __vsnprintf_chk (char *__restrict __s, size_t __n, int __flag,
 			    size_t __slen, __const char *__restrict __format,
 			    _G_va_list __ap) __THROW;
 
-# define snprintf(str, len, ...) \
+# ifdef __va_arg_pack
+__extern_always_inline int
+__NTH (snprintf (char *__restrict __s, size_t __n,
+		 __const char *__restrict __fmt, ...))
+{
+  return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+				   __bos (__s), __fmt, __va_arg_pack ());
+}
+# elif !defined __cplusplus
+#  define snprintf(str, len, ...) \
   __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
 			    __VA_ARGS__)
-# define vsnprintf(str, len, fmt, ap) \
-  __builtin___vsnprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \
-			     fmt, ap)
+# endif
+
+__extern_always_inline int
+__NTH (vsnprintf (char *__restrict __s, size_t __n,
+		  __const char *__restrict __fmt, _G_va_list __ap))
+{
+  return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+				    __bos (__s), __fmt, __ap);
+}
 
 #endif
 
@@ -61,14 +91,42 @@ extern int __vfprintf_chk (FILE *__restrict __stream, int __flag,
 extern int __vprintf_chk (int __flag, __const char *__restrict __format,
 			  _G_va_list __ap);
 
-# define printf(...) \
+# ifdef __va_arg_pack
+__extern_always_inline int
+fprintf (FILE *__restrict __stream, __const char *__restrict __fmt, ...)
+{
+  return __fprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
+			__va_arg_pack ());
+}
+
+__extern_always_inline int
+printf (__const char *__restrict __fmt, ...)
+{
+  return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
+}
+# elif !defined __cplusplus
+#  define printf(...) \
   __printf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
-# define fprintf(stream, ...) \
+#  define fprintf(stream, ...) \
   __fprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
-# define vprintf(format, ap) \
-  __vprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
-# define vfprintf(stream, format, ap) \
-  __vfprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
+# endif
+
+__extern_always_inline int
+vprintf (__const char *__restrict __fmt, _G_va_list __ap)
+{
+#ifdef __USE_EXTERN_INLINES
+  return __vfprintf_chk (stdout, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+#else
+  return __vprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+#endif
+}
+
+__extern_always_inline int
+vfprintf (FILE *__restrict __stream,
+	  __const char *__restrict __fmt, _G_va_list __ap)
+{
+  return __vfprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+}
 
 #endif
 
diff --git a/libio/stdio.h b/libio/stdio.h
index 8e6694a6b3..c1ba9b2235 100644
--- a/libio/stdio.h
+++ b/libio/stdio.h
@@ -838,7 +838,7 @@ extern void funlockfile (FILE *__stream) __THROW;
 #ifdef __USE_EXTERN_INLINES
 # include <bits/stdio.h>
 #endif
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 # include <bits/stdio2.h>
 #endif
 #ifdef __LDBL_COMPAT
diff --git a/math/bits/cmathcalls.h b/math/bits/cmathcalls.h
index db7f69c72e..9c7fdbe9e3 100644
--- a/math/bits/cmathcalls.h
+++ b/math/bits/cmathcalls.h
@@ -132,7 +132,8 @@ __MATHDECL (_Mdouble_,creal, (_Mdouble_complex_ __z));
 /* Now some optimized versions.  GCC has handy notations for these
    functions.  Recent GCC handles these as builtin functions so does
    not need inlines.  */
-#if defined __GNUC__ && !__GNUC_PREREQ (2, 97) && defined __OPTIMIZE__
+#if defined __GNUC__ && !__GNUC_PREREQ (2, 97) && defined __OPTIMIZE__ \
+    && defined __extern_inline
 
 /* Imaginary part of Z.  */
 __extern_inline _Mdouble_
diff --git a/misc/bits/syslog-ldbl.h b/misc/bits/syslog-ldbl.h
index d153c8f8cd..714e70c201 100644
--- a/misc/bits/syslog-ldbl.h
+++ b/misc/bits/syslog-ldbl.h
@@ -27,7 +27,7 @@ __LDBL_REDIR_DECL (syslog)
 __LDBL_REDIR_DECL (vsyslog)
 #endif
 
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 __LDBL_REDIR_DECL (__syslog_chk)
 
 # ifdef __USE_BSD
diff --git a/misc/bits/syslog.h b/misc/bits/syslog.h
index c0427214e3..f8c81dd9e4 100644
--- a/misc/bits/syslog.h
+++ b/misc/bits/syslog.h
@@ -1,5 +1,5 @@
 /* Checking macros for syslog functions.
-   Copyright (C) 2005 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007 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
@@ -25,8 +25,16 @@
 extern void __syslog_chk (int __pri, int __flag, __const char *__fmt, ...)
      __attribute__ ((__format__ (__printf__, 3, 4)));
 
-#define syslog(pri, ...) \
+#ifdef __va_arg_pack
+__extern_always_inline void
+syslog (int __pri, int __flag, __const char *__fmt, ...)
+{
+  return __syslog_chk (__pri, __flag, __fmt, __va_arg_pack ());
+}
+#elif !defined __cplusplus
+# define syslog(pri, ...) \
   __syslog_chk (pri, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
+#endif
 
 
 #ifdef __USE_BSD
@@ -34,6 +42,9 @@ extern void __vsyslog_chk (int __pri, int __flag, __const char *__fmt,
 			   __gnuc_va_list __ap)
      __attribute__ ((__format__ (__printf__, 3, 0)));
 
-# define vsyslog(pri, fmt, ap)						\
-  __vsyslog_chk (pri, __USE_FORTIFY_LEVEL - 1, fmt, ap)
+__extern_always_inline void
+vsyslog (int __pri, __const char *__fmt, __gnuc_va_list __ap)
+{
+  return __vsyslog_chk (__pri,  __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+}
 #endif
diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h
index ab7d327c59..bacfe2f63f 100644
--- a/misc/sys/cdefs.h
+++ b/misc/sys/cdefs.h
@@ -281,13 +281,21 @@
 
 /* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
    inline semantics, unless -fgnu89-inline is used.  */
-#ifdef __GNUC_STDC_INLINE__
-# define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
-# define __extern_always_inline \
+#if !defined __cplusplus || __GNUC_PREREQ (4,3)
+# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
+#  define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
+#  define __extern_always_inline \
   extern __always_inline __attribute__ ((__gnu_inline__))
-#else
-# define __extern_inline extern __inline
-# define __extern_always_inline extern __always_inline
+# else
+#  define __extern_inline extern __inline
+#  define __extern_always_inline extern __always_inline
+# endif
+#endif
+
+/* GCC 4.3 and above allow passing all anonymous arguments of an
+   __extern_always_inline function to some other vararg function.  */
+#if __GNUC_PREREQ (4,3)
+# define __va_arg_pack() __builtin_va_arg_pack ()
 #endif
 
 /* It is possible to compile containing GCC extensions even if GCC is
diff --git a/misc/sys/syslog.h b/misc/sys/syslog.h
index 4ed57c2787..22da1ce3e9 100644
--- a/misc/sys/syslog.h
+++ b/misc/sys/syslog.h
@@ -203,7 +203,7 @@ extern void vsyslog (int __pri, __const char *__fmt, __gnuc_va_list __ap)
 
 
 /* Define some macros helping to catch buffer overflows.  */
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 # include <bits/syslog.h>
 #endif
 #ifdef __LDBL_COMPAT
diff --git a/posix/unistd.h b/posix/unistd.h
index a86968a8db..476c1f3cbc 100644
--- a/posix/unistd.h
+++ b/posix/unistd.h
@@ -1096,7 +1096,7 @@ extern char *ctermid (char *__s) __THROW;
 
 
 /* Define some macros helping to catch buffer overflows.  */
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 # include <bits/unistd.h>
 #endif
 
diff --git a/socket/sys/socket.h b/socket/sys/socket.h
index 4112852ebb..6d9eab7f94 100644
--- a/socket/sys/socket.h
+++ b/socket/sys/socket.h
@@ -1,5 +1,6 @@
 /* Declarations of socket constants, types, and functions.
-   Copyright (C) 1991,92,1994-2001,2003,2005 Free Software Foundation, Inc.
+   Copyright (C) 1991,92,1994-2001,2003,2005,2007
+   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
@@ -233,7 +234,7 @@ extern int isfdtype (int __fd, int __fdtype) __THROW;
 
 
 /* Define some macros helping to catch buffer overflows.  */
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 # include <bits/socket2.h>
 #endif
 
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index d405cbf7b6..3c2ea72a53 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -870,7 +870,7 @@ extern int getloadavg (double __loadavg[], int __nelem)
 
 
 /* Define some macros helping to catch buffer overflows.  */
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 # include <bits/stdlib.h>
 #endif
 #ifdef __LDBL_COMPAT
diff --git a/string/bits/string3.h b/string/bits/string3.h
index f68ce5899f..876fe77929 100644
--- a/string/bits/string3.h
+++ b/string/bits/string3.h
@@ -20,27 +20,40 @@
 # error "Never use <bits/string3.h> directly; include <string.h> instead."
 #endif
 
+__warndecl (__warn_memset_zero_len,
+	    "memset used with constant zero length parameter; this could be due to transposed parameters");
+
+#ifndef __cplusplus
 /* XXX This is temporarily.  We should not redefine any of the symbols
    and instead integrate the error checking into the original
    definitions.  */
-#undef memcpy
-#undef memmove
-#undef memset
-#undef strcat
-#undef strcpy
-#undef strncat
-#undef strncpy
-#ifdef __USE_GNU
-# undef mempcpy
-# undef stpcpy
-#endif
-#ifdef __USE_BSD
-# undef bcopy
-# undef bzero
+# undef memcpy
+# undef memmove
+# undef memset
+# undef strcat
+# undef strcpy
+# undef strncat
+# undef strncpy
+# ifdef __USE_GNU
+#  undef mempcpy
+#  undef stpcpy
+# endif
+# ifdef __USE_BSD
+#  undef bcopy
+#  undef bzero
+# endif
 #endif
 
 
-#define memcpy(dest, src, len) \
+#ifdef __cplusplus
+__extern_always_inline void *
+__NTH (memcpy (void *__restrict __dest, __const void *__restrict __src,
+	       size_t __len))
+{
+  return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
+}
+#else
+# define memcpy(dest, src, len) \
   ((__bos0 (dest) != (size_t) -1)					\
    ? __builtin___memcpy_chk (dest, src, len, __bos0 (dest))		\
    : __memcpy_ichk (dest, src, len))
@@ -50,9 +63,17 @@ __NTH (__memcpy_ichk (void *__restrict __dest, __const void *__restrict __src,
 {
   return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest));
 }
+#endif
 
-
-#define memmove(dest, src, len) \
+#ifdef __cplusplus
+__extern_always_inline void *
+__NTH (memmove (void *__restrict __dest, __const void *__restrict __src,
+		size_t __len))
+{
+  return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
+}
+#else
+# define memmove(dest, src, len) \
   ((__bos0 (dest) != (size_t) -1)					\
    ? __builtin___memmove_chk (dest, src, len, __bos0 (dest))		\
    : __memmove_ichk (dest, src, len))
@@ -61,10 +82,18 @@ __NTH (__memmove_ichk (void *__dest, __const void *__src, size_t __len))
 {
   return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
 }
-
+#endif
 
 #ifdef __USE_GNU
-# define mempcpy(dest, src, len) \
+# ifdef __cplusplus
+__extern_always_inline void *
+__NTH (mempcpy (void *__restrict __dest, __const void *__restrict __src,
+		size_t __len))
+{
+  return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
+}
+# else
+#  define mempcpy(dest, src, len) \
   ((__bos0 (dest) != (size_t) -1)					\
    ? __builtin___mempcpy_chk (dest, src, len, __bos0 (dest))		\
    : __mempcpy_ichk (dest, src, len))
@@ -74,6 +103,7 @@ __NTH (__mempcpy_ichk (void *__restrict __dest,
 {
   return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest));
 }
+# endif
 #endif
 
 
@@ -82,9 +112,19 @@ __NTH (__mempcpy_ichk (void *__restrict __dest,
    especially problematic if the intended fill value is zero.  In this
    case no work is done at all.  We detect these problems by referring
    non-existing functions.  */
-__warndecl (__warn_memset_zero_len,
-	    "memset used with constant zero length parameter; this could be due to transposed parameters");
-#define memset(dest, ch, len) \
+#ifdef __cplusplus
+__extern_always_inline void *
+__NTH (memset (void *__dest, int __ch, size_t __len))
+{
+  if (__builtin_constant_p (__len) && __len == 0)
+    {
+      __warn_memset_zero_len ();
+      return __dest;
+    }
+  return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
+}
+#else
+# define memset(dest, ch, len) \
   (__builtin_constant_p (len) && (len) == 0				      \
    ? (__warn_memset_zero_len (), (void) (ch), (void) (len), (void *) (dest))  \
    : ((__bos0 (dest) != (size_t) -1)					      \
@@ -95,20 +135,41 @@ __NTH (__memset_ichk (void *__dest, int __ch, size_t __len))
 {
   return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest));
 }
+#endif
 
 #ifdef __USE_BSD
-# define bcopy(src, dest, len) ((void) \
+# ifdef __cplusplus
+__extern_always_inline void
+__NTH (bcopy (__const void *__restrict __src, void *__restrict __dest,
+	      size_t __len))
+{
+  __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest));
+}
+__extern_always_inline void
+__NTH (bzero (void *__dest, size_t __len))
+{
+  __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest));
+}
+# else
+#  define bcopy(src, dest, len) ((void) \
   ((__bos0 (dest) != (size_t) -1)					\
    ? __builtin___memmove_chk (dest, src, len, __bos0 (dest))		\
    : __memmove_ichk (dest, src, len)))
-# define bzero(dest, len) ((void) \
+#  define bzero(dest, len) ((void) \
   ((__bos0 (dest) != (size_t) -1)					\
    ? __builtin___memset_chk (dest, '\0', len, __bos0 (dest))		\
    : __memset_ichk (dest, '\0', len)))
+# endif
 #endif
 
-
-#define strcpy(dest, src) \
+#ifdef __cplusplus
+__extern_always_inline char *
+__NTH (strcpy (char *__restrict __dest, __const char *__restrict __src))
+{
+  return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
+}
+#else
+# define strcpy(dest, src) \
   ((__bos (dest) != (size_t) -1)					\
    ? __builtin___strcpy_chk (dest, src, __bos (dest))			\
    : __strcpy_ichk (dest, src))
@@ -117,10 +178,17 @@ __NTH (__strcpy_ichk (char *__restrict __dest, __const char *__restrict __src))
 {
   return __builtin___strcpy_chk (__dest, __src, __bos (__dest));
 }
-
+#endif
 
 #ifdef __USE_GNU
-# define stpcpy(dest, src) \
+# ifdef __cplusplus
+__extern_always_inline char *
+__NTH (stpcpy (char *__restrict __dest, __const char *__restrict __src))
+{
+  return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
+}
+# else
+#  define stpcpy(dest, src) \
   ((__bos (dest) != (size_t) -1)					\
    ? __builtin___stpcpy_chk (dest, src, __bos (dest))			\
    : __stpcpy_ichk (dest, src))
@@ -129,10 +197,19 @@ __NTH (__stpcpy_ichk (char *__restrict __dest, __const char *__restrict __src))
 {
   return __builtin___stpcpy_chk (__dest, __src, __bos (__dest));
 }
+# endif
 #endif
 
 
-#define strncpy(dest, src, len) \
+#ifdef __cplusplus
+__extern_always_inline char *
+__NTH (strncpy (char *__restrict __dest, __const char *__restrict __src,
+		size_t __len))
+{
+  return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
+}
+#else
+# define strncpy(dest, src, len) \
   ((__bos (dest) != (size_t) -1)					\
    ? __builtin___strncpy_chk (dest, src, len, __bos (dest))		\
    : __strncpy_ichk (dest, src, len))
@@ -142,7 +219,7 @@ __NTH (__strncpy_ichk (char *__restrict __dest, __const char *__restrict __src,
 {
   return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest));
 }
-
+#endif
 
 // XXX We have no corresponding builtin yet.
 extern char *__stpncpy_chk (char *__dest, __const char *__src, size_t __n,
@@ -161,7 +238,14 @@ __NTH (stpncpy (char *__dest, __const char *__src, size_t __n))
 }
 
 
-#define strcat(dest, src) \
+#ifdef __cplusplus
+__extern_always_inline char *
+__NTH (strcat (char *__restrict __dest, __const char *__restrict __src))
+{
+  return __builtin___strcat_chk (__dest, __src, __bos (__dest));
+}
+#else
+# define strcat(dest, src) \
   ((__bos (dest) != (size_t) -1)					\
    ? __builtin___strcat_chk (dest, src, __bos (dest))			\
    : __strcat_ichk (dest, src))
@@ -170,9 +254,18 @@ __NTH (__strcat_ichk (char *__restrict __dest, __const char *__restrict __src))
 {
   return __builtin___strcat_chk (__dest, __src, __bos (__dest));
 }
+#endif
 
 
-#define strncat(dest, src, len) \
+#ifdef __cplusplus
+__extern_always_inline char *
+__NTH (strncat (char *__restrict __dest, __const char *__restrict __src,
+		size_t __len))
+{
+  return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
+}
+#else
+# define strncat(dest, src, len) \
   ((__bos (dest) != (size_t) -1)					\
    ? __builtin___strncat_chk (dest, src, len, __bos (dest))		\
    : __strncat_ichk (dest, src, len))
@@ -182,3 +275,4 @@ __NTH (__strncat_ichk (char *__restrict __dest, __const char *__restrict __src,
 {
   return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest));
 }
+#endif
diff --git a/string/string.h b/string/string.h
index 5e1a96fc06..90c92d4527 100644
--- a/string/string.h
+++ b/string/string.h
@@ -423,7 +423,7 @@ extern char *basename (__const char *__filename) __THROW __nonnull ((1));
 #  include <bits/string2.h>
 # endif
 
-# if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+# if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 /* Functions with security checks.  */
 #  include <bits/string3.h>
 # endif
diff --git a/sysdeps/alpha/fpu/bits/mathinline.h b/sysdeps/alpha/fpu/bits/mathinline.h
index 250171eeb4..5378a181c6 100644
--- a/sysdeps/alpha/fpu/bits/mathinline.h
+++ b/sysdeps/alpha/fpu/bits/mathinline.h
@@ -23,7 +23,7 @@
 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
 #endif
 
-#ifdef __cplusplus
+#ifndef __extern_inline
 # define __MATH_INLINE __inline
 #else
 # define __MATH_INLINE __extern_inline
diff --git a/sysdeps/i386/fpu/bits/mathinline.h b/sysdeps/i386/fpu/bits/mathinline.h
index a0f630e240..a786cc69cd 100644
--- a/sysdeps/i386/fpu/bits/mathinline.h
+++ b/sysdeps/i386/fpu/bits/mathinline.h
@@ -23,7 +23,7 @@
 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
 #endif
 
-#ifdef __cplusplus
+#ifndef __extern_inline
 # define __MATH_INLINE __inline
 #else
 # define __MATH_INLINE __extern_inline
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index 2db9abc9e4..cf5f4847fa 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -32,7 +32,7 @@
     && defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
 
 #ifndef __STRING_INLINE
-# ifdef __cplusplus
+# ifndef __extern_inline
 #  define __STRING_INLINE inline
 # else
 #  define __STRING_INLINE __extern_inline
diff --git a/sysdeps/ia64/fpu/bits/mathinline.h b/sysdeps/ia64/fpu/bits/mathinline.h
index 1e90257182..cd90b06d3a 100644
--- a/sysdeps/ia64/fpu/bits/mathinline.h
+++ b/sysdeps/ia64/fpu/bits/mathinline.h
@@ -21,7 +21,7 @@
 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
 #endif
 
-#ifdef __cplusplus
+#ifndef __extern_inline
 # define __MATH_INLINE __inline
 #else
 # define __MATH_INLINE __extern_inline
diff --git a/sysdeps/powerpc/fpu/bits/mathinline.h b/sysdeps/powerpc/fpu/bits/mathinline.h
index 6c01fa436c..4d4612dac0 100644
--- a/sysdeps/powerpc/fpu/bits/mathinline.h
+++ b/sysdeps/powerpc/fpu/bits/mathinline.h
@@ -22,7 +22,7 @@
 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
 #endif
 
-#ifdef __cplusplus
+#ifndef __extern_inline
 # define __MATH_INLINE __inline
 #else
 # define __MATH_INLINE __extern_inline
diff --git a/sysdeps/s390/bits/string.h b/sysdeps/s390/bits/string.h
index e16c7cb829..87550c5f67 100644
--- a/sysdeps/s390/bits/string.h
+++ b/sysdeps/s390/bits/string.h
@@ -31,7 +31,7 @@
     && defined __GNUC__ && __GNUC__ >= 2
 
 #ifndef __STRING_INLINE
-# ifdef __cplusplus
+# ifndef __extern_inline
 #  define __STRING_INLINE inline
 # else
 #  define __STRING_INLINE __extern_inline
diff --git a/sysdeps/s390/fpu/bits/mathinline.h b/sysdeps/s390/fpu/bits/mathinline.h
index 06a6368450..03af01c2b1 100644
--- a/sysdeps/s390/fpu/bits/mathinline.h
+++ b/sysdeps/s390/fpu/bits/mathinline.h
@@ -21,7 +21,7 @@
 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
 #endif
 
-#ifdef __cplusplus
+#ifndef __extern_inline
 # define __MATH_INLINE __inline
 #else
 # define __MATH_INLINE __extern_inline
diff --git a/sysdeps/sparc/fpu/bits/mathinline.h b/sysdeps/sparc/fpu/bits/mathinline.h
index 16ad22e666..d3ff44c5a9 100644
--- a/sysdeps/sparc/fpu/bits/mathinline.h
+++ b/sysdeps/sparc/fpu/bits/mathinline.h
@@ -128,7 +128,7 @@
 
 #if (!defined __NO_MATH_INLINES || defined __LIBC_INTERNAL_MATH_INLINES) && defined __OPTIMIZE__
 
-# ifdef __cplusplus
+# ifndef __extern_inline
 #  define __MATH_INLINE __inline
 # else
 #  define __MATH_INLINE __extern_inline
diff --git a/sysdeps/unix/sysv/linux/sys/sysmacros.h b/sysdeps/unix/sysv/linux/sys/sysmacros.h
index e59672980e..92b3a19d4f 100644
--- a/sysdeps/unix/sysv/linux/sys/sysmacros.h
+++ b/sysdeps/unix/sysv/linux/sys/sysmacros.h
@@ -28,17 +28,17 @@
    they need.  */
 #ifdef __GLIBC_HAVE_LONG_LONG
 __extension__
-__extern_inline unsigned int gnu_dev_major (unsigned long long int __dev)
+extern unsigned int gnu_dev_major (unsigned long long int __dev)
      __THROW;
 __extension__
-__extern_inline unsigned int gnu_dev_minor (unsigned long long int __dev)
+extern unsigned int gnu_dev_minor (unsigned long long int __dev)
      __THROW;
 __extension__
-__extern_inline unsigned long long int gnu_dev_makedev (unsigned int __major,
-							unsigned int __minor)
+extern unsigned long long int gnu_dev_makedev (unsigned int __major,
+					       unsigned int __minor)
      __THROW;
 
-# if defined __GNUC__ && __GNUC__ >= 2
+# if defined __GNUC__ && __GNUC__ >= 2 && defined __USE_EXTERN_INLINES
 __extension__ __extern_inline unsigned int
 __NTH (gnu_dev_major (unsigned long long int __dev))
 {
diff --git a/sysdeps/x86_64/fpu/bits/mathinline.h b/sysdeps/x86_64/fpu/bits/mathinline.h
index d08a9b033b..e8a919fe92 100644
--- a/sysdeps/x86_64/fpu/bits/mathinline.h
+++ b/sysdeps/x86_64/fpu/bits/mathinline.h
@@ -22,7 +22,7 @@
 # error "Never use <bits/mathinline.h> directly; include <math.h> instead."
 #endif
 
-#ifdef __cplusplus
+#ifndef __extern_inline
 # define __MATH_INLINE __inline
 #else
 # define __MATH_INLINE __extern_inline
diff --git a/wcsmbs/bits/wchar-ldbl.h b/wcsmbs/bits/wchar-ldbl.h
index 56a28d33b9..f398aecc65 100644
--- a/wcsmbs/bits/wchar-ldbl.h
+++ b/wcsmbs/bits/wchar-ldbl.h
@@ -48,7 +48,7 @@ __END_NAMESPACE_C99
 __LDBL_REDIR1_DECL (wcstold_l, wcstod_l);
 #endif
 
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 __LDBL_REDIR_DECL (__swprintf_chk)
 __LDBL_REDIR_DECL (__vswprintf_chk)
 # if __USE_FORTIFY_LEVEL > 1
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
index 697b9f2cd8..e1b7c13023 100644
--- a/wcsmbs/bits/wchar2.h
+++ b/wcsmbs/bits/wchar2.h
@@ -18,7 +18,7 @@
    02111-1307 USA.  */
 
 #ifndef _WCHAR_H
-# error "Never include <bits/wchar.h> directly; use <wchar.h> instead."
+# error "Never include <bits/wchar2.h> directly; use <wchar.h> instead."
 #endif
 
 
@@ -198,12 +198,28 @@ extern int __swprintf_chk (wchar_t *__restrict __s, size_t __n,
 			   __const wchar_t *__restrict __format, ...)
      __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 6))) */;
 
+extern int __REDIRECT_NTH (__swprintf_alias,
+			   (wchar_t *__restrict __s, size_t __n,
+			    __const wchar_t *__restrict __fmt, ...),
+			    swprintf);
+
+#ifdef __va_arg_pack
+__extern_always_inline int
+__NTH (swprintf (wchar_t *__restrict __s, size_t __n,
+		 __const wchar_t *__restrict __fmt, ...))
+{
+  if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
+    return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, __bos (__s),
+			   __fmt, __va_arg_pack ());
+  return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
+}
+#elif !defined __cplusplus
 /* XXX We might want to have support in gcc for swprintf.  */
-#define swprintf(s, n, ...) \
+# define swprintf(s, n, ...) \
   (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1			      \
    ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), __VA_ARGS__)   \
    : swprintf (s, n, __VA_ARGS__))
-
+#endif
 
 extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
 			    int __flag, size_t __s_len,
@@ -211,10 +227,20 @@ extern int __vswprintf_chk (wchar_t *__restrict __s, size_t __n,
 			    __gnuc_va_list __arg)
      __THROW /* __attribute__ ((__format__ (__wprintf__, 5, 0))) */;
 
-#define vswprintf(s, n, fmt, ap) \
-  (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1			      \
-   ? __vswprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, __bos (s), fmt, ap)      \
-   : vswprintf (s, n, fmt, ap))
+extern int __REDIRECT_NTH (__vswprintf_alias,
+			   (wchar_t *__restrict __s, size_t __n,
+			    __const wchar_t *__restrict __fmt,
+			    __gnuc_va_list __ap), vswprintf);
+
+__extern_always_inline int
+__NTH (vswprintf (wchar_t *__restrict __s, size_t __n,
+		  __const wchar_t *__restrict __fmt, __gnuc_va_list __ap))
+{
+  if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
+    return __vswprintf_chk (__s, __n,  __USE_FORTIFY_LEVEL - 1, __bos (__s),
+			    __fmt, __ap);
+  return __vswprintf_alias (__s, __n, __fmt, __ap);
+}
 
 
 #if __USE_FORTIFY_LEVEL > 1
@@ -229,14 +255,38 @@ extern int __vfwprintf_chk (__FILE *__restrict __stream, int __flag,
 extern int __vwprintf_chk (int __flag, __const wchar_t *__restrict __format,
 			   __gnuc_va_list __ap);
 
-# define wprintf(...) \
+# ifdef __va_arg_pack
+__extern_always_inline int
+wprintf (__const wchar_t *__restrict __fmt, ...)
+{
+  return __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
+}
+
+__extern_always_inline int
+fwprintf (__FILE *__restrict __stream, __const wchar_t *__restrict __fmt, ...)
+{
+  return __fwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt,
+			 __va_arg_pack ());
+}
+# elif !defined __cplusplus
+#  define wprintf(...) \
   __wprintf_chk (__USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
-# define fwprintf(stream, ...) \
+#  define fwprintf(stream, ...) \
   __fwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, __VA_ARGS__)
-# define vwprintf(format, ap) \
-  __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, format, ap)
-# define vfwprintf(stream, format, ap) \
-  __vfwprintf_chk (stream, __USE_FORTIFY_LEVEL - 1, format, ap)
+# endif
+
+__extern_always_inline int
+vwprintf (__const wchar_t *__restrict __fmt, __gnuc_va_list __ap)
+{
+  return __vwprintf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+}
+
+__extern_always_inline int
+vfwprintf (__FILE *__restrict __stream,
+	   __const wchar_t *__restrict __fmt, __gnuc_va_list __ap)
+{
+  return __vfwprintf_chk (__stream, __USE_FORTIFY_LEVEL - 1, __fmt, __ap);
+}
 
 #endif
 
diff --git a/wcsmbs/wchar.h b/wcsmbs/wchar.h
index b334e06231..8deaddab97 100644
--- a/wcsmbs/wchar.h
+++ b/wcsmbs/wchar.h
@@ -327,7 +327,6 @@ __END_NAMESPACE_C99
 #ifdef __USE_EXTERN_INLINES
 /* Define inline function as optimization.  */
 
-# ifndef __cplusplus
 /* We can use the BTOWC and WCTOB optimizations since we know that all
    locales must use ASCII encoding for the values in the ASCII range
    and because the wchar_t encoding is always ISO 10646.  */
@@ -342,7 +341,6 @@ __extern_inline int
 __NTH (wctob (wint_t __wc))
 { return (__builtin_constant_p (__wc) && __wc >= L'\0' && __wc <= L'\x7f'
 	  ? (int) __wc : __wctob_alias (__wc)); }
-# endif
 
 __extern_inline size_t
 __NTH (mbrlen (__const char *__restrict __s, size_t __n,
@@ -763,7 +761,7 @@ extern size_t wcsftime_l (wchar_t *__restrict __s, size_t __maxsize,
 #endif
 
 /* Define some macros helping to catch buffer overflows.  */
-#if __USE_FORTIFY_LEVEL > 0 && !defined __cplusplus
+#if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline
 # include <bits/wchar2.h>
 #endif