• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// std::function support for "blocks" when ARC is enabled
10
11// UNSUPPORTED: c++03
12
13// This test requires the Blocks runtime, which is (only?) available on Darwin
14// out-of-the-box.
15// REQUIRES: has-fblocks && has-fobjc-arc && darwin
16
17// ADDITIONAL_COMPILE_FLAGS: -fblocks -fobjc-arc
18
19#include <functional>
20
21#include <cassert>
22#include <cstddef>
23#include <string>
24
25struct Foo {
26  Foo() = default;
27  Foo(std::size_t (^bl)()) : f(bl) {}
28
29  std::function<int()> f;
30};
31
32Foo Factory(std::size_t (^bl)()) {
33  Foo result(bl);
34  return result;
35}
36
37Foo Factory2() {
38  auto hello = std::string("Hello world");
39  return Factory(^() {
40    return hello.size();
41  });
42}
43
44Foo AssignmentFactory(std::size_t (^bl)()) {
45  Foo result;
46  result.f = bl;
47  return result;
48}
49
50Foo AssignmentFactory2() {
51  auto hello = std::string("Hello world");
52  return AssignmentFactory(^() {
53    return hello.size();
54  });
55}
56
57int main(int, char **) {
58  // Case 1, works
59  {
60    auto hello = std::string("Hello world");
61    auto f = AssignmentFactory(^() {
62      return hello.size();
63    });
64    assert(f.f() == 11);
65  }
66
67  // Case 2, works
68  {
69    auto f = AssignmentFactory2();
70    assert(f.f() == 11);
71  }
72
73  // Case 3, works
74  {
75    auto hello = std::string("Hello world");
76    auto f = Factory(^() {
77      return hello.size();
78    });
79    assert(f.f() == 11);
80  }
81
82  // Case 4, used to crash under ARC
83  {
84    auto f = Factory2();
85    assert(f.f() == 11);
86  }
87
88  return 0;
89}
90