166 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks2 3void tovoid(void*);4 5void tovoid_test(int (^f)(int, int)) {6 tovoid(f);7}8 9void reference_lvalue_test(int& (^f)()) {10 f() = 10;11}12 13// PR 716514namespace test1 {15 void g(void (^)());16 struct Foo {17 void foo(); 18 void test() {19 (void) ^{ foo(); };20 }21 };22}23 24namespace 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 45namespace radar8382559 {46 void func(bool& outHasProperty);47 48 int test3() {49 __attribute__((__blocks__(byref))) bool hasProperty = false;50 bool has = true;51 52 bool (^b)() = ^ {53 func(hasProperty);54 if (hasProperty)55 hasProperty = 0;56 if (has)57 hasProperty = 1;58 return hasProperty;59 };60 func(hasProperty);61 func(has);62 b();63 if (hasProperty)64 hasProperty = 1;65 if (has)66 has = 2;67 return hasProperty = 1;68 }69}70 71// Move __block variables to the heap when possible.72class MoveOnly {73public:74 MoveOnly();75 MoveOnly(const MoveOnly&) = delete;76 MoveOnly(MoveOnly&&);77};78 79void move_block() {80 __block MoveOnly mo;81}82 83// Don't crash after failing to build a block due to a capture of an84// invalid declaration.85namespace test5 {86 struct B { // expected-note 2 {{candidate constructor}}87 void *p;88 B(int); // expected-note {{candidate constructor}}89 };90 91 void use_block(void (^)());92 void use_block_2(void (^)(), const B &a);93 94 void test() {95 B x; // expected-error {{no matching constructor for initialization}}96 use_block(^{97 int y;98 use_block_2(^{ (void) y; }, x);99 });100 }101}102 103 104// Ensure that we can end function bodies while parsing an105// expression that requires an explicitly-tracked cleanup object106// (i.e. a block literal).107 108// The nested function body in this test case is a template109// instantiation. The template function has to be constexpr because110// we'll otherwise delay its instantiation to the end of the111// translation unit.112namespace test6a {113 template <class T> constexpr int func() { return 0; }114 void run(void (^)(), int);115 116 void test() {117 int aCapturedVar = 0;118 run(^{ (void) aCapturedVar; }, func<int>());119 }120}121 122// The nested function body in this test case is a method of a local123// class.124namespace test6b {125 void run(void (^)(), void (^)());126 void test() {127 int aCapturedVar = 0;128 run(^{ (void) aCapturedVar; },129 ^{ struct A { static void foo() {} };130 A::foo(); });131 }132}133 134// The nested function body in this test case is a lambda invocation135// function.136namespace test6c {137 void run(void (^)(), void (^)());138 void test() {139 int aCapturedVar = 0;140 run(^{ (void) aCapturedVar; },141 ^{ struct A { static void foo() {} };142 A::foo(); });143 }144}145 146namespace test7 {147struct S {};148void f() {149 constexpr S s;150 auto some_block = ^{ (void)s; };151}152}153 154void static_data_member() {155 auto block = ^{156 class X {157 static int x; // expected-error {{static data member 'x' not allowed in local class 'X'}}158 };159 class Y {160 struct Z {161 static int z; // expected-error {{static data member 'z' not allowed in local struct 'Z'}}162 };163 };164 };165}166