1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // <functional>
11 
12 // class function<R(ArgTypes...)>
13 
14 // template<class F> function(F);
15 
16 // Allow incomplete argument types in the __is_callable check
17 
18 #include <functional>
19 #include <cassert>
20 
21 struct X{
22     typedef std::function<void(X&)> callback_type;
~XX23     virtual ~X() {}
24 private:
25     callback_type _cb;
26 };
27 
28 struct IncompleteReturnType {
29   std::function<IncompleteReturnType ()> fn;
30 };
31 
32 
33 int called = 0;
test_fn()34 IncompleteReturnType test_fn() {
35   ++called;
36   IncompleteReturnType I;
37   return I;
38 }
39 
40 // See llvm.org/PR34298
test_pr34298()41 void test_pr34298()
42 {
43   static_assert(std::is_copy_constructible<IncompleteReturnType>::value, "");
44   static_assert(std::is_copy_assignable<IncompleteReturnType>::value, "");
45   {
46     IncompleteReturnType X;
47     X.fn = test_fn;
48     const IncompleteReturnType& CX = X;
49     IncompleteReturnType X2 = CX;
50     assert(X2.fn);
51     assert(called == 0);
52     X2.fn();
53     assert(called == 1);
54   }
55   {
56     IncompleteReturnType Empty;
57     IncompleteReturnType X2 = Empty;
58     assert(!X2.fn);
59   }
60 }
61 
main()62 int main() {
63   test_pr34298();
64 }
65