atomicProperty.mm   [plain text]


// TEST_CONFIG CC=clang

#include "test.h"
#include <objc/runtime.h>
#include <objc/objc-internal.h>
#import <Foundation/NSObject.h>

class SerialNumber {
    size_t _number;
public:
    SerialNumber() : _number(42) {}
    SerialNumber(const SerialNumber &number) : _number(number._number + 1) {}
    SerialNumber &operator=(const SerialNumber &number) { _number = number._number + 1; return *this; }

    int operator==(const SerialNumber &number) { return _number == number._number; }
    int operator!=(const SerialNumber &number) { return _number != number._number; }
};

@interface TestAtomicProperty : NSObject {
    SerialNumber number;
}
@property(atomic) SerialNumber number;
@end

@implementation TestAtomicProperty

#if 1 // with new enough compiler, this will be synthesized automatically.

extern void objc_copyCppObjectAtomic(void *dest, const void *src, void (*copyHelper) (void *dest, const void *source));

static void copySerialNumber(void *d, const void *s) {
    SerialNumber *dest = (SerialNumber *)d;
    const SerialNumber *src = (const SerialNumber *)s;
    dest->operator=(*src);
}

- (SerialNumber)number {
    SerialNumber result;
    objc_copyCppObjectAtomic(&result, &number, copySerialNumber);
    return result;
}

- (void)setNumber:(SerialNumber)aNumber {
    objc_copyCppObjectAtomic(&number, &aNumber, copySerialNumber);
}

+(void)initialize {
    testwarn("rdar://6137845 compiler should synthesize calls to objc_copyCppObjectAtomic");
}

#else
@synthesize number;
#endif    

@end

int main()
{
    PUSH_POOL {
        SerialNumber number;
        TestAtomicProperty *test = [TestAtomicProperty new];
        test.number = number;
        testassert(test.number != number);
    } POP_POOL;

    succeed(__FILE__);
}