ball@udel.EDU (Gene Ball) (11/12/88)
g++ 1.27.0 generates incorrect code when passing class parameters by value. Bad arguments are passed to the (non-inline) constructor that copies the actual parameter. Example: #include <std.h> #include <stream.h> class F { public: int v; F(){} F(F &f); }; F::F(F &f) { v = f.v; } void test(F p) { cout << "p.v = " << p.v << "\n"; } main() { F x; x.v = 77; test(x); cout << "x.v = " << x.v << "\n"; } ================================================================ g++ 1.27.0 tm-sun3.h ra[1] g++ -v -S bug.cc g++ version 1.27.0 /usr/gnu/lib/gcc-cpp+ -v -undef -D__GNU__ -D__GNUG__ -Dmc68000 -Dsun -Dunix bug.cc /tmp/cca02245.cpp GNU CPP version 1.27.0 /usr/gnu/lib/gcc-c++ /tmp/cca02245.cpp -quiet -dumpbase bug.cc -noreg -version -o bug.s GNU C++ version 1.27.0 (68k, MIT syntax) compiled by GNU C version 1.27. ra[2] bug p.v = 251657660 // this should be 77 x.v = 77 ================================================================ _main: link a6,#-4 // reserve frame space for x moveml #0x3c00,sp@- movel a6,d0 subql #4,d0 movel d0,sp@- // push &x jbsr _F_PSF // init x moveq #77,d1 movel d1,a6@(-4) // x.v = 77 // test(x); movel sp,d2 // save sp subql #4,sp // reserve temp space for the actual parm // now, sp = &tmp movel a6,d0 subql #4,d0 // d0 = &x movel d0,sp@- // push d0 (&x) movel sp,sp@- // push sp // this should be &tmp, but it ISN'T because // &x was pushed in between jbsr _F_PSF_SF // call constructor F(&F) to copy parm movel d0,d0 jbsr _test // actual already loaded into stack movel d2,sp movel #_cout,d3 // cout << etc ================================================================ When the constructur is expanded inline and optimized, the address of the temporary is saved in a register (apparently to allow the unecessary test for it being NULL), so it gets passed correctly. movel sp,d2 subql #4,sp movel sp,d3 // d3 = &tmp movel a6,d4 subql #4,d4 movel a6,d0 subql #4,d0 tstl d3 // test d3 == 0 --- silly jne L153 pea 4:w jbsr ___builtin_new movel d0,d3 addqw #4,sp L153: movel d3,a0 movel d4,a1 movel a1@,a0@ // tmp.v = x.v movel d3,d0 movel d0,d1 jra L152 L152: jbsr _test movel d2,sp