brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · 997ac2b Raw
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