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