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 // UNSUPPORTED: c++03
10 
11 // <functional>
12 
13 // class function<R(ArgTypes...)>
14 
15 // template<class F> function(F);
16 
17 // Allow incomplete argument types in the __is_callable check
18 
19 #include <functional>
20 #include <cassert>
21 
22 #include "test_macros.h"
23 
24 struct X{
25     typedef std::function<void(X&)> callback_type;
~XX26     virtual ~X() {}
27 private:
28     callback_type _cb;
29 };
30 
31 struct IncompleteReturnType {
32   std::function<IncompleteReturnType ()> fn;
33 };
34 
35 
36 int called = 0;
test_fn()37 IncompleteReturnType test_fn() {
38   ++called;
39   IncompleteReturnType I;
40   return I;
41 }
42 
43 // See llvm.org/PR34298
test_pr34298()44 void test_pr34298()
45 {
46   static_assert(std::is_copy_constructible<IncompleteReturnType>::value, "");
47   static_assert(std::is_copy_assignable<IncompleteReturnType>::value, "");
48   {
49     IncompleteReturnType X;
50     X.fn = test_fn;
51     const IncompleteReturnType& CX = X;
52     IncompleteReturnType X2 = CX;
53     assert(X2.fn);
54     assert(called == 0);
55     X2.fn();
56     assert(called == 1);
57   }
58   {
59     IncompleteReturnType Empty;
60     IncompleteReturnType X2 = Empty;
61     assert(!X2.fn);
62   }
63 }
64 
main(int,char **)65 int main(int, char**) {
66   test_pr34298();
67 
68   return 0;
69 }
70