[comp.sys.amiga.tech] Manx Aztec C bug

tas@mtuxo.att.com (XMPC2-T.SKROBALA) (01/18/89)

- - - - -

The following bug report will be sent to Manx.  Most people probably won't
hit it, but if you do, it can be a real pain to track down.

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

Aztec C 3.6 for the Amiga produces incorrect code for the following
short program.  Note that, in this example, a bitwise '|' is used where
a logical '||' would make more sense, but it still is valid C code, and
such use does occur from time to time.

From the assembly code produced, you can see that the compiler saves the
temporary value in d0 on the stack before calling function2.  The 
problem is that that value is popped off the stack even in the case when
function2 is not called and the value isn't on the stack in the first
place.  When this happens, an invalid value is popped off, and, worse,
the stack is corrupted and all sorts of bad things can result.

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

main()
{
	register k;

	if( (k == 259 && function1()) | (k == 260 && function2()) )
	{
		k = 0 ;
	}
}

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

;:ts=8
;main()
;{
	public	_main
_main:
	link	a5,#.2
	movem.l	.3,-(sp)
;	register k;
;
;	if( (k == 259 && function1()) | (k == 260 && function2()) )
;	{
	cmp.w	#259,d4
	bne	.5
	jsr	_function1
	tst.w	d0
	beq	.5
	move.l	#1,d0
	bra	.6
.5
	move.l	#0,d0
.6
	cmp.w	#260,d4
	bne	.7
	move.w	d0,-(sp)    ; this doesn't get executed if bne above happens
	jsr	_function2
	tst.w	d0
	beq	.7
	move.l	#1,d0
	bra	.8
.7
	move.l	#0,d0
.8
	move.w	(sp)+,d1   ; but this always happens, making sp and d1 wrong
	or.w	d0,d1
	beq	.4
;		k = 0 ;
	move.l	#0,d4
;	}
;}
.4
.9
	movem.l	(sp)+,.3
	unlk	a5
	rts
.2	equ	0
.3	reg	d4
	public	_function2
	public	_function1
	public	.begin
	dseg
	end