1 | // RUN: %clang_cc1 -triple i686-pc-linux -std=c++11 -fblocks %s -verify |
2 | |
3 | void block_capture_errors() { |
4 | __block int var; // expected-note 2{{'var' declared here}} |
5 | (void)[var] { }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} |
6 | |
7 | (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} |
8 | } |
9 | |
10 | void conversion_to_block(int captured) { |
11 | int (^b1)(int) = [=](int x) { return x + captured; }; |
12 | |
13 | const auto lambda = [=](int x) { return x + captured; }; |
14 | int (^b2)(int) = lambda; |
15 | } |
16 | |
17 | template<typename T> |
18 | class ConstCopyConstructorBoom { |
19 | public: |
20 | ConstCopyConstructorBoom(ConstCopyConstructorBoom&); |
21 | |
22 | ConstCopyConstructorBoom(const ConstCopyConstructorBoom&) { |
23 | T *ptr = 1; // expected-error{{cannot initialize a variable of type 'float *' with an rvalue of type 'int'}} |
24 | } |
25 | |
26 | void foo() const; |
27 | }; |
28 | |
29 | void conversion_to_block_init(ConstCopyConstructorBoom<int> boom, |
30 | ConstCopyConstructorBoom<float> boom2) { |
31 | const auto& lambda1([=] { boom.foo(); }); // okay |
32 | |
33 | const auto& lambda2([=] { boom2.foo(); }); // expected-note{{in instantiation of member function}} |
34 | void (^block)(void) = lambda2; |
35 | } |
36 | |
37 | |
38 | void nesting() { |
39 | int array[7]; // expected-note 2{{'array' declared here}} |
40 | [=] () mutable { |
41 | [&] { |
42 | ^ { |
43 | int i = array[2]; |
44 | i += array[3]; |
45 | }(); |
46 | }(); |
47 | }(); |
48 | |
49 | [&] { |
50 | [=] () mutable { |
51 | ^ { |
52 | int i = array[2]; // expected-error{{cannot refer to declaration with an array type inside block}} |
53 | i += array[3]; // expected-error{{cannot refer to declaration with an array type inside block}} |
54 | }(); |
55 | }(); |
56 | }(); |
57 | } |
58 | |
59 | namespace overloading { |
60 | void bool_conversion() { |
61 | if ([](){}) { |
62 | } |
63 | |
64 | bool b = []{}; |
65 | b = (bool)[]{}; |
66 | } |
67 | |
68 | void conversions() { |
69 | int (*fp)(int) = [](int x) { return x + 1; }; |
70 | fp = [](int x) { return x + 1; }; |
71 | |
72 | typedef int (*func_ptr)(int); |
73 | fp = (func_ptr)[](int x) { return x + 1; }; |
74 | |
75 | int (^bp)(int) = [](int x) { return x + 1; }; |
76 | bp = [](int x) { return x + 1; }; |
77 | |
78 | typedef int (^block_ptr)(int); |
79 | bp = (block_ptr)[](int x) { return x + 1; }; |
80 | } |
81 | |
82 | int &accept_lambda_conv(int (*fp)(int)); |
83 | float &accept_lambda_conv(int (^bp)(int)); |
84 | |
85 | void call_with_lambda() { |
86 | int &ir = accept_lambda_conv([](int x) { return x + 1; }); |
87 | } |
88 | |
89 | template<typename T> using id = T; |
90 | |
91 | auto a = [](){}; |
92 | struct C : decltype(a) { |
93 | using decltype(a)::operator id<void(*)()>; |
94 | private: |
95 | using decltype(a)::operator id<void(^)()>; |
96 | } extern c; |
97 | |
98 | struct D : decltype(a) { |
99 | using decltype(a)::operator id<void(^)()>; |
100 | private: |
101 | using decltype(a)::operator id<void(*)()>; // expected-note {{here}} |
102 | } extern d; |
103 | |
104 | bool r1 = c; |
105 | bool r2 = d; // expected-error {{private}} |
106 | } |
107 | |
108 | namespace PR13117 { |
109 | struct A { |
110 | template<typename ... Args> static void f(Args...); |
111 | |
112 | template<typename ... Args> static void f1() |
113 | { |
114 | (void)^(Args args) { // expected-error{{block contains unexpanded parameter pack 'Args'}} |
115 | }; |
116 | } |
117 | |
118 | template<typename ... Args> static void f2() |
119 | { |
120 | // FIXME: Allow this. |
121 | f( |
122 | ^(Args args) // expected-error{{block contains unexpanded parameter pack 'Args'}} |
123 | { } |
124 | ... // expected-error{{pack expansion does not contain any unexpanded parameter packs}} |
125 | ); |
126 | } |
127 | |
128 | template<typename ... Args> static void f3() |
129 | { |
130 | (void)[](Args args) { // expected-error{{expression contains unexpanded parameter pack 'Args'}} |
131 | }; |
132 | } |
133 | |
134 | template<typename ... Args> static void f4() |
135 | { |
136 | f([](Args args) { } ...); |
137 | } |
138 | }; |
139 | |
140 | void g() { |
141 | A::f1<int, int>(); |
142 | A::f2<int, int>(); |
143 | } |
144 | } |
145 | |