aboutsummaryrefslogtreecommitdiff
path: root/newlib/libc/stdlib/strtod.c
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2008-06-25 01:45:02 +0000
committerHans-Peter Nilsson <hp@axis.com>2008-06-25 01:45:02 +0000
commit5592f939b4762cf0eda460d502f880baa179e201 (patch)
tree7ca59247975079e18eee83310a288e635639b886 /newlib/libc/stdlib/strtod.c
parent7b3e3bfd49bef27c5df703e9c079c0c1eb454ecc (diff)
downloadnewlib-5592f939b4762cf0eda460d502f880baa179e201.zip
newlib-5592f939b4762cf0eda460d502f880baa179e201.tar.gz
newlib-5592f939b4762cf0eda460d502f880baa179e201.tar.bz2
Fix strict-aliasing issues with _strtod_r and Storeinc.
* libc/stdlib/strtod.c (_strtod_r): Change local variables aadj, rv, rv0 from double to type U. Use accessor macros dval, dword0 and dword1 for all accesses except for the ULtod call, where rv.i replaces the pointer cast. * libc/stdlib/mprec.h (U): Rename member L to i for easier re-use of access macros. Tweak comment. Remove #ifdef'd YES_ALIAS code. (dword0, dword1, dval): Define in terms of uncast union member access. Ditto for _DOUBLE_IS_32BITS variants. (Storeinc): Replace aliasing-flawed microoptimized definition with alternative suggested in comment. Remove now stale comment.
Diffstat (limited to 'newlib/libc/stdlib/strtod.c')
-rw-r--r--newlib/libc/stdlib/strtod.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/newlib/libc/stdlib/strtod.c b/newlib/libc/stdlib/strtod.c
index 80e5aac..703fbce 100644
--- a/newlib/libc/stdlib/strtod.c
+++ b/newlib/libc/stdlib/strtod.c
@@ -218,7 +218,8 @@ _DEFUN (_strtod_r, (ptr, s00, se),
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, decpt, dsign,
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
_CONST char *s, *s0, *s1;
- double aadj, aadj1, adj, rv, rv0;
+ double aadj, adj;
+ U aadj1, rv, rv0;
Long L;
__ULong y, z;
_Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
@@ -286,7 +287,7 @@ _DEFUN (_strtod_r, (ptr, s00, se),
copybits(bits, fpi.nbits, bb);
Bfree(ptr,bb);
}
- ULtod(((U*)&rv)->L, bits, exp, i);
+ ULtod(rv.i, bits, exp, i);
}}
goto ret;
}
@@ -469,7 +470,7 @@ _DEFUN (_strtod_r, (ptr, s00, se),
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) {
- rv = -rv;
+ dval(rv) = -dval(rv);
sign = 0;
}
#endif
@@ -485,7 +486,7 @@ _DEFUN (_strtod_r, (ptr, s00, se),
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) {
- rv = -rv;
+ dval(rv) = -dval(rv);
sign = 0;
}
#endif
@@ -513,7 +514,7 @@ _DEFUN (_strtod_r, (ptr, s00, se),
#ifdef Honor_FLT_ROUNDS
/* round correctly FLT_ROUNDS = 2 or 3 */
if (sign) {
- rv = -rv;
+ dval(rv) = -dval(rv);
sign = 0;
}
#endif
@@ -976,14 +977,14 @@ _DEFUN (_strtod_r, (ptr, s00, se),
}
if ((aadj = ratio(delta, bs)) <= 2.) {
if (dsign)
- aadj = aadj1 = 1.;
+ aadj = dval(aadj1) = 1.;
else if (dword1(rv) || dword0(rv) & Bndry_mask) {
#ifndef Sudden_Underflow
if (dword1(rv) == Tiny1 && !dword0(rv))
goto undfl;
#endif
aadj = 1.;
- aadj1 = -1.;
+ dval(aadj1) = -1.;
}
else {
/* special case -- power of FLT_RADIX to be */
@@ -993,24 +994,24 @@ _DEFUN (_strtod_r, (ptr, s00, se),
aadj = 1./FLT_RADIX;
else
aadj *= 0.5;
- aadj1 = -aadj;
+ dval(aadj1) = -aadj;
}
}
else {
aadj *= 0.5;
- aadj1 = dsign ? aadj : -aadj;
+ dval(aadj1) = dsign ? aadj : -aadj;
#ifdef Check_FLT_ROUNDS
switch(Rounding) {
case 2: /* towards +infinity */
- aadj1 -= 0.5;
+ dval(aadj1) -= 0.5;
break;
case 0: /* towards 0 */
case 3: /* towards -infinity */
- aadj1 += 0.5;
+ dval(aadj1) += 0.5;
}
#else
if (Flt_Rounds == 0)
- aadj1 += 0.5;
+ dval(aadj1) += 0.5;
#endif /*Check_FLT_ROUNDS*/
}
y = dword0(rv) & Exp_mask;
@@ -1020,7 +1021,7 @@ _DEFUN (_strtod_r, (ptr, s00, se),
if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
dval(rv0) = dval(rv);
dword0(rv) -= P*Exp_msk1;
- adj = aadj1 * ulp(dval(rv));
+ adj = dval(aadj1) * ulp(dval(rv));
dval(rv) += adj;
if ((dword0(rv) & Exp_mask) >=
Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
@@ -1042,18 +1043,18 @@ _DEFUN (_strtod_r, (ptr, s00, se),
if ((z = aadj) <= 0)
z = 1;
aadj = z;
- aadj1 = dsign ? aadj : -aadj;
+ dval(aadj1) = dsign ? aadj : -aadj;
}
dword0(aadj1) += (2*P+1)*Exp_msk1 - y;
}
- adj = aadj1 * ulp(dval(rv));
+ adj = dval(aadj1) * ulp(dval(rv));
dval(rv) += adj;
#else
#ifdef Sudden_Underflow
if ((dword0(rv) & Exp_mask) <= P*Exp_msk1) {
dval(rv0) = dval(rv);
dword0(rv) += P*Exp_msk1;
- adj = aadj1 * ulp(dval(rv));
+ adj = dval(aadj1) * ulp(dval(rv));
dval(rv) += adj;
#ifdef IBM
if ((dword0(rv) & Exp_mask) < P*Exp_msk1)
@@ -1076,7 +1077,7 @@ _DEFUN (_strtod_r, (ptr, s00, se),
dword0(rv) -= P*Exp_msk1;
}
else {
- adj = aadj1 * ulp(dval(rv));
+ adj = dval(aadj1) * ulp(dval(rv));
dval(rv) += adj;
}
#else /*Sudden_Underflow*/
@@ -1088,11 +1089,11 @@ _DEFUN (_strtod_r, (ptr, s00, se),
* example: 1.2e-307 .
*/
if (y <= (P-1)*Exp_msk1 && aadj > 1.) {
- aadj1 = (double)(int)(aadj + 0.5);
+ dval(aadj1) = (double)(int)(aadj + 0.5);
if (!dsign)
- aadj1 = -aadj1;
+ dval(aadj1) = -dval(aadj1);
}
- adj = aadj1 * ulp(dval(rv));
+ adj = dval(aadj1) * ulp(dval(rv));
dval(rv) += adj;
#endif /*Sudden_Underflow*/
#endif /*Avoid_Underflow*/