1// RUN: %clang_analyze_cc1 -triple x86_64-apple-darwin10 -analyzer-checker=core,alpha.core.StackAddressAsyncEscape -fblocks -verify %s 2 3typedef struct dispatch_queue_s *dispatch_queue_t; 4typedef void (^dispatch_block_t)(void); 5void dispatch_async(dispatch_queue_t queue, dispatch_block_t block); 6extern dispatch_queue_t queue; 7 8void test_block_inside_block_async_no_leak() { 9 int x = 123; 10 int *p = &x; 11 void (^inner)(void) = ^void(void) { 12 int y = x; 13 ++y; 14 }; 15 // Block_copy(...) copies the captured block ("inner") too, 16 // there is no leak in this case. 17 dispatch_async(queue, ^void(void) { 18 int z = x; 19 ++z; 20 inner(); 21 }); // no-warning 22} 23 24dispatch_block_t test_block_inside_block_async_leak() { 25 int x = 123; 26 void (^inner)(void) = ^void(void) { 27 int y = x; 28 ++y; 29 }; 30 void (^outer)(void) = ^void(void) { 31 int z = x; 32 ++z; 33 inner(); 34 }; 35 return outer; // expected-warning-re{{Address of stack-allocated block declared on line {{.+}} is captured by a returned block}} 36} 37 38