Merge pull request #149 from gnustep/checkARCAccessors-fix

Fix detection of ARC-incompatible memory management methods
main
David Chisnall 6 years ago committed by GitHub
commit ec8782e396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -26,6 +26,7 @@ set(TESTS
ConstantString.m ConstantString.m
Category.m Category.m
ExceptionTest.m ExceptionTest.m
FastARC.m
Forward.m Forward.m
ManyManySelectors.m ManyManySelectors.m
NestedExceptions.m NestedExceptions.m

@ -0,0 +1,104 @@
#include "Test.h"
#include <stdio.h>
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;
}

@ -77,8 +77,9 @@ static BOOL ownsMethod(Class cls, SEL sel)
} }
#define DEBUG_ARC_COMPAT
#ifdef DEBUG_ARC_COMPAT #ifdef DEBUG_ARC_COMPAT
#define ARC_DEBUG_LOG(...) fprintf(stderr, __VA_LIST__) #define ARC_DEBUG_LOG(...) fprintf(stderr, __VA_ARGS__)
#else #else
#define ARC_DEBUG_LOG(...) do {} while(0) #define ARC_DEBUG_LOG(...) do {} while(0)
#endif #endif
@ -104,14 +105,14 @@ static void checkARCAccessors(Class cls)
objc_clear_class_flag(cls, objc_class_flag_fast_arc); objc_clear_class_flag(cls, objc_class_flag_fast_arc);
return; return;
} }
owner = ownerForMethod(cls, retain); owner = ownerForMethod(cls, release);
if ((NULL != owner) && !ownsMethod(owner, isARC)) if ((NULL != owner) && !ownsMethod(owner, isARC))
{ {
ARC_DEBUG_LOG("%s does not support ARC correctly (implements release)\n", cls->name); ARC_DEBUG_LOG("%s does not support ARC correctly (implements release)\n", cls->name);
objc_clear_class_flag(cls, objc_class_flag_fast_arc); objc_clear_class_flag(cls, objc_class_flag_fast_arc);
return; return;
} }
owner = ownerForMethod(cls, retain); owner = ownerForMethod(cls, autorelease);
if ((NULL != owner) && !ownsMethod(owner, isARC)) if ((NULL != owner) && !ownsMethod(owner, isARC))
{ {
ARC_DEBUG_LOG("%s does not support ARC correctly (implements autorelease)\n", cls->name); ARC_DEBUG_LOG("%s does not support ARC correctly (implements autorelease)\n", cls->name);

Loading…
Cancel
Save