This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

c++ PATCH: vbase dtors called multiple times



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);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]