bug-gnustep
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #41111] C++ destructors not called correctly in finalize breaking o


From: Doug Warren
Subject: [bug #41111] C++ destructors not called correctly in finalize breaking objc_setAssociatedObject
Date: Sun, 05 Jan 2014 18:30:37 +0000
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36

URL:
  <http://savannah.gnu.org/bugs/?41111>

                 Summary: C++ destructors not called correctly in finalize
breaking objc_setAssociatedObject
                 Project: GNUstep
            Submitted by: doug_w
            Submitted on: Sun 05 Jan 2014 06:30:36 PM GMT
                Category: Base/Foundation
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any

    _______________________________________________________

Details:

NSObject -finalize method does not call C++ destructors correctly in every
case.  This breaks libobjc2's objc_setAssociatedObject retain policy.  I've
attached a GNUStep style test that fails to demonstrate this.

The problem looks like it was this optimization:
  /* C++ destructors must be called in the opposite order to their
   * creators, so start at the leaf class and then go up the tree until we
   * get to the root class.  As a small optimisation, we don't bother
   * visiting any classes that don't have an implementation of this method
   * (including one inherited from a superclass).
   *
   * Care must be taken not to call inherited .cxx_destruct methods.
   */
  while (class_respondsToSelector(destructorClass, cxx_destruct))
    {
      IMP newDestructor;

      newDestructor
        = class_getMethodImplementation(destructorClass, cxx_destruct);
      destructorClass = class_getSuperclass(destructorClass);

      if (newDestructor != destructor)
          {
          newDestructor(self, cxx_destruct);
          destructor = newDestructor;
        }
    }

In my local tree I've replaced it with:
        while (destructorClass)
        {
                if (class_respondsToSelector(destructorClass, cxx_destruct))
                {
                        IMP newDestructor = 
class_getMethodImplementation(destructorClass,
cxx_destruct);
                        destructorClass = class_getSuperclass(destructorClass);

                        if (newDestructor != destructor)
                        {
                                newDestructor(self, cxx_destruct);
                                destructor = newDestructor;
                        }
                }
                else
                {
                        destructorClass = class_getSuperclass(destructorClass);
                }
        }

And I've been using it for about a month now with no ill effect.



    _______________________________________________________

File Attachments:


-------------------------------------------------------
Date: Sun 05 Jan 2014 06:30:36 PM GMT  Name: associated.m  Size: 1kB   By:
doug_w

<http://savannah.gnu.org/bugs/download.php?file_id=30195>

    _______________________________________________________

Reply to this item at:

  <http://savannah.gnu.org/bugs/?41111>

_______________________________________________
  Message sent via/by Savannah
  http://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]