Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: utzoo!mnetor!seismo!uwvax!crystal!solomon
From: solomon@crys.WISC.EDU (Marvin Solomon)
Newsgroups: comp.lang.c++
Subject: Re: RETBUG in cfront. Passing/Returning Class Instances.
Message-ID: <213@crys.WISC.EDU>
Date: Sun, 21-Dec-86 08:39:00 EST
Article-I.D.: crys.213
Posted: Sun Dec 21 08:39:00 1986
Date-Received: Sun, 21-Dec-86 21:00:24 EST
References: <59@otc.OZ>
Organization: U of Wisconsin CS Dept
Lines: 95
Summary: The test program for RETBUG may not show the bug even if it's present (as in the VAX 4.3 BSD C compiler).


Mike Mowbray pointed out that cfront contains an option (turned on in
the default version) to generate code to get around a C compiler bug,
and supplies a test program to check whether your C compiler has that bug.
His instructions are:

> The following c program allows you to determine whether your c compiler
> has the bug. Compile and run it. If it dumps core you have the bug. If
> it doesn't, then you may wish to edit the cfront makefile to undefine
> RETBUG, and then re-make cfront.

Unfortunately, the bug may be present even if the program compiles and
runs "correctly".  The Berkeley 4.3 UNIX compiler for the VAX (as well
as the 4.3beta and, I suspect, all earlier compliers) generates incorrect
code, but the incorrect code is harmless.  It copies a longword from
location 0 to another location.  On a SUN, virtual address 0 is not
a legal address, but on a VAX (under Berkeley UNIX) it is.  To make the
program core dump, change the initialization of i from 0 to -1.  Here
is the modified test program:
	struct Crap {
		int i;
	};

	struct Crap f(cp,ip)
	struct Crap *cp;
	int *ip;
	{
	cp->i = (*ip)++;
	return;
	}

	main()
	{
	struct Crap c;
	int i = -1;
	f(&c,&i);

	printf("%d %d\n",c.i,i);	/* should just print:  0 1  */
	}
And here is the assembler language generated by 'cc -S' (with annotation):
LL0:
	.data
	.text
	.align	1
	.globl	_f
_f:
	.word	L12
	jbr 	L14
L15:
	movl	*8(ap),r0	/ r0 = *ip
	incl	*8(ap)		/ ip++
	movl	r0,*4(ap)	/ cp->i = *ip
	jbr 	L13
L13:
	.lcomm	L16,4		/ return:
	movab	L16,r1		/ r1 = &temp
	movl	(r0),(r1)	/ *r1 = *r0      (!)
	movab	L16,r0		/ return &temp
	ret
	.set	L12,0x0
L14:
	jbr 	L15
	.data
	.text
	.align	1
	.globl	_main
_main:
	.word	L18
	jbr 	L20
L21:
	mnegl	$1,-8(fp)
	subl3	$8,fp,r0
	pushl	r0
	subl3	$4,fp,r0
	pushl	r0
	calls	$2,_f
	.data	1
L23:
	.ascii	"%d %d\12\0"
	.text
	pushl	-8(fp)
	pushl	-4(fp)
	pushl	$L23
	calls	$3,_printf
	ret
	.set	L18,0x0
L20:
	subl2	$8,sp
	jbr 	L21
	.data
-- 
	Marvin Solomon
	Computer Sciences Department
	University of Wisconsin, Madison WI
	solomon@gjetost.wisc.edu or seismo!uwvax!solomon