This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH: Fix double destruction
- From: Mark Mitchell <mark at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 13 Feb 2002 12:48:25 -0800
- Subject: C++ PATCH: Fix double destruction
I checked in the attached patch from Richard Smith on the GCC 3.0
branch. It fixes a regression from GCC 2.95.x whereby we generated
incorrect code when passing classes by value through thunks.
Commited on the 3.0 branch only; Richard performed the testing.
I will also commit the test on the trunk.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.747.2.36
diff -c -p -r1.747.2.36 decl.c
*** decl.c 2002/01/18 03:36:08 1.747.2.36
--- decl.c 2002/02/13 18:12:23
*************** maybe_build_cleanup (decl)
*** 14348,14354 ****
{
tree type = TREE_TYPE (decl);
! if (type != error_mark_node && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
{
int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
tree rval;
--- 14348,14358 ----
{
tree type = TREE_TYPE (decl);
! if (type != error_mark_node && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
! /* The destructor must not be called on the parameters of a thunk
! because they are not copied when the thunk calls the function
! to which is thunking. */
! && (! DECL_CONTEXT (decl) || ! DECL_THUNK_P (DECL_CONTEXT (decl))))
{
int flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR;
tree rval;
Index: testsuite/g++.old-deja/g++.other/thunk1.C
===================================================================
RCS file: thunk1.C
diff -N thunk1.C
*** /dev/null Tue May 5 13:32:27 1998
--- thunk1.C Wed Feb 13 10:12:40 2002
***************
*** 0 ****
--- 1,35 ----
+ extern "C" void abort();
+
+ int ic;
+
+ struct X
+ {
+ X() { ++ic; }
+ X( const X & ) { ++ic; }
+ ~X() { if (--ic < 0) abort(); }
+ };
+
+ struct V
+ {
+ virtual ~V() {}
+ };
+
+ struct A : public virtual V
+ {
+ };
+
+ struct B : public virtual V
+ {
+ virtual void foo( X ) = 0;
+ };
+
+ struct D : public A, public virtual B
+ {
+ virtual void foo( X ) {}
+ };
+
+ int main()
+ {
+ B *b = new D;
+ b->foo( X() );
+ }