Douglas Gregor | 0e8ff39 | 2012-02-01 00:09:55 +0000 | [diff] [blame] | 1 | // RUN: %clang_cc1 -std=c++11 -fblocks %s -verify |
| 2 | |
| 3 | void block_capture_errors() { |
| 4 | __block int var; // expected-note 2{{'var' declared here}} |
Douglas Gregor | 656bc62 | 2012-02-09 08:26:42 +0000 | [diff] [blame] | 5 | (void)[var] { }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} |
Douglas Gregor | 0e8ff39 | 2012-02-01 00:09:55 +0000 | [diff] [blame] | 6 | |
Douglas Gregor | 656bc62 | 2012-02-09 08:26:42 +0000 | [diff] [blame] | 7 | (void)[=] { var = 17; }; // expected-error{{__block variable 'var' cannot be captured in a lambda}} |
Douglas Gregor | 0e8ff39 | 2012-02-01 00:09:55 +0000 | [diff] [blame] | 8 | } |
Douglas Gregor | 33e863c | 2012-02-15 22:08:38 +0000 | [diff] [blame] | 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 | } |
Douglas Gregor | d3b672c | 2012-02-16 01:06:16 +0000 | [diff] [blame] | 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 | } |
Douglas Gregor | fdf598e | 2012-02-18 09:37:24 +0000 | [diff] [blame] | 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 | } |
Douglas Gregor | 2837aa2 | 2012-02-22 17:32:19 +0000 | [diff] [blame^] | 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 | } |