/* * Copyright (c) 2010 Apple Inc. All rights reserved. * * @APPLE_LLVM_LICENSE_HEADER@ */ // TEST_CONFIG rdar://6214670 // TEST_CFLAGS -framework Foundation #import #import #import #import "test.h" int constructors = 0; int destructors = 0; #import void hack(void *block) { printf("Block_dump says: %s\n", _Block_dump(block)); } #define CONST const class TestObject { public: TestObject(CONST TestObject& inObj); TestObject(); ~TestObject(); TestObject& operator=(CONST TestObject& inObj); int version() CONST { return _version; } private: mutable int _version; }; TestObject::TestObject(CONST TestObject& inObj) { ++constructors; _version = inObj._version; //printf("%p (%d) -- TestObject(const TestObject&) called\n", this, _version); } TestObject::TestObject() { _version = ++constructors; //printf("%p (%d) -- TestObject() called\n", this, _version); } TestObject::~TestObject() { //printf("%p -- ~TestObject() called\n", this); ++destructors; } TestObject& TestObject::operator=(CONST TestObject& inObj) { //printf("%p -- operator= called\n", this); _version = inObj._version; return *this; } void testRoutine() { TestObject one; void (^b)(void) = [^{ printf("my copy of one is %d\n", one.version()); } copy]; #if 0 // just try one copy, one release for (int i = 0; i < 10; ++i) [b retain]; for (int i = 0; i < 10; ++i) [b release]; for (int i = 0; i < 10; ++i) Block_copy(b); for (int i = 0; i < 10; ++i) Block_release(b); #endif //hack(^{ printf("my copy of one is %d\n", one.version()); }); //hack(b); [b release]; } int main() { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; //testGC(); for (int i = 0; i < 200; ++i) // do enough to trigger TLC if GC is on testRoutine(); objc_collect(OBJC_EXHAUSTIVE_COLLECTION | OBJC_WAIT_UNTIL_DONE); [pool drain]; if (constructors != destructors) { fail("didn't recover %d const copies", constructors - destructors); } succeed(__FILE__); }