| /* APPLE LOCAL file radar 6214617 - modified for radar 5847213 */ |
| /* { dg-options "-mmacosx-version-min=10.5 -ObjC++" { target *-*-darwin* } } */ |
| /* { dg-do run } */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| |
| int constructors = 0; |
| int destructors = 0; |
| |
| void * _NSConcreteStackBlock[32]; |
| |
| #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 hack(void *block) { |
| /* APPLE LOCAL begin radar 6329245 */ |
| // check flags to see if constructor/destructor is available; |
| struct myblock { |
| void *isa; |
| int flags; |
| int reserved; |
| void (*Block_invoke)(void *); |
| struct Block_descriptor_1 { |
| unsigned long int reserved; // NULL |
| unsigned long int Block_size; // sizeof(struct Block_literal_1) |
| |
| // optional helper functions |
| void (*copyhelper)(void *dst, void *src); |
| void (*disposehelper)(void *src); |
| } *descriptor; |
| long space[32]; |
| } myversion, *mbp = (struct myblock *)block; |
| /* APPLE LOCAL end radar 6329245 */ |
| printf("flags -> %x\n", mbp->flags); |
| if (! ((1<<25) & mbp->flags)) { |
| printf("no copy/dispose helper functions provided!\n"); |
| exit(1); |
| } |
| if (! ((1<<26) & mbp->flags)) { |
| printf("no marking for ctor/dtors present!\n"); |
| exit(1); |
| } |
| printf("copyhelper -> %p\n", mbp->descriptor->copyhelper); |
| // simulate copy |
| mbp->descriptor->copyhelper(&myversion, mbp); |
| if (constructors != 3) { |
| printf("copy helper didn't do the constructor part\n"); |
| exit(1); |
| } |
| printf("disposehelper -> %p\n", mbp->descriptor->disposehelper); |
| // simulate destroy |
| mbp->descriptor->disposehelper(&myversion); |
| if (destructors != 1) { |
| printf("dispose helper didn't do the dispose\n"); |
| exit(1); |
| } |
| } |
| void testRoutine() { |
| TestObject one; |
| |
| void (^b)(void) = ^{ printf("my copy of one is %d\n", one.version()); }; |
| hack(b); |
| } |
| |
| int main(char *argc, char *argv[]) { |
| testRoutine(); |
| exit(0); |
| } |