[gnu.g++.bug] BUG??

dlin@NYNEXST.COM (David Lin) (06/15/89)

Name : David Lin
Organization : NYNEX corp.
E-Mail : dlin@nynexst.com

Machine : Sun 3/110 with 68881
OS : SunOS 3.5
configuration : config.g++ sun3
G++ version : 1.35.0

***********************************************
Command for compilation :

g++ -S bug.cc -v

******************* Output *********************

g++ version 1.35.0
 /usr/local1/lib/gcc-cpp -+ -v -undef -D__GNU__ -D__GNUG__ -D__cplusplus -Dmc68000 -Dsun -Dunix -D__mc68000__ -D__sun__ -D__unix__ -D__HAVE_68881__ -Dmc68020 bug.cc /tmp/cca17942.cpp
GNU CPP version 1.35
 /usr/local1/lib/gcc-cc1plus /tmp/cca17942.cpp -quiet -dumpbase bug.cc -noreg -version -o bug.s
GNU C++ version 1.35.0 (68k, MIT syntax) compiled by GNU C version 1.35.

******************** List of source *********************

01	#include <stream.h>
02	
03	/* when no constructor is defined, program works fine */
04	
05	class A {
06		int i;
07	public:	//  constructors :
08		A() { cout << "construct 1\n"; }
09		A(const A& b) { cout << "construct 2\n"; }
10	public:
11		A operator-(A);
12		friend ostream& operator<<(ostream& k, A) { return k; }
13	};
14	
15	A A::operator-(A k) {
16		cout << "doing minus\n";
17		return(k);
18	}
19	
20	main ()
21	{
22		A a, d;
23		cout << "assignment done\n";
24		cout << (a-d) << "Got it\n";
25	}

********************************************

Problem:
	The program suppose to print out "Got it\n" at line 24.
	But it prints out garbage instead.  Getting rid of both
	constructors eliminates the problem.  Compilation with
	-S flag produced the following:

Sympton:
	Incorrect assembly instruction in output.
	The temporary data space on stack is not allocated right.
	Therefore clobbering the data on the stack.

********************************************

#NO_APP
gcc_compiled.:
.text
	.even
LC0:
	.double 0r0.00000000000000000000e+00
	.even
_op$alshift_expr_Sostream_SA:
	link a6,#0
	movel a6@(8),d1
	movel d1,d0
	jra L513
L513:
	unlk a6
	rts
LC1:
	.ascii "construct 2\12\0"
	.even
_A_PSA_SA:
	link a6,#0
	movel d2,sp@-
	movel a6@(8),d2
	tstl d2
	jne L515
	pea 4:w
	jbsr ___builtin_new
	movel d0,d2
	addqw #4,sp
L515:
	pea LC1
	pea _cout
	jbsr _op$alshift_expr_PSostream_PQI
	addqw #8,sp
	movel d2,d1
	movel d1,d0
	jra L514
L514:
	movel a6@(-4),d2
	unlk a6
	rts
LC2:
	.ascii "construct 1\12\0"
	.even
_A_PSA:
	link a6,#0
	movel d2,sp@-
	movel a6@(8),d2
	tstl d2
	jne L517
	pea 4:w
	jbsr ___builtin_new
	movel d0,d2
	addqw #4,sp
L517:
	pea LC2
	pea _cout
	jbsr _op$alshift_expr_PSostream_PQI
	addqw #8,sp
	movel d2,d1
	movel d1,d0
	jra L516
L516:
	movel a6@(-4),d2
	unlk a6
	rts
LC3:
	.ascii "doing minus\12\0"
	.even
.globl _op$minus_expr_PSA_SA
_op$minus_expr_PSA_SA:
	link a6,#0
	moveml #0x3800,sp@-
	movel a6@(8),d2
	movel a1,d4
	pea LC3
	pea _cout
	jbsr _op$alshift_expr_PSostream_PQI
	moveq #12,d0
	addl a6,d0
	movel d0,sp@-
	movel d4,d3
	movel d3,sp@-
	jbsr _A_PSA_SA
	jra L518
	movel d4,d0
L518:
	moveml a6@(-12),#0x1c
	unlk a6
	rts
LC4:
	.ascii "assignment done\12\0"
LC5:
	.ascii "Got it\12\0"
	.even
.globl _main
_main:
	link a6,#-8
	moveml #0x3e00,sp@-
	movel a6,d2
	subql #4,d2
	movel d2,sp@-
	jbsr _A_PSA
	movel a6,d3
	subql #8,d3
	movel d3,sp@-
	jbsr _A_PSA
	pea LC4
	pea _cout
	jbsr _op$alshift_expr_PSostream_PQI
	pea LC5
****************************
	subw #0,sp	| should be subw #8,sp
	movel sp,d6
	addql #4,d6
	subw #0,sp	| should be subw #8,sp
	movel sp,d0
	addql #4,d0
*****************************
	movel a6,d1
	subql #8,d1
	movel d1,sp@-
	movel d0,sp@-
	jbsr _A_PSA_SA
	addqw #8,sp
	movel d0,d0
	movel a6,d4
	subql #4,d4
	movel d4,sp@
	movel d6,a1
	jbsr _op$minus_expr_PSA_SA
	addqw #8,sp
	movel #_cout,sp@
	jbsr _op$alshift_expr_Sostream_SA
	addqw #8,sp
	movel d0,d5
	movel d5,sp@-
	jbsr _op$alshift_expr_PSostream_PQI
	addqw #8,sp
L519:
	moveml a6@(-28),#0x7c
	unlk a6
	rts

*****************************************************

At the location marked, the rtl output is:

*****************************************************

(insn 15 14 16 (set (reg:SI 15)
       (minus:SI (reg:SI 15)
           (const_int 0))) -1 (nil)
   (nil))

(insn 16 15 17 (set (reg:SI 59)
       (plus:SI (reg:SI 15)
           (const_int 4))) -1 (nil)
   (nil))

(insn 17 16 18 (set (reg:SI 15)
       (minus:SI (reg:SI 15)
           (const_int 0))) -1 (nil)
   (nil))

(insn 18 17 19 (set (reg:SI 60)
       (plus:SI (reg:SI 15)
           (const_int 4))) -1 (nil)
   (nil))

*****************************************************

If you need more info, please feel free to mail me.  I have no
access to gnu newsgroup, so I have no idea if the problem is
been posted or not.

-David