Fix a bug with blocks in ARC mode being incorrectly released.

This commit is contained in:
theraven 2013-03-12 08:51:59 +00:00
parent 93e297fd87
commit 193629d8a2
3 changed files with 33 additions and 1 deletions

17
Test/BlockTest_arc.m Normal file
View File

@ -0,0 +1,17 @@
#include <stdio.h>
int foo() {
__block id x;
void (^hello)(void) = ^(void) {
printf("hello is running, %p\n", x);
};
printf("1\n");
hello();
printf("2\n");
hello = 0; // Here ARC is releasing the block, that's why we don't see '3' printed.
printf("3\n");
return 0;
}
int main() {
return foo();
}

View File

@ -7,6 +7,7 @@
set(TESTS
AllocatePair.m
BlockImpTest.m
BlockTest_arc.m
BoxedForeignException.m
ExceptionTest.m
ForeignException.m
@ -26,9 +27,13 @@ set(TESTS
function(addtest_flags TEST FLAGS TEST_SOURCE)
add_executable(${TEST} ${TEST_SOURCE})
add_test(${TEST} ${TEST})
set(ARC "")
if (TEST MATCHES ".*_arc")
set(ARC "-fobjc-arc")
endif()
set_target_properties(${TEST} PROPERTIES
INCLUDE_DIRECTORIES "${CMAKE_SOURCE_DIR}"
COMPILE_FLAGS "-fobjc-runtime=gnustep-1.7 -fblocks ${FLAGS}"
COMPILE_FLAGS "-fobjc-runtime=gnustep-1.7 -fblocks ${FLAGS} ${ARC}"
LINKER_LANGUAGE C
)
set_property(TEST ${TEST} PROPERTY

10
arc.m
View File

@ -185,6 +185,16 @@ static inline void release(id obj)
{
if (isSmallObject(obj)) { return; }
Class cls = obj->isa;
if (cls == &_NSConcreteMallocBlock)
{
_Block_release(obj);
return;
}
if ((cls == &_NSConcreteStackBlock) ||
(cls == &_NSConcreteGlobalBlock))
{
return;
}
if (objc_test_class_flag(cls, objc_class_flag_fast_arc))
{
intptr_t *refCount = ((intptr_t*)obj) - 1;