15a83710eSEric Fiselier //===----------------------------------------------------------------------===//
25a83710eSEric Fiselier //
357b08b09SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
457b08b09SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
557b08b09SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65a83710eSEric Fiselier //
75a83710eSEric Fiselier //===----------------------------------------------------------------------===//
85a83710eSEric Fiselier 
95a83710eSEric Fiselier // <functional>
105a83710eSEric Fiselier 
115a83710eSEric Fiselier // class function<R(ArgTypes...)>
125a83710eSEric Fiselier 
135a83710eSEric Fiselier // template<class F> function(F);
145a83710eSEric Fiselier 
155a83710eSEric Fiselier // Allow incomplete argument types in the __is_callable check
165a83710eSEric Fiselier 
17b4fb705eSLouis Dionne // This test runs in C++03, but we have deprecated using std::function in C++03.
18*c475e31aSNikolas Klauser // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION
19b4fb705eSLouis Dionne 
205a83710eSEric Fiselier #include <functional>
2194d55511SEric Fiselier #include <cassert>
225a83710eSEric Fiselier 
237fc6a556SMarshall Clow #include "test_macros.h"
247fc6a556SMarshall Clow 
255a83710eSEric Fiselier struct X{
265a83710eSEric Fiselier     typedef std::function<void(X&)> callback_type;
~XX275a83710eSEric Fiselier     virtual ~X() {}
285a83710eSEric Fiselier private:
295a83710eSEric Fiselier     callback_type _cb;
305a83710eSEric Fiselier };
315a83710eSEric Fiselier 
3294d55511SEric Fiselier struct IncompleteReturnType {
3394d55511SEric Fiselier   std::function<IncompleteReturnType ()> fn;
3494d55511SEric Fiselier };
3594d55511SEric Fiselier 
3694d55511SEric Fiselier 
3794d55511SEric Fiselier int called = 0;
test_fn()3894d55511SEric Fiselier IncompleteReturnType test_fn() {
3994d55511SEric Fiselier   ++called;
4094d55511SEric Fiselier   IncompleteReturnType I;
4194d55511SEric Fiselier   return I;
4294d55511SEric Fiselier }
4394d55511SEric Fiselier 
4494d55511SEric Fiselier // See llvm.org/PR34298
test_pr34298()4594d55511SEric Fiselier void test_pr34298()
465a83710eSEric Fiselier {
4794d55511SEric Fiselier   static_assert(std::is_copy_constructible<IncompleteReturnType>::value, "");
4894d55511SEric Fiselier   static_assert(std::is_copy_assignable<IncompleteReturnType>::value, "");
4994d55511SEric Fiselier   {
5094d55511SEric Fiselier     IncompleteReturnType X;
5194d55511SEric Fiselier     X.fn = test_fn;
5294d55511SEric Fiselier     const IncompleteReturnType& CX = X;
5394d55511SEric Fiselier     IncompleteReturnType X2 = CX;
5494d55511SEric Fiselier     assert(X2.fn);
5594d55511SEric Fiselier     assert(called == 0);
5694d55511SEric Fiselier     X2.fn();
5794d55511SEric Fiselier     assert(called == 1);
5894d55511SEric Fiselier   }
5994d55511SEric Fiselier   {
6094d55511SEric Fiselier     IncompleteReturnType Empty;
6194d55511SEric Fiselier     IncompleteReturnType X2 = Empty;
6294d55511SEric Fiselier     assert(!X2.fn);
6394d55511SEric Fiselier   }
6494d55511SEric Fiselier }
6594d55511SEric Fiselier 
main(int,char **)662df59c50SJF Bastien int main(int, char**) {
6794d55511SEric Fiselier   test_pr34298();
682df59c50SJF Bastien 
692df59c50SJF Bastien   return 0;
705a83710eSEric Fiselier }
71