1// RUN: %clang_cc1 -triple i686-pc-linux -std=c++11 -fblocks %s -verify 2 3void 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 10void 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 17template<typename T> 18class ConstCopyConstructorBoom { 19public: 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 29void 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 38void 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]; 54 }(); 55 }(); 56 57 [=] () mutable { 58 ^ { 59 int i = 0; 60 i += array[3]; // expected-error{{cannot refer to declaration with an array type inside block}} 61 }(); 62 }(); 63 }(); 64} 65 66namespace overloading { 67 void bool_conversion() { 68 if ([](){}) { 69 } 70 71 bool b = []{}; 72 b = (bool)[]{}; 73 } 74 75 void conversions() { 76 int (*fp)(int) = [](int x) { return x + 1; }; 77 fp = [](int x) { return x + 1; }; 78 79 typedef int (*func_ptr)(int); 80 fp = (func_ptr)[](int x) { return x + 1; }; 81 82 int (^bp)(int) = [](int x) { return x + 1; }; 83 bp = [](int x) { return x + 1; }; 84 85 typedef int (^block_ptr)(int); 86 bp = (block_ptr)[](int x) { return x + 1; }; 87 } 88 89 int &accept_lambda_conv(int (*fp)(int)); 90 float &accept_lambda_conv(int (^bp)(int)); 91 92 void call_with_lambda() { 93 int &ir = accept_lambda_conv([](int x) { return x + 1; }); 94 } 95 96 template<typename T> using id = T; 97 98 auto a = [](){}; 99 struct C : decltype(a) { 100 using decltype(a)::operator id<void(*)()>; 101 private: 102 using decltype(a)::operator id<void(^)()>; 103 } extern c; 104 105 struct D : decltype(a) { 106 using decltype(a)::operator id<void(^)()>; 107 private: 108 using decltype(a)::operator id<void(*)()>; // expected-note {{here}} 109 } extern d; 110 111 bool r1 = c; 112 bool r2 = d; // expected-error {{private}} 113} 114 115namespace PR13117 { 116 struct A { 117 template<typename ... Args> static void f(Args...); 118 119 template<typename ... Args> static void f1() 120 { 121 (void)^(Args args) { // expected-error{{block contains unexpanded parameter pack 'Args'}} 122 }; 123 } 124 125 template<typename ... Args> static void f2() 126 { 127 // FIXME: Allow this. 128 f( 129 ^(Args args) // expected-error{{block contains unexpanded parameter pack 'Args'}} 130 { } 131 ... // expected-error{{pack expansion does not contain any unexpanded parameter packs}} 132 ); 133 } 134 135 template<typename ... Args> static void f3() 136 { 137 (void)[](Args args) { // expected-error{{expression contains unexpanded parameter pack 'Args'}} 138 }; 139 } 140 141 template<typename ... Args> static void f4() 142 { 143 f([](Args args) { } ...); 144 } 145 }; 146 147 void g() { 148 A::f1<int, int>(); 149 A::f2<int, int>(); 150 } 151} 152