about summary refs log tree commit diff
path: root/sysdeps/ieee754/ldbl-64-128/strtold_l.c
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2015-11-24 22:24:52 +0000
committerJoseph Myers <joseph@codesourcery.com>2015-11-24 22:24:52 +0000
commite02cabecf0d025ec4f4ddee290bdf7aadb873bb3 (patch)
treeaf7aa7390dbc613f881677122a888946d294d333 /sysdeps/ieee754/ldbl-64-128/strtold_l.c
parenta7f0c5ae4184916f0e145de3aefc794bf2e280ad (diff)
downloadglibc-e02cabecf0d025ec4f4ddee290bdf7aadb873bb3.tar.gz
glibc-e02cabecf0d025ec4f4ddee290bdf7aadb873bb3.tar.xz
glibc-e02cabecf0d025ec4f4ddee290bdf7aadb873bb3.zip
Refactor strtod parsing of NaN payloads.
The nan* functions handle their string argument by constructing a
NAN(...) string on the stack as a VLA and passing it to strtod
functions.

This approach has problems discussed in bug 16961 and bug 16962: the
stack usage is unbounded, and it gives incorrect results in certain
cases where the argument is not a valid n-char-sequence.

The natural fix for both issues is to refactor the NaN payload parsing
out of strtod into a separate function that the nan* functions can
call directly, so that no temporary string needs constructing on the
stack at all.  This patch does that refactoring in preparation for
fixing those bugs (but without actually using the new functions from
nan* - which will also require exporting them from libc at version
GLIBC_PRIVATE).  This patch is not intended to change any user-visible
behavior, so no tests are added (fixes for the above bugs will of
course add tests for them).

This patch builds on my recent fixes for strtol and strtod issues in
Turkish locales.  Given those fixes, the parsing of NaN payloads is
locale-independent; thus, the new functions do not need to take a
locale_t argument.

Tested for x86_64, x86, mips64 and powerpc.

	* stdlib/strtod_nan.c: New file.
	* stdlib/strtod_nan_double.h: Likewise.
	* stdlib/strtod_nan_float.h: Likewise.
	* stdlib/strtod_nan_main.c: Likewise.
	* stdlib/strtod_nan_narrow.h: Likewise.
	* stdlib/strtod_nan_wide.h: Likewise.
	* stdlib/strtof_nan.c: Likewise.
	* stdlib/strtold_nan.c: Likewise.
	* sysdeps/ieee754/ldbl-128/strtod_nan_ldouble.h: Likewise.
	* sysdeps/ieee754/ldbl-128ibm/strtod_nan_ldouble.h: Likewise.
	* sysdeps/ieee754/ldbl-96/strtod_nan_ldouble.h: Likewise.
	* wcsmbs/wcstod_nan.c: Likewise.
	* wcsmbs/wcstof_nan.c: Likewise.
	* wcsmbs/wcstold_nan.c: Likewise.
	* stdlib/Makefile (routines): Add strtof_nan, strtod_nan and
	strtold_nan.
	* wcsmbs/Makefile (routines): Add wcstod_nan, wcstold_nan and
	wcstof_nan.
	* include/stdlib.h (__strtof_nan): Declare and use
	libc_hidden_proto.
	(__strtod_nan): Likewise.
	(__strtold_nan): Likewise.
	(__wcstof_nan): Likewise.
	(__wcstod_nan): Likewise.
	(__wcstold_nan): Likewise.
	* include/wchar.h (____wcstoull_l_internal): Declare.
	* stdlib/strtod_l.c: Do not include <ieee754.h>.
	(____strtoull_l_internal): Remove declaration.
	(STRTOF_NAN): Define macro.
	(SET_MANTISSA): Remove macro.
	(STRTOULL): Likewise.
	(____STRTOF_INTERNAL): Use STRTOF_NAN to parse NaN payload.
	* stdlib/strtof_l.c (____strtoull_l_internal): Remove declaration.
	(STRTOF_NAN): Define macro.
	(SET_MANTISSA): Remove macro.
	* sysdeps/ieee754/ldbl-128/strtold_l.c (STRTOF_NAN): Define macro.
	(SET_MANTISSA): Remove macro.
	* sysdeps/ieee754/ldbl-128ibm/strtold_l.c (STRTOF_NAN): Define
	macro.
	(SET_MANTISSA): Remove macro.
	* sysdeps/ieee754/ldbl-64-128/strtold_l.c (STRTOF_NAN): Define
	macro.
	(SET_MANTISSA): Remove macro.
	* sysdeps/ieee754/ldbl-96/strtold_l.c (STRTOF_NAN): Define macro.
	(SET_MANTISSA): Remove macro.
	* wcsmbs/wcstod_l.c (____wcstoull_l_internal): Remove declaration.
	* wcsmbs/wcstof_l.c (____wcstoull_l_internal): Likewise.
	* wcsmbs/wcstold_l.c (____wcstoull_l_internal): Likewise.
Diffstat (limited to 'sysdeps/ieee754/ldbl-64-128/strtold_l.c')
-rw-r--r--sysdeps/ieee754/ldbl-64-128/strtold_l.c13
1 files changed, 2 insertions, 11 deletions
diff --git a/sysdeps/ieee754/ldbl-64-128/strtold_l.c b/sysdeps/ieee754/ldbl-64-128/strtold_l.c
index 3944a43643..6cd963b2cc 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>