8ae002
From 8f5e8b01a1da2a207228f2072c934fa5918554b8 Mon Sep 17 00:00:00 2001
8ae002
From: Joseph Myers <joseph@codesourcery.com>
8ae002
Date: Fri, 4 Dec 2015 20:36:28 +0000
8ae002
Subject: [PATCH] Fix nan functions handling of payload strings (bug 16961, bug
8ae002
 16962).
8ae002
8ae002
The nan, nanf and nanl functions handle payload strings by doing e.g.:
8ae002
8ae002
  if (tagp[0] != '\0')
8ae002
    {
8ae002
      char buf[6 + strlen (tagp)];
8ae002
      sprintf (buf, "NAN(%s)", tagp);
8ae002
      return strtod (buf, NULL);
8ae002
    }
8ae002
8ae002
This is an unbounded stack allocation based on the length of the
8ae002
argument.  Furthermore, if the argument starts with an n-char-sequence
8ae002
followed by ')', that n-char-sequence is wrongly treated as
8ae002
significant for determining the payload of the resulting NaN, when ISO
8ae002
C says the call should be equivalent to strtod ("NAN", NULL), without
8ae002
being affected by that initial n-char-sequence.  This patch fixes both
8ae002
those problems by using the __strtod_nan etc. functions recently
8ae002
factored out of strtod etc. for that purpose, with those functions
8ae002
being exported from libc at version GLIBC_PRIVATE.
8ae002
8ae002
Tested for x86_64, x86, mips64 and powerpc.
8ae002
8ae002
	[BZ #16961]
8ae002
	[BZ #16962]
8ae002
	* math/s_nan.c (__nan): Use __strtod_nan instead of constructing a
8ae002
	string on the stack for strtod.
8ae002
	* math/s_nanf.c (__nanf): Use __strtof_nan instead of constructing
8ae002
	a string on the stack for strtof.
8ae002
	* math/s_nanl.c (__nanl): Use __strtold_nan instead of
8ae002
	constructing a string on the stack for strtold.
8ae002
	* stdlib/Versions (libc): Add __strtof_nan, __strtod_nan and
8ae002
	__strtold_nan to GLIBC_PRIVATE.
8ae002
	* math/test-nan-overflow.c: New file.
8ae002
	* math/test-nan-payload.c: Likewise.
8ae002
	* math/Makefile (tests): Add test-nan-overflow and
8ae002
	test-nan-payload.
8ae002
8ae002
From e02cabecf0d025ec4f4ddee290bdf7aadb873bb3 Mon Sep 17 00:00:00 2001
8ae002
From: Joseph Myers <joseph@codesourcery.com>
8ae002
Date: Tue, 24 Nov 2015 22:24:52 +0000
8ae002
Subject: [PATCH] Refactor strtod parsing of NaN payloads.
8ae002
8ae002
The nan* functions handle their string argument by constructing a
8ae002
NAN(...) string on the stack as a VLA and passing it to strtod
8ae002
functions.
8ae002
8ae002
This approach has problems discussed in bug 16961 and bug 16962: the
8ae002
stack usage is unbounded, and it gives incorrect results in certain
8ae002
cases where the argument is not a valid n-char-sequence.
8ae002
8ae002
The natural fix for both issues is to refactor the NaN payload parsing
8ae002
out of strtod into a separate function that the nan* functions can
8ae002
call directly, so that no temporary string needs constructing on the
8ae002
stack at all.  This patch does that refactoring in preparation for
8ae002
fixing those bugs (but without actually using the new functions from
8ae002
nan* - which will also require exporting them from libc at version
8ae002
GLIBC_PRIVATE).  This patch is not intended to change any user-visible
8ae002
behavior, so no tests are added (fixes for the above bugs will of
8ae002
course add tests for them).
8ae002
8ae002
This patch builds on my recent fixes for strtol and strtod issues in
8ae002
Turkish locales.  Given those fixes, the parsing of NaN payloads is
8ae002
locale-independent; thus, the new functions do not need to take a
8ae002
locale_t argument.
8ae002
8ae002
Tested for x86_64, x86, mips64 and powerpc.
8ae002
8ae002
	* stdlib/strtod_nan.c: New file.
8ae002
	* stdlib/strtod_nan_double.h: Likewise.
8ae002
	* stdlib/strtod_nan_float.h: Likewise.
8ae002
	* stdlib/strtod_nan_main.c: Likewise.
8ae002
	* stdlib/strtod_nan_narrow.h: Likewise.
8ae002
	* stdlib/strtod_nan_wide.h: Likewise.
8ae002
	* stdlib/strtof_nan.c: Likewise.
8ae002
	* stdlib/strtold_nan.c: Likewise.
8ae002
	* sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise.
8ae002
	* sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise.
8ae002
	* sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise.
8ae002
	* wcsmbs/wcstod_nan.c: Likewise.
8ae002
	* wcsmbs/wcstof_nan.c: Likewise.
8ae002
	* wcsmbs/wcstold_nan.c: Likewise.
8ae002
	* stdlib/Makefile (routines): Add strtof_nan, strtod_nan and
8ae002
	strtold_nan.
8ae002
	* wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and
8ae002
	wcstof_nan.
8ae002
	* include/stdlib.h (__strtof_nan): Declare and use
8ae002
	libc_hidden_proto.
8ae002
	(__strtod_nan): Likewise.
8ae002
	(__strtold_nan): Likewise.
8ae002
	(__wcstof_nan): Likewise.
8ae002
	(__wcstod_nan): Likewise.
8ae002
	(__wcstold_nan): Likewise.
8ae002
	* include/wchar.h (____wcstoull_l_internal): Declare.
8ae002
	* stdlib/strtod_l.c: Do not include <ieee754.h>.
8ae002
	(____strtoull_l_internal): Remove declaration.
8ae002
	(STRTOF_NAN): Define macro.
8ae002
	(SET_MANTISSA): Remove macro.
8ae002
	(STRTOULL): Likewise.
8ae002
	(____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload.
8ae002
	* stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration.
8ae002
	(STRTOF_NAN): Define macro.
8ae002
	(SET_MANTISSA): Remove macro.
8ae002
	* sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro.
8ae002
	(SET_MANTISSA): Remove macro.
8ae002
	* sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define
8ae002
	macro.
8ae002
	(SET_MANTISSA): Remove macro.
8ae002
	* sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define
8ae002
	macro.
8ae002
	(SET_MANTISSA): Remove macro.
8ae002
	* sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro.
8ae002
	(SET_MANTISSA): Remove macro.
8ae002
	* wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration.
8ae002
	* wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise.
8ae002
	* wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise.
8ae002
8ae002
diff -rupN a/include/stdlib.h b/include/stdlib.h
8ae002
--- a/include/stdlib.h	2017-03-02 16:34:01.000000000 -0500
8ae002
+++ b/include/stdlib.h	2017-03-02 16:45:05.457639119 -0500
8ae002
@@ -193,6 +193,24 @@ libc_hidden_proto (strtoll)
8ae002
 libc_hidden_proto (strtoul)
8ae002
 libc_hidden_proto (strtoull)
8ae002
 
8ae002
+extern float __strtof_nan (const char *, char **, char) internal_function;
8ae002
+extern double __strtod_nan (const char *, char **, char) internal_function;
8ae002
+extern long double __strtold_nan (const char *, char **, char)
8ae002
+     internal_function;
8ae002
+extern float __wcstof_nan (const wchar_t *, wchar_t **, wchar_t)
8ae002
+     internal_function;
8ae002
+extern double __wcstod_nan (const wchar_t *, wchar_t **, wchar_t)
8ae002
+     internal_function;
8ae002
+extern long double __wcstold_nan (const wchar_t *, wchar_t **, wchar_t)
8ae002
+     internal_function;
8ae002
+
8ae002
+libc_hidden_proto (__strtof_nan)
8ae002
+libc_hidden_proto (__strtod_nan)
8ae002
+libc_hidden_proto (__strtold_nan)
8ae002
+libc_hidden_proto (__wcstof_nan)
8ae002
+libc_hidden_proto (__wcstod_nan)
8ae002
+libc_hidden_proto (__wcstold_nan)
8ae002
+
8ae002
 extern char *__ecvt (double __value, int __ndigit, int *__restrict __decpt,
8ae002
 		     int *__restrict __sign);
8ae002
 extern char *__fcvt (double __value, int __ndigit, int *__restrict __decpt,
8ae002
diff -rupN a/include/wchar.h b/include/wchar.h
8ae002
--- a/include/wchar.h	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/include/wchar.h	2017-03-02 16:45:05.461639109 -0500
8ae002
@@ -52,6 +52,9 @@ extern unsigned long long int __wcstoull
8ae002
 						   __restrict __endptr,
8ae002
 						   int __base,
8ae002
 						   int __group) __THROW;
8ae002
+extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
8ae002
+						       wchar_t **, int, int,
8ae002
+						       __locale_t);
8ae002
 libc_hidden_proto (__wcstof_internal)
8ae002
 libc_hidden_proto (__wcstod_internal)
8ae002
 libc_hidden_proto (__wcstold_internal)
8ae002
diff -rupN a/math/Makefile b/math/Makefile
8ae002
--- a/math/Makefile	2017-03-02 16:34:02.000000000 -0500
8ae002
+++ b/math/Makefile	2017-03-02 16:44:30.659725844 -0500
8ae002
@@ -88,7 +88,8 @@ long-c-yes = $(calls:=l)
8ae002
 tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \
8ae002
 	test-misc test-fpucw tst-definitions test-tgmath test-tgmath-ret \
8ae002
 	bug-nextafter bug-nexttoward bug-tgmath1 test-tgmath-int \
8ae002
-	test-tgmath2 test-powl tst-CMPLX tst-CMPLX2
8ae002
+	test-tgmath2 test-powl tst-CMPLX tst-CMPLX2 \
8ae002
+	test-nan-overflow test-nan-payload
8ae002
 # We do the `long double' tests only if this data type is available and
8ae002
 # distinct from `double'.
8ae002
 test-longdouble-yes = test-ldouble test-ildoubl
8ae002
diff -rupN a/math/s_nan.c b/math/s_nan.c
8ae002
--- a/math/s_nan.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/math/s_nan.c	2017-03-02 16:43:01.680999065 -0500
8ae002
@@ -28,14 +28,7 @@
8ae002
 double
8ae002
 __nan (const char *tagp)
8ae002
 {
8ae002
-  if (tagp[0] != '\0')
8ae002
-    {
8ae002
-      char buf[6 + strlen (tagp)];
8ae002
-      sprintf (buf, "NAN(%s)", tagp);
8ae002
-      return strtod (buf, NULL);
8ae002
-    }
8ae002
-
8ae002
-  return NAN;
8ae002
+  return __strtod_nan (tagp, NULL, 0);
8ae002
 }
8ae002
 weak_alias (__nan, nan)
8ae002
 #ifdef NO_LONG_DOUBLE
8ae002
diff -rupN a/math/s_nanf.c b/math/s_nanf.c
8ae002
--- a/math/s_nanf.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/math/s_nanf.c	2017-03-02 16:43:01.683999054 -0500
8ae002
@@ -28,13 +28,6 @@
8ae002
 float
8ae002
 __nanf (const char *tagp)
8ae002
 {
8ae002
-  if (tagp[0] != '\0')
8ae002
-    {
8ae002
-      char buf[6 + strlen (tagp)];
8ae002
-      sprintf (buf, "NAN(%s)", tagp);
8ae002
-      return strtof (buf, NULL);
8ae002
-    }
8ae002
-
8ae002
-  return NAN;
8ae002
+  return __strtof_nan (tagp, NULL, 0);
8ae002
 }
8ae002
 weak_alias (__nanf, nanf)
8ae002
diff -rupN a/math/s_nanl.c b/math/s_nanl.c
8ae002
--- a/math/s_nanl.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/math/s_nanl.c	2017-03-02 16:43:01.686999044 -0500
8ae002
@@ -28,13 +28,6 @@
8ae002
 long double
8ae002
 __nanl (const char *tagp)
8ae002
 {
8ae002
-  if (tagp[0] != '\0')
8ae002
-    {
8ae002
-      char buf[6 + strlen (tagp)];
8ae002
-      sprintf (buf, "NAN(%s)", tagp);
8ae002
-      return strtold (buf, NULL);
8ae002
-    }
8ae002
-
8ae002
-  return NAN;
8ae002
+  return __strtold_nan (tagp, NULL, 0);
8ae002
 }
8ae002
 weak_alias (__nanl, nanl)
8ae002
diff -rupN a/math/test-nan-overflow.c b/math/test-nan-overflow.c
8ae002
--- a/math/test-nan-overflow.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/math/test-nan-overflow.c	2017-03-02 16:43:01.689999033 -0500
8ae002
@@ -0,0 +1,66 @@
8ae002
+/* Test nan functions stack overflow (bug 16962).
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include <math.h>
8ae002
+#include <stdio.h>
8ae002
+#include <string.h>
8ae002
+#include <sys/resource.h>
8ae002
+
8ae002
+#define STACK_LIM 1048576
8ae002
+#define STRING_SIZE (2 * STACK_LIM)
8ae002
+
8ae002
+static int
8ae002
+do_test (void)
8ae002
+{
8ae002
+  int result = 0;
8ae002
+  struct rlimit lim;
8ae002
+  getrlimit (RLIMIT_STACK, &lim);
8ae002
+  lim.rlim_cur = STACK_LIM;
8ae002
+  setrlimit (RLIMIT_STACK, &lim);
8ae002
+  char *nanstr = malloc (STRING_SIZE);
8ae002
+  if (nanstr == NULL)
8ae002
+    {
8ae002
+      puts ("malloc failed, cannot test");
8ae002
+      return 77;
8ae002
+    }
8ae002
+  memset (nanstr, '0', STRING_SIZE - 1);
8ae002
+  nanstr[STRING_SIZE - 1] = 0;
8ae002
+#define NAN_TEST(TYPE, FUNC)			\
8ae002
+  do						\
8ae002
+    {						\
8ae002
+      char *volatile p = nanstr;		\
8ae002
+      volatile TYPE v = FUNC (p);		\
8ae002
+      if (isnan (v))				\
8ae002
+	puts ("PASS: " #FUNC);			\
8ae002
+      else					\
8ae002
+	{					\
8ae002
+	  puts ("FAIL: " #FUNC);		\
8ae002
+	  result = 1;				\
8ae002
+	}					\
8ae002
+    }						\
8ae002
+  while (0)
8ae002
+  NAN_TEST (float, nanf);
8ae002
+  NAN_TEST (double, nan);
8ae002
+#ifndef NO_LONG_DOUBLE
8ae002
+  NAN_TEST (long double, nanl);
8ae002
+#endif
8ae002
+  return result;
8ae002
+}
8ae002
+
8ae002
+#define TEST_FUNCTION do_test ()
8ae002
+#include "../test-skeleton.c"
8ae002
diff -rupN a/math/test-nan-payload.c b/math/test-nan-payload.c
8ae002
--- a/math/test-nan-payload.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/math/test-nan-payload.c	2017-03-02 16:43:01.693999019 -0500
8ae002
@@ -0,0 +1,122 @@
8ae002
+/* Test nan functions payload handling (bug 16961).
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include <float.h>
8ae002
+#include <math.h>
8ae002
+#include <stdio.h>
8ae002
+#include <stdlib.h>
8ae002
+#include <string.h>
8ae002
+
8ae002
+/* Avoid built-in functions.  */
8ae002
+#define WRAP_NAN(FUNC, STR) \
8ae002
+  ({ const char *volatile wns = (STR); FUNC (wns); })
8ae002
+#define WRAP_STRTO(FUNC, STR) \
8ae002
+  ({ const char *volatile wss = (STR); FUNC (wss, NULL); })
8ae002
+
8ae002
+#define CHECK_IS_NAN(TYPE, A)			\
8ae002
+  do						\
8ae002
+    {						\
8ae002
+      if (isnan (A))				\
8ae002
+	puts ("PASS: " #TYPE " " #A);		\
8ae002
+      else					\
8ae002
+	{					\
8ae002
+	  puts ("FAIL: " #TYPE " " #A);		\
8ae002
+	  result = 1;				\
8ae002
+	}					\
8ae002
+    }						\
8ae002
+  while (0)
8ae002
+
8ae002
+#define CHECK_SAME_NAN(TYPE, A, B)			\
8ae002
+  do							\
8ae002
+    {							\
8ae002
+      if (memcmp (&(A), &(B), sizeof (A)) == 0)		\
8ae002
+	puts ("PASS: " #TYPE " " #A " = " #B);		\
8ae002
+      else						\
8ae002
+	{						\
8ae002
+	  puts ("FAIL: " #TYPE " " #A " = " #B);	\
8ae002
+	  result = 1;					\
8ae002
+	}						\
8ae002
+    }							\
8ae002
+  while (0)
8ae002
+
8ae002
+#define CHECK_DIFF_NAN(TYPE, A, B)			\
8ae002
+  do							\
8ae002
+    {							\
8ae002
+      if (memcmp (&(A), &(B), sizeof (A)) != 0)		\
8ae002
+	puts ("PASS: " #TYPE " " #A " != " #B);		\
8ae002
+      else						\
8ae002
+	{						\
8ae002
+	  puts ("FAIL: " #TYPE " " #A " != " #B);	\
8ae002
+	  result = 1;					\
8ae002
+	}						\
8ae002
+    }							\
8ae002
+  while (0)
8ae002
+
8ae002
+/* Cannot test payloads by memcmp for formats where NaNs have padding
8ae002
+   bits.  */
8ae002
+#define CAN_TEST_EQ(MANT_DIG) ((MANT_DIG) != 64 && (MANT_DIG) != 106)
8ae002
+
8ae002
+#define RUN_TESTS(TYPE, SFUNC, FUNC, MANT_DIG)		\
8ae002
+  do							\
8ae002
+    {							\
8ae002
+     TYPE n123 = WRAP_NAN (FUNC, "123");		\
8ae002
+     CHECK_IS_NAN (TYPE, n123);				\
8ae002
+     TYPE s123 = WRAP_STRTO (SFUNC, "NAN(123)");	\
8ae002
+     CHECK_IS_NAN (TYPE, s123);				\
8ae002
+     TYPE n456 = WRAP_NAN (FUNC, "456");		\
8ae002
+     CHECK_IS_NAN (TYPE, n456);				\
8ae002
+     TYPE s456 = WRAP_STRTO (SFUNC, "NAN(456)");	\
8ae002
+     CHECK_IS_NAN (TYPE, s456);				\
8ae002
+     TYPE n123x = WRAP_NAN (FUNC, "123)");		\
8ae002
+     CHECK_IS_NAN (TYPE, n123x);			\
8ae002
+     TYPE nemp = WRAP_NAN (FUNC, "");			\
8ae002
+     CHECK_IS_NAN (TYPE, nemp);				\
8ae002
+     TYPE semp = WRAP_STRTO (SFUNC, "NAN()");		\
8ae002
+     CHECK_IS_NAN (TYPE, semp);				\
8ae002
+     TYPE sx = WRAP_STRTO (SFUNC, "NAN");		\
8ae002
+     CHECK_IS_NAN (TYPE, sx);				\
8ae002
+     if (CAN_TEST_EQ (MANT_DIG))			\
8ae002
+       CHECK_SAME_NAN (TYPE, n123, s123);		\
8ae002
+     if (CAN_TEST_EQ (MANT_DIG))			\
8ae002
+       CHECK_SAME_NAN (TYPE, n456, s456);		\
8ae002
+     if (CAN_TEST_EQ (MANT_DIG))			\
8ae002
+       CHECK_SAME_NAN (TYPE, nemp, semp);		\
8ae002
+     if (CAN_TEST_EQ (MANT_DIG))			\
8ae002
+       CHECK_SAME_NAN (TYPE, n123x, sx);		\
8ae002
+     CHECK_DIFF_NAN (TYPE, n123, n456);			\
8ae002
+     CHECK_DIFF_NAN (TYPE, n123, nemp);			\
8ae002
+     CHECK_DIFF_NAN (TYPE, n123, n123x);		\
8ae002
+     CHECK_DIFF_NAN (TYPE, n456, nemp);			\
8ae002
+     CHECK_DIFF_NAN (TYPE, n456, n123x);		\
8ae002
+    }							\
8ae002
+  while (0)
8ae002
+
8ae002
+static int
8ae002
+do_test (void)
8ae002
+{
8ae002
+  int result = 0;
8ae002
+  RUN_TESTS (float, strtof, nanf, FLT_MANT_DIG);
8ae002
+  RUN_TESTS (double, strtod, nan, DBL_MANT_DIG);
8ae002
+#ifndef NO_LONG_DOUBLE
8ae002
+  RUN_TESTS (long double, strtold, nanl, LDBL_MANT_DIG);
8ae002
+#endif
8ae002
+  return result;
8ae002
+}
8ae002
+
8ae002
+#define TEST_FUNCTION do_test ()
8ae002
+#include "../test-skeleton.c"
8ae002
diff -rupN a/stdlib/Makefile b/stdlib/Makefile
8ae002
--- a/stdlib/Makefile	2017-03-02 16:34:02.000000000 -0500
8ae002
+++ b/stdlib/Makefile	2017-03-02 16:45:05.463639105 -0500
8ae002
@@ -47,6 +47,7 @@ routines	:=							      \
8ae002
 	strtol_l strtoul_l strtoll_l strtoull_l				      \
8ae002
 	strtof strtod strtold						      \
8ae002
 	strtof_l strtod_l strtold_l					      \
8ae002
+	strtof_nan strtod_nan strtold_nan				      \
8ae002
 	system canonicalize						      \
8ae002
 	a64l l64a							      \
8ae002
 	rpmatch strfmon strfmon_l getsubopt xpg_basename fmtmsg		      \
8ae002
diff -rupN a/stdlib/Versions b/stdlib/Versions
8ae002
--- a/stdlib/Versions	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/stdlib/Versions	2017-03-02 16:44:52.140671064 -0500
8ae002
@@ -114,5 +114,6 @@ libc {
8ae002
     __abort_msg;
8ae002
     # Used from other libraries
8ae002
     __libc_secure_getenv;
8ae002
+    __strtof_nan; __strtod_nan; __strtold_nan;
8ae002
   }
8ae002
 }
8ae002
diff -rupN a/stdlib/strtod_l.c b/stdlib/strtod_l.c
8ae002
--- a/stdlib/strtod_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/stdlib/strtod_l.c	2017-03-02 16:59:50.224590342 -0500
8ae002
@@ -20,8 +20,6 @@
8ae002
 #include <xlocale.h>
8ae002
 
8ae002
 extern double ____strtod_l_internal (const char *, char **, int, __locale_t);
8ae002
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
8ae002
-						       int, int, __locale_t);
8ae002
 
8ae002
 /* Configuration part.  These macros are defined by `strtold.c',
8ae002
    `strtof.c', `wcstod.c', `wcstold.c', and `wcstof.c' to produce the
8ae002
@@ -33,28 +31,20 @@ extern unsigned long long int ____strtou
8ae002
 # ifdef USE_WIDE_CHAR
8ae002
 #  define STRTOF	wcstod_l
8ae002
 #  define __STRTOF	__wcstod_l
8ae002
+#  define STRTOF_NAN	__wcstod_nan
8ae002
 # else
8ae002
 #  define STRTOF	strtod_l
8ae002
 #  define __STRTOF	__strtod_l
8ae002
+#  define STRTOF_NAN	__strtod_nan
8ae002
 # endif
8ae002
 # define MPN2FLOAT	__mpn_construct_double
8ae002
 # define FLOAT_HUGE_VAL	HUGE_VAL
8ae002
-# define SET_MANTISSA(flt, mant) \
8ae002
-  do { union ieee754_double u;						      \
8ae002
-       u.d = (flt);							      \
8ae002
-       if ((mant & 0xfffffffffffffULL) == 0)				      \
8ae002
-	 mant = 0x8000000000000ULL;					      \
8ae002
-       u.ieee.mantissa0 = ((mant) >> 32) & 0xfffff;			      \
8ae002
-       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
8ae002
-       (flt) = u.d;							      \
8ae002
-  } while (0)
8ae002
 #endif
8ae002
 /* End of configuration part.  */
8ae002
 
8ae002
 #include <ctype.h>
8ae002
 #include <errno.h>
8ae002
 #include <float.h>
8ae002
-#include <ieee754.h>
8ae002
 #include "../locale/localeinfo.h"
8ae002
 #include <locale.h>
8ae002
 #include <math.h>
8ae002
@@ -105,7 +95,6 @@ extern unsigned long long int ____strtou
8ae002
 # define TOLOWER_C(Ch) __towlower_l ((Ch), _nl_C_locobj_ptr)
8ae002
 # define STRNCASECMP(S1, S2, N) \
8ae002
   __wcsncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
8ae002
-# define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0, loc)
8ae002
 #else
8ae002
 # define STRING_TYPE char
8ae002
 # define CHAR_TYPE char
8ae002
@@ -117,7 +106,6 @@ extern unsigned long long int ____strtou
8ae002
 # define TOLOWER_C(Ch) __tolower_l ((Ch), _nl_C_locobj_ptr)
8ae002
 # define STRNCASECMP(S1, S2, N) \
8ae002
   __strncasecmp_l ((S1), (S2), (N), _nl_C_locobj_ptr)
8ae002
-# define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0, loc)
8ae002
 #endif
8ae002
 
8ae002
 
8ae002
@@ -649,33 +637,14 @@ ____STRTOF_INTERNAL (nptr, endptr, group
8ae002
 	  if (*cp == L_('('))
8ae002
 	    {
8ae002
 	      const STRING_TYPE *startp = cp;
8ae002
-	      do
8ae002
-		++cp;
8ae002
-	      while ((*cp >= L_('0') && *cp <= L_('9'))
8ae002
-		     || ({ CHAR_TYPE lo = TOLOWER (*cp);
8ae002
-			   lo >= L_('a') && lo <= L_('z'); })
8ae002
-		     || *cp == L_('_'));
8ae002
-
8ae002
-	      if (*cp != L_(')'))
8ae002
-		/* The closing brace is missing.  Only match the NAN
8ae002
-		   part.  */
8ae002
-		cp = startp;
8ae002
+	      STRING_TYPE *endp;
8ae002
+	      retval = STRTOF_NAN (cp + 1, &endp, L_(')'));
8ae002
+	      if (*endp == L_(')'))
8ae002
+		/* Consume the closing parenthesis.  */
8ae002
+		cp = endp + 1;
8ae002
 	      else
8ae002
-		{
8ae002
-		  /* This is a system-dependent way to specify the
8ae002
-		     bitmask used for the NaN.  We expect it to be
8ae002
-		     a number which is put in the mantissa of the
8ae002
-		     number.  */
8ae002
-		  STRING_TYPE *endp;
8ae002
-		  unsigned long long int mant;
8ae002
-
8ae002
-		  mant = STRTOULL (startp + 1, &endp, 0);
8ae002
-		  if (endp == cp)
8ae002
-		    SET_MANTISSA (retval, mant);
8ae002
-
8ae002
-		  /* Consume the closing brace.  */
8ae002
-		  ++cp;
8ae002
-		}
8ae002
+		/* Only match the NAN part.  */
8ae002
+		cp = startp;
8ae002
 	    }
8ae002
 
8ae002
 	  if (endptr != NULL)
8ae002
diff -rupN a/stdlib/strtod_nan.c b/stdlib/strtod_nan.c
8ae002
--- a/stdlib/strtod_nan.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtod_nan.c	2017-03-02 16:45:05.473639081 -0500
8ae002
@@ -0,0 +1,24 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Narrow
8ae002
+   strings, double.
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include <strtod_nan_narrow.h>
8ae002
+#include <strtod_nan_double.h>
8ae002
+
8ae002
+#define STRTOD_NAN __strtod_nan
8ae002
+#include <strtod_nan_main.c>
8ae002
diff -rupN a/stdlib/strtod_nan_double.h b/stdlib/strtod_nan_double.h
8ae002
--- a/stdlib/strtod_nan_double.h	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtod_nan_double.h	2017-03-02 16:45:05.477639072 -0500
8ae002
@@ -0,0 +1,30 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  For double.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#define FLOAT		double
8ae002
+#define SET_MANTISSA(flt, mant)				\
8ae002
+  do							\
8ae002
+    {							\
8ae002
+      union ieee754_double u;				\
8ae002
+      u.d = (flt);					\
8ae002
+      u.ieee_nan.mantissa0 = (mant) >> 32;		\
8ae002
+      u.ieee_nan.mantissa1 = (mant);			\
8ae002
+      if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)	\
8ae002
+	(flt) = u.d;					\
8ae002
+    }							\
8ae002
+  while (0)
8ae002
diff -rupN a/stdlib/strtod_nan_float.h b/stdlib/strtod_nan_float.h
8ae002
--- a/stdlib/strtod_nan_float.h	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtod_nan_float.h	2017-03-02 16:45:05.480639065 -0500
8ae002
@@ -0,0 +1,29 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  For float.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#define	FLOAT		float
8ae002
+#define SET_MANTISSA(flt, mant)			\
8ae002
+  do						\
8ae002
+    {						\
8ae002
+      union ieee754_float u;			\
8ae002
+      u.f = (flt);				\
8ae002
+      u.ieee_nan.mantissa = (mant);		\
8ae002
+      if (u.ieee.mantissa != 0)			\
8ae002
+	(flt) = u.f;				\
8ae002
+    }						\
8ae002
+  while (0)
8ae002
diff -rupN a/stdlib/strtod_nan_main.c b/stdlib/strtod_nan_main.c
8ae002
--- a/stdlib/strtod_nan_main.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtod_nan_main.c	2017-03-02 16:45:05.483639058 -0500
8ae002
@@ -0,0 +1,63 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include <ieee754.h>
8ae002
+#include <locale.h>
8ae002
+#include <math.h>
8ae002
+#include <stdlib.h>
8ae002
+#include <wchar.h>
8ae002
+
8ae002
+
8ae002
+/* If STR starts with an optional n-char-sequence as defined by ISO C
8ae002
+   (a sequence of ASCII letters, digits and underscores), followed by
8ae002
+   ENDC, return a NaN whose payload is set based on STR.  Otherwise,
8ae002
+   return a default NAN.  If ENDPTR is not NULL, set *ENDPTR to point
8ae002
+   to the character after the initial n-char-sequence.  */
8ae002
+
8ae002
+internal_function
8ae002
+FLOAT
8ae002
+STRTOD_NAN (const STRING_TYPE *str, STRING_TYPE **endptr, STRING_TYPE endc)
8ae002
+{
8ae002
+  const STRING_TYPE *cp = str;
8ae002
+
8ae002
+  while ((*cp >= L_('0') && *cp <= L_('9'))
8ae002
+	 || (*cp >= L_('A') && *cp <= L_('Z'))
8ae002
+	 || (*cp >= L_('a') && *cp <= L_('z'))
8ae002
+	 || *cp == L_('_'))
8ae002
+    ++cp;
8ae002
+
8ae002
+  FLOAT retval = NAN;
8ae002
+  if (*cp != endc)
8ae002
+    goto out;
8ae002
+
8ae002
+  /* This is a system-dependent way to specify the bitmask used for
8ae002
+     the NaN.  We expect it to be a number which is put in the
8ae002
+     mantissa of the number.  */
8ae002
+  STRING_TYPE *endp;
8ae002
+  unsigned long long int mant;
8ae002
+
8ae002
+  mant = STRTOULL (str, &endp, 0);
8ae002
+  if (endp == cp)
8ae002
+    SET_MANTISSA (retval, mant);
8ae002
+
8ae002
+ out:
8ae002
+  if (endptr != NULL)
8ae002
+    *endptr = (STRING_TYPE *) cp;
8ae002
+  return retval;
8ae002
+}
8ae002
+libc_hidden_def (STRTOD_NAN)
8ae002
diff -rupN a/stdlib/strtod_nan_narrow.h b/stdlib/strtod_nan_narrow.h
8ae002
--- a/stdlib/strtod_nan_narrow.h	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtod_nan_narrow.h	2017-03-02 16:45:05.486639051 -0500
8ae002
@@ -0,0 +1,22 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Narrow strings.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#define STRING_TYPE char
8ae002
+#define L_(Ch) Ch
8ae002
+#define STRTOULL(S, E, B) ____strtoull_l_internal ((S), (E), (B), 0,	\
8ae002
+						   _nl_C_locobj_ptr)
8ae002
diff -rupN a/stdlib/strtod_nan_wide.h b/stdlib/strtod_nan_wide.h
8ae002
--- a/stdlib/strtod_nan_wide.h	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtod_nan_wide.h	2017-03-02 16:45:05.489639044 -0500
8ae002
@@ -0,0 +1,22 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Wide strings.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#define STRING_TYPE wchar_t
8ae002
+#define L_(Ch) L##Ch
8ae002
+#define STRTOULL(S, E, B) ____wcstoull_l_internal ((S), (E), (B), 0,	\
8ae002
+						   _nl_C_locobj_ptr)
8ae002
diff -rupN a/stdlib/strtof_l.c b/stdlib/strtof_l.c
8ae002
--- a/stdlib/strtof_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/stdlib/strtof_l.c	2017-03-02 17:06:34.349227993 -0500
8ae002
@@ -20,27 +20,19 @@
8ae002
 #include <xlocale.h>
8ae002
 
8ae002
 extern float ____strtof_l_internal (const char *, char **, int, __locale_t);
8ae002
-extern unsigned long long int ____strtoull_l_internal (const char *, char **,
8ae002
-						       int, int, __locale_t);
8ae002
 
8ae002
 #define	FLOAT		float
8ae002
 #define	FLT		FLT
8ae002
 #ifdef USE_WIDE_CHAR
8ae002
 # define STRTOF		wcstof_l
8ae002
 # define __STRTOF	__wcstof_l
8ae002
+# define STRTOF_NAN	__wcstof_nan
8ae002
 #else
8ae002
 # define STRTOF		strtof_l
8ae002
 # define __STRTOF	__strtof_l
8ae002
+# define STRTOF_NAN	__strtof_nan
8ae002
 #endif
8ae002
 #define	MPN2FLOAT	__mpn_construct_float
8ae002
 #define	FLOAT_HUGE_VAL	HUGE_VALF
8ae002
-#define SET_MANTISSA(flt, mant) \
8ae002
-  do { union ieee754_float u;						      \
8ae002
-       u.f = (flt);							      \
8ae002
-       if ((mant & 0x7fffff) == 0)					      \
8ae002
-	 mant = 0x400000;						      \
8ae002
-       u.ieee.mantissa = (mant) & 0x7fffff;				      \
8ae002
-       (flt) = u.f;							      \
8ae002
-  } while (0)
8ae002
 
8ae002
 #include "strtod_l.c"
8ae002
diff -rupN a/stdlib/strtof_nan.c b/stdlib/strtof_nan.c
8ae002
--- a/stdlib/strtof_nan.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtof_nan.c	2017-03-02 16:45:05.498639023 -0500
8ae002
@@ -0,0 +1,24 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Narrow
8ae002
+   strings, float.
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include <strtod_nan_narrow.h>
8ae002
+#include <strtod_nan_float.h>
8ae002
+
8ae002
+#define STRTOD_NAN __strtof_nan
8ae002
+#include <strtod_nan_main.c>
8ae002
diff -rupN a/stdlib/strtold_nan.c b/stdlib/strtold_nan.c
8ae002
--- a/stdlib/strtold_nan.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/stdlib/strtold_nan.c	2017-03-02 16:45:05.501639016 -0500
8ae002
@@ -0,0 +1,30 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Narrow
8ae002
+   strings, long double.
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include <math.h>
8ae002
+
8ae002
+/* This function is unused if long double and double have the same
8ae002
+   representation.  */
8ae002
+#ifndef __NO_LONG_DOUBLE_MATH
8ae002
+# include <strtod_nan_narrow.h>
8ae002
+# include <strtod_nan_ldouble.h>
8ae002
+
8ae002
+# define STRTOD_NAN __strtold_nan
8ae002
+# include <strtod_nan_main.c>
8ae002
+#endif
8ae002
diff -rupN a/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h
8ae002
--- a/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h	2017-03-02 16:45:05.502639014 -0500
8ae002
@@ -0,0 +1,33 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  For ldbl-128.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#define FLOAT		long double
8ae002
+#define SET_MANTISSA(flt, mant)				\
8ae002
+  do							\
8ae002
+    {							\
8ae002
+      union ieee854_long_double u;			\
8ae002
+      u.d = (flt);					\
8ae002
+      u.ieee_nan.mantissa0 = 0;				\
8ae002
+      u.ieee_nan.mantissa1 = 0;				\
8ae002
+      u.ieee_nan.mantissa2 = (mant) >> 32;		\
8ae002
+      u.ieee_nan.mantissa3 = (mant);			\
8ae002
+      if ((u.ieee.mantissa0 | u.ieee.mantissa1		\
8ae002
+	   | u.ieee.mantissa2 | u.ieee.mantissa3) != 0)	\
8ae002
+	(flt) = u.d;					\
8ae002
+    }							\
8ae002
+  while (0)
8ae002
diff -rupN a/sysdeps/ieee754/ldbl-128/strtold_l.c b/sysdeps/ieee754/ldbl-128/strtold_l.c
8ae002
--- a/sysdeps/ieee754/ldbl-128/strtold_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/sysdeps/ieee754/ldbl-128/strtold_l.c	2017-03-02 17:07:43.540018882 -0500
8ae002
@@ -25,20 +25,13 @@
8ae002
 #ifdef USE_WIDE_CHAR
8ae002
 # define STRTOF		wcstold_l
8ae002
 # define __STRTOF	__wcstold_l
8ae002
+# define STRTOF_NAN	__wcstold_nan
8ae002
 #else
8ae002
 # define STRTOF		strtold_l
8ae002
 # define __STRTOF	__strtold_l
8ae002
+# define STRTOF_NAN	__strtold_nan
8ae002
 #endif
8ae002
 #define MPN2FLOAT	__mpn_construct_long_double
8ae002
 #define FLOAT_HUGE_VAL	HUGE_VALL
8ae002
-#define SET_MANTISSA(flt, mant) \
8ae002
-  do { union ieee854_long_double u;					      \
8ae002
-       u.d = (flt);							      \
8ae002
-       u.ieee.mantissa0 = 0x8000;					      \
8ae002
-       u.ieee.mantissa1 = 0;						      \
8ae002
-       u.ieee.mantissa2 = ((mant) >> 32);	      			      \
8ae002
-       u.ieee.mantissa3 = (mant) & 0xffffffff;				      \
8ae002
-       (flt) = u.d;							      \
8ae002
-  } while (0)
8ae002
 
8ae002
 #include <strtod_l.c>
8ae002
diff -rupN a/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h
8ae002
--- a/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h	2017-03-02 16:45:05.505639007 -0500
8ae002
@@ -0,0 +1,30 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  For ldbl-128ibm.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#define FLOAT		long double
8ae002
+#define SET_MANTISSA(flt, mant)					\
8ae002
+  do								\
8ae002
+    {								\
8ae002
+      union ibm_extended_long_double u;				\
8ae002
+      u.ld = (flt);						\
8ae002
+      u.d[0].ieee_nan.mantissa0 = (mant) >> 32;			\
8ae002
+      u.d[0].ieee_nan.mantissa1 = (mant);			\
8ae002
+      if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0)	\
8ae002
+	(flt) = u.ld;						\
8ae002
+    }								\
8ae002
+  while (0)
8ae002
diff -rupN a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c
8ae002
--- a/sysdeps/ieee754/ldbl-128ibm/strtold_l.c	2017-03-02 16:33:54.000000000 -0500
8ae002
+++ b/sysdeps/ieee754/ldbl-128ibm/strtold_l.c	2017-03-02 17:10:22.516584043 -0500
8ae002
@@ -30,25 +30,19 @@ extern long double ____new_wcstold_l (co
8ae002
 # define STRTOF		__new_wcstold_l
8ae002
 # define __STRTOF	____new_wcstold_l
8ae002
 # define ____STRTOF_INTERNAL ____wcstold_l_internal
8ae002
+# define STRTOF_NAN	__wcstold_nan
8ae002
 #else
8ae002
 extern long double ____new_strtold_l (const char *, char **, __locale_t);
8ae002
 # define STRTOF		__new_strtold_l
8ae002
 # define __STRTOF	____new_strtold_l
8ae002
 # define ____STRTOF_INTERNAL ____strtold_l_internal
8ae002
+# define STRTOF_NAN	__strtold_nan
8ae002
 #endif
8ae002
 extern __typeof (__STRTOF) STRTOF;
8ae002
 libc_hidden_proto (__STRTOF)
8ae002
 libc_hidden_proto (STRTOF)
8ae002
 #define MPN2FLOAT	__mpn_construct_long_double
8ae002
 #define FLOAT_HUGE_VAL	HUGE_VALL
8ae002
-# define SET_MANTISSA(flt, mant) \
8ae002
-  do { union ibm_extended_long_double u;				      \
8ae002
-       u.ld = (flt);							      \
8ae002
-       u.d[0].ieee_nan.mantissa0 = (mant) >> 32;				      \
8ae002
-       u.d[0].ieee_nan.mantissa1 = (mant);				   	      \
8ae002
-       if ((u.d[0].ieee.mantissa0 | u.d[0].ieee.mantissa1) != 0)	      \
8ae002
-         (flt) = u.ld;							      \
8ae002
-  } while (0)
8ae002
 
8ae002
 #include <strtod_l.c>
8ae002
 
8ae002
diff -rupN a/sysdeps/ieee754/ldbl-64-128/strtold_l.c b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
8ae002
--- a/sysdeps/ieee754/ldbl-64-128/strtold_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/sysdeps/ieee754/ldbl-64-128/strtold_l.c	2017-03-02 17:11:06.062475088 -0500
8ae002
@@ -30,26 +30,19 @@ extern long double ____new_wcstold_l (co
8ae002
 # define STRTOF		__new_wcstold_l
8ae002
 # define __STRTOF	____new_wcstold_l
8ae002
 # define ____STRTOF_INTERNAL ____wcstold_l_internal
8ae002
+# define STRTOF_NAN	__wcstold_nan
8ae002
 #else
8ae002
 extern long double ____new_strtold_l (const char *, char **, __locale_t);
8ae002
 # define STRTOF		__new_strtold_l
8ae002
 # define __STRTOF	____new_strtold_l
8ae002
 # define ____STRTOF_INTERNAL ____strtold_l_internal
8ae002
+# define STRTOF_NAN	__strtold_nan
8ae002
 #endif
8ae002
 extern __typeof (__STRTOF) STRTOF;
8ae002
 libc_hidden_proto (__STRTOF)
8ae002
 libc_hidden_proto (STRTOF)
8ae002
 #define MPN2FLOAT	__mpn_construct_long_double
8ae002
 #define FLOAT_HUGE_VAL	HUGE_VALL
8ae002
-#define SET_MANTISSA(flt, mant) \
8ae002
-  do { union ieee854_long_double u;					      \
8ae002
-       u.d = (flt);							      \
8ae002
-       u.ieee.mantissa0 = 0x8000;					      \
8ae002
-       u.ieee.mantissa1 = 0;						      \
8ae002
-       u.ieee.mantissa2 = ((mant) >> 32);	      			      \
8ae002
-       u.ieee.mantissa3 = (mant) & 0xffffffff;				      \
8ae002
-       (flt) = u.d;							      \
8ae002
-  } while (0)
8ae002
 
8ae002
 #include <strtod_l.c>
8ae002
 
8ae002
diff -rupN a/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h
8ae002
--- a/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h	2017-03-02 16:45:05.521638969 -0500
8ae002
@@ -0,0 +1,30 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  For ldbl-96.
8ae002
+   Copyright (C) 1997-2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#define FLOAT		long double
8ae002
+#define SET_MANTISSA(flt, mant)				\
8ae002
+  do							\
8ae002
+    {							\
8ae002
+      union ieee854_long_double u;			\
8ae002
+      u.d = (flt);					\
8ae002
+      u.ieee_nan.mantissa0 = (mant) >> 32;		\
8ae002
+      u.ieee_nan.mantissa1 = (mant);			\
8ae002
+      if ((u.ieee.mantissa0 | u.ieee.mantissa1) != 0)	\
8ae002
+	(flt) = u.d;					\
8ae002
+    }							\
8ae002
+  while (0)
8ae002
diff -rupN a/sysdeps/ieee754/ldbl-96/strtold_l.c b/sysdeps/ieee754/ldbl-96/strtold_l.c
8ae002
--- a/sysdeps/ieee754/ldbl-96/strtold_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/sysdeps/ieee754/ldbl-96/strtold_l.c	2017-03-02 17:11:52.927362322 -0500
8ae002
@@ -25,20 +25,13 @@
8ae002
 #ifdef USE_WIDE_CHAR
8ae002
 # define STRTOF		wcstold_l
8ae002
 # define __STRTOF	__wcstold_l
8ae002
+# define STRTOF_NAN	__wcstold_nan
8ae002
 #else
8ae002
 # define STRTOF		strtold_l
8ae002
 # define __STRTOF	__strtold_l
8ae002
+# define STRTOF_NAN	__strtold_nan
8ae002
 #endif
8ae002
 #define MPN2FLOAT	__mpn_construct_long_double
8ae002
 #define FLOAT_HUGE_VAL	HUGE_VALL
8ae002
-#define SET_MANTISSA(flt, mant) \
8ae002
-  do { union ieee854_long_double u;					      \
8ae002
-       u.d = (flt);							      \
8ae002
-       if ((mant & 0x7fffffffffffffffULL) == 0)				      \
8ae002
-	 mant = 0x4000000000000000ULL;					      \
8ae002
-       u.ieee.mantissa0 = (((mant) >> 32) & 0x7fffffff) | 0x80000000;	      \
8ae002
-       u.ieee.mantissa1 = (mant) & 0xffffffff;				      \
8ae002
-       (flt) = u.d;							      \
8ae002
-  } while (0)
8ae002
 
8ae002
 #include <stdlib/strtod_l.c>
8ae002
diff -rupN a/wcsmbs/Makefile b/wcsmbs/Makefile
8ae002
--- a/wcsmbs/Makefile	2017-03-02 16:33:59.000000000 -0500
8ae002
+++ b/wcsmbs/Makefile	2017-03-02 16:45:05.529638950 -0500
8ae002
@@ -32,6 +32,7 @@ routines := wcscat wcschr wcscmp wcscpy
8ae002
 	    wcstol wcstoul wcstoll wcstoull wcstod wcstold wcstof \
8ae002
 	    wcstol_l wcstoul_l wcstoll_l wcstoull_l \
8ae002
 	    wcstod_l wcstold_l wcstof_l \
8ae002
+	    wcstod_nan wcstold_nan wcstof_nan \
8ae002
 	    wcscoll wcsxfrm \
8ae002
 	    wcwidth wcswidth \
8ae002
 	    wcscoll_l wcsxfrm_l \
8ae002
diff -rupN a/wcsmbs/wcstod_l.c b/wcsmbs/wcstod_l.c
8ae002
--- a/wcsmbs/wcstod_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/wcsmbs/wcstod_l.c	2017-03-02 16:45:05.532638943 -0500
8ae002
@@ -23,9 +23,6 @@
8ae002
 
8ae002
 extern double ____wcstod_l_internal (const wchar_t *, wchar_t **, int,
8ae002
 				     __locale_t);
8ae002
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
8ae002
-						       wchar_t **, int, int,
8ae002
-						       __locale_t);
8ae002
 
8ae002
 #define	USE_WIDE_CHAR	1
8ae002
 
8ae002
diff -rupN a/wcsmbs/wcstod_nan.c b/wcsmbs/wcstod_nan.c
8ae002
--- a/wcsmbs/wcstod_nan.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/wcsmbs/wcstod_nan.c	2017-03-02 16:45:05.535638936 -0500
8ae002
@@ -0,0 +1,23 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Wide strings, double.
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include "../stdlib/strtod_nan_wide.h"
8ae002
+#include "../stdlib/strtod_nan_double.h"
8ae002
+
8ae002
+#define STRTOD_NAN __wcstod_nan
8ae002
+#include "../stdlib/strtod_nan_main.c"
8ae002
diff -rupN a/wcsmbs/wcstof_l.c b/wcsmbs/wcstof_l.c
8ae002
--- a/wcsmbs/wcstof_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/wcsmbs/wcstof_l.c	2017-03-02 16:45:05.538638929 -0500
8ae002
@@ -25,8 +25,5 @@
8ae002
 
8ae002
 extern float ____wcstof_l_internal (const wchar_t *, wchar_t **, int,
8ae002
 				    __locale_t);
8ae002
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
8ae002
-						       wchar_t **, int, int,
8ae002
-						       __locale_t);
8ae002
 
8ae002
 #include <stdlib/strtof_l.c>
8ae002
diff -rupN a/wcsmbs/wcstof_nan.c b/wcsmbs/wcstof_nan.c
8ae002
--- a/wcsmbs/wcstof_nan.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/wcsmbs/wcstof_nan.c	2017-03-02 16:45:05.541638922 -0500
8ae002
@@ -0,0 +1,23 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Wide strings, float.
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include "../stdlib/strtod_nan_wide.h"
8ae002
+#include "../stdlib/strtod_nan_float.h"
8ae002
+
8ae002
+#define STRTOD_NAN __wcstof_nan
8ae002
+#include "../stdlib/strtod_nan_main.c"
8ae002
diff -rupN a/wcsmbs/wcstold_l.c b/wcsmbs/wcstold_l.c
8ae002
--- a/wcsmbs/wcstold_l.c	2012-12-24 22:02:13.000000000 -0500
8ae002
+++ b/wcsmbs/wcstold_l.c	2017-03-02 16:45:05.544638915 -0500
8ae002
@@ -24,8 +24,5 @@
8ae002
 
8ae002
 extern long double ____wcstold_l_internal (const wchar_t *, wchar_t **, int,
8ae002
 					   __locale_t);
8ae002
-extern unsigned long long int ____wcstoull_l_internal (const wchar_t *,
8ae002
-						       wchar_t **, int, int,
8ae002
-						       __locale_t);
8ae002
 
8ae002
 #include <strtold_l.c>
8ae002
diff -rupN a/wcsmbs/wcstold_nan.c b/wcsmbs/wcstold_nan.c
8ae002
--- a/wcsmbs/wcstold_nan.c	1969-12-31 19:00:00.000000000 -0500
8ae002
+++ b/wcsmbs/wcstold_nan.c	2017-03-02 16:45:05.547638908 -0500
8ae002
@@ -0,0 +1,30 @@
8ae002
+/* Convert string for NaN payload to corresponding NaN.  Wide strings,
8ae002
+   long double.
8ae002
+   Copyright (C) 2015 Free Software Foundation, Inc.
8ae002
+   This file is part of the GNU C Library.
8ae002
+
8ae002
+   The GNU C Library is free software; you can redistribute it and/or
8ae002
+   modify it under the terms of the GNU Lesser General Public
8ae002
+   License as published by the Free Software Foundation; either
8ae002
+   version 2.1 of the License, or (at your option) any later version.
8ae002
+
8ae002
+   The GNU C Library is distributed in the hope that it will be useful,
8ae002
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
8ae002
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
8ae002
+   Lesser General Public License for more details.
8ae002
+
8ae002
+   You should have received a copy of the GNU Lesser General Public
8ae002
+   License along with the GNU C Library; if not, see
8ae002
+   <http://www.gnu.org/licenses/>.  */
8ae002
+
8ae002
+#include <math.h>
8ae002
+
8ae002
+/* This function is unused if long double and double have the same
8ae002
+   representation.  */
8ae002
+#ifndef __NO_LONG_DOUBLE_MATH
8ae002
+# include "../stdlib/strtod_nan_wide.h"
8ae002
+# include <strtod_nan_ldouble.h>
8ae002
+
8ae002
+# define STRTOD_NAN __wcstold_nan
8ae002
+# include "../stdlib/strtod_nan_main.c"
8ae002
+#endif