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