c++ PATCH: vbase dtors called multiple times
scott snyder
snyder@fnal.gov
Sun Apr 30 20:20:00 GMT 2000
hi -
For a recent cvs version of g++ (2.96 20000428 on i686-pc-linux-gnu),
gcc generates invalid code for the following input:
-------------------------------------------------------------------------
extern "C" int printf (...);
class CC
{
public:
CC () { printf ("CC ctor %x\n", (unsigned)this); }
virtual ~CC () { printf ("CC dtor %x\n", (unsigned)this); }
};
class BB : virtual public CC
{
public:
BB() {printf ("BB ctor %x\n", (unsigned)this); }
~BB() {printf ("BB dtor %x\n", (unsigned)this); }
};
class AA : public virtual BB
{
public:
AA () { printf ("AA ctor %x\n", (unsigned)this); }
~AA () { printf ("AA dtor %x\n", (unsigned)this); }
};
int main ()
{
AA xx;
return 0;
}
-------------------------------------------------------------------------
Here's what happens when i compile and run this:
$ g++ -o egcsbug17 egcsbug17.cc
$ ./egcsbug17
CC ctor bffff8e4
BB ctor bffff8e8
AA ctor bffff8e0
AA dtor bffff8e0
BB dtor bffff8e8
CC dtor bffff8e4
CC dtor bffff8e4
Note that the CC destructor gets run twice.
Here's an excerpt from the generated code for ~AA, after the printf
call:
movl 12(%ebp), %eax
andl $2, %eax
testl %eax, %eax
je .L26
subl $8, %esp
pushl $2
movl 8(%ebp), %eax
pushl (%eax)
call _._2BB
addl $16, %esp
subl $8, %esp
pushl $2
movl 8(%ebp), %edx
movl (%edx), %eax
pushl (%eax)
call _._2CC
addl $16, %esp
The destructor starts by testing the internal in_chrg parameter.
If bit 1 (0x02) is set, that means we're to call the destructors
for virtual bases. However, when we call the virtual bases,
we pass them in turn an in_chrg parameter of 0x02 -- telling them
also to delete any virtual bases. So destructors for vbases nested
more than one level deep get run more than once.
Here's what looks to me like the fix.
It makes the test case given here execute correctly, and doesn't
change the testsuite results.
thanks,
sss
2000-04-29 scott snyder <snyder@fnal.gov>
* decl.c (finish_destructor_body): When we delete the vbases, use
base_dtor_identifier, not complete_dtor_identifier.
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.598
diff -u -p -r1.598 decl.c
--- decl.c 2000/04/28 22:10:24 1.598
+++ decl.c 2000/05/01 02:54:00
@@ -13875,7 +13877,7 @@ finish_destructor_body ()
TYPE_BINFO (current_class_type));
finish_expr_stmt
(build_scoped_method_call
- (current_class_ref, vb, complete_dtor_identifier,
+ (current_class_ref, vb, base_dtor_identifier,
NULL_TREE));
}
vbases = TREE_CHAIN (vbases);
More information about the Gcc-patches
mailing list