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