1 // RUN: %clang_cc1 %s -emit-llvm -o %t -fblocks
2 // RUN: grep "_Block_object_dispose" %t | count 17
3 // RUN: grep "__copy_helper_block_" %t | count 14
4 // RUN: grep "__destroy_helper_block_" %t | count 14
5 // RUN: grep "__Block_byref_object_copy_" %t | count 2
6 // RUN: grep "__Block_byref_object_dispose_" %t | count 2
7 // RUN: grep "i32 135)" %t | count 2
8 // RUN: grep "_Block_object_assign" %t | count 10
9 
10 int printf(const char *, ...);
11 
12 void test1() {
13   __block int a;
14   int b=2;
15   a=1;
16   printf("a is %d, b is %d\n", a, b);
17   ^{ a = 10; printf("a is %d, b is %d\n", a, b); }(); // needs copy/dispose
18   printf("a is %d, b is %d\n", a, b);
19   a = 1;
20   printf("a is %d, b is %d\n", a, b);
21 }
22 
23 void test2() {
24   __block int a;
25   a=1;
26   printf("a is %d\n", a);
27   ^{ // needs copy/dispose
28     ^{ // needs copy/dispose
29       a = 10;
30     }();
31   }();
32   printf("a is %d\n", a);
33   a = 1;
34   printf("a is %d\n", a);
35 }
36 
37 void test3() {
38   __block int k;
39   __block int (^j)(int);
40   ^{j=0; k=0;}(); // needs copy/dispose
41 }
42 
43 int test4() {
44   extern int g;
45   static int i = 1;
46   ^(int j){ i = j; g = 0; }(0); // does not need copy/dispose
47   return i + g;
48 }
49 
50 int g;
51 
52 void test5() {
53   __block struct { int i; } i;
54   ^{ (void)i; }(); // needs copy/dispose
55 }
56 
57 void test6() {
58   __block int i;
59   ^{ i=1; }(); // needs copy/dispose
60   ^{}(); // does not need copy/dispose
61 }
62 
63 void test7() {
64   ^{ // does not need copy/dispose
65     __block int i;
66     ^{ i = 1; }(); // needs copy/dispose
67   }();
68 }
69 
70 int main() {
71   int rv = 0;
72   test1();
73   test2();
74   test3();
75   rv += test4();
76   test5();
77   return rv;
78 }
79