summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/function.objects
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2017-09-10 23:41:20 +0000
committerEric Fiselier <eric@efcs.ca>2017-09-10 23:41:20 +0000
commit94d555116cbdc1522656a205f579da31f0bc14d1 (patch)
tree47281eddf135ce5538f632098cb37eb16e318326 /libcxx/test/std/utilities/function.objects
parent85cde7d2f410353ee5c143ad931da571e9be11bf (diff)
downloadbcm5719-llvm-94d555116cbdc1522656a205f579da31f0bc14d1.tar.gz
bcm5719-llvm-94d555116cbdc1522656a205f579da31f0bc14d1.zip
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. llvm-svn: 312892
Diffstat (limited to 'libcxx/test/std/utilities/function.objects')
-rw-r--r--libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp37
1 files changed, 36 insertions, 1 deletions
diff --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp
index c8f4178a26b..75e2ecac3c4 100644
--- a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_incomplete.pass.cpp
+++ b/libcxx/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();
}
OpenPOWER on IntegriCloud