Logo Search packages:      
Sourcecode: gcc-2.96 version File versions

bug-70743.cc

/*
From: Andy Roosen <andrew.roosen@nist.gov>
To: submit@bugs.debian.org
Subject: Bug#70743: g++ on Alpha optimizes -O2 incorrectly
Date: Fri, 1 Sep 2000 17:31:50 -0400

Package: g++
Version: 2.95.2-13
Platform: alpha

Something somewhat subtle is failing in the following code when using
g++ on the Alpha with -O2. -O1 produces correct output, and it works
on i386 as well. Almost any changes to the code also make it produce
correct output.
*/

// -*- C++ -*-

// The expected output is:
//  here=[0, 0] here.x=0 here.y=0
//              up=[0, 1] down=[0, -1] left=[-1, 0] right=[1, 0]
//  here=[1, 0] here.x=1 here.y=0
//              up=[1, 1] down=[1, -1] left=[0, 0] right=[2, 0]
//  here=[0, 1] here.x=0 here.y=1
//              up=[0, 2] down=[0, 0] left=[-1, 1] right=[1, 1]
//  here=[1, 1] here.x=1 here.y=1
//              up=[1, 2] down=[1, 0] left=[0, 1] right=[2, 1]

// When compiled -O2 on the Alpha, the output is:
//  here=[0, 0] here.x=0 here.y=0
//              up=[0, 1] down=[0, -1] left=[-1, 0] right=[1, 0]
//  here=[1, 0] here.x=0 here.y=0
//              up=[0, 1] down=[0, -1] left=[-1, 0] right=[1, 0]
//  here=[0, 1] here.x=0 here.y=1
//              up=[0, 2] down=[0, 0] left=[-1, 1] right=[1, 1]
//  here=[1, 1] here.x=0 here.y=1
//              up=[0, 2] down=[0, 0] left=[-1, 1] right=[1, 1]
// Note that 'here.x' is not being correctly updated, while 'here.y'
// is.

// When compiled -O1 on the Alpha or -O2 on an Intel, the program
// works correctly.

#include <iostream.h>

class Cell_coordinate {
public:
  short x, y;
  Cell_coordinate(void) {
    x = 0;
    y = 0;
  }

  Cell_coordinate(const int X, const int Y) {
    x = X;
    y = Y;
  }
};

ostream &operator<<(ostream &os, const Cell_coordinate &c) {
    os << "[" << c.x << ", " << c.y << "]";
    return os;
}

//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//=\\=//

class Array {
private:
  double **data;
  int height, width;
public:
  Array(const int h, const int w);
  double &operator[](const Cell_coordinate &z) {
    return data[z.y][z.x];
  }
  int query_height() const { return height; }
  int query_width() const { return width; }
};

// If this constructor is inlined above, the output is correct
Array::Array(const int h, const int w)
  : height(h), width(w)
{
  data = new double*[height];
  data[0] = new double[height*width];
  for(int i=1; i<height; i++)
    data[i] = data[i-1] + width;
  for(int i=0; i<width*height; i++)
    data[0][i] = 0.0;
}


class ArrayIterator {
private:
  int i, j;     // current point
  int x1, y1;   // upper limits
  int x0, y0;   // lower limits
public:
  ArrayIterator(const Array &a)
    : i(0), j(0), x0(0), y0(0), y1(a.query_height()), x1(a.query_width()) {}
  int operator()(Cell_coordinate &pxl) {
    if(j == x1) {
      j = x0;
      i++;
      if(i >= y1) return 0;
    }
    pxl.x = j;
    pxl.y = i;
    j++;
    return 1;
  }
};

static const int size = 2;      // can be any value > 0

int main(int argc, char *argv[]) {
  Array array(size, size);
  Cell_coordinate here;
  ArrayIterator iter(array);
  // replacing these two lines with "int h=size; int w=size" makes the
  // program work correctly.
  int h = array.query_height();
  int w = array.query_width();

  while(iter(here)) {           // loop over elements of the array
    cerr << "here=" << here << " here.x=" << here.x << " here.y=" << here.y
         << endl;
    Cell_coordinate up(here.x, here.y + 1);
    Cell_coordinate down(here.x, here.y - 1);
    Cell_coordinate right(here.x+1, here.y);
    Cell_coordinate left(here.x-1, here.y);

    // Commenting out the following line makes the program work correctly.
    cerr << "           " << " up=" << up << " down=" << down
         << " left=" << left << " right=" << right << endl;

    // Commenting out any of the following lines make the program work.
    if(up.y == h)
      up = down;
    else if(down.y < 0)
      down = up;
    if(left.x < 0)
      left = right;
    else if(right.x == w)
      right = left;
  }
  return 0;
}

Generated by  Doxygen 1.6.0   Back to index