robert@POLYA.STANFORD.EDU (James R. Kennedy) (08/03/89)
This is a bug report for GNU c++, version 1.35.1-
I ran the following session on a Sun 4/110 under SunOS Release
4.0 (CGSDST2SMT110S) #1.
The file used for tm.h was tm-sparc.h.
The file used for md was sparc.md
The problem I experienced was a signal 11 due to segmentation
violation in gcc-cc1plus.
----------------- begin annotated terminal session ----------------
#
# verify g++ version
#
kalonia% g++ -v
g++ version 1.35.1-
#
# produce input file to gcc-cc1plus and show file for bug report
#
kalonia% g++ -E quad.cc | tee quad.i
----------------------- begin input to gcc-cc1plus ---------------
# 1 "quad.cc"
# 1 "quad.h"
inline double maxabs(double& a, double& b)
{
if (fabs(a) > fabs(b)) return a;
else return b;
}
inline double minabs(double& a, double& b)
{
if (fabs(a) < fabs(b)) return a;
else return b;
}
class quad
{
double high, low;
public:
inline quad(double a, double b = 0.0);
inline quad();
quad operator + (quad& a);
quad operator - (quad& a);
quad operator - ();
quad operator * (quad& a);
quad operator / (quad& a);
inline double operator double();
};
inline quad::quad(double a, double b = 0.0)
{
high = a + b;
double q = maxabs(a, b) - high;
low = q + minabs(a, b);
}
inline quad::quad()
{
}
inline double quad::operator double()
{
return(high + low);
}
# 19 "quad.cc"
# 1 "/import/lib/g++-include/math.h"
#pragma once
overload acos;
overload acosh;
overload asin;
overload asinh;
overload atan;
overload atan2;
overload atanh;
overload ceil;
overload cos;
overload cosh;
overload exp;
overload floor;
overload gamma;
overload hypot;
overload log;
overload log10;
overload pow;
overload sin;
overload sinh;
overload sqrt;
overload tan;
overload tanh;
# 79 "/import/lib/g++-include/math.h"
extern "C" {
double acos(double);
double acosh(double);
double asin(double);
double asinh(double);
double atan(double);
double atan2(double, double);
double atanh(double);
double cbrt(double);
double ceil(double);
double copysign(double,double);
double cos(double);
double cosh(double);
double drem(double,double);
double erf(double);
double erfc(double);
double exp(double);
double expm1(double);
double fabs(double);
double finite(double);
double floor(double);
double frexp(double, int*);
double gamma(double);
double hypot(double,double);
double infnan(int);
int isinf(double);
int isnan(double);
double j0(double);
double j1(double);
double jn(int, double);
double ldexp(double, int);
double lgamma(double);
double log(double);
double log10(double);
double log1p(double);
double logb(double);
double modf(double, double*);
double pow(double, double);
double rint(double);
double scalb(double, int);
double sin(double);
double sinh(double);
double sqrt(double);
double tan(double);
double tanh(double);
double y0(double);
double y1(double);
double yn(int, double);
}
struct exception
{
int type;
char* name;
double arg1, arg2, retval;
};
extern "C" int matherr(exception*);
# 1 "/import/lib/g++-include/values.h"
#pragma once
# 108 "/import/lib/g++-include/values.h"
# 156 "/import/lib/g++-include/math.h"
# 20 "quad.cc"
double split_const = 0.0;
void init_precision()
{
double b = 1.0 / ((4.0 / 3.0 - 1.0) * 3.0 - 1.0);
double r = sqrt(4.0 * b);
double rb = r * b;
split_const = r + rb;
split_const -= rb;
split_const += 1.0;
}
void quad::split(double x, double& x1, double& x2)
{
if (split_const == 0.0) init_precision();
double tmp = split_const * x;
x1 = tmp - x;
x1 = tmp - x1;
x2 = x - x1;
}
quad quad::exdblmul(double& a, double& b)
{
double a1, a2,
b1, b2,
p, q;
quad ans(0.0, 0.0);
split(a, a1, a2);
split(b, b1, b2);
p = a1 * b1;
q = a1 * b2 + b1 * a2;
ans.high = p + q;
ans.low = p - ans.high + q + a2 * b2;
return ans;
}
quad quad::operator + (quad& a)
{
quad x, y;
if (fabs(a.high) > fabs(high))
{
x = a;
y = *this;
}
else
{
x = *this;
y = a;
}
double t = x.low + y.high;
t += x.high;
double tau = x.high - t;
tau += y.high;
tau += x.low;
tau += y.low;
return quad(t, tau);
}
quad quad::operator - ()
{
return quad(-this->high, -this->low);
}
quad quad::operator - (quad& a)
{
return *this + (-a);
}
quad quad::operator * (quad& a)
{
quad c = exdblmul(high, a.high);
c.low += high * a.low + low * a.high;
return quad(c.high, c.low);
}
quad quad::operator / (quad& a)
{
double c = high / a.high;
c = high / a.high;
quad u = exdblmul(c, a.high);
double cc = high - u.high;
cc -= u.low;
cc += low;
cc -= c * a.low;
cc /= a.high;
return quad(c, cc);
}
----------------------- end input to gcc-cc1plus ---------------
#
# now demonstrate the bug
#
kalonia% /import/lib/gcc-cc1plus quad.i
double maxabs (double &, double &);
quad.h:4: warning: implicit declaration of function `fabs'
double minabs (double &, double &); struct quad *quad::quad (double, double (= 0 )); struct quad *quad::quad (); quad::operator double ();
At top level:
/import/lib/g++-include/math.h:99: warning: `fabs' was previously implicitly declared to return `int'
void init_precision ();
At top level:
quad.cc:50: no `split' member function declared in class
void quad::split (double, double &, double &);
At top level:
quad.cc:71: no `exdblmul' member function declared in class
struct quad quad::exdblmul (double &, double &);
quad.h:4: quad.cc:75: Segmentation violation
Segmentation fault (core dumped)
kalonia%
----------------------- end annotated terminal session -----------------------
And there you have it. Thanks.
-- Robert Kennedy
robert@polya.stanford.edu