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
10int printf(const char *, ...);
11
12void 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
23void 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
37void test3() {
38  __block int k;
39  __block int (^j)(int);
40  ^{j=0; k=0;}(); // needs copy/dispose
41}
42
43int 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
50int g;
51
52void test5() {
53  __block struct { int i; } i;
54  ^{ (void)i; }(); // needs copy/dispose
55}
56
57void test6() {
58  __block int i;
59  ^{ i=1; }(); // needs copy/dispose
60  ^{}(); // does not need copy/dispose
61}
62
63void test7() {
64  ^{ // does not need copy/dispose
65    __block int i;
66    ^{ i = 1; }(); // needs copy/dispose
67  }();
68}
69
70int main() {
71  int rv = 0;
72  test1();
73  test2();
74  test3();
75  rv += test4();
76  test5();
77  return rv;
78}
79