egcs-1.0.3a: Bug with local classes in function templates
Florian Weimer
fw@cygnus.stuttgart.netsurf.de
Thu Jun 11 01:46:00 GMT 1998
Hi!
Alexandre Oliva <oliva@dcc.unicamp.br> writes:
> Florian Weimer <fw@cygnus.stuttgart.netsurf.de> writes:
>
> > #include <vector>
> > main () { vector<int&> vec; int i = 1; vec.push_back(i); }
>
> The May 30 snapshot prints lots of error messages, as expected. You
> can't create containers of reference types.
I knew that, the code was intended for educational purposes only. ;)
I've finally taken the hint and downloaded and built egcs-19980608,
but alas, it's got the same old bug I spotted in almost every
gcc-based C compiler (but failed to report until now).
Here's the code that triggers the bug:
----------------------------------------------------------------------
/* From glibc-2.05c, /usr/include/__math.h */
#include <stdio.h>
extern __inline double
sin (double __x)
{
register double __value;
__asm __volatile__
("fsin"
: "=t" (__value) : "0" (__x));
return __value;
}
extern __inline double
cos (double __x)
{
register double __value;
__asm __volatile__
("fcos"
: "=t" (__value): "0" (__x));
return __value;
}
extern __inline double
exp (double __x)
{
register double __value, __exponent;
__asm __volatile__
("fldl2e # e^x = 2^(x * log2(e))\n\t"
"fmul %%st(1) # x * log2(e)\n\t"
"fstl %%st(1)\n\t"
"frndint # int(x * log2(e))\n\t"
"fxch\n\t"
"fsub %%st(1) # fract(x * log2(e))\n\t"
"f2xm1 # 2^(fract(x * log2(e))) - 1\n\t"
: "=t" (__value), "=u" (__exponent) : "0" (__x));
__value += 1.0;
__asm __volatile__
("fscale"
: "=t" (__value) : "0" (__value), "u" (__exponent));
return __value;
}
/* From Python 1.5b2 */
typedef struct {
double real;
double imag;
} Py_complex;
/* compiled incorrectly */
Py_complex
c_exp(x)
Py_complex x;
{
Py_complex r;
double l = exp(x.real);
r.real = l*cos(x.imag);
r.imag = l*sin(x.imag);
return r;
}
int main(void)
{
Py_complex x, y;
x.real = 1.0;
x.imag = 1.0;
y = c_exp(x);
printf("(%f, %f)\n", y.real, y.imag);
return 0;
}
----------------------------------------------------------------------
Here's the command line I used
[fw@deneb /tmp]$ /opt/egcs-ss/bin/gcc --version
egcs-2.91.40
[fw@deneb /tmp]$ /opt/egcs-ss/bin/gcc -Wall -O2 -fomit-frame-pointer -fpic bug.c
[fw@deneb /tmp]$ ./a.out
Segmentation fault (core dumped)
[fw@deneb /tmp]$
Looking at the machine code generated for c_exp(), I can image why the
program crashes:
----------------------------------------------------------------------
c_exp:
subl $32,%esp
pushl %ebx
call .LPR0
addl $_GLOBAL_OFFSET_TABLE_,%ebx
movl 40(%esp),%edx
fldl 44(%esp)
#APP
fldl2e # e^x = 2^(x * log2(e))
fmul %st(1) # x * log2(e)
fstl %st(1)
frndint # int(x * log2(e))
fxch
fsub %st(1) # fract(x * log2(e))
f2xm1 # 2^(fract(x * log2(e))) - 1
#NO_APP
faddl .LC0@GOTOFF(%ebx)
#APP
fscale
#NO_APP
fstp %st(1)
fstpl (%esp)
----------------------------------------------------------------------
The last instruction above destroys the saved value of the caller's
%ebx register. :( (I was a bit surprised when I discovered this. gcc
2.7.2.x miscompiles the code as well, but uses the return address as
if it was the pointer for the struct return.)
Florian
More information about the Gcc-bugs
mailing list