[comp.lang.c++] Bug

kanner@apple.UUCP (Herbert Kanner) (07/01/87)

Can anyone shed light on the following:

The file dcl1.c contains the following four lines.

int thing1(int *());
int thing2(int, int *());
int thing3(int (*)());
int thing4(int, int (*)());

The result of a C++ compilation is below:
CC  dcl1.c:
"dcl1.c", line 1: error: syntax error
"dcl1.c", line 2: error: syntax error
"dcl1.c", line 3: error: syntax error
"dcl1.c", line 3: error: syntax error
"dcl1.c", line 3: error: syntax error
5 errors


The one I really want is thing3.  I want to declare a function whose
parameter is a pointer to a function returning an int.  The other
three lines were exploratory, trying to isolate the apparent bug.  It
is interesting that the compiler accepts thing4 but not thing3.
-- 
Herb Kanner
Apple Computer, Inc.
{idi, ios, nsc}!apple!kanner

pabuhr@water.UUCP (09/29/87)

/*
It took me 4 hours to locate this problem in a large program.
If you look at the C++ code generated for the inline procedure
`identity', you will notice that it has been optimized into the
same single constant! I need a drink.
*/

class test {
    public:
	inline int identity(test *);
};

inline int test::identity(test *h) {
	if (this != h) {
		return(0);
	} else {
		return(1);
	}
};

main() {
	test a, b;

	a.identity(&a);
	a.identity(&b);
}

================================= C++ output
cd /u/pabuhr/sm/string/
ccc -F test.cc
#line 1 "test.cc"

/* <<cfront 1.2.1 2/16/87>> */
/* < test.cc */
char *_new(); char _delete(); char *_vec_new(); char _vec_delete();

#line 1 "test.cc"

#line 8 "test.cc"
struct test {	/* sizeof test == 1 */
char _dummy; };

#line 13 "test.cc"

#line 21 "test.cc"
int main (){ _main(); { 
#line 22 "test.cc"
struct test _au1_a ;

#line 22 "test.cc"
struct test _au1_b ;

#line 24 "test.cc"
( (1 )) ;            <=== where's the beef ???
( (1 )) ;            <=== where's the beef ???
}
};

/* the end */

Compilation finished at Mon Sep 28 21:53:05

bs@alice.UUCP (10/01/87)

# From cbosgd!water.UUCP!pabuhr Mon Sep 28 22:05:29 1987
# Organization: U. of Waterloo, Ontario
# 
# /*
# It took me 4 hours to locate this problem in a large program.
# If you look at the C++ code generated for the inline procedure
# `identity', you will notice that it has been optimized into the
# same single constant! I need a drink.

	I guess I owe you one. Sorry. Thank you for finding that one.
	Have a look at my test::id() function.
	It doesn't trigger that bug.
# */
# 
# class test {
#    public:
# 	inline int identity(test *);
 	int id(test *h) { return this==h; }
# };
# 
# inline int test::identity(test *h) {
# 	if (this != h) {
# 		return(0);
# 	} else {
# 		return(1);
# 	}
# };
# 
# main() {
# 	test a, b;
# 
# 	a.identity(&a);
# 	a.identity(&b);

	a.id(&a);
	a.id(&b);
# }

You can fix that bug by going into expr::eval() in expr2.c and
adding one statement:

	int i1 = (e1) ? e1->eval() : 0;				// after
	int i2 = (e2) ? e2->eval() : 0;				// this

	if (binary_val && i1==9999 && i2==9999) {		// add this
		Neval = "";					// add this
		return 1;					// add this
	}							// add this
};

amit@cybvax0.UUCP (Amit Green) (01/03/88)

Problem:
	double x (a, b, c, d)
	long a;
	double b, c;
	char d;
	{ return a + b + c + d;		//  Avoid "not used" error message
	}

Produces the following code (shortened & comment added):
	"", line 1: warning: old style definition of x()

	/* <<cfront 1.2.1 2/16/87>> */
	double x (_au0_a , _au0_b , _au0_c , _au0_d )
	long _au0_a ;
	double _au0_b ;
	int _au0_c ;		//  <=  This line is wrong, should be a double
	char _au0_d ;
	{ return (((_au0_a + _au0_b )+ _au0_c )+ _au0_d );
	}
	;

Notice:
	The declaration of 'c' as a double is lost (and it defaults to
	an int).  In fact the following may be presented to the compiler:

	double x (a, b, c, d)
	long a;
	double b, c;
	char d;
	short c;	//  Redeclare 'c' as the declaration above was lost
	{ return a + b + c + d;		//  Avoid "not used" error message
	}

Analysis:
	gram.y (from cfront 1.2.1) has a bug:
	line 1: /*ident	"@(#)cfront:src/gram.y	1.10" */
	line 1225:                error("FD inAL (%n)",$<pn>2);
	line 1226:	       else if ($1)
	line 1227:		  $<nl>1->add($<pn>2);

	The statement should be '$<nl>1->add_list($<pn>2)' since '$<pn>2'
	may be list, as it is in the declaration 'double b, c'.

	The problem exist only when '$<nl>1' is already a list (as it is
	from the declaration 'long a'), and is then appended to
	again (as it is in the declaration 'char d').

Final Comment:
	This bug may have been mentioned before, I am not sure.  I have
	printed out all the previous message since comp.lang.c++ started
	(even from when it was called net.lang.c++), and am still in
	the process of reading them; if this is a repeat, sorry.

				Amit Green
				{harvard,mit-eddie}!cybvax0!amit