🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: net.lang.c++
Article #279

1.1 bugs & fixes

#279
From: Bjarne Stroustrup
Date: Sat, 09 Aug 1986 01:38
99 lines
2792 bytes
Here are two nasty bugs we have found in Release 1.1 - and their fixes.
Please note that this relates to release 1.1 only.

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

``destroy before return'' bug:

class foo {
public:
	foo();
	~foo();
};

foo func(int i)
{
	foo my_foo;
	return my_foo;
}

This causes cfront to generate bad code.
A bug causes my_foo to be destroyed and THEN returned.
There is no compile time warning.

This is fixed by adding the code in case NAME: of not_safe() in simpl.c:

bit not_safe(Pexpr e)
{

	switch (e->base) {
	default:
		return 1;
/*
	case CALL:
	case G_CALL:
	case DOT:
	case REF:
	case ANAME:
		return 1;
*/
	case NAME:
		// if the name is automatic and has a destructor it is not safe
		// to destroy it before returning an expression depending on it
	{	Pname n = Pname(e);
		if (n->n_table!=gtbl && n->n_table->t_name==0) {
			Pname cn = n->tp->is_cl_obj();
			if (cn && Pclass(cn->tp)->has_dtor()) return 1;
		}
	}
	case IVAL:
	case ICON:

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

bad code for pointer to function bug:

struct X {
	X(X&);
};

void f(register X (*fp)(char*, double))
{
	(*pf)("arg",1.0));	// produces bad code
	pf("arg",1.0);		// produces good code
}

The problem shows up as a cc complaint about casts.
The problem only occurs when with a pointer to function returning an X for
which X(X&) is declared.

The fix is in case CALL of expr::print() in print.c:

	case G_CALL:
	case CALL:
	{	Pname fn = fct_name;
		Pname at;
		if (fn && print_mode==SIMPL) {
			Pfct f = (Pfct)fn->tp;
//error('d',"call%n: %t",fn,f);
			if (f->base==OVERLOAD) { /* overloaded after call */
				Pgen g = (Pgen)f;
				fct_name = fn = g->fct_list->f;
				f = (Pfct)fn->tp;
			}
			fn->print();
			at = (f->f_this) ? f->f_this : (f->f_result) ? f->f_result : f->argtype;
		}
		else {
//error('d',"e1%k e1->tp %d %d%t",e1->base,e1->tp,e1->tp->base,e1->tp);
			Pfct f = Pfct(e1->tp);
			eprint(e1);
			if (f)	{	// pointer to fct
				while (f->base == TYPE) f = Pfct(Pbase(f)->b_name->tp);
				at = (f->f_result) ? f->f_result : f->argtype;
			}
			else			// virtual: argtype encoded
				at = (Pname)e1->e1->tp;
		}

********************************************************************
Technical Details
Message-ID: <5933@alice.uUCp>
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!caip!princeton!allegra!alice!bs

Show Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Path: arc1-ca.pugleaf.net!utzoo!watmath!clyde!caip!princeton!allegra!alice!bs
From: bs@alice.UucP (Bjarne Stroustrup)
Newsgroups: net.lang.c++
Subject: 1.1 bugs & fixes
Message-ID: <5933@alice.uUCp>
Date: Fri, 8-Aug-86 21:38:09 EDT
Article-I.D.: alice.5933
Posted: Fri Aug  8 21:38:09 1986
Date-Received: Mon, 11-Aug-86 01:39:55 EDT
Organization: Bell Labs, Murray Hill
Lines: 99