This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
egcs error in generated assembly for c++'s setw()?
- To: egcs at cygnus dot com
- Subject: egcs error in generated assembly for c++'s setw()?
- From: Westley Weimer <weimer at wrw3 dot resnet dot cornell dot edu>
- Date: Tue, 2 Dec 1997 21:01:25 -0500 (EST)
- cc: egcs-bugs at cygnus dot com
[ Same story as before, but this time I believe I can point to a mistake
in the generated assembly code ... please take a look! ]
Recent versions of egcs (for example, egcs-2.90.17p 971114 (gcc2-970802
experimental) and egcs-2.90.06 970907) produce flawed executables for C++
code that uses setw(). Here's the code:
--- begin testing.cc ---
#include <iomanip.h>
#include <iostream.h>
#include <stdlib.h>
int main(void)
{
int i;
cout << endl << "The numbers 0 through 9 using setw(3):" << endl;
for (i = 0 ; i <= 9 ; i++)
cout << setw(3) << i;
cout << endl;
cout << "The numbers 0 through 9 using \" \" to separate:" << endl;
for (i = 0 ; i <= 9 ; i++)
cout << " " << i;
cout << endl << endl;
return(0);
}
--- end testing.cc --
On machines running gcc 2.7.2 ...
mbs15:~$ a.out
The numbers 0 through 9 using setw(3):
0 1 2 3 4 5 6 7 8 9
The numbers 0 through 9 using " " to separate:
0 1 2 3 4 5 6 7 8 9
On machines running egcs ...
merentha:/tmp$ a.out
The numbers 0 through 9 using setw(3):
3 3 3 3 3 3 3 3 3 3
The numbers 0 through 9 using " " to separate:
0 1 2 3 4 5 6 7 8 9
So, here's the interesting part. Using "g++ -O0 -S testing.cc -o
testing.s" to look at the generated assembly ...
--- begin gcc 2.7.2 correctly-working assembly ---
[ snip to the interesting part where we call setw() ]
leal -12(%ebp),%eax
pushl $3 // 3 is the argument
pushl %eax
call setw__Fi // with which we call setw()
addl $8,%esp
leal -12(%ebp),%eax
pushl %eax
pushl $cout
call __ls__FR7ostreamRCt6smanip1Zi
[ snip ]
--- begin egcs incorrect assembly ---
[ snip to same spot ]
leal -16(%ebp),%eax
pushl $3 // 3 is the argument
.LCFI13:
pushl %eax
.LCFI14:
call setw__Fi // with which we call setw()
addl $4,%esp // *problem*: should be $8?
.LCFI15:
leal -16(%ebp),%eax
pushl %eax
.LCFI16:
pushl $cout
.LCFI17:
call __ls__FR7ostreamRCt6smanip1Zi
[ snip ]
If I hand-modify the "bad" assembly file to contain $8 instead of $4 on
that one line, the resulting executable file produces the correct output.
It seems (to my inexperienced eye) that since the stack pointer is off by
exactly one word (in the "bad" code) that the call to "cout" is getting
the leftover argument to "setw" (still on the stack since it wasn't
popped off by adjusting %esp correctly) and treating it as its argument.
Hence all the 3's in the output. But don't trust my judgment.
As a side note, grabbing and installing old copies of libg++ and libstdc++
did not fix the problem, so I don't believe it to be a badly intalled
library issue.
If anyone out there has any ideas about this, or if this is the wrong
place to be asking this sort of question, please let me know. If this
assembly output comparison is not enough information to attack the
problem, I would be happy to run more test cases :-). If this is a FAQ of
some sort, please point me in the right direction. Thanks!
-Wes Weimer
wrw3@cornell.edu
[ I don't receive egcs-bugs, so please cc any replies to me ]