1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks |
2 | |
3 | void tovoid(void*); |
4 | |
5 | void tovoid_test(int (^f)(int, int)) { |
6 | tovoid(f); |
7 | } |
8 | |
9 | void reference_lvalue_test(int& (^f)()) { |
10 | f() = 10; |
11 | } |
12 | |
13 | // PR 7165 |
14 | namespace test1 { |
15 | void g(void (^)()); |
16 | struct Foo { |
17 | void foo(); |
18 | void test() { |
19 | (void) ^{ foo(); }; |
20 | } |
21 | }; |
22 | } |
23 | |
24 | namespace test2 { |
25 | int repeat(int value, int (^block)(int), unsigned n) { |
26 | while (n--) value = block(value); |
27 | return value; |
28 | } |
29 | |
30 | class Power { |
31 | int base; |
32 | |
33 | public: |
34 | Power(int base) : base(base) {} |
35 | int calculate(unsigned n) { |
36 | return repeat(1, ^(int v) { return v * base; }, n); |
37 | } |
38 | }; |
39 | |
40 | int test() { |
41 | return Power(2).calculate(10); |
42 | } |
43 | } |
44 | |
45 | // rdar: // 8382559 |
46 | namespace radar8382559 { |
47 | void func(bool& outHasProperty); |
48 | |
49 | int test3() { |
50 | __attribute__((__blocks__(byref))) bool hasProperty = false; |
51 | bool has = true; |
52 | |
53 | bool (^b)() = ^ { |
54 | func(hasProperty); |
55 | if (hasProperty) |
56 | hasProperty = 0; |
57 | if (has) |
58 | hasProperty = 1; |
59 | return hasProperty; |
60 | }; |
61 | func(hasProperty); |
62 | func(has); |
63 | b(); |
64 | if (hasProperty) |
65 | hasProperty = 1; |
66 | if (has) |
67 | has = 2; |
68 | return hasProperty = 1; |
69 | } |
70 | } |
71 | |
72 | // Move __block variables to the heap when possible. |
73 | class MoveOnly { |
74 | public: |
75 | MoveOnly(); |
76 | MoveOnly(const MoveOnly&) = delete; |
77 | MoveOnly(MoveOnly&&); |
78 | }; |
79 | |
80 | void move_block() { |
81 | __block MoveOnly mo; |
82 | } |
83 | |
84 | // Don't crash after failing to build a block due to a capture of an |
85 | // invalid declaration. |
86 | namespace test5 { |
87 | struct B { // expected-note 2 {{candidate constructor}} |
88 | void *p; |
89 | B(int); // expected-note {{candidate constructor}} |
90 | }; |
91 | |
92 | void use_block(void (^)()); |
93 | void use_block_2(void (^)(), const B &a); |
94 | |
95 | void test() { |
96 | B x; // expected-error {{no matching constructor for initialization}} |
97 | use_block(^{ |
98 | int y; |
99 | use_block_2(^{ (void) y; }, x); |
100 | }); |
101 | } |
102 | } |
103 | |
104 | |
105 | // rdar://16356628 |
106 | // |
107 | // Ensure that we can end function bodies while parsing an |
108 | // expression that requires an explicitly-tracked cleanup object |
109 | // (i.e. a block literal). |
110 | |
111 | // The nested function body in this test case is a template |
112 | // instantiation. The template function has to be constexpr because |
113 | // we'll otherwise delay its instantiation to the end of the |
114 | // translation unit. |
115 | namespace test6a { |
116 | template <class T> constexpr int func() { return 0; } |
117 | void run(void (^)(), int); |
118 | |
119 | void test() { |
120 | int aCapturedVar = 0; |
121 | run(^{ (void) aCapturedVar; }, func<int>()); |
122 | } |
123 | } |
124 | |
125 | // The nested function body in this test case is a method of a local |
126 | // class. |
127 | namespace test6b { |
128 | void run(void (^)(), void (^)()); |
129 | void test() { |
130 | int aCapturedVar = 0; |
131 | run(^{ (void) aCapturedVar; }, |
132 | ^{ struct A { static void foo() {} }; |
133 | A::foo(); }); |
134 | } |
135 | } |
136 | |
137 | // The nested function body in this test case is a lambda invocation |
138 | // function. |
139 | namespace test6c { |
140 | void run(void (^)(), void (^)()); |
141 | void test() { |
142 | int aCapturedVar = 0; |
143 | run(^{ (void) aCapturedVar; }, |
144 | ^{ struct A { static void foo() {} }; |
145 | A::foo(); }); |
146 | } |
147 | } |
148 | |
149 | namespace test7 { |
150 | struct S {}; |
151 | void f() { |
152 | constexpr S s; |
153 | auto some_block = ^{ (void)s; }; |
154 | } |
155 | } |
156 | |