Two small ARC fixes:

- Make objc_retain() check for stack blocks and implicitly copy them.  This fixes the case where a block pointer is stored in an object-typed variable and is assigned.
- Tweak objc_retainAutoreleaseReturnValue() so that the ARC optimiser doesn't detect that the body looks like a call to objc_retainAutoreleaseReturnValue() and replace it with an infinitely recursive call.

The second fix now means that arc.m will compile with clang without producing a function that calls itself.
main
theraven 15 years ago
parent fce7c776b6
commit 73891aaecc

10
arc.m

@ -7,12 +7,14 @@
#import "visibility.h" #import "visibility.h"
#import "objc/hooks.h" #import "objc/hooks.h"
#import "objc/objc-arc.h" #import "objc/objc-arc.h"
#import "objc/blocks_runtime.h"
#ifndef NO_PTHREADS #ifndef NO_PTHREADS
#include <pthread.h> #include <pthread.h>
pthread_key_t ReturnRetained; pthread_key_t ReturnRetained;
#endif #endif
extern struct objc_class _NSConcreteStackBlock;
@interface NSAutoreleasePool @interface NSAutoreleasePool
+ (Class)class; + (Class)class;
@ -31,6 +33,11 @@ extern BOOL FastARCAutorelease;
static inline id retain(id obj) static inline id retain(id obj)
{ {
if ((Class)&_NSConcreteStackBlock == obj->isa)
{
fprintf(stderr, "Retaining block\n");
return Block_copy(obj);
}
if (objc_test_class_flag(obj->isa, objc_class_flag_fast_arc)) if (objc_test_class_flag(obj->isa, objc_class_flag_fast_arc))
{ {
intptr_t *refCount = ((intptr_t*)obj) - 1; intptr_t *refCount = ((intptr_t*)obj) - 1;
@ -158,7 +165,8 @@ id objc_retainAutorelease(id obj)
id objc_retainAutoreleaseReturnValue(id obj) id objc_retainAutoreleaseReturnValue(id obj)
{ {
return objc_autoreleaseReturnValue(objc_retain(obj)); if (nil == obj) { return obj; }
return objc_autoreleaseReturnValue(retain(obj));
} }

Loading…
Cancel
Save