klaiber@CS.WASHINGTON.EDU (Alexander Klaiber) (11/18/89)
Summary:
g++ doesn't clean up the stack after calling constructors, thus messing up
the stack and argument lists, as in fun(1, new Foo(..), 2)
Note:
problem doesn't show (but is still there) if constructors are not used as
actuals.
System:
g++ 1.36.1
Sun3, os3
----------------------------------------
[uw-larry - 1] % cat main.c
#include "stdio.h"
class Foo {
private:
char* name;
public:
Foo(char* s);
};
Foo::Foo(char* s) {
name = s;
}
void fun(int a, Foo* f, int b) {
printf("%d %d %d\n", a, (int)f, b);
}
main() {
fun(1, new Foo("crash"), 2);
}
[uw-larry - 2] % g++ -v main.c
gcc version 1.36.1 (based on GCC 1.36)
/usr/larry/users/klaiber/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -D__HAVE_68881__ -Dmc68020 main.c /usr/tmp/cca03962.cpp
GNU CPP version 1.36
/usr/larry/users/klaiber/lib/gcc-cc1plus /usr/tmp/cca03962.cpp -quiet -dumpbase main.c -version -o /usr/tmp/cca03962.s
GNU C++ version 1.36.1 (based on GCC 1.36) (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -m68881 -mbitfield
as -mc68020 -o main.o /usr/tmp/cca03962.s
/usr/larry/users/klaiber/lib/gcc-ld -e start -dc -dp /lib/crt0.o /lib/Mcrt1.o main.o -lg++ /usr/larry/users/klaiber/lib/gcc-gnulib -lc
[uw-larry - 3] % a.out
1 148520 148520
^^^^^^
this is most definitely wrong!
----------------------------------------
Here's the generated assembly code: (w/o the -g option for readability)
#NO_APP
gcc_compiled.:
.text
.even
.globl ___3FooPc
___3FooPc:
link a6,#0
movel a6@(8),a0
movel a6@(12),a0@
movel a0,d0
L1:
unlk a6
rts
LC0:
.ascii "%d %d %d\12\0"
.even
.globl _fun__FiP3Fooi
_fun__FiP3Fooi:
link a6,#0
movel a6@(16),sp@-
movel a6@(12),sp@-
movel a6@(8),sp@-
pea LC0
jbsr _printf
addw #16,sp
L2:
unlk a6
rts
LC1:
.ascii "crash\0"
.even
.globl _main
_main:
link a6,#0
movel d2,sp@-
jbsr ___main
movel d0,d0
pea 2:w
pea LC1
pea 4:w
jbsr ___builtin_new
addqw #4,sp
movel d0,d2
movel d2,sp@-
jbsr ___3FooPc <== **** PROBLEM right here ****
movel d2,sp@-
pea 1:w
jbsr _fun__FiP3Fooi
addw #20,sp
clrl d0
jra L3
L3:
movel a6@(-4),d2
unlk a6
rts
----------------------------------------
The error is clear: after the jbsr, we ned an addqw #8,sp to pop the 2 args
for Foo::Foo (this & s)
----------------------------------------
If a temporary variable is used, things seem to be fine:
[uw-larry - 4] % cat other.c
#include "stdio.h"
class Foo {
private:
char* name;
public:
Foo(char* s);
};
Foo::Foo(char* s) {
name = s;
}
void fun(int a, Foo* f, int b) {
printf("%d %d %d\n", a, (int)f, b);
}
main() {
Foo* temp = new Foo("crash");
fun(1, temp, 2);
}
[uw-larry - 5] % g++ -v other.c
gcc version 1.36.1 (based on GCC 1.36)
/usr/larry/users/klaiber/lib/gcc-cpp -+ -v -undef -D__GNUC__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -D__HAVE_68881__ -Dmc68020 other.c /usr/tmp/cca03969.cpp
GNU CPP version 1.36
/usr/larry/users/klaiber/lib/gcc-cc1plus /usr/tmp/cca03969.cpp -quiet -dumpbase other.c -version -o /usr/tmp/cca03969.s
GNU C++ version 1.36.1 (based on GCC 1.36) (68k, MIT syntax) compiled by GNU C version 1.36.
default target switches: -m68020 -mc68020 -m68881 -mbitfield
as -mc68020 -o other.o /usr/tmp/cca03969.s
/usr/larry/users/klaiber/lib/gcc-ld -e start -dc -dp /lib/crt0.o /lib/Mcrt1.o other.o -lg++ /usr/larry/users/klaiber/lib/gcc-gnulib -lc
[uw-larry - 6] % a.out
1 148520 2
^^^^
it's the correct output allright
----------------------------------------
***HOWEVER***, as can be seen from the assembly code, g++ still doesn't
clean up the stack after the call to the constructor:
#NO_APP
gcc_compiled.:
.text
.even
.globl ___3FooPc
___3FooPc:
link a6,#0
movel a6@(8),a0
movel a6@(12),a0@
movel a0,d0
L1:
unlk a6
rts
LC0:
.ascii "%d %d %d\12\0"
.even
.globl _fun__FiP3Fooi
_fun__FiP3Fooi:
link a6,#0
movel a6@(16),sp@-
movel a6@(12),sp@-
movel a6@(8),sp@-
pea LC0
jbsr _printf
addw #16,sp
L2:
unlk a6
rts
LC1:
.ascii "crash\0"
.even
.globl _main
_main:
link a6,#-4
movel d2,sp@-
jbsr ___main
movel d0,d0
pea LC1
pea 4:w
jbsr ___builtin_new
addqw #4,sp
movel d0,d2
movel d2,sp@-
jbsr ___3FooPc
movel d2,a6@(-4)
pea 2:w
movel a6@(-4),sp@-
pea 1:w
jbsr _fun__FiP3Fooi
addw #20,sp
clrl d0
jra L3
L3:
movel a6@(-8),d2
unlk a6
rts
===========================================================================
PLEEEASE, try this and tell me whether you can reproduce the bug or whether
I have a screwed-up installation!
A quick bug fix would be even more greatly appreciated!
Alexander Klaiber
klaiber@cs.washington.edu