16cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s -fblocks
2b65f2425e9847d30bae499323a2d5cc29808d0b5Douglas Gregor
3b65f2425e9847d30bae499323a2d5cc29808d0b5Douglas Gregorvoid tovoid(void*);
4b65f2425e9847d30bae499323a2d5cc29808d0b5Douglas Gregor
5b65f2425e9847d30bae499323a2d5cc29808d0b5Douglas Gregorvoid tovoid_test(int (^f)(int, int)) {
6b65f2425e9847d30bae499323a2d5cc29808d0b5Douglas Gregor  tovoid(f);
7b65f2425e9847d30bae499323a2d5cc29808d0b5Douglas Gregor}
85e5783180acb42c9d9b1be2838370ea5930a2a8bAnders Carlsson
95e5783180acb42c9d9b1be2838370ea5930a2a8bAnders Carlssonvoid reference_lvalue_test(int& (^f)()) {
105e5783180acb42c9d9b1be2838370ea5930a2a8bAnders Carlsson  f() = 10;
115e5783180acb42c9d9b1be2838370ea5930a2a8bAnders Carlsson}
12ea1471e0e967548c596a71469702f8846dbaf3c0John McCall
13ea1471e0e967548c596a71469702f8846dbaf3c0John McCall// PR 7165
14ea1471e0e967548c596a71469702f8846dbaf3c0John McCallnamespace test1 {
15ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  void g(void (^)());
16ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  struct Foo {
17ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    void foo();
18ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    void test() {
19ea1471e0e967548c596a71469702f8846dbaf3c0John McCall      (void) ^{ foo(); };
20ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    }
21ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  };
22ea1471e0e967548c596a71469702f8846dbaf3c0John McCall}
23ea1471e0e967548c596a71469702f8846dbaf3c0John McCall
24ea1471e0e967548c596a71469702f8846dbaf3c0John McCallnamespace test2 {
25ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  int repeat(int value, int (^block)(int), unsigned n) {
26ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    while (n--) value = block(value);
27ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    return value;
28ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  }
29ea1471e0e967548c596a71469702f8846dbaf3c0John McCall
30ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  class Power {
31ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    int base;
32ea1471e0e967548c596a71469702f8846dbaf3c0John McCall
33ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  public:
34ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    Power(int base) : base(base) {}
35ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    int calculate(unsigned n) {
36ea1471e0e967548c596a71469702f8846dbaf3c0John McCall      return repeat(1, ^(int v) { return v * base; }, n);
37ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    }
38ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  };
39ea1471e0e967548c596a71469702f8846dbaf3c0John McCall
40ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  int test() {
41ea1471e0e967548c596a71469702f8846dbaf3c0John McCall    return Power(2).calculate(10);
42ea1471e0e967548c596a71469702f8846dbaf3c0John McCall  }
43ea1471e0e967548c596a71469702f8846dbaf3c0John McCall}
447925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian
457925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian// rdar: // 8382559
467925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahaniannamespace radar8382559 {
477925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian  void func(bool& outHasProperty);
487925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian
497925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian  int test3() {
507925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian    __attribute__((__blocks__(byref))) bool hasProperty = false;
51469a20de757ff872c90ff6b1134f6346909ff652Fariborz Jahanian    bool has = true;
52469a20de757ff872c90ff6b1134f6346909ff652Fariborz Jahanian
537925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian    bool (^b)() = ^ {
547925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian     func(hasProperty);
557925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian     if (hasProperty)
567925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian       hasProperty = 0;
57469a20de757ff872c90ff6b1134f6346909ff652Fariborz Jahanian     if (has)
58469a20de757ff872c90ff6b1134f6346909ff652Fariborz Jahanian       hasProperty = 1;
597925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian     return hasProperty;
607925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian     };
617925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian    func(hasProperty);
62469a20de757ff872c90ff6b1134f6346909ff652Fariborz Jahanian    func(has);
637925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian    b();
647925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian    if (hasProperty)
657925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian      hasProperty = 1;
66469a20de757ff872c90ff6b1134f6346909ff652Fariborz Jahanian    if (has)
67469a20de757ff872c90ff6b1134f6346909ff652Fariborz Jahanian      has = 2;
687925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian    return hasProperty = 1;
697925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian  }
707925561e702430c0d632c5e5db1a74673b44ea18Fariborz Jahanian}
716cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor
726cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor// Move __block variables to the heap when possible.
736cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregorclass MoveOnly {
746cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregorpublic:
756cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor  MoveOnly();
766cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor  MoveOnly(const MoveOnly&) = delete;
776cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor  MoveOnly(MoveOnly&&);
786cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor};
796cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor
806cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregorvoid move_block() {
816cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor  __block MoveOnly mo;
826cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor}
836cda3e604f2a2fa289cc9145719ba84461315e21Douglas Gregor
84b760f11fae94e3003b9241ac50c02617465f2fa2John McCall// Don't crash after failing to build a block due to a capture of an
85b760f11fae94e3003b9241ac50c02617465f2fa2John McCall// invalid declaration.
86b760f11fae94e3003b9241ac50c02617465f2fa2John McCallnamespace test5 {
87b760f11fae94e3003b9241ac50c02617465f2fa2John McCall  struct B { // expected-note 2 {{candidate constructor}}
88b760f11fae94e3003b9241ac50c02617465f2fa2John McCall    void *p;
89b760f11fae94e3003b9241ac50c02617465f2fa2John McCall    B(int); // expected-note {{candidate constructor}}
90b760f11fae94e3003b9241ac50c02617465f2fa2John McCall  };
91b760f11fae94e3003b9241ac50c02617465f2fa2John McCall
92b760f11fae94e3003b9241ac50c02617465f2fa2John McCall  void use_block(void (^)());
93b760f11fae94e3003b9241ac50c02617465f2fa2John McCall  void use_block_2(void (^)(), const B &a);
94b760f11fae94e3003b9241ac50c02617465f2fa2John McCall
95b760f11fae94e3003b9241ac50c02617465f2fa2John McCall  void test() {
96b760f11fae94e3003b9241ac50c02617465f2fa2John McCall    B x; // expected-error {{no matching constructor for initialization}}
97b760f11fae94e3003b9241ac50c02617465f2fa2John McCall    use_block(^{
98b760f11fae94e3003b9241ac50c02617465f2fa2John McCall        int y;
99b760f11fae94e3003b9241ac50c02617465f2fa2John McCall        use_block_2(^{ (void) y; }, x);
100b760f11fae94e3003b9241ac50c02617465f2fa2John McCall      });
101b760f11fae94e3003b9241ac50c02617465f2fa2John McCall  }
102b760f11fae94e3003b9241ac50c02617465f2fa2John McCall}
103