2005-06-16 Christopher Faylor <cgf@timesys.com>

* 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.
This commit is contained in:
Jeff Johnston 2005-06-16 19:14:01 +00:00
parent ec3b136a64
commit 68cdbb18da
3 changed files with 37 additions and 14 deletions

View File

@ -1,3 +1,12 @@
2005-06-16 Christopher Faylor <cgf@timesys.com>
* 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 <jjohnstn@redhat.com> 2005-06-03 Jeff Johnston <jjohnstn@redhat.com>
* libc/stdlib/mallocr.c (MALLOC_COPY): Switch to use memmove * libc/stdlib/mallocr.c (MALLOC_COPY): Switch to use memmove

View File

@ -1260,7 +1260,11 @@ _DEFUN(cvt, (data, value, ndigits, flags, sign, decpt, ch, length),
#ifdef _NO_LONGDBL #ifdef _NO_LONGDBL
union double_union tmp; union double_union tmp;
#else #else
struct ldieee *ldptr; union
{
struct ldieee ieee;
_LONG_DOUBLE val;
} ld;
#endif #endif
if (ch == 'f') { 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); digits = _dtoa_r (data, value, mode, ndigits, decpt, &dsgn, &rve);
#else /* !_NO_LONGDBL */ #else /* !_NO_LONGDBL */
ldptr = (struct ldieee *)&value; ld.val = value;
if (ldptr->sign) { /* this will check for < 0 and -0.0 */ if (ld.ieee.sign) { /* this will check for < 0 and -0.0 */
value = -value; value = -value;
*sign = '-'; *sign = '-';
} else } else

View File

@ -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 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); 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 #if LDBL_MANT_DIG == 24
static void e24toe(short unsigned int *pe, short unsigned int *y, LDPARMS *ldp); static void e24toe(short unsigned int *pe, short unsigned int *y, LDPARMS *ldp);
#elif LDBL_MANT_DIG == 53 #elif LDBL_MANT_DIG == 53
@ -2712,6 +2718,8 @@ LDPARMS rnd;
LDPARMS *ldp = &rnd; LDPARMS *ldp = &rnd;
char *outstr; char *outstr;
char outbuf[NDEC + MAX_EXP_DIGITS + 10]; char outbuf[NDEC + MAX_EXP_DIGITS + 10];
union uconv du;
du.d = d;
orig_ndigits = ndigits; orig_ndigits = ndigits;
rnd.rlast = -1; rnd.rlast = -1;
@ -2729,13 +2737,13 @@ if (_REENT_MP_RESULT(ptr))
} }
#if LDBL_MANT_DIG == 24 #if LDBL_MANT_DIG == 24
e24toe( (unsigned short *)&d, e, ldp ); e24toe( &du.pe, e, ldp );
#elif LDBL_MANT_DIG == 53 #elif LDBL_MANT_DIG == 53
e53toe( (unsigned short *)&d, e, ldp ); e53toe( &du.pe, e, ldp );
#elif LDBL_MANT_DIG == 64 #elif LDBL_MANT_DIG == 64
e64toe( (unsigned short *)&d, e, ldp ); e64toe( &du.pe, e, ldp );
#else #else
e113toe( (unsigned short *)&d, e, ldp ); e113toe( &du.pe, e, ldp );
#endif #endif
if( eisneg(e) ) if( eisneg(e) )
@ -2864,14 +2872,16 @@ LDPARMS *ldp = &rnd;
rnd.rlast = -1; rnd.rlast = -1;
rnd.rndprc = NBITS; rnd.rndprc = NBITS;
union uconv du;
du.d = *d;
#if LDBL_MANT_DIG == 24 #if LDBL_MANT_DIG == 24
e24toe( (unsigned short *)d, e, ldp ); e24toe( &du.pe, e, ldp );
#elif LDBL_MANT_DIG == 53 #elif LDBL_MANT_DIG == 53
e53toe( (unsigned short *)d, e, ldp ); e53toe( &du.pe, e, ldp );
#elif LDBL_MANT_DIG == 64 #elif LDBL_MANT_DIG == 64
e64toe( (unsigned short *)d, e, ldp ); e64toe( &du.pe, e, ldp );
#else #else
e113toe( (unsigned short *)d, e, ldp ); e113toe( &du.pe, e, ldp );
#endif #endif
if( (e[NE-1] & 0x7fff) == 0x7fff ) if( (e[NE-1] & 0x7fff) == 0x7fff )
@ -3220,7 +3230,7 @@ ldp->outexpon = expon;
long double _strtold (char *s, char **se) long double _strtold (char *s, char **se)
{ {
long double x; union uconv x;
LDPARMS rnd; LDPARMS rnd;
LDPARMS *ldp = &rnd; LDPARMS *ldp = &rnd;
int lenldstr; int lenldstr;
@ -3228,10 +3238,10 @@ long double _strtold (char *s, char **se)
rnd.rlast = -1; rnd.rlast = -1;
rnd.rndprc = NBITS; rnd.rndprc = NBITS;
lenldstr = asctoeg( s, (unsigned short *)&x, LDBL_MANT_DIG, ldp ); lenldstr = asctoeg( s, &x.pe, LDBL_MANT_DIG, ldp );
if (se) if (se)
*se = s + lenldstr; *se = s + lenldstr;
return x; return x.d;
} }
#define REASONABLE_LEN 200 #define REASONABLE_LEN 200