1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* util.c: suppress strict-aliasing warning with gcc-4.4.0 -O2 to fix

infinite loop by ruby -e "1.402e-45" .


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@23353 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2009-05-06 17:02:29 +00:00
parent c38db982ab
commit b5898e70b0
2 changed files with 48 additions and 32 deletions

View file

@ -1,3 +1,8 @@
Thu May 7 01:59:35 2009 Tanaka Akira <akr@fsij.org>
* util.c: suppress strict-aliasing warning with gcc-4.4.0 -O2 to fix
infinite loop by ruby -e "1.402e-45" .
Wed May 6 09:27:04 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> Wed May 6 09:27:04 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* README.ja: code for THINK_C does not exist already. [Bug #1435] * README.ja: code for THINK_C does not exist already. [Bug #1435]

75
util.c
View file

@ -956,23 +956,25 @@ Exactly one of IEEE_LITTLE_ENDIAN, IEEE_BIG_ENDIAN, VAX, or IBM should be define
typedef union { double d; ULong L[2]; } U; typedef union { double d; ULong L[2]; } U;
#ifdef YES_ALIAS #ifdef YES_ALIAS
#define dval(x) x typedef double double_u;
#ifdef IEEE_LITTLE_ENDIAN # define dval(x) x
#define word0(x) ((ULong *)&x)[1] # ifdef IEEE_LITTLE_ENDIAN
#define word1(x) ((ULong *)&x)[0] # define word0(x) (((ULong *)&x)[1])
# define word1(x) (((ULong *)&x)[0])
# else
# define word0(x) (((ULong *)&x)[0])
# define word1(x) (((ULong *)&x)[1])
# endif
#else #else
#define word0(x) ((ULong *)&x)[0] typedef U double_u;
#define word1(x) ((ULong *)&x)[1] # ifdef IEEE_LITTLE_ENDIAN
#endif # define word0(x) (x.L[1])
#else # define word1(x) (x.L[0])
#ifdef IEEE_LITTLE_ENDIAN # else
#define word0(x) ((U*)&x)->L[1] # define word0(x) (x.L[0])
#define word1(x) ((U*)&x)->L[0] # define word1(x) (x.L[1])
#else # endif
#define word0(x) ((U*)&x)->L[0] # define dval(x) (x.d)
#define word1(x) ((U*)&x)->L[1]
#endif
#define dval(x) ((U*)&x)->d
#endif #endif
/* The following definition of Storeinc is appropriate for MIPS processors. /* The following definition of Storeinc is appropriate for MIPS processors.
@ -1702,10 +1704,11 @@ diff(Bigint *a, Bigint *b)
} }
static double static double
ulp(double x) ulp(double x_)
{ {
register Long L; register Long L;
double a; double_u x, a;
dval(x) = x_;
L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1; L = (word0(x) & Exp_mask) - (P-1)*Exp_msk1;
#ifndef Avoid_Underflow #ifndef Avoid_Underflow
@ -1743,7 +1746,7 @@ b2d(Bigint *a, int *e)
{ {
ULong *xa, *xa0, w, y, z; ULong *xa, *xa0, w, y, z;
int k; int k;
double d; double_u d;
#ifdef VAX #ifdef VAX
ULong d0, d1; ULong d0, d1;
#else #else
@ -1804,8 +1807,9 @@ ret_d:
} }
static Bigint * static Bigint *
d2b(double d, int *e, int *bits) d2b(double d_, int *e, int *bits)
{ {
double_u d;
Bigint *b; Bigint *b;
int de, k; int de, k;
ULong *x, y, z; ULong *x, y, z;
@ -1814,6 +1818,9 @@ d2b(double d, int *e, int *bits)
#endif #endif
#ifdef VAX #ifdef VAX
ULong d0, d1; ULong d0, d1;
#endif
dval(d) = d_;
#ifdef VAX
d0 = word0(d) >> 16 | word0(d) << 16; d0 = word0(d) >> 16 | word0(d) << 16;
d1 = word1(d) >> 16 | word1(d) << 16; d1 = word1(d) >> 16 | word1(d) << 16;
#else #else
@ -1939,7 +1946,7 @@ d2b(double d, int *e, int *bits)
static double static double
ratio(Bigint *a, Bigint *b) ratio(Bigint *a, Bigint *b)
{ {
double da, db; double_u da, db;
int k, ka, kb; int k, ka, kb;
dval(da) = b2d(a, &ka); dval(da) = b2d(a, &ka);
@ -2098,7 +2105,8 @@ ruby_strtod(const char *s00, char **se)
int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign,
e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign;
const char *s, *s0, *s1; const char *s, *s0, *s1;
double aadj, aadj1, adj, rv, rv0; double aadj, adj;
double_u aadj1, rv, rv0;
Long L; Long L;
ULong y, z; ULong y, z;
Bigint *bb, *bb1, *bd, *bd0, *bs, *delta; Bigint *bb, *bb1, *bd, *bd0, *bs, *delta;
@ -2797,14 +2805,14 @@ drop_down:
} }
if ((aadj = ratio(delta, bs)) <= 2.) { if ((aadj = ratio(delta, bs)) <= 2.) {
if (dsign) if (dsign)
aadj = aadj1 = 1.; aadj = dval(aadj1) = 1.;
else if (word1(rv) || word0(rv) & Bndry_mask) { else if (word1(rv) || word0(rv) & Bndry_mask) {
#ifndef Sudden_Underflow #ifndef Sudden_Underflow
if (word1(rv) == Tiny1 && !word0(rv)) if (word1(rv) == Tiny1 && !word0(rv))
goto undfl; goto undfl;
#endif #endif
aadj = 1.; aadj = 1.;
aadj1 = -1.; dval(aadj1) = -1.;
} }
else { else {
/* special case -- power of FLT_RADIX to be */ /* special case -- power of FLT_RADIX to be */
@ -2814,12 +2822,12 @@ drop_down:
aadj = 1./FLT_RADIX; aadj = 1./FLT_RADIX;
else else
aadj *= 0.5; aadj *= 0.5;
aadj1 = -aadj; dval(aadj1) = -aadj;
} }
} }
else { else {
aadj *= 0.5; aadj *= 0.5;
aadj1 = dsign ? aadj : -aadj; dval(aadj1) = dsign ? aadj : -aadj;
#ifdef Check_FLT_ROUNDS #ifdef Check_FLT_ROUNDS
switch (Rounding) { switch (Rounding) {
case 2: /* towards +infinity */ case 2: /* towards +infinity */
@ -2831,7 +2839,7 @@ drop_down:
} }
#else #else
if (Flt_Rounds == 0) if (Flt_Rounds == 0)
aadj1 += 0.5; dval(aadj1) += 0.5;
#endif /*Check_FLT_ROUNDS*/ #endif /*Check_FLT_ROUNDS*/
} }
y = word0(rv) & Exp_mask; y = word0(rv) & Exp_mask;
@ -2841,7 +2849,7 @@ drop_down:
if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) { if (y == Exp_msk1*(DBL_MAX_EXP+Bias-1)) {
dval(rv0) = dval(rv); dval(rv0) = dval(rv);
word0(rv) -= P*Exp_msk1; word0(rv) -= P*Exp_msk1;
adj = aadj1 * ulp(dval(rv)); adj = dval(aadj1) * ulp(dval(rv));
dval(rv) += adj; dval(rv) += adj;
if ((word0(rv) & Exp_mask) >= if ((word0(rv) & Exp_mask) >=
Exp_msk1*(DBL_MAX_EXP+Bias-P)) { Exp_msk1*(DBL_MAX_EXP+Bias-P)) {
@ -2861,11 +2869,11 @@ drop_down:
if ((z = aadj) <= 0) if ((z = aadj) <= 0)
z = 1; z = 1;
aadj = z; aadj = z;
aadj1 = dsign ? aadj : -aadj; dval(aadj1) = dsign ? aadj : -aadj;
} }
word0(aadj1) += (2*P+1)*Exp_msk1 - y; word0(aadj1) += (2*P+1)*Exp_msk1 - y;
} }
adj = aadj1 * ulp(dval(rv)); adj = dval(aadj1) * ulp(dval(rv));
dval(rv) += adj; dval(rv) += adj;
#else #else
#ifdef Sudden_Underflow #ifdef Sudden_Underflow
@ -3178,7 +3186,7 @@ freedtoa(char *s)
*/ */
char * char *
dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) dtoa(double d_, int mode, int ndigits, int *decpt, int *sign, char **rve)
{ {
/* Arguments ndigits, decpt, sign are similar to those /* Arguments ndigits, decpt, sign are similar to those
of ecvt and fcvt; trailing zeros are suppressed from of ecvt and fcvt; trailing zeros are suppressed from
@ -3223,7 +3231,8 @@ dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
ULong x; ULong x;
#endif #endif
Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S; Bigint *b, *b1, *delta, *mlo = 0, *mhi = 0, *S;
double d2, ds, eps; double ds;
double_u d, d2, eps;
char *s, *s0; char *s, *s0;
#ifdef Honor_FLT_ROUNDS #ifdef Honor_FLT_ROUNDS
int rounding; int rounding;
@ -3232,6 +3241,8 @@ dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve)
int inexact, oldinexact; int inexact, oldinexact;
#endif #endif
dval(d) = d_;
#ifndef MULTIPLE_THREADS #ifndef MULTIPLE_THREADS
if (dtoa_result) { if (dtoa_result) {
freedtoa(dtoa_result); freedtoa(dtoa_result);