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