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]
Other format: [Raw text]

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() );
+ }


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