aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2017-01-19 14:01:46 -0800
committerStan Shebs <stanshebs@google.com>2017-01-19 14:01:46 -0800
commit353f79819c75c698a29536a743c511252d2bc19b (patch)
treef4baa6463db47018df337ce101b7cafded5643ac
parente1c67173bfead6f83584f5042947591d731a06a5 (diff)
downloadglibc-353f79819c75c698a29536a743c511252d2bc19b.tar
glibc-353f79819c75c698a29536a743c511252d2bc19b.tar.gz
glibc-353f79819c75c698a29536a743c511252d2bc19b.tar.bz2
glibc-353f79819c75c698a29536a743c511252d2bc19b.zip
Fix nan functions handling of payload strings (BZ16962, CVE-2014-9761)
-rw-r--r--README.google39
-rw-r--r--include/stdlib.h18
-rw-r--r--include/wchar.h3
-rw-r--r--math/Makefile1
-rw-r--r--math/s_nan.c9
-rw-r--r--math/s_nanf.c9
-rw-r--r--math/s_nanl.c9
-rw-r--r--math/test-nan-overflow.c66
-rw-r--r--math/test-nan-payload.c122
-rw-r--r--stdlib/Makefile1
-rw-r--r--stdlib/Versions1
-rw-r--r--stdlib/strtod_l.c48
-rw-r--r--stdlib/strtod_nan.c24
-rw-r--r--stdlib/strtod_nan_double.h30
-rw-r--r--stdlib/strtod_nan_float.h29
-rw-r--r--stdlib/strtod_nan_main.c63
-rw-r--r--stdlib/strtod_nan_narrow.h22
-rw-r--r--stdlib/strtod_nan_wide.h22
-rw-r--r--stdlib/strtof_l.c11
-rw-r--r--stdlib/strtof_nan.c24
-rw-r--r--stdlib/strtold_nan.c30
-rw-r--r--sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h33
-rw-r--r--sysdeps/ieee754/ldbl-128/strtold_l.c13
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h30
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/strtold_l.c10
-rw-r--r--sysdeps/ieee754/ldbl-64-128/strtold_l.c13
-rw-r--r--sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h30
-rw-r--r--sysdeps/ieee754/ldbl-96/strtold_l.c10
-rw-r--r--wcsmbs/Makefile1
-rw-r--r--wcsmbs/wcstod_l.c3
-rw-r--r--wcsmbs/wcstod_nan.c23
-rw-r--r--wcsmbs/wcstof_l.c3
-rw-r--r--wcsmbs/wcstof_nan.c23
-rw-r--r--wcsmbs/wcstold_l.c3
-rw-r--r--wcsmbs/wcstold_nan.c30
35 files changed, 687 insertions, 119 deletions
diff --git a/README.google b/README.google
index 943deec446..0533b87ebf 100644
--- a/README.google
+++ b/README.google
@@ -662,3 +662,42 @@ ports/sysdeps/unix/sysv/linux/arm/setcontext.S
Missing unwind info in __startcontext causes infinite loop (BZ20435, CVE-2016-6323)
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=9e2ff6c9cc54c0b4402b8d49e4abe7000fde7617
(stanshebs, backport)
+
+include/stdlib.h
+include/wchar.h
+math/Makefile
+math/s_nan.c
+math/s_nanf.c
+math/s_nanl.c
+math/test-nan-overflow.c
+math/test-nan-payload.c
+stdlib/Makefile
+stdlib/Versions
+stdlib/strtod_l.c
+stdlib/strtod_nan.c
+stdlib/strtod_nan_double.h
+stdlib/strtod_nan_float.h
+stdlib/strtod_nan_main.c
+stdlib/strtod_nan_narrow.h
+stdlib/strtod_nan_wide.h
+stdlib/strtof_l.c
+stdlib/strtof_nan.c
+stdlib/strtold_nan.c
+sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
+sysdeps/ieee754/ldbl-128/strtold_l.c
+sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
+sysdeps/ieee754/ldbl-128ibm/strtold_l.c
+sysdeps/ieee754/ldbl-64-128/strtold_l.c
+sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
+sysdeps/ieee754/ldbl-96/strtold_l.c
+wcsmbs/Makefile
+wcsmbs/wcstod_l.c
+wcsmbs/wcstod_nan.c
+wcsmbs/wcstof_l.c
+wcsmbs/wcstof_nan.c
+wcsmbs/wcstold_l.c
+wcsmbs/wcstold_nan.c
+ Fix nan functions handling of payload strings (BZ16962, CVE-2014-9761)
+ https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=e02cabecf0d025ec4f4ddee290bdf7aadb873bb3
+ https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=8f5e8b01a1da2a207228f2072c934fa5918554b8
+ (stanshebs, backport)
diff --git a/include/stdlib.h b/include/stdlib.h
index e50985a5b8..647ea02525 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -203,6 +203,24 @@ libc_hidden_proto (strtoll)
libc_hidden_proto (strtoul)
libc_hidden_proto (strtoull)
+extern float __strtof_nan (const char *, char **, char) internal_function;
+extern double __strtod_nan (const char *, char **, char) internal_function;
+extern long double __strtold_nan (const char *, char **, char)
+ internal_function;
+extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t)
+ internal_function;
+extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t)
+ internal_function;
+extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t)
+ internal_function;
+
+libc_hidden_proto (__strtof_nan)
+libc_hidden_proto (__strtod_nan)
+libc_hidden_proto (__strtold_nan)
+libc_hidden_proto (__wcstof_nan)
+libc_hidden_proto (__wcstod_nan)
+libc_hidden_proto (__wcstold_nan)
+
extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt,
int *__restrict __sign);
extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt,
diff --git a/include/wchar.h b/include/wchar.h
index f927a95fdf..4997737454 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -52,6 +52,9 @@ extern unsigned long long int __wcstoull_internal (const wchar_t *
__restrict __endptr,
int __base,
int __group) __THROW;
+extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
+ wchar_t **, int, int,
+ __locale_t);
libc_hidden_proto (__wcstof_internal)
libc_hidden_proto (__wcstod_internal)
libc_hidden_proto (__wcstold_internal)
diff --git a/math/Makefile b/math/Makefile
index cc27935acd..25c4237245 100644
--- a/math/Makefile
+++ b/math/Makefile
@@ -90,6 +90,7 @@ tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \
test-misc test-fpucw test-fpucw-ieee tst-definitions test-tgmath \
test-tgmath-ret bug-nextafter bug-nexttoward bug-tgmath1 \
test-tgmath-int test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 test-snan \
+ test-nan-overflow test-nan-payload \
test-fenv-tls $(tests-static)
tests-static = test-fpucw-static test-fpucw-ieee-static
# We do the `long double' tests only if this data type is available and
diff --git a/math/s_nan.c b/math/s_nan.c
index c01085f09e..3dc9f77116 100644
--- a/math/s_nan.c
+++ b/math/s_nan.c
@@ -28,14 +28,7 @@
double
__nan (const char *tagp)
{
- if (tagp[0] != '\0')
- {
- char buf[6 + strlen (tagp)];
- sprintf (buf, "NAN(%s)", tagp);
- return strtod (buf, NULL);
- }
-
- return NAN;
+ return __strtod_nan (tagp, NULL, 0);
}
weak_alias (__nan, nan)
#ifdef NO_LONG_DOUBLE
diff --git a/math/s_nanf.c b/math/s_nanf.c
index a16fdbf7aa..103fb8cad6 100644
--- a/math/s_nanf.c
+++ b/math/s_nanf.c
@@ -28,13 +28,6 @@
float
__nanf (const char *tagp)
{
- if (tagp[0] != '\0')
- {
- char buf[6 + strlen (tagp)];
- sprintf (buf, "NAN(%s)", tagp);
- return strtof (buf, NULL);
- }
-
- return NAN;
+ return __strtof_nan (tagp, NULL, 0);
}
weak_alias (__nanf, nanf)
diff --git a/math/s_nanl.c b/math/s_nanl.c
index 3769f17bee..3ccd3bc244 100644
--- a/math/s_nanl.c
+++ b/math/s_nanl.c
@@ -28,13 +28,6 @@
long double
__nanl (const char *tagp)
{
- if (tagp[0] != '\0')
- {
- char buf[6 + strlen (tagp)];
- sprintf (buf, "NAN(%s)", tagp);
- return strtold (buf, NULL);
- }
-
- return NAN;
+ return __strtold_nan (tagp, NULL, 0);
}
weak_alias (__nanl, nanl)
diff --git a/math/test-nan-overflow.c b/math/test-nan-overflow.c
new file mode 100644
index 0000000000..f56aaf3c92
--- /dev/null
+++ b/math/test-nan-overflow.c
@@ -0,0 +1,66 @@
+/* Test nan functions stack overflow (bug 16962).
+ Copyright (C) 2015 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/>. */
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/resource.h>
+
+#define STACK_LIM 1048576
+#define STRING_SIZE (2 * STACK_LIM)
+
+static int
+do_test (void)
+{
+ int result = 0;
+ struct rlimit lim;
+ getrlimit (RLIMIT_STACK, &lim);
+ lim.rlim_cur = STACK_LIM;
+ setrlimit (RLIMIT_STACK, &lim);
+ char *nanstr = malloc (STRING_SIZE);
+ if (nanstr == NULL)
+ {
+ puts ("malloc failed, cannot test");
+ return 77;
+ }
+ memset (nanstr, '0', STRING_SIZE - 1);
+ nanstr[STRING_SIZE - 1] = 0;
+#define NAN_TEST(TYPE, FUNC) \
+ do \
+ { \
+ char *volatile p = nanstr; \
+ volatile TYPE v = FUNC (p); \
+ if (isnan (v)) \
+ puts ("PASS: " #FUNC); \
+ else \
+ { \
+ puts ("FAIL: " #FUNC); \
+ result = 1; \
+ } \
+ } \
+ while (0)
+ NAN_TEST (float, nanf);
+ NAN_TEST (double, nan);
+#ifndef NO_LONG_DOUBLE
+ NAN_TEST (long double, nanl);
+#endif
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/math/test-nan-payload.c b/math/test-nan-payload.c
new file mode 100644
index 0000000000..358ff7199e
--- /dev/null
+++ b/math/test-nan-payload.c
@@ -0,0 +1,122 @@
+/* Test nan functions payload handling (bug 16961).
+ Copyright (C) 2015 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/>. */
+
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Avoid built-in functions. */
+#define WRAP_NAN(FUNC, STR) \
+ ({ const char *volatile wns = (STR); FUNC (wns); })
+#define WRAP_STRTO(FUNC, STR) \
+ ({ const char *volatile wss = (STR); FUNC (wss, NULL); })
+
+#define CHECK_IS_NAN(TYPE, A) \
+ do \
+ { \
+ if (isnan (A)) \
+ puts ("PASS: " #TYPE " " #A); \
+ else \
+ { \
+ puts ("FAIL: " #TYPE " " #A); \
+ result = 1; \
+ } \
+ } \
+ while (0)
+
+#define CHECK_SAME_NAN(TYPE, A, B) \
+ do \
+ { \
+ if (memcmp (&(A), &(B), sizeof (A)) == 0) \
+ puts ("PASS: " #TYPE " " #A " = " #B); \
+ else \
+ { \
+ puts ("FAIL: " #TYPE " " #A " = " #B); \
+ result = 1; \
+ } \
+ } \
+ while (0)
+
+#define CHECK_DIFF_NAN(TYPE, A, B) \
+ do \
+ { \
+ if (memcmp (&(A), &(B), sizeof (A)) != 0) \
+ puts ("PASS: " #TYPE " " #A " != " #B); \
+ else \
+ { \
+ puts ("FAIL: " #TYPE " " #A " != " #B); \
+ result = 1; \
+ } \
+ } \
+ while (0)
+
+/* Cannot test payloads by memcmp for formats where NaNs have padding
+ bits. */
+#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
+
+#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG) \
+ do \
+ { \
+ TYPE n123 = WRAP_NAN (FUNC, "123"); \
+ CHECK_IS_NAN (TYPE, n123); \
+ TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)"); \
+ CHECK_IS_NAN (TYPE, s123); \
+ TYPE n456 = WRAP_NAN (FUNC, "456"); \
+ CHECK_IS_NAN (TYPE, n456); \
+ TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)"); \
+ CHECK_IS_NAN (TYPE, s456); \
+ TYPE n123x = WRAP_NAN (FUNC, "123)"); \
+ CHECK_IS_NAN (TYPE, n123x); \
+ TYPE nemp = WRAP_NAN (FUNC, ""); \
+ CHECK_IS_NAN (TYPE, nemp); \
+ TYPE semp = WRAP_STRTO (SFUNC, "NAN()"); \
+ CHECK_IS_NAN (TYPE, semp); \
+ TYPE sx = WRAP_STRTO (SFUNC, "NAN"); \
+ CHECK_IS_NAN (TYPE, sx); \
+ if (CAN_TEST_EQ (MANT_DIG)) \
+ CHECK_SAME_NAN (TYPE, n123, s123); \
+ if (CAN_TEST_EQ (MANT_DIG)) \
+ CHECK_SAME_NAN (TYPE, n456, s456); \
+ if (CAN_TEST_EQ (MANT_DIG)) \
+ CHECK_SAME_NAN (TYPE, nemp, semp); \
+ if (CAN_TEST_EQ (MANT_DIG)) \
+ CHECK_SAME_NAN (TYPE, n123x, sx); \
+ CHECK_DIFF_NAN (TYPE, n123, n456); \
+ CHECK_DIFF_NAN (TYPE, n123, nemp); \
+ CHECK_DIFF_NAN (TYPE, n123, n123x); \
+ CHECK_DIFF_NAN (TYPE, n456, nemp); \
+ CHECK_DIFF_NAN (TYPE, n456, n123x); \
+ } \
+ while (0)
+
+static int
+do_test (void)
+{
+ int result = 0;
+ RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG);
+ RUN_TESTS (double, strtod, nan, DBL_MANT_DIG);
+#ifndef NO_LONG_DOUBLE
+ RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG);
+#endif
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/stdlib/Makefile b/stdlib/Makefile
index 1be16eb8d0..c3edbb4c14 100644
--- a/stdlib/Makefile
+++ b/stdlib/Makefile
@@ -48,6 +48,7 @@ routines := \
strtol_l strtoul_l strtoll_l strtoull_l \
strtof strtod strtold \
strtof_l strtod_l strtold_l \
+ strtof_nan strtod_nan strtold_nan \
system canonicalize \
a64l l64a \
rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg \
diff --git a/stdlib/Versions b/stdlib/Versions
index f1777dfcf4..60b628d47a 100644
--- a/stdlib/Versions
+++ b/stdlib/Versions
@@ -118,5 +118,6 @@ libc {
# Used from other libraries
__libc_secure_getenv;
__call_tls_dtors;
+ __strtof_nan; __strtod_nan; __strtold_nan;
}
}
diff --git a/stdlib/strtod_l.c b/stdlib/strtod_l.c
index c80306deef..eb2b7c80b2 100644
--- a/stdlib/strtod_l.c
+++ b/stdlib/strtod_l.c
@@ -20,8 +20,6 @@
#include <xlocale.h>
extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
- int, int, __locale_t);
/* Configuration part. These macros are defined by `strtold.c',
`strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
@@ -33,27 +31,20 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
# ifdef USE_WIDE_CHAR
# define STRTOF wcstod_l
# define __STRTOF __wcstod_l
+# define STRTOF_NAN __wcstod_nan
# else
# define STRTOF strtod_l
# define __STRTOF __strtod_l
+# define STRTOF_NAN __strtod_nan
# endif
# define MPN2FLOAT __mpn_construct_double
# define FLOAT_HUGE_VAL HUGE_VAL
-# define SET_MANTISSA(flt, mant) \
- do { union ieee754_double u; \
- u.d = (flt); \
- u.ieee_nan.mantissa0 = (mant) >> 32; \
- u.ieee_nan.mantissa1 = (mant); \
- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
- (flt) = u.d; \
- } while (0)
#endif
/* End of configuration part. */
#include <ctype.h>
#include <errno.h>
#include <float.h>
-#include <ieee754.h>
#include "../locale/localeinfo.h"
#include <locale.h>
#include <math.h>
@@ -104,7 +95,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
# define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr)
# define STRNCASECMP(S1, S2, N) \
__wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc)
#else
# define STRING_TYPE char
# define CHAR_TYPE char
@@ -116,7 +106,6 @@ extern unsigned long long int ____strtoull_l_internal (const char *, char **,
# define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr)
# define STRNCASECMP(S1, S2, N) \
__strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc)
#endif
@@ -650,33 +639,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group, loc)
if (*cp == L_('('))
{
const STRING_TYPE *startp = cp;
- do
- ++cp;
- while ((*cp >= L_('0') && *cp <= L_('9'))
- || ({ CHAR_TYPE lo = TOLOWER (*cp);
- lo >= L_('a') && lo <= L_('z'); })
- || *cp == L_('_'));
-
- if (*cp != L_(')'))
- /* The closing brace is missing. Only match the NAN
- part. */
- cp = startp;
+ STRING_TYPE *endp;
+ retval = STRTOF_NAN (cp + 1, &endp, L_(')'));
+ if (*endp == L_(')'))
+ /* Consume the closing parenthesis. */
+ cp = endp + 1;
else
- {
- /* This is a system-dependent way to specify the
- bitmask used for the NaN. We expect it to be
- a number which is put in the mantissa of the
- number. */
- STRING_TYPE *endp;
- unsigned long long int mant;
-
- mant = STRTOULL (startp + 1, &endp, 0);
- if (endp == cp)
- SET_MANTISSA (retval, mant);
-
- /* Consume the closing brace. */
- ++cp;
- }
+ /* Only match the NAN part. */
+ cp = startp;
}
if (endptr != NULL)
diff --git a/stdlib/strtod_nan.c b/stdlib/strtod_nan.c
new file mode 100644
index 0000000000..2a0a89fc73
--- /dev/null
+++ b/stdlib/strtod_nan.c
@@ -0,0 +1,24 @@
+/* Convert string for NaN payload to corresponding NaN. Narrow
+ strings, double.
+ Copyright (C) 2015 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/>. */
+
+#include <strtod_nan_narrow.h>
+#include <strtod_nan_double.h>
+
+#define STRTOD_NAN __strtod_nan
+#include <strtod_nan_main.c>
diff --git a/stdlib/strtod_nan_double.h b/stdlib/strtod_nan_double.h
new file mode 100644
index 0000000000..f5bdb03e90
--- /dev/null
+++ b/stdlib/strtod_nan_double.h
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN. For double.
+ Copyright (C) 1997-2015 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/>. */
+
+#define FLOAT double
+#define SET_MANTISSA(flt, mant) \
+ do \
+ { \
+ union ieee754_double u; \
+ u.d = (flt); \
+ u.ieee_nan.mantissa0 = (mant) >> 32; \
+ u.ieee_nan.mantissa1 = (mant); \
+ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
+ (flt) = u.d; \
+ } \
+ while (0)
diff --git a/stdlib/strtod_nan_float.h b/stdlib/strtod_nan_float.h
new file mode 100644
index 0000000000..4c52de8bed
--- /dev/null
+++ b/stdlib/strtod_nan_float.h
@@ -0,0 +1,29 @@
+/* Convert string for NaN payload to corresponding NaN. For float.
+ Copyright (C) 1997-2015 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/>. */
+
+#define FLOAT float
+#define SET_MANTISSA(flt, mant) \
+ do \
+ { \
+ union ieee754_float u; \
+ u.f = (flt); \
+ u.ieee_nan.mantissa = (mant); \
+ if (u.ieee.mantissa != 0) \
+ (flt) = u.f; \
+ } \
+ while (0)
diff --git a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
new file mode 100644
index 0000000000..bc37a63a27
--- /dev/null
+++ b/stdlib/strtod_nan_main.c
@@ -0,0 +1,63 @@
+/* Convert string for NaN payload to corresponding NaN.
+ Copyright (C) 1997-2015 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/>. */
+
+#include <ieee754.h>
+#include <locale.h>
+#include <math.h>
+#include <stdlib.h>
+#include <wchar.h>
+
+
+/* If STR starts with an optional n-char-sequence as defined by ISO C
+ (a sequence of ASCII letters, digits and underscores), followed by
+ ENDC, return a NaN whose payload is set based on STR. Otherwise,
+ return a default NAN. If ENDPTR is not NULL, set *ENDPTR to point
+ to the character after the initial n-char-sequence. */
+
+internal_function
+FLOAT
+STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
+{
+ const STRING_TYPE *cp = str;
+
+ while ((*cp >= L_('0') && *cp <= L_('9'))
+ || (*cp >= L_('A') && *cp <= L_('Z'))
+ || (*cp >= L_('a') && *cp <= L_('z'))
+ || *cp == L_('_'))
+ ++cp;
+
+ FLOAT retval = NAN;
+ if (*cp != endc)
+ goto out;
+
+ /* This is a system-dependent way to specify the bitmask used for
+ the NaN. We expect it to be a number which is put in the
+ mantissa of the number. */
+ STRING_TYPE *endp;
+ unsigned long long int mant;
+
+ mant = STRTOULL (str, &endp, 0);
+ if (endp == cp)
+ SET_MANTISSA (retval, mant);
+
+ out:
+ if (endptr != NULL)
+ *endptr = (STRING_TYPE *) cp;
+ return retval;
+}
+libc_hidden_def (STRTOD_NAN)
diff --git a/stdlib/strtod_nan_narrow.h b/stdlib/strtod_nan_narrow.h
new file mode 100644
index 0000000000..bd7704529b
--- /dev/null
+++ b/stdlib/strtod_nan_narrow.h
@@ -0,0 +1,22 @@
+/* Convert string for NaN payload to corresponding NaN. Narrow strings.
+ Copyright (C) 1997-2015 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/>. */
+
+#define STRING_TYPE char
+#define L_(Ch) Ch
+#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, \
+ _nl_C_locobj_ptr)
diff --git a/stdlib/strtod_nan_wide.h b/stdlib/strtod_nan_wide.h
new file mode 100644
index 0000000000..783fbf4796
--- /dev/null
+++ b/stdlib/strtod_nan_wide.h
@@ -0,0 +1,22 @@
+/* Convert string for NaN payload to corresponding NaN. Wide strings.
+ Copyright (C) 1997-2015 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/>. */
+
+#define STRING_TYPE wchar_t
+#define L_(Ch) L##Ch
+#define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, \
+ _nl_C_locobj_ptr)
diff --git a/stdlib/strtof_l.c b/stdlib/strtof_l.c
index 63105a5d40..306132c3d6 100644
--- a/stdlib/strtof_l.c
+++ b/stdlib/strtof_l.c
@@ -20,26 +20,19 @@
#include <xlocale.h>
extern float ____strtof_l_internal (const char *, char **, int, __locale_t);
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
- int, int, __locale_t);
#define FLOAT float
#define FLT FLT
#ifdef USE_WIDE_CHAR
# define STRTOF wcstof_l
# define __STRTOF __wcstof_l
+# define STRTOF_NAN __wcstof_nan
#else
# define STRTOF strtof_l
# define __STRTOF __strtof_l
+# define STRTOF_NAN __strtof_nan
#endif
#define MPN2FLOAT __mpn_construct_float
#define FLOAT_HUGE_VAL HUGE_VALF
-#define SET_MANTISSA(flt, mant) \
- do { union ieee754_float u; \
- u.f = (flt); \
- u.ieee_nan.mantissa = (mant); \
- if (u.ieee.mantissa != 0) \
- (flt) = u.f; \
- } while (0)
#include "strtod_l.c"
diff --git a/stdlib/strtof_nan.c b/stdlib/strtof_nan.c
new file mode 100644
index 0000000000..b971310f7c
--- /dev/null
+++ b/stdlib/strtof_nan.c
@@ -0,0 +1,24 @@
+/* Convert string for NaN payload to corresponding NaN. Narrow
+ strings, float.
+ Copyright (C) 2015 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/>. */
+
+#include <strtod_nan_narrow.h>
+#include <strtod_nan_float.h>
+
+#define STRTOD_NAN __strtof_nan
+#include <strtod_nan_main.c>
diff --git a/stdlib/strtold_nan.c b/stdlib/strtold_nan.c
new file mode 100644
index 0000000000..dd43032609
--- /dev/null
+++ b/stdlib/strtold_nan.c
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN. Narrow
+ strings, long double.
+ Copyright (C) 2015 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/>. */
+
+#include <math.h>
+
+/* This function is unused if long double and double have the same
+ representation. */
+#ifndef __NO_LONG_DOUBLE_MATH
+# include <strtod_nan_narrow.h>
+# include <strtod_nan_ldouble.h>
+
+# define STRTOD_NAN __strtold_nan
+# include <strtod_nan_main.c>
+#endif
diff --git a/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
new file mode 100644
index 0000000000..e0da4e217e
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
@@ -0,0 +1,33 @@
+/* Convert string for NaN payload to corresponding NaN. For ldbl-128.
+ Copyright (C) 1997-2015 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/>. */
+
+#define FLOAT long double
+#define SET_MANTISSA(flt, mant) \
+ do \
+ { \
+ union ieee854_long_double u; \
+ u.d = (flt); \
+ u.ieee_nan.mantissa0 = 0; \
+ u.ieee_nan.mantissa1 = 0; \
+ u.ieee_nan.mantissa2 = (mant) >> 32; \
+ u.ieee_nan.mantissa3 = (mant); \
+ if ((u.ieee.mantissa0 | u.ieee.mantissa1 \
+ | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \
+ (flt) = u.d; \
+ } \
+ while (0)
diff --git a/sysdeps/ieee754/ldbl-128/strtold_l.c b/sysdeps/ieee754/ldbl-128/strtold_l.c
index b22cfe7651..d002f74f1e 100644
--- a/sysdeps/ieee754/ldbl-128/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-128/strtold_l.c
@@ -25,22 +25,13 @@
#ifdef USE_WIDE_CHAR
# define STRTOF wcstold_l
# define __STRTOF __wcstold_l
+# define STRTOF_NAN __wcstold_nan
#else
# define STRTOF strtold_l
# define __STRTOF __strtold_l
+# define STRTOF_NAN __strtold_nan
#endif
#define MPN2FLOAT __mpn_construct_long_double
#define FLOAT_HUGE_VAL HUGE_VALL
-#define SET_MANTISSA(flt, mant) \
- do { union ieee854_long_double u; \
- u.d = (flt); \
- u.ieee_nan.mantissa0 = 0; \
- u.ieee_nan.mantissa1 = 0; \
- u.ieee_nan.mantissa2 = (mant) >> 32; \
- u.ieee_nan.mantissa3 = (mant); \
- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \
- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \
- (flt) = u.d; \
- } while (0)
#include <strtod_l.c>
diff --git a/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
new file mode 100644
index 0000000000..876a4bba03
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN. For ldbl-128ibm.
+ Copyright (C) 1997-2015 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/>. */
+
+#define FLOAT long double
+#define SET_MANTISSA(flt, mant) \
+ do \
+ { \
+ union ibm_extended_long_double u; \
+ u.ld = (flt); \
+ u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \
+ u.d[0].ieee_nan.mantissa1 = (mant); \
+ if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \
+ (flt) = u.ld; \
+ } \
+ while (0)
diff --git a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
index 0830a10e33..5745d3e86c 100644
--- a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
@@ -30,25 +30,19 @@ extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
# define STRTOF __new_wcstold_l
# define __STRTOF ____new_wcstold_l
# define ____STRTOF_INTERNAL ____wcstold_l_internal
+# define STRTOF_NAN __wcstold_nan
#else
extern long double ____new_strtold_l (const char *, char **, __locale_t);
# define STRTOF __new_strtold_l
# define __STRTOF ____new_strtold_l
# define ____STRTOF_INTERNAL ____strtold_l_internal
+# define STRTOF_NAN __strtold_nan
#endif
extern __typeof (__STRTOF) STRTOF;
libc_hidden_proto (__STRTOF)
libc_hidden_proto (STRTOF)
#define MPN2FLOAT __mpn_construct_long_double
#define FLOAT_HUGE_VAL HUGE_VALL
-# define SET_MANTISSA(flt, mant) \
- do { union ibm_extended_long_double u; \
- u.ld = (flt); \
- u.d[0].ieee_nan.mantissa0 = (mant) >> 32; \
- u.d[0].ieee_nan.mantissa1 = (mant); \
- if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0) \
- (flt) = u.ld; \
- } while (0)
#include <strtod_l.c>
diff --git a/sysdeps/ieee754/ldbl-64-128/strtold_l.c b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
index dfa79e99fa..5745d3e86c 100644
--- a/sysdeps/ieee754/ldbl-64-128/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
@@ -30,28 +30,19 @@ extern long double ____new_wcstold_l (const wchar_t *, wchar_t **, __locale_t);
# define STRTOF __new_wcstold_l
# define __STRTOF ____new_wcstold_l
# define ____STRTOF_INTERNAL ____wcstold_l_internal
+# define STRTOF_NAN __wcstold_nan
#else
extern long double ____new_strtold_l (const char *, char **, __locale_t);
# define STRTOF __new_strtold_l
# define __STRTOF ____new_strtold_l
# define ____STRTOF_INTERNAL ____strtold_l_internal
+# define STRTOF_NAN __strtold_nan
#endif
extern __typeof (__STRTOF) STRTOF;
libc_hidden_proto (__STRTOF)
libc_hidden_proto (STRTOF)
#define MPN2FLOAT __mpn_construct_long_double
#define FLOAT_HUGE_VAL HUGE_VALL
-#define SET_MANTISSA(flt, mant) \
- do { union ieee854_long_double u; \
- u.d = (flt); \
- u.ieee_nan.mantissa0 = 0; \
- u.ieee_nan.mantissa1 = 0; \
- u.ieee_nan.mantissa2 = (mant) >> 32; \
- u.ieee_nan.mantissa3 = (mant); \
- if ((u.ieee.mantissa0 | u.ieee.mantissa1 \
- | u.ieee.mantissa2 | u.ieee.mantissa3) != 0) \
- (flt) = u.d; \
- } while (0)
#include <strtod_l.c>
diff --git a/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
new file mode 100644
index 0000000000..6f033594ac
--- /dev/null
+++ b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN. For ldbl-96.
+ Copyright (C) 1997-2015 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/>. */
+
+#define FLOAT long double
+#define SET_MANTISSA(flt, mant) \
+ do \
+ { \
+ union ieee854_long_double u; \
+ u.d = (flt); \
+ u.ieee_nan.mantissa0 = (mant) >> 32; \
+ u.ieee_nan.mantissa1 = (mant); \
+ if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
+ (flt) = u.d; \
+ } \
+ while (0)
diff --git a/sysdeps/ieee754/ldbl-96/strtold_l.c b/sysdeps/ieee754/ldbl-96/strtold_l.c
index 82c33e52d6..a1e911cb12 100644
--- a/sysdeps/ieee754/ldbl-96/strtold_l.c
+++ b/sysdeps/ieee754/ldbl-96/strtold_l.c
@@ -25,19 +25,13 @@
#ifdef USE_WIDE_CHAR
# define STRTOF wcstold_l
# define __STRTOF __wcstold_l
+# define STRTOF_NAN __wcstold_nan
#else
# define STRTOF strtold_l
# define __STRTOF __strtold_l
+# define STRTOF_NAN __strtold_nan
#endif
#define MPN2FLOAT __mpn_construct_long_double
#define FLOAT_HUGE_VAL HUGE_VALL
-#define SET_MANTISSA(flt, mant) \
- do { union ieee854_long_double u; \
- u.d = (flt); \
- u.ieee_nan.mantissa0 = (mant) >> 32; \
- u.ieee_nan.mantissa1 = (mant); \
- if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0) \
- (flt) = u.d; \
- } while (0)
#include <stdlib/strtod_l.c>
diff --git a/wcsmbs/Makefile b/wcsmbs/Makefile
index c139b4fd30..ee939a05fa 100644
--- a/wcsmbs/Makefile
+++ b/wcsmbs/Makefile
@@ -31,6 +31,7 @@ routines := wcscat wcschr wcscmp wcscpy wcscspn wcsdup wcslen wcsncat \
wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
wcstol_l wcstoul_l wcstoll_l wcstoull_l \
wcstod_l wcstold_l wcstof_l \
+ wcstod_nan wcstold_nan wcstof_nan \
wcscoll wcsxfrm \
wcwidth wcswidth \
wcscoll_l wcsxfrm_l \
diff --git a/wcsmbs/wcstod_l.c b/wcsmbs/wcstod_l.c
index 2f5a9159cf..8529a38794 100644
--- a/wcsmbs/wcstod_l.c
+++ b/wcsmbs/wcstod_l.c
@@ -23,9 +23,6 @@
extern double ____wcstod_l_internal (const wchar_t *, wchar_t **, int,
__locale_t);
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
- wchar_t **, int, int,
- __locale_t);
#define USE_WIDE_CHAR 1
diff --git a/wcsmbs/wcstod_nan.c b/wcsmbs/wcstod_nan.c
new file mode 100644
index 0000000000..b3dd6af835
--- /dev/null
+++ b/wcsmbs/wcstod_nan.c
@@ -0,0 +1,23 @@
+/* Convert string for NaN payload to corresponding NaN. Wide strings, double.
+ Copyright (C) 2015 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/>. */
+
+#include "../stdlib/strtod_nan_wide.h"
+#include "../stdlib/strtod_nan_double.h"
+
+#define STRTOD_NAN __wcstod_nan
+#include "../stdlib/strtod_nan_main.c"
diff --git a/wcsmbs/wcstof_l.c b/wcsmbs/wcstof_l.c
index b90c9f1dc7..d46b862f60 100644
--- a/wcsmbs/wcstof_l.c
+++ b/wcsmbs/wcstof_l.c
@@ -25,8 +25,5 @@
extern float ____wcstof_l_internal (const wchar_t *, wchar_t **, int,
__locale_t);
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
- wchar_t **, int, int,
- __locale_t);
#include <stdlib/strtof_l.c>
diff --git a/wcsmbs/wcstof_nan.c b/wcsmbs/wcstof_nan.c
new file mode 100644
index 0000000000..c5f667a8e5
--- /dev/null
+++ b/wcsmbs/wcstof_nan.c
@@ -0,0 +1,23 @@
+/* Convert string for NaN payload to corresponding NaN. Wide strings, float.
+ Copyright (C) 2015 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/>. */
+
+#include "../stdlib/strtod_nan_wide.h"
+#include "../stdlib/strtod_nan_float.h"
+
+#define STRTOD_NAN __wcstof_nan
+#include "../stdlib/strtod_nan_main.c"
diff --git a/wcsmbs/wcstold_l.c b/wcsmbs/wcstold_l.c
index c18264c1c1..35088fc599 100644
--- a/wcsmbs/wcstold_l.c
+++ b/wcsmbs/wcstold_l.c
@@ -24,8 +24,5 @@
extern long double ____wcstold_l_internal (const wchar_t *, wchar_t **, int,
__locale_t);
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
- wchar_t **, int, int,
- __locale_t);
#include <strtold_l.c>
diff --git a/wcsmbs/wcstold_nan.c b/wcsmbs/wcstold_nan.c
new file mode 100644
index 0000000000..ef905d3c2c
--- /dev/null
+++ b/wcsmbs/wcstold_nan.c
@@ -0,0 +1,30 @@
+/* Convert string for NaN payload to corresponding NaN. Wide strings,
+ long double.
+ Copyright (C) 2015 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/>. */
+
+#include <math.h>
+
+/* This function is unused if long double and double have the same
+ representation. */
+#ifndef __NO_LONG_DOUBLE_MATH
+# include "../stdlib/strtod_nan_wide.h"
+# include <strtod_nan_ldouble.h>
+
+# define STRTOD_NAN __wcstold_nan
+# include "../stdlib/strtod_nan_main.c"
+#endif