From 73891aaeccc91c5ef3d4ea62713e0db48e840908 Mon Sep 17 00:00:00 2001 From: theraven Date: Mon, 4 Jul 2011 15:04:56 +0000 Subject: [PATCH] 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. --- arc.m | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arc.m b/arc.m index e47020c..acde75a 100644 --- a/arc.m +++ b/arc.m @@ -7,12 +7,14 @@ #import "visibility.h" #import "objc/hooks.h" #import "objc/objc-arc.h" +#import "objc/blocks_runtime.h" #ifndef NO_PTHREADS #include pthread_key_t ReturnRetained; #endif +extern struct objc_class _NSConcreteStackBlock; @interface NSAutoreleasePool + (Class)class; @@ -31,6 +33,11 @@ extern BOOL FastARCAutorelease; 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)) { intptr_t *refCount = ((intptr_t*)obj) - 1; @@ -158,7 +165,8 @@ id objc_retainAutorelease(id obj) id objc_retainAutoreleaseReturnValue(id obj) { - return objc_autoreleaseReturnValue(objc_retain(obj)); + if (nil == obj) { return obj; } + return objc_autoreleaseReturnValue(retain(obj)); }