* util.c: fix SEGV by test_time.rb with

gcc version 4.4.0 20090219 (Red Hat 4.4.0-0.21) on Fedora 11 Alpha.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22663 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2009-02-27 13:05:30 +00:00
parent 506af65de1
commit f252633804
2 changed files with 48 additions and 32 deletions

View File

@ -1,3 +1,8 @@
Fri Feb 27 22:02:34 2009 Tanaka Akira <akr@fsij.org>
* util.c: fix SEGV by test_time.rb with
gcc version 4.4.0 20090219 (Red Hat 4.4.0-0.21) on Fedora 11 Alpha.
Fri Feb 27 18:30:51 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> Fri Feb 27 18:30:51 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
* compile.c (cdhash_type, iseq_set_sequence): should not call * compile.c (cdhash_type, iseq_set_sequence): should not call

75
util.c
View File

@ -906,23 +906,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.
@ -1657,10 +1659,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
@ -1698,7 +1701,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
@ -1759,8 +1762,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;
@ -1769,6 +1773,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
@ -1894,7 +1901,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);
@ -2053,7 +2060,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;
@ -2752,14 +2760,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 */
@ -2769,12 +2777,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 */
@ -2786,7 +2794,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;
@ -2796,7 +2804,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)) {
@ -2816,11 +2824,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
@ -3118,7 +3126,7 @@ freedtoa(char *s)
*/ */
char * char *
ruby_dtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve) ruby_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
@ -3163,7 +3171,8 @@ ruby_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;
@ -3172,6 +3181,8 @@ ruby_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);