[gnu.g++.bug] GNU C++ bug -- signal 11

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