[gnu.g++.bug] -O optimizes out assignment to middle component of this 3-vector

ngo%tammy@HARVARD.HARVARD.EDU (Tom Ngo) (02/10/90)

    g++ :     1.36.4
    Machine : Convex C220
    
    The following program exercises a stripped-down class of
    3-vectors.  The important lines are 

	nx = Vec(7000,8000,9000);
	ny = nx + nx;

    One expects the final value of ny to be (14000,16000,18000)... but
    when -O is used, it is (14000,40,18000).  The 40 comes from the
    assignment x[1]=20 from the initialization of x.

    The bug depends on everything upstream of the two lines that I
    called important.  I have chosen initial values for the vectors
    that help track where later values come from.

    If x is accessed prior to "ny = nx + nx" (as in cout << "x "), the
    bug goes away.

--Tom Ngo
  ngo@harvard.edu

=== bug.cc (25 lines) =================================================

#include <stream.h>

class Vec {
  public:
    int n[3];
    Vec(int x,int y,int z) { n[0]=x; n[1]=y; n[2]=z; }
    ~Vec() {}
    Vec(const Vec& that) { *this = that; }
    Vec& operator = (const Vec& that) {
	n[0] = that.n[0]; n[1] = that.n[1]; n[2] = that.n[2]; }
    friend Vec operator + (const Vec& a, const Vec& b)
      { return Vec( a.n[0]+b.n[0], a.n[1]+b.n[1], a.n[2]+b.n[2] ); }
};

main()
{
    Vec nx(10,20,30);
    Vec nz(400,500,600);
    Vec ny(0,0,0);
    ny = nz + nx;		// Final value of ny never shows any nz
    nx = Vec(7000,8000,9000);	// nx[1]=8000 appears to get optimized out
    ny = nx + nx;		// Interchange with next line to remove diffs
    cout << "x " << nx.n[0] << " " << nx.n[1] << " " << nx.n[2] << "\n";
    cout << "y " << ny.n[0] << " " << ny.n[1] << " " << ny.n[2] << "\n";
}

=== Makefile (7 lines) ====================================================

test: opt nopt
	nopt
	opt
opt: bug.cc
	g++ -g -O bug.cc -lm -o opt
nopt: bug.cc
	g++ -g bug.cc -lm -o nopt

===========================================================================