[LLVMbugs] [Bug 8678] New: Destructors are not called for C++ temp objects that are created when C++ objects are copied via ObjC dot syntax
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Wed Nov 24 02:44:39 PST 2010
http://llvm.org/bugs/show_bug.cgi?id=8678
Summary: Destructors are not called for C++ temp objects that
are created when C++ objects are copied via ObjC dot
syntax
Product: clang
Version: trunk
Platform: Macintosh
OS/Version: MacOS X
Status: NEW
Severity: normal
Priority: P
Component: -New Bugs
AssignedTo: unassignedclangbugs at nondot.org
ReportedBy: lgerbarg at gmail.com
CC: llvmbugs at cs.uiuc.edu
While tracing down a a ref leak with C++ shared_ptrs I found a situation where
the shared_ptr's destructor was not being called, which was artificially
increasing the ref count of the object and preventing its deletion. Below is a
reduced case that demonstrates the problem and two workaround. The bug only
occurs using ObjC dot syntax, if you use the getter via bracket syntax
everything works as expected.
#include <Foundation/Foundation.h>
#include <tr1/memory>
#include <stdio.h>
class CXXClass {
private:
unsigned long identity;
public:
CXXClass(short I) : identity(I) {
printf("Constructing: %lu\n", identity);
}
~CXXClass(void) {
printf("Destructing: %lu\n", identity);
}
unsigned long getIdentity(void) { return identity; }
};
@interface OBJCClass : NSObject {
std::tr1::shared_ptr<CXXClass> cxxClass;
}
@property (nonatomic) std::tr1::shared_ptr<CXXClass> cxxClass;
@end
@implementation OBJCClass
@end
int main (void) {
OBJCClass *test1 = [[OBJCClass alloc] init];
OBJCClass *test2 = [[OBJCClass alloc] init];
OBJCClass *test3 = [[OBJCClass alloc] init];
OBJCClass *test4 = [[OBJCClass alloc] init];
test1.cxxClass = std::tr1::shared_ptr<CXXClass>(new CXXClass(1));
test2.cxxClass = std::tr1::shared_ptr<CXXClass>(new CXXClass(2));
test3.cxxClass = std::tr1::shared_ptr<CXXClass>(new CXXClass(3));
test4.cxxClass = std::tr1::shared_ptr<CXXClass>(new CXXClass(4));
printf("Purposefully ignoring id 1 as a control group\n");
//BUG
//The property accessor copies cxxClass into a temp variable that is not
registered for cleanup
//Therefore the shared_ptr destructor is never called, and we leak the
CXXClass pointed to by
//test2.cxxClass
printf("Reading id %lu\n", test2.cxxClass->getIdentity());
//Workaround 1
//If you use normal ObjC message syntax instead of dot accessors everything
works correctly
printf("Reading id %lu\n", [test3 cxxClass]->getIdentity());
//Workaround 2
//If we explicitly assign the object to a name it will work fine
std::tr1::shared_ptr<CXXClass> temp = test4.cxxClass;
printf("Reading id %lu\n", temp->getIdentity());
//Control group, destructor called
[test1 release];
//Bugged version, destructor not called
[test2 release];
//Workaround 1 (destructor called later, at scope collapse);
[test3 release];
//Workaround 2 (destructor called later, at scope collapse);
[test4 release];
return 0;
}
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list