summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%google.com <devnull@localhost>2009-03-20 03:33:11 +0000
committerwtc%google.com <devnull@localhost>2009-03-20 03:33:11 +0000
commit85bdf4aa280f5528afa1ffa76046ba633cfefecd (patch)
treeacace9c9a60fa263a034930660003b03e7f1b1bf
parent6a8a79ae8f1d44f44ec493cac1b7812145c1733c (diff)
downloadnspr-hg-85bdf4aa280f5528afa1ffa76046ba633cfefecd.tar.gz
Bug 439144: fix strict aliasing issues for gcc 4.4. r=kaie.
Tag: NSPR_4_7_BRANCH
-rw-r--r--pr/src/misc/prdtoa.c67
1 files changed, 32 insertions, 35 deletions
diff --git a/pr/src/misc/prdtoa.c b/pr/src/misc/prdtoa.c
index dd3134fa..2af610eb 100644
--- a/pr/src/misc/prdtoa.c
+++ b/pr/src/misc/prdtoa.c
@@ -217,11 +217,6 @@ void _PR_CleanupDtoa(void)
* floating-point numbers and flushes underflows to zero rather
* than implementing gradual underflow, then you must also #define
* Sudden_Underflow.
- * #define YES_ALIAS to permit aliasing certain double values with
- * arrays of ULongs. This leads to slightly better code with
- * some compilers and was always used prior to 19990916, but it
- * is not strictly legal and can cause trouble with aggressively
- * optimizing compilers (e.g., gcc 2.95.1 under -O2).
* #define USE_LOCALE to use the current locale's decimal_point value.
* #define SET_INEXACT if IEEE arithmetic is being used and extra
* computation should be done to set the inexact flag when the
@@ -358,24 +353,13 @@ Exactly one of IEEE_8087, IEEE_MC68k, IEEE_ARM, VAX, or IBM should be defined.
typedef union { double d; ULong L[2]; } U;
-#ifdef YES_ALIAS
-#define dval(x) x
+#define dval(x) (x).d
#ifdef IEEE_8087
-#define word0(x) ((ULong *)&x)[1]
-#define word1(x) ((ULong *)&x)[0]
+#define word0(x) (x).L[1]
+#define word1(x) (x).L[0]
#else
-#define word0(x) ((ULong *)&x)[0]
-#define word1(x) ((ULong *)&x)[1]
-#endif
-#else
-#ifdef IEEE_8087
-#define word0(x) ((U*)&x)->L[1]
-#define word1(x) ((U*)&x)->L[0]
-#else
-#define word0(x) ((U*)&x)->L[0]
-#define word1(x) ((U*)&x)->L[1]
-#endif
-#define dval(x) ((U*)&x)->d
+#define word0(x) (x).L[0]
+#define word1(x) (x).L[1]
#endif
/* The following definition of Storeinc is appropriate for MIPS processors.
@@ -1184,14 +1168,15 @@ diff
static double
ulp
#ifdef KR_headers
- (x) double x;
+ (dx) double dx;
#else
- (double x)
+ (double dx)
#endif
{
register Long L;
- double a;
+ U x, a;
+ dval(x) = dx;
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
#ifndef Avoid_Underflow
#ifndef Sudden_Underflow
@@ -1233,7 +1218,7 @@ b2d
{
ULong *xa, *xa0, w, y, z;
int k;
- double d;
+ U d;
#ifdef VAX
ULong d0, d1;
#else
@@ -1296,11 +1281,12 @@ b2d
static Bigint *
d2b
#ifdef KR_headers
- (d, e, bits) double d; int *e, *bits;
+ (dd, e, bits) double dd; int *e, *bits;
#else
- (double d, int *e, int *bits)
+ (double dd, int *e, int *bits)
#endif
{
+ U d;
Bigint *b;
int de, k;
ULong *x, y, z;
@@ -1309,6 +1295,10 @@ d2b
#endif
#ifdef VAX
ULong d0, d1;
+#endif
+
+ dval(d) = dd;
+#ifdef VAX
d0 = word0(d) >> 16 | word0(d) << 16;
d1 = word1(d) >> 16 | word1(d) << 16;
#else
@@ -1439,7 +1429,7 @@ ratio
(Bigint *a, Bigint *b)
#endif
{
- double da, db;
+ U da, db;
int k, ka, kb;
dval(da) = b2d(a, &ka);
@@ -1613,7 +1603,8 @@ PR_strtod
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, 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, aadj1, adj;
+ U aadj2, rv, rv0;
Long L;
ULong y, z;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
@@ -2376,7 +2367,9 @@ PR_strtod
aadj = z;
aadj1 = dsign ? aadj : -aadj;
}
- word0(aadj1) += (2*P+1)*Exp_msk1 - y;
+ dval(aadj2) = aadj1;
+ word0(aadj2) += (2*P+1)*Exp_msk1 - y;
+ aadj1 = dval(aadj2);
}
adj = aadj1 * ulp(dval(rv));
dval(rv) += adj;
@@ -2711,10 +2704,10 @@ freedtoa(char *s)
static char *
dtoa
#ifdef KR_headers
- (d, mode, ndigits, decpt, sign, rve)
- double d; int mode, ndigits, *decpt, *sign; char **rve;
+ (dd, mode, ndigits, decpt, sign, rve)
+ double dd; int mode, ndigits, *decpt, *sign; char **rve;
#else
- (double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
+ (double dd, int mode, int ndigits, int *decpt, int *sign, char **rve)
#endif
{
/* Arguments ndigits, decpt, sign are similar to those
@@ -2760,7 +2753,8 @@ dtoa
ULong x;
#endif
Bigint *b, *b1, *delta, *mlo, *mhi, *S;
- double d2, ds, eps;
+ U d, d2, eps;
+ double ds;
char *s, *s0;
#ifdef Honor_FLT_ROUNDS
int rounding;
@@ -2776,6 +2770,7 @@ dtoa
}
#endif
+ dval(d) = dd;
if (word0(d) & Sign_bit) {
/* set sign for everything, including 0's and NaNs */
*sign = 1;
@@ -3435,13 +3430,15 @@ PR_dtoa(PRFloat64 d, PRIntn mode, PRIntn ndigits,
** '+' or '-' after the 'e' in scientific notation
*/
PR_IMPLEMENT(void)
-PR_cnvtf(char *buf,int bufsz, int prcsn,double fval)
+PR_cnvtf(char *buf, int bufsz, int prcsn, double dfval)
{
PRIntn decpt, sign, numdigits;
char *num, *nump;
char *bufp = buf;
char *endnum;
+ U fval;
+ dval(fval) = dfval;
/* If anything fails, we store an empty string in 'buf' */
num = (char*)PR_MALLOC(bufsz);
if (num == NULL) {