optimizer bug
Mark van Doesburg
m.j.s.vandoesburg@student.utwente.nl
Wed Jun 24 04:10:00 GMT 1998
When compiling the attached program with:
gcc -O test.ii
Executing a.out causes a segmentation fault.
Without the -O it runs without errors.
The following function is translated
void SetTransformation(int const &M)
{
coord<fract,3> corner[8];
corner[0][0]=corner[0][1]=corner[0][2]=0;
}
into:
test.o: file format elf32-i386
Disassembly of section .text:
00000000 <SetTransformation(int const &)>:
0: 55 pushl %ebp
1: 89 e5 movl %esp,%ebp
3: 83 ec 60 subl $0x60,%esp
6: 53 pushl %ebx
7: b9 07 00 00 00 movl $0x7,%ecx
c: 8d 74 26 00 leal 0x0(%esi,1),%esi
10: ba 02 00 00 00 movl $0x2,%edx
15: 83 ea 01 subl $0x1,%edx
18: 73 fb jae 15 <SetTransformation(int const &)+0x15>
1a: 83 e9 01 subl $0x1,%ecx
1d: 73 f1 jae 10 <SetTransformation(int const &)+0x10>
1f: c7 45 a8 00 00 movl $0x0,0xffffffa8(%ebp)
24: 00 00
26: 8b 00 movl (%eax),%eax <---------- ?
28: 89 45 a4 movl %eax,0xffffffa4(%ebp)
2b: 8b 03 movl (%ebx),%eax <---------- ?
2d: 89 45 a0 movl %eax,0xffffffa0(%ebp)
30: 8b 5d 9c movl 0xffffff9c(%ebp),%ebx
33: 89 ec movl %ebp,%esp
35: 5d popl %ebp
36: c3 ret
37: 90 nop
Which is obviously(?) incorrect since eax and ebx are never initialized.
The system used:
Linux 2.0.34
libc 5.4.33
Intel pentium/AMD K5
binutils 2.9.1
Reading specs from /usr/local/lib/gcc-lib/i586-pc-linux-gnulibc1/egcs-2.91.42/specs
gcc version egcs-2.91.42 19980621 (gcc2 ss-980502 experimental)
If you need more information you can mail me directly or via the egcs mailing
list (not egcs-bugs).
greetings, Mark.
-------------------------- test.ii ----------------------------------------
# 1 "test.cpp"
# 1 "coord.h" 1
# 1 "fract.h" 1
typedef int int32;
typedef long long int64;
class fract {
static const int shift=16;
int32 d;
public:
fract() {}
fract(int i) { d=i<<shift; }
fract(double o) { d=(int)((1<<shift)*o+0.5); }
operator bool() const { return d; }
operator int() const { return d>>shift; }
operator double() const { return (double)d/(1<<shift); }
int32 &direct() { return d; }
int32 fp() const { return d&((1<<shift)-1); }
fract &operator=(fract f) { d=f.d; }
fract &operator=(int f) { d=f<<shift; }
fract &operator=(double f) { d=(int)((1<<shift)*f+0.5); }
fract operator+(fract f) const { fract t; t.d=d+f.d; return t; }
fract operator+(int f) const { fract t; t=*this+(fract)f; return t; }
fract operator+(double f) const { fract t; t=*this+(fract)f; return t; }
fract operator-(fract f) const { fract t; t.d=d-f.d; return t; }
fract operator-(int f) const { fract t; t=*this-(fract)f; return t; }
fract operator-(double f) const { fract t; t=*this-(fract)f; return t; }
fract operator*(fract) const;
fract operator*(int32 i) const { fract t; t.d=d*i; return t; }
fract operator*(double i) const;
fract operator/(fract f) const;
fract operator/(int i) const { fract t; t.d=d/i; return t; }
fract operator/(double i) const;
fract operator-() const { fract t; t.d=-d; return t; }
fract &operator+=(fract f) { d+=f.d; return *this; }
fract &operator-=(fract f) { d-=f.d; return *this; }
int operator<(fract f) const { return d<f.d; }
int operator<=(fract f) const { return d<=f.d; }
int operator>(fract f) const { return d>f.d; }
int operator>=(fract f) const { return d>=f.d; }
int operator!=(fract f) const { return d!=f.d; }
int operator==(fract f) const { return d==f.d; }
int operator<(int i) const { return *this<fract(i); }
int operator<=(int i) const { return *this<=fract(i); }
int operator>(int i) const { return *this>fract(i); }
int operator>=(int i) const { return *this>=fract(i); }
int operator!=(int i) const { return *this!=fract(i); }
int operator==(int i) const { return *this==fract(i); }
int operator<(double i) const { return *this<fract(i); }
int operator<=(double i) const { return *this<=fract(i); }
int operator>(double i) const { return *this>fract(i); }
int operator>=(double i) const { return *this>=fract(i); }
int operator!=(double i) const { return *this!=fract(i); }
int operator==(double i) const { return *this==fract(i); }
};
inline fract fract::operator*(fract f) const
{
fract t;
t.d=((long long)d*f.d)>>shift;
return t;
}
inline fract fract::operator*(double i) const
{
fract t;
t.d=(int32)(d*i+0.5);
return t;
}
inline fract fract::operator/(fract f) const
{
fract t;
t.d=(((int64)d<<shift)/f.d);
return t;
}
inline fract fract::operator/(double i) const
{
fract t;
t.d=(int)(d/i+0.5);
return t;
}
inline int operator*(int i,fract f)
{
return i*(int)f;
}
inline double operator*(double i,fract f)
{
return i*(double)f;
}
inline int operator/(int i,fract f)
{
return i/(int)f;
}
inline double operator/(double d,fract f)
{
return d/(double)f;
}
inline int operator+(int i,fract f)
{
return i+(int)f;
}
inline double operator+(double i,fract f)
{
return i+(double)f;
}
inline int operator-(int i,fract f)
{
return i-(int)f;
}
inline double operator-(double i,fract f)
{
return i-(double)f;
}
# 4 "coord.h" 2
template<class T,int S>
class coord {
T c[S];
public:
coord() {};
template<class TT> coord(coord<TT,S> const &o);
template<class TT> coord<T,S> &operator=(TT[S]);
T &operator[](int i) { return c[i]; }
T const &operator[](int i) const { return c[i]; }
T get(int i) const { return c[i]; }
coord<T,S> operator-() const;
coord<T,S> operator+(coord<T,S> const &o) const;
coord<T,S> operator+=(coord<T,S> const &o) { *this=*this+o; }
coord<T,S> operator-(coord<T,S> const &o) const;
coord<T,S> operator-=(coord<T,S> const &o) { *this=*this-o; }
template<class TT> T operator*(coord<TT,S> const &o) const;
coord<T,S> &operator*=(int);
coord<T,S> &operator*=(double);
coord<T,S> &operator*=(fract);
coord<T,S> &operator/=(int);
coord<T,S> &operator/=(double);
coord<T,S> &operator/=(fract);
coord<T,S> operator*(int) const;
coord<T,S> operator*(double) const;
coord<T,S> operator*(fract) const;
coord<T,S> operator/(int) const;
coord<T,S> operator/(double) const;
coord<T,S> operator/(fract) const;
int operator==(coord<T,S> const &) const;
int operator!=(coord<T,S> const&o) const { return !(*this==o); }
void print();
};
template<class T,int S>
inline void coord<T,S>::print()
{
printf("(");
for(int i=0;i<S;i++) {
printf("%lf",(double)c[i]);
if(i<S-1)
printf(",");
}
printf(")");
}
template<class T,int S> template<class TT>
inline coord<T,S>::coord(coord<TT,S> const &o)
{
for(int i=0;i<S;i++)
c[i]=o.get(i);
}
template<class T,int S> template<class TT>
inline coord<T,S> &coord<T,S>::operator=(TT d[S])
{
for(int i=0;i<S;i++)
c[i]=d[i];
return *this;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator+(coord<T,S> const &o) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t.c[i]=c[i]+o.get(i);
return t;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator-(coord<T,S> const &o) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t.c[i]=c[i]-o.c[i];
return t;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator-() const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t[i]=-c[i];
return t;
}
template<class T,int S> template<class TT>
inline T coord<T,S>::operator*(coord<TT,S> const &o) const
{
T t;
t=c[0]*o.get(0);
for(int i=1;i<S;i++)
t+=c[i]*o.get(i);
return t;
}
template<class T,int S>
inline coord<T,S> &coord<T,S>::operator*=(int x)
{
for(int i=0;i<S;i++)
c[i]*=x;
return *this;
}
template<class T,int S>
inline coord<T,S> &coord<T,S>::operator*=(double x)
{
for(int i=0;i<S;i++)
c[i]*=x;
return *this;
}
template<class T,int S>
inline coord<T,S> &coord<T,S>::operator*=(fract x)
{
for(int i=0;i<S;i++)
c[i]*=x;
return *this;
}
template<class T,int S>
inline coord<T,S> &coord<T,S>::operator/=(int x)
{
for(int i=0;i<S;i++)
c[i]/=x;
return *this;
}
template<class T,int S>
inline coord<T,S> &coord<T,S>::operator/=(double x)
{
for(int i=0;i<S;i++)
c[i]/=x;
return *this;
}
template<class T,int S>
inline coord<T,S> &coord<T,S>::operator/=(fract x)
{
for(int i=0;i<S;i++)
c[i]/=x;
return *this;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator*(int x) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t[i]=c[i]*x;
return t;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator*(double x) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t[i]=c[i]*x;
return t;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator*(fract x) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t[i]=c[i]*x;
return t;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator/(int x) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t[i]=c[i]/x;
return t;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator/(double x) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t[i]=c[i]/x;
return t;
}
template<class T,int S>
inline coord<T,S> coord<T,S>::operator/(fract x) const
{
coord<T,S> t;
for(int i=0;i<S;i++)
t[i]=c[i]/x;
return t;
}
template<class T,int S>
inline int coord<T,S>::operator==(coord<T,S> const &o) const
{
for(int i=0;i<S;i++)
if(c[i]!=o.c[i])
return 0;
return 1;
}
template <class T,int S>
inline coord<int,S> operator*(int i,coord<T,S> c)
{
return c*i;
}
template <class T,int S>
inline coord<double,S> operator*(double i,coord<T,S> c)
{
return (coord<double,S>)c*i;
}
template <class T,int S>
inline coord<fract,S> operator*(fract i,coord<T,S> c)
{
return (coord<fract,S>)c*i;
}
# 1 "test.cpp" 2
void SetTransformation(int const &M)
{
coord<fract,3> corner[8];
corner[0][0]=corner[0][1]=corner[0][2]=0;
}
main()
{
int M;
SetTransformation(M);
}
More information about the Gcc-bugs
mailing list