From: mrs@cygnus.com (Mike Stump)
Subject: Re:  GCC-2.2.1-bug-report
Organization: GNUs Not Usenet
Distribution: gnu
Date: Sat, 29 Aug 1992 14:45:01 GMT

This problem should not exist in the next release of gcc.

> Date: Sat, 25 Jul 92 18:41:56 +0400
> From: vogr@wisdom.weizmann.ac.il (Ogranovich Vadim)
> Message-Id: <9207251441.AA08244@white.wisdom.weizmann.ac.il>
> To: bug-gcc@prep.ai.mit.edu

> Hello,
> This is a programm which fails GCC 2.2.1 for DEC.
> I'm sorry but I really could not reduce the size and
> locate the error-causing spot. ( Read continuation after
> the code ).

> #include <stream.h>

> int const TRUE =1;
> int const FALSE =0;

> enum Rescale {
>   half,  // "halves" the # of slices and doubles the coupled meshsize
>   same,
>   twice  // "doubles" the # of slices and halfs the coupled meshsize
> };

> class Vector {
> public:
>   double h;
>   int n;
>   double &value(int);
> };

> void interpolation(Vector &from, Vector &to);


> class GridAttr {
> public:
>   int  nx;
>   int  ny;
>   double  x0, y0;  // left-down corner. Default zeros
>   double  x1, y1;  // right-upper corner. Default ones
>   
>   double hx;     // x-mesh-size
>   double hy;     // y-mesh-size
>   
>   inline double x(int i) { return x0 + hx*i; }
>   inline double y(int i) { return y0 + hy*i; }

>   GridAttr(int nnx, int nny, 
> 	   double xx0 = 0.0, double xx1 = 1.0,
> 	   double yy0 = 0.0, double yy1 =1.0);

>   GridAttr(GridAttr &, Rescale xscale = same, Rescale yscale = same);

> };

> // from # of slices, right-upper and left-down corners
> GridAttr::GridAttr(int nnx, int nny, 
> 		   double xx0 = 0.0, double xx1 = 1.0,
> 		   double yy0 = 0.0, double yy1 =1.0)
> : nx(nnx), ny(nny), x1(xx1), y1(yy1), x0(xx0), y0(yy0)
> {
>   hx = (x1-x0)/(nx-1);
>   hy = (y1-y0)/(ny-1);
> }

> GridAttr::GridAttr(GridAttr &from, 
> 		   Rescale xscale = same, Rescale yscale = same)
> : x1(from.x1), y1(from.y1), x0(from.x0), y0(from.y0)
> {
>   switch(xscale) {
>   case half:      // 
> //    if((from.nx % 2) == 0)
> //    cerr << "Warning: halving grid with even #slices\n" << from;
>     
>     nx = (from.nx + 1)/2;
>     break;
>     
>   case same:
>     nx = from.nx;
>     break;
>     
>   case twice:
>     nx = 2*from.nx - 1;
>     break;
>   }
>   
>   switch(yscale) {
>   case half:
> //    if((from.ny % 2) == 0)
> //    cerr << "Warning: halving grid with even #slices\n" << from;
>     
>     ny = (from.ny + 1)/2;
>     break;
>     
>   case same:
>     ny = from.ny;
>     break;
>     
>   case twice:
>     ny = 2*from.ny - 1;
>     break;
>   }
>   
>   hx = (x1-x0)/(nx-1);
>   hy = (y1-y0)/(ny-1);
> }

> class Grid : public GridAttr {
> public:
>   double &value(int xs, int ys);
>   double dxdx(int xs, int ys)
>   { return (value(xs-1, ys) - 2*value(xs, ys) + value(xs+1,ys))/(hx*hx); }
>   double dydy(int xs, int ys)
>   { return (value(xs, ys-1) - 2*value(xs, ys) + value(xs,ys+1))/(hy*hy); }

>   Grid(GridAttr &attr, Rescale xscale = same, Rescale yscale = same) : 
>   GridAttr(attr, xscale, yscale) {}
> };


> // XVector is a column, i.e. all the entries
> // have the same X-coordinate

> class XVector : public Vector {
>   Grid &g;
>   int xs;
> public:
>   double &value(int ys) 
>   { return g.value(xs, ys); }
>   
>   XVector(Grid &gg, int xss) : g(gg)
>   { xs=xss ; h=gg.hy; n=gg.ny; }
> };


> // YVector is a row. i.e. all the entries
> // have the same Y-coordinate 

> class YVector : public Vector {
>   Grid &g;
>   int ys;
> public:
>   double &value(int xs) 
>   { return g.value(xs, ys); }
>   
>   YVector(Grid &gg, int yss) : g(gg)
>   { ys=yss ; h=gg.hx; n=gg.nx; }
> };



> class GridGeneral : public Grid {
>   double *p;
> public:
>   double &value(int xs, int ys)
>   { return p[xs + ys * nx]; }

>   void operator +=(Grid &);

>   GridGeneral(GridAttr attr, Rescale xscale =same, Rescale yscale =same) : 
>   (attr, xscale, yscale)
>   { p =new double[attr.nx*attr.ny]; }
>   ~GridGeneral() { delete p; }
> };

> void GridGeneral::operator +=(Grid &g)
> {
>   for(int xs=0; xs<nx; xs++)
>   for(int ys=0; ys<ny; ys++)
>   value(xs, ys)+=g.value(xs, ys);
> }

> void interpolation(Grid &from, GridGeneral &to);
> void injection(Grid &from, GridGeneral &to);
> void full_weighting(Grid &from, GridGeneral &to);


> class Operator : public GridGeneral {
> public:
>   double lh_value(int xs, int ys);
>   double point_relaxation(int xs, int ys, double rhs);
>   Operator(GridAttr &attr, Rescale xscale =same, Rescale yscale =same) : 
>   (attr, xscale, yscale) {}
> };


> void gauss_seidel(Operator &lhs, Grid &rhs);

> //
> // Coarse-to-fine
> // ~~~~~~~~~~~~~~

> void
> interpolation(Vector &from, Vector &to)
> {
>   int scale =(from.n<to.n) ? 2 : 1;
>   
>   for(int i=0; i<from.n; i++)	// copying
>   to.value(scale*i)=from.value(i);
>   
>   if(from.n<to.n)		// filling gaps
>   for(i=0; i<from.n-1; i++)
>   to.value(2*i+1)=0.5*(from.value(i)+from.value(i+1));
> }


> void
> interpolation(Grid &from, GridGeneral &to)
> {
>   int scale =(from.nx<to.nx) ? 2 : 1;
>   
>   for(int i=0; i<from.nx; i++)
>   interpolation(XVector(from, i), XVector(to, scale*i));
>   
>   if(from.nx<to.nx)
>   for(i=0; i<to.ny; i++)
>   interpolation(YVector(from, i), YVector(to, i));
> }

> //
> // Fine-to-coarse
> // ~~~~~~~~~~~~~~

> void
> injection(Grid &from, GridGeneral &to)
> {
>   int xscale=(from.nx=to.nx) ? 1 : 2;
>   int yscale=(from.ny=to.ny) ? 1 : 2;

>   for(int xs=0; xs<to.nx; xs++)
>   for(int ys=0; ys<to.ny; ys++)
>   to.value(xs, ys)=from.value(xscale*xs, yscale*ys);
> }


> void
> full_weighting(Grid &from, GridGeneral &to)
> {
>   int xscale=(from.nx=to.nx) ? 1 : 2;
>   int yscale=(from.ny=to.ny) ? 1 : 2;
>   
>   for(int xs=1; xs<to.nx-1; xs++)
>   for(int ys=1; ys<to.ny-1; ys++)
>   {
>     to.value(xs, ys)=
>     from.value(xscale*xs, yscale*ys)+
>     (from.nx>to.nx) ? 
>     0.5*(from.value(xscale*xs-1, yscale*ys) + 
> 	 from.value(xscale*xs+1, yscale*ys))
>     : 0.0 +
>     (from.ny>to.ny) ? 
>     0.5*(from.value(xscale*xs, yscale*ys-1) + 
> 	 from.value(xscale*xs, yscale*ys+1))
>     : 0.0 +
>     (from.nx>to.nx && from.ny>to.ny) ?
>     0.25*(from.value(xscale*xs-1, yscale*ys-1) + 
> 	  from.value(xscale*xs-1, yscale*ys+1) +
> 	  from.value(xscale*xs+1, yscale*ys-1) + 
> 	  from.value(xscale*xs+1, yscale*ys+1))
>     : 0.0;
>     to.value(xs, ys)*=.25;
>   }
> }



> Having compiled the program as it is

> > g++ -Wall bug.C -lg++ -c

> the compiler produces the following output

> > /usr/local/bin/gcc: Internal compiler error: program cc1plus got fatal signal 4
> > 
> > Compilation exited abnormally with code 1 at Sat Jul 25 17:00:35


> If one removes the definition of the function full_weighting(Grid &, GridGeneral &)

> > bug.C:3: warning: `TRUE' defined but not used
> > bug.C:4: warning: `FALSE' defined but not used
> > /usr/local/bin/gcc: -lg++: linker input file unused since linking not done
> > 
> > Compilation finished at Sat Jul 25 17:16:29

> But if instead of the function full_weighting one removed the
> definitions of the functions interpolation(Grid &from, GridGeneral
> &to) and injection(Grid &from, GridGeneral &to) compilation would be
> successful too.

> And the last remark is that the whole code can be fixed by putting
> extra parentheses around the (... ? ... : ... ) operations in the
> function full_weighting.

Newsgroups: gnu.g++.bug