diff options
author | Eric Fiselier <eric@efcs.ca> | 2017-09-10 23:41:20 +0000 |
---|---|---|
committer | Eric Fiselier <eric@efcs.ca> | 2017-09-10 23:41:20 +0000 |
commit | f2c4a96359e4cbf7fa575f27d7e94248e5fd84b8 (patch) | |
tree | 798dfa389c809b7f4320179c407964c0091c6d03 /test | |
parent | d5a494e0585b16faa97c8ddf3c8ca6d996cc95b1 (diff) |
Fix PR34298 - Allow std::function with an incomplete return type.
This patch fixes llvm.org/PR34298. Previously libc++ incorrectly evaluated
the __invokable trait via the converting constructor `function(Tp)` [with Tp = std::function]
whenever the copy constructor or copy assignment operator
was required. This patch further constrains that constructor to short
circut before evaluating the troublesome SFINAE when `Tp` matches
std::function.
The original patch is from Alex Lorenz.
git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@312892 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test')
-rw-r--r-- | test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp index c8f4178a2..75e2ecac3 100644 --- a/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp +++ b/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp @@ -16,6 +16,7 @@ // Allow incomplete argument types in the __is_callable check #include <functional> +#include <cassert> struct X{ typedef std::function<void(X&)> callback_type; @@ -24,6 +25,40 @@ private: callback_type _cb; }; -int main() +struct IncompleteReturnType { + std::function<IncompleteReturnType ()> fn; +}; + + +int called = 0; +IncompleteReturnType test_fn() { + ++called; + IncompleteReturnType I; + return I; +} + +// See llvm.org/PR34298 +void test_pr34298() { + static_assert(std::is_copy_constructible<IncompleteReturnType>::value, ""); + static_assert(std::is_copy_assignable<IncompleteReturnType>::value, ""); + { + IncompleteReturnType X; + X.fn = test_fn; + const IncompleteReturnType& CX = X; + IncompleteReturnType X2 = CX; + assert(X2.fn); + assert(called == 0); + X2.fn(); + assert(called == 1); + } + { + IncompleteReturnType Empty; + IncompleteReturnType X2 = Empty; + assert(!X2.fn); + } +} + +int main() { + test_pr34298(); } |