[gnu.g++.bug] G++ 1.27.0 bug passing class args by value

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