(__wmemcpy_chk_warn, __wmemmove_chk_warn,
authordrepper <drepper>
Wed, 26 Sep 2007 20:44:15 +0000 (20:44 +0000)
committerdrepper <drepper>
Wed, 26 Sep 2007 20:44:15 +0000 (20:44 +0000)
__wmempcpy_chk_warn, __wmemset_chk_warn, __wcsncpy_chk_warn,
__wcpncpy_chk_warn, __fgetws_chk_warn, __fgetws_unlocked_chk_warn,
__mbsrtowcs_chk_warn, __wcsrtombs_chk_warn, __mbsnrtowcs_chk_warn,
__wcsnrtombs_chk_warn): New aliases with __warnattr.
(wmemcpy, wmemmove, wmempcpy, wmemset, mbsrtowcs, wcsrtombs,
mbsnrtowcs, wcsnrtombs): Call __*_chk_warn instead of __*_chk if
compile time detectable overflow is found.
(wcsncpy, wcpncpy): Likewise.  For constant __n fix check whether
to use __*_chk or not.
(fgetws, fgetws_unlocked): Divide __bos by sizeof (wchar_t), both
in comparisons which function should be called and in __*_chk*
arguments.  Call __*_chk_warn instead of __*_chk if compile time
detectable overflow is found.
(swprintf, vswprintf): Divide __bos by sizeof (wchar_t) in
__*_chk argument.

wcsmbs/bits/wchar2.h

index e1b7c13..0c940d7 100644 (file)
@@ -29,13 +29,27 @@ extern wchar_t *__REDIRECT_NTH (__wmemcpy_alias,
                                (wchar_t *__restrict __s1,
                                 __const wchar_t *__restrict __s2, size_t __n),
                                wmemcpy);
                                (wchar_t *__restrict __s1,
                                 __const wchar_t *__restrict __s2, size_t __n),
                                wmemcpy);
+extern wchar_t *__REDIRECT_NTH (__wmemcpy_chk_warn,
+                               (wchar_t *__restrict __s1,
+                                __const wchar_t *__restrict __s2, size_t __n,
+                                size_t __ns1), __wmemcpy_chk)
+     __warnattr ("wmemcpy called with length bigger than size of destination "
+                "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (wmemcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
                size_t __n))
 {
   if (__bos0 (__s1) != (size_t) -1)
 
 __extern_always_inline wchar_t *
 __NTH (wmemcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
                size_t __n))
 {
   if (__bos0 (__s1) != (size_t) -1)
-    return __wmemcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+    {
+      if (!__builtin_constant_p (__n))
+       return __wmemcpy_chk (__s1, __s2, __n,
+                             __bos0 (__s1) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s1) / sizeof (wchar_t))
+       return __wmemcpy_chk_warn (__s1, __s2, __n,
+                                  __bos0 (__s1) / sizeof (wchar_t));
+    }
   return __wmemcpy_alias (__s1, __s2, __n);
 }
 
   return __wmemcpy_alias (__s1, __s2, __n);
 }
 
@@ -45,13 +59,27 @@ extern wchar_t *__wmemmove_chk (wchar_t *__s1, __const wchar_t *__s2,
 extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1,
                                                   __const wchar_t *__s2,
                                                   size_t __n), wmemmove);
 extern wchar_t *__REDIRECT_NTH (__wmemmove_alias, (wchar_t *__s1,
                                                   __const wchar_t *__s2,
                                                   size_t __n), wmemmove);
+extern wchar_t *__REDIRECT_NTH (__wmemmove_chk_warn,
+                               (wchar_t *__restrict __s1,
+                                __const wchar_t *__restrict __s2, size_t __n,
+                                size_t __ns1), __wmemmove_chk)
+     __warnattr ("wmemmove called with length bigger than size of destination "
+                "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (wmemmove (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
                 size_t __n))
 {
   if (__bos0 (__s1) != (size_t) -1)
 
 __extern_always_inline wchar_t *
 __NTH (wmemmove (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
                 size_t __n))
 {
   if (__bos0 (__s1) != (size_t) -1)
-    return __wmemmove_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+    {
+      if (!__builtin_constant_p (__n))
+       return __wmemmove_chk (__s1, __s2, __n,
+                              __bos0 (__s1) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s1) / sizeof (wchar_t))
+       return __wmemmove_chk_warn (__s1, __s2, __n,
+                                   __bos0 (__s1) / sizeof (wchar_t));
+    }
   return __wmemmove_alias (__s1, __s2, __n);
 }
 
   return __wmemmove_alias (__s1, __s2, __n);
 }
 
@@ -64,13 +92,27 @@ extern wchar_t *__REDIRECT_NTH (__wmempcpy_alias,
                                (wchar_t *__restrict __s1,
                                 __const wchar_t *__restrict __s2,
                                 size_t __n), wmempcpy);
                                (wchar_t *__restrict __s1,
                                 __const wchar_t *__restrict __s2,
                                 size_t __n), wmempcpy);
+extern wchar_t *__REDIRECT_NTH (__wmempcpy_chk_warn,
+                               (wchar_t *__restrict __s1,
+                                __const wchar_t *__restrict __s2, size_t __n,
+                                size_t __ns1), __wmempcpy_chk)
+     __warnattr ("wmempcpy called with length bigger than size of destination "
+                "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (wmempcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
                 size_t __n))
 {
   if (__bos0 (__s1) != (size_t) -1)
 
 __extern_always_inline wchar_t *
 __NTH (wmempcpy (wchar_t *__restrict __s1, __const wchar_t *__restrict __s2,
                 size_t __n))
 {
   if (__bos0 (__s1) != (size_t) -1)
-    return __wmempcpy_chk (__s1, __s2, __n, __bos0 (__s1) / sizeof (wchar_t));
+    {
+      if (!__builtin_constant_p (__n))
+       return __wmempcpy_chk (__s1, __s2, __n,
+                              __bos0 (__s1) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s1) / sizeof (wchar_t))
+       return __wmempcpy_chk_warn (__s1, __s2, __n,
+                                   __bos0 (__s1) / sizeof (wchar_t));
+    }
   return __wmempcpy_alias (__s1, __s2, __n);
 }
 #endif
   return __wmempcpy_alias (__s1, __s2, __n);
 }
 #endif
@@ -80,12 +122,24 @@ extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
                               size_t __ns) __THROW;
 extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c,
                                                  size_t __n), wmemset);
                               size_t __ns) __THROW;
 extern wchar_t *__REDIRECT_NTH (__wmemset_alias, (wchar_t *__s, wchar_t __c,
                                                  size_t __n), wmemset);
+extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn,
+                               (wchar_t *__s, wchar_t __c, size_t __n,
+                                size_t __ns), __wmemset_chk)
+     __warnattr ("wmemset called with length bigger than size of destination "
+                "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (wmemset (wchar_t *__restrict __s, wchar_t __c, size_t __n))
 {
   if (__bos0 (__s) != (size_t) -1)
 
 __extern_always_inline wchar_t *
 __NTH (wmemset (wchar_t *__restrict __s, wchar_t __c, size_t __n))
 {
   if (__bos0 (__s) != (size_t) -1)
-    return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
+    {
+      if (!__builtin_constant_p (__n))
+       return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t));
+
+      if (__n > __bos0 (__s) / sizeof (wchar_t))
+       return __wmemset_chk_warn (__s, __c, __n,
+                                  __bos0 (__s) / sizeof (wchar_t));
+    }
   return __wmemset_alias (__s, __c, __n);
 }
 
   return __wmemset_alias (__s, __c, __n);
 }
 
@@ -128,14 +182,25 @@ extern wchar_t *__REDIRECT_NTH (__wcsncpy_alias,
                                (wchar_t *__restrict __dest,
                                 __const wchar_t *__restrict __src,
                                 size_t __n), wcsncpy);
                                (wchar_t *__restrict __dest,
                                 __const wchar_t *__restrict __src,
                                 size_t __n), wcsncpy);
+extern wchar_t *__REDIRECT_NTH (__wcsncpy_chk_warn,
+                               (wchar_t *__restrict __dest,
+                                __const wchar_t *__restrict __src,
+                                size_t __n, size_t __destlen), __wcsncpy_chk)
+     __warnattr ("wcsncpy called with length bigger than size of destination "
+                "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (wcsncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n))
 {
 
 __extern_always_inline wchar_t *
 __NTH (wcsncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n))
 {
-  if (__bos (__dest) != (size_t) -1
-      && (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
-    return __wcsncpy_chk (__dest, __src, __n,
-                         __bos (__dest) / sizeof (wchar_t));
+  if (__bos (__dest) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n))
+       return __wcsncpy_chk (__dest, __src, __n,
+                             __bos (__dest) / sizeof (wchar_t));
+      if (__n > __bos (__dest) / sizeof (wchar_t))
+       return __wcsncpy_chk_warn (__dest, __src, __n,
+                                  __bos (__dest) / sizeof (wchar_t));
+    }
   return __wcsncpy_alias (__dest, __src, __n);
 }
 
   return __wcsncpy_alias (__dest, __src, __n);
 }
 
@@ -147,14 +212,25 @@ extern wchar_t *__REDIRECT_NTH (__wcpncpy_alias,
                                (wchar_t *__restrict __dest,
                                 __const wchar_t *__restrict __src,
                                 size_t __n), wcpncpy);
                                (wchar_t *__restrict __dest,
                                 __const wchar_t *__restrict __src,
                                 size_t __n), wcpncpy);
+extern wchar_t *__REDIRECT_NTH (__wcpncpy_chk_warn,
+                               (wchar_t *__restrict __dest,
+                                __const wchar_t *__restrict __src,
+                                size_t __n, size_t __destlen), __wcpncpy_chk)
+     __warnattr ("wcpncpy called with length bigger than size of destination "
+                "buffer");
 
 __extern_always_inline wchar_t *
 __NTH (wcpncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n))
 {
 
 __extern_always_inline wchar_t *
 __NTH (wcpncpy (wchar_t *__dest, __const wchar_t *__src, size_t __n))
 {
-  if (__bos (__dest) != (size_t) -1
-      && (!__builtin_constant_p (__n) || __bos (__dest) >= __n))
-    return __wcpncpy_chk (__dest, __src, __n,
-                         __bos (__dest) / sizeof (wchar_t));
+  if (__bos (__dest) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n))
+       return __wcpncpy_chk (__dest, __src, __n,
+                             __bos (__dest) / sizeof (wchar_t));
+      if (__n > __bos (__dest) / sizeof (wchar_t))
+       return __wcpncpy_chk_warn (__dest, __src, __n,
+                                  __bos (__dest) / sizeof (wchar_t));
+    }
   return __wcpncpy_alias (__dest, __src, __n);
 }
 
   return __wcpncpy_alias (__dest, __src, __n);
 }
 
@@ -209,7 +285,8 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
                 __const wchar_t *__restrict __fmt, ...))
 {
   if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1)
                 __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),
+    return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
+                          __bos (__s) / sizeof (wchar_t),
                           __fmt, __va_arg_pack ());
   return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
 }
                           __fmt, __va_arg_pack ());
   return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ());
 }
@@ -217,7 +294,8 @@ __NTH (swprintf (wchar_t *__restrict __s, size_t __n,
 /* XXX We might want to have support in gcc for swprintf.  */
 # define swprintf(s, n, ...) \
   (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1                       \
 /* XXX We might want to have support in gcc for swprintf.  */
 # 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_chk (s, n, __USE_FORTIFY_LEVEL - 1,                          \
+                    __bos (s) / sizeof (wchar_t), __VA_ARGS__)               \
    : swprintf (s, n, __VA_ARGS__))
 #endif
 
    : swprintf (s, n, __VA_ARGS__))
 #endif
 
@@ -237,8 +315,8 @@ __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)
                  __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_chk (__s, __n,  __USE_FORTIFY_LEVEL - 1,
+                           __bos (__s) / sizeof (wchar_t), __fmt, __ap);
   return __vswprintf_alias (__s, __n, __fmt, __ap);
 }
 
   return __vswprintf_alias (__s, __n, __fmt, __ap);
 }
 
@@ -295,13 +373,25 @@ extern wchar_t *__fgetws_chk (wchar_t *__restrict __s, size_t __size, int __n,
 extern wchar_t *__REDIRECT (__fgetws_alias,
                            (wchar_t *__restrict __s, int __n,
                             __FILE *__restrict __stream), fgetws) __wur;
 extern wchar_t *__REDIRECT (__fgetws_alias,
                            (wchar_t *__restrict __s, int __n,
                             __FILE *__restrict __stream), fgetws) __wur;
+extern wchar_t *__REDIRECT (__fgetws_chk_warn,
+                           (wchar_t *__restrict __s, size_t __size, int __n,
+                            __FILE *__restrict __stream), __fgetws_chk)
+     __wur __warnattr ("fgetws called with bigger size than length "
+                      "of destination buffer");
 
 __extern_always_inline __wur wchar_t *
 fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
 {
 
 __extern_always_inline __wur wchar_t *
 fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
 {
-  if (__bos (__s) != (size_t) -1
-      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
-    return __fgetws_chk (__s, __bos (__s), __n, __stream);
+  if (__bos (__s) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n) || __n <= 0)
+       return __fgetws_chk (__s, __bos (__s) / sizeof (wchar_t),
+                            __n, __stream);
+
+      if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
+       return __fgetws_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
+                                 __n, __stream);
+    }
   return __fgetws_alias (__s, __n, __stream);
 }
 
   return __fgetws_alias (__s, __n, __stream);
 }
 
@@ -313,13 +403,26 @@ extern wchar_t *__REDIRECT (__fgetws_unlocked_alias,
                            (wchar_t *__restrict __s, int __n,
                             __FILE *__restrict __stream), fgetws_unlocked)
   __wur;
                            (wchar_t *__restrict __s, int __n,
                             __FILE *__restrict __stream), fgetws_unlocked)
   __wur;
+extern wchar_t *__REDIRECT (__fgetws_unlocked_chk_warn,
+                           (wchar_t *__restrict __s, size_t __size, int __n,
+                            __FILE *__restrict __stream),
+                           __fgetws_unlocked_chk)
+     __wur __warnattr ("fgetws_unlocked called with bigger size than length "
+                      "of destination buffer");
 
 __extern_always_inline __wur wchar_t *
 fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
 {
 
 __extern_always_inline __wur wchar_t *
 fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream)
 {
-  if (__bos (__s) != (size_t) -1
-      && (!__builtin_constant_p (__n) || (size_t) __n > __bos (__s)))
-    return __fgetws_unlocked_chk (__s, __bos (__s), __n, __stream);
+  if (__bos (__s) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__n) || __n <= 0)
+       return __fgetws_unlocked_chk (__s, __bos (__s) / sizeof (wchar_t),
+                                     __n, __stream);
+
+      if ((size_t) __n > __bos (__s) / sizeof (wchar_t))
+       return __fgetws_unlocked_chk_warn (__s, __bos (__s) / sizeof (wchar_t),
+                                          __n, __stream);
+    }
   return __fgetws_unlocked_alias (__s, __n, __stream);
 }
 #endif
   return __fgetws_unlocked_alias (__s, __n, __stream);
 }
 #endif
@@ -356,16 +459,28 @@ extern size_t __REDIRECT_NTH (__mbsrtowcs_alias,
                               __const char **__restrict __src,
                               size_t __len, mbstate_t *__restrict __ps),
                              mbsrtowcs);
                               __const char **__restrict __src,
                               size_t __len, mbstate_t *__restrict __ps),
                              mbsrtowcs);
+extern size_t __REDIRECT_NTH (__mbsrtowcs_chk_warn,
+                             (wchar_t *__restrict __dst,
+                              __const char **__restrict __src,
+                              size_t __len, mbstate_t *__restrict __ps,
+                              size_t __dstlen), __mbsrtowcs_chk)
+     __warnattr ("mbsrtowcs called with dst buffer smaller than len "
+                "* sizeof (wchar_t)");
 
 __extern_always_inline size_t
 __NTH (mbsrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
                  size_t __len, mbstate_t *__restrict __ps))
 {
 
 __extern_always_inline size_t
 __NTH (mbsrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
                  size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len)
-         || __len > __bos (__dst) / sizeof (wchar_t)))
-    return __mbsrtowcs_chk (__dst, __src, __len, __ps,
-                           __bos (__dst) / sizeof (wchar_t));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+       return __mbsrtowcs_chk (__dst, __src, __len, __ps,
+                               __bos (__dst) / sizeof (wchar_t));
+
+      if (__len > __bos (__dst) / sizeof (wchar_t))
+       return __mbsrtowcs_chk_warn (__dst, __src, __len, __ps,
+                                    __bos (__dst) / sizeof (wchar_t));
+    }
   return __mbsrtowcs_alias (__dst, __src, __len, __ps);
 }
 
   return __mbsrtowcs_alias (__dst, __src, __len, __ps);
 }
 
@@ -379,14 +494,25 @@ extern size_t __REDIRECT_NTH (__wcsrtombs_alias,
                               __const wchar_t **__restrict __src,
                               size_t __len, mbstate_t *__restrict __ps),
                              wcsrtombs);
                               __const wchar_t **__restrict __src,
                               size_t __len, mbstate_t *__restrict __ps),
                              wcsrtombs);
+extern size_t __REDIRECT_NTH (__wcsrtombs_chk_warn,
+                             (char *__restrict __dst,
+                              __const wchar_t **__restrict __src,
+                              size_t __len, mbstate_t *__restrict __ps,
+                              size_t __dstlen), __wcsrtombs_chk)
+    __warnattr ("wcsrtombs called with dst buffer smaller than len");
 
 __extern_always_inline size_t
 __NTH (wcsrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
                  size_t __len, mbstate_t *__restrict __ps))
 {
 
 __extern_always_inline size_t
 __NTH (wcsrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
                  size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
-    return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+       return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst));
+
+      if (__len > __bos (__dst))
+       return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, __bos (__dst));
+    }
   return __wcsrtombs_alias (__dst, __src, __len, __ps);
 }
 
   return __wcsrtombs_alias (__dst, __src, __len, __ps);
 }
 
@@ -401,16 +527,28 @@ extern size_t __REDIRECT_NTH (__mbsnrtowcs_alias,
                               __const char **__restrict __src, size_t __nmc,
                               size_t __len, mbstate_t *__restrict __ps),
                              mbsnrtowcs);
                               __const char **__restrict __src, size_t __nmc,
                               size_t __len, mbstate_t *__restrict __ps),
                              mbsnrtowcs);
+extern size_t __REDIRECT_NTH (__mbsnrtowcs_chk_warn,
+                             (wchar_t *__restrict __dst,
+                              __const char **__restrict __src, size_t __nmc,
+                              size_t __len, mbstate_t *__restrict __ps,
+                              size_t __dstlen), __mbsnrtowcs_chk)
+     __warnattr ("mbsnrtowcs called with dst buffer smaller than len "
+                "* sizeof (wchar_t)");
 
 __extern_always_inline size_t
 __NTH (mbsnrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
                   size_t __nmc, size_t __len, mbstate_t *__restrict __ps))
 {
 
 __extern_always_inline size_t
 __NTH (mbsnrtowcs (wchar_t *__restrict __dst, __const char **__restrict __src,
                   size_t __nmc, size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len)
-         || __len > __bos (__dst) / sizeof (wchar_t)))
-    return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps,
-                            __bos (__dst) / sizeof (wchar_t));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+       return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps,
+                                __bos (__dst) / sizeof (wchar_t));
+
+      if (__len > __bos (__dst) / sizeof (wchar_t))
+       return __mbsnrtowcs_chk_warn (__dst, __src, __nmc, __len, __ps,
+                                     __bos (__dst) / sizeof (wchar_t));
+    }
   return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps);
 }
 
   return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps);
 }
 
@@ -425,14 +563,28 @@ extern size_t __REDIRECT_NTH (__wcsnrtombs_alias,
                               __const wchar_t **__restrict __src,
                               size_t __nwc, size_t __len,
                               mbstate_t *__restrict __ps), wcsnrtombs);
                               __const wchar_t **__restrict __src,
                               size_t __nwc, size_t __len,
                               mbstate_t *__restrict __ps), wcsnrtombs);
+extern size_t __REDIRECT_NTH (__wcsnrtombs_chk_warn,
+                             (char *__restrict __dst,
+                              __const wchar_t **__restrict __src,
+                              size_t __nwc, size_t __len,
+                              mbstate_t *__restrict __ps,
+                              size_t __dstlen), __wcsnrtombs_chk)
+     __warnattr ("wcsnrtombs called with dst buffer smaller than len");
 
 __extern_always_inline size_t
 __NTH (wcsnrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
                   size_t __nwc, size_t __len, mbstate_t *__restrict __ps))
 {
 
 __extern_always_inline size_t
 __NTH (wcsnrtombs (char *__restrict __dst, __const wchar_t **__restrict __src,
                   size_t __nwc, size_t __len, mbstate_t *__restrict __ps))
 {
-  if (__bos (__dst) != (size_t) -1
-      && (!__builtin_constant_p (__len) || __len > __bos (__dst)))
-    return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps, __bos (__dst));
+  if (__bos (__dst) != (size_t) -1)
+    {
+      if (!__builtin_constant_p (__len))
+       return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps,
+                                __bos (__dst));
+
+      if (__len > __bos (__dst))
+       return __wcsnrtombs_chk_warn (__dst, __src, __nwc, __len, __ps,
+                                     __bos (__dst));
+    }
   return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps);
 }
 #endif
   return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps);
 }
 #endif