From 68cdbb18dac8d6cc6990e1de7b4f481ccbbfcd1d Mon Sep 17 00:00:00 2001 From: Jeff Johnston Date: Thu, 16 Jun 2005 19:14:01 +0000 Subject: [PATCH] 2005-06-16 Christopher Faylor * libc/stdio/vfprintf.c (cvt): Don't rely on pointer aliasing to determine characteristics of long double. Use a union instead. * ldtoa.c (_ldtoa_r): Ditto. (_ldcheck): Ditto. (_strtold): Ditto. (union uconv): New union. --- newlib/ChangeLog | 9 +++++++++ newlib/libc/stdio/vfprintf.c | 10 +++++++--- newlib/libc/stdlib/ldtoa.c | 32 +++++++++++++++++++++----------- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 52df833e0..ae9584373 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,12 @@ +2005-06-16 Christopher Faylor + + * libc/stdio/vfprintf.c (cvt): Don't rely on pointer aliasing to + determine characteristics of long double. Use a union instead. + * ldtoa.c (_ldtoa_r): Ditto. + (_ldcheck): Ditto. + (_strtold): Ditto. + (union uconv): New union. + 2005-06-03 Jeff Johnston * libc/stdlib/mallocr.c (MALLOC_COPY): Switch to use memmove diff --git a/newlib/libc/stdio/vfprintf.c b/newlib/libc/stdio/vfprintf.c index c10fed8e9..c51b6b821 100644 --- a/newlib/libc/stdio/vfprintf.c +++ b/newlib/libc/stdio/vfprintf.c @@ -1260,7 +1260,11 @@ _DEFUN(cvt, (data, value, ndigits, flags, sign, decpt, ch, length), #ifdef _NO_LONGDBL union double_union tmp; #else - struct ldieee *ldptr; + union + { + struct ldieee ieee; + _LONG_DOUBLE val; + } ld; #endif if (ch == 'f') { @@ -1287,8 +1291,8 @@ _DEFUN(cvt, (data, value, ndigits, flags, sign, decpt, ch, length), digits = _dtoa_r (data, value, mode, ndigits, decpt, &dsgn, &rve); #else /* !_NO_LONGDBL */ - ldptr = (struct ldieee *)&value; - if (ldptr->sign) { /* this will check for < 0 and -0.0 */ + ld.val = value; + if (ld.ieee.sign) { /* this will check for < 0 and -0.0 */ value = -value; *sign = '-'; } else diff --git a/newlib/libc/stdlib/ldtoa.c b/newlib/libc/stdlib/ldtoa.c index 7af35d5e8..6a29dda9b 100644 --- a/newlib/libc/stdlib/ldtoa.c +++ b/newlib/libc/stdlib/ldtoa.c @@ -80,6 +80,12 @@ static void einfin(register short unsigned int *x, register LDPARMS *ldp); static void efloor(short unsigned int *x, short unsigned int *y, LDPARMS *ldp); static void etoasc(short unsigned int *x, char *string, int ndigs, int outformat, LDPARMS *ldp); +union uconv +{ + unsigned short pe; + long double d; +}; + #if LDBL_MANT_DIG == 24 static void e24toe(short unsigned int *pe, short unsigned int *y, LDPARMS *ldp); #elif LDBL_MANT_DIG == 53 @@ -2712,6 +2718,8 @@ LDPARMS rnd; LDPARMS *ldp = &rnd; char *outstr; char outbuf[NDEC + MAX_EXP_DIGITS + 10]; +union uconv du; +du.d = d; orig_ndigits = ndigits; rnd.rlast = -1; @@ -2729,13 +2737,13 @@ if (_REENT_MP_RESULT(ptr)) } #if LDBL_MANT_DIG == 24 -e24toe( (unsigned short *)&d, e, ldp ); +e24toe( &du.pe, e, ldp ); #elif LDBL_MANT_DIG == 53 -e53toe( (unsigned short *)&d, e, ldp ); +e53toe( &du.pe, e, ldp ); #elif LDBL_MANT_DIG == 64 -e64toe( (unsigned short *)&d, e, ldp ); +e64toe( &du.pe, e, ldp ); #else -e113toe( (unsigned short *)&d, e, ldp ); +e113toe( &du.pe, e, ldp ); #endif if( eisneg(e) ) @@ -2864,14 +2872,16 @@ LDPARMS *ldp = &rnd; rnd.rlast = -1; rnd.rndprc = NBITS; +union uconv du; +du.d = *d; #if LDBL_MANT_DIG == 24 -e24toe( (unsigned short *)d, e, ldp ); +e24toe( &du.pe, e, ldp ); #elif LDBL_MANT_DIG == 53 -e53toe( (unsigned short *)d, e, ldp ); +e53toe( &du.pe, e, ldp ); #elif LDBL_MANT_DIG == 64 -e64toe( (unsigned short *)d, e, ldp ); +e64toe( &du.pe, e, ldp ); #else -e113toe( (unsigned short *)d, e, ldp ); +e113toe( &du.pe, e, ldp ); #endif if( (e[NE-1] & 0x7fff) == 0x7fff ) @@ -3220,7 +3230,7 @@ ldp->outexpon = expon; long double _strtold (char *s, char **se) { - long double x; + union uconv x; LDPARMS rnd; LDPARMS *ldp = &rnd; int lenldstr; @@ -3228,10 +3238,10 @@ long double _strtold (char *s, char **se) rnd.rlast = -1; rnd.rndprc = NBITS; - lenldstr = asctoeg( s, (unsigned short *)&x, LDBL_MANT_DIG, ldp ); + lenldstr = asctoeg( s, &x.pe, LDBL_MANT_DIG, ldp ); if (se) *se = s + lenldstr; - return x; + return x.d; } #define REASONABLE_LEN 200