Article View: net.lang.c++
Article #2791.1 bugs & fixes
From: Bjarne Stroustrup
Date: Sat, 09 Aug 1986 01:38
Date: Sat, 09 Aug 1986 01:38
99 lines
2792 bytes
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!bsShow 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