diff --git a/Test/CMakeLists.txt b/Test/CMakeLists.txt index bec7f2b..10993b8 100644 --- a/Test/CMakeLists.txt +++ b/Test/CMakeLists.txt @@ -26,6 +26,7 @@ set(TESTS ConstantString.m Category.m ExceptionTest.m + FastARC.m Forward.m ManyManySelectors.m NestedExceptions.m diff --git a/Test/FastARC.m b/Test/FastARC.m new file mode 100644 index 0000000..d7c6d6a --- /dev/null +++ b/Test/FastARC.m @@ -0,0 +1,104 @@ +#include "Test.h" +#include + +static BOOL called; + +@interface AllUnsafe : Test @end +@implementation AllUnsafe +- (id)retain +{ + return self; +} +- (void)release {} +- (id)autorelease +{ + return self; +} +@end + +@interface Retain : AllUnsafe @end +@implementation Retain +- (id)retain +{ + called = YES; + return self; +} +@end + +@interface RetainSafe : AllUnsafe @end +@implementation RetainSafe +- (id)retain +{ + return self; +} +- (void)_ARCCompliantRetainRelease {} +@end + +@interface Release : AllUnsafe @end +@implementation Release +- (void)release +{ + called = YES; +} +@end + +@interface ReleaseSafe : AllUnsafe @end +@implementation ReleaseSafe +- (void)release +{ +} +- (void)_ARCCompliantRetainRelease {} +@end + +@interface Autorelease : AllUnsafe @end +@implementation Autorelease +- (id)autorelease +{ + called = YES; + return self; +} +@end + +@interface AutoreleaseSafe : AllUnsafe @end +@implementation AutoreleaseSafe +- (id)autorelease +{ + return self; +} +- (void)_ARCCompliantRetainRelease {} +@end + +void check(id obj, BOOL expected) +{ + fprintf(stderr, "Checking %s\n", class_getName(object_getClass(obj))); +} + +int main() +{ + called = NO; + objc_retain([Retain new]); + assert(called == YES); + + called = NO; + objc_retain([RetainSafe new]); + assert(called == NO); + + called = NO; + objc_release([Release new]); + assert(called == YES); + + called = NO; + objc_release([ReleaseSafe new]); + assert(called == NO); + + called = NO; + objc_autorelease([Autorelease new]); + assert(called == YES); + + called = NO; + objc_autorelease([AutoreleaseSafe new]); + assert(called == NO); + + return 0; +} + diff --git a/dtable.c b/dtable.c index 8190089..aa6eb96 100644 --- a/dtable.c +++ b/dtable.c @@ -77,8 +77,9 @@ static BOOL ownsMethod(Class cls, SEL sel) } +#define DEBUG_ARC_COMPAT #ifdef DEBUG_ARC_COMPAT -#define ARC_DEBUG_LOG(...) fprintf(stderr, __VA_LIST__) +#define ARC_DEBUG_LOG(...) fprintf(stderr, __VA_ARGS__) #else #define ARC_DEBUG_LOG(...) do {} while(0) #endif @@ -104,14 +105,14 @@ static void checkARCAccessors(Class cls) objc_clear_class_flag(cls, objc_class_flag_fast_arc); return; } - owner = ownerForMethod(cls, retain); + owner = ownerForMethod(cls, release); if ((NULL != owner) && !ownsMethod(owner, isARC)) { ARC_DEBUG_LOG("%s does not support ARC correctly (implements release)\n", cls->name); objc_clear_class_flag(cls, objc_class_flag_fast_arc); return; } - owner = ownerForMethod(cls, retain); + owner = ownerForMethod(cls, autorelease); if ((NULL != owner) && !ownsMethod(owner, isARC)) { ARC_DEBUG_LOG("%s does not support ARC correctly (implements autorelease)\n", cls->name);