This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

egcs error in generated assembly for c++'s setw()?


[ 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 ] 



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]