summaryrefslogtreecommitdiffstats
path: root/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2014-12-23 05:54:34 +0000
committerEric Fiselier <eric@efcs.ca>2014-12-23 05:54:34 +0000
commit279663c1b4bfcec7f849dd2becf207841c45c0cf (patch)
tree4e5c40e651838113b837c26cbbfc2e0f714b365a /libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind
parent2c55974da59db63db5835ea7f4b2ed1f64afc954 (diff)
downloadbcm5719-llvm-279663c1b4bfcec7f849dd2becf207841c45c0cf.tar.gz
bcm5719-llvm-279663c1b4bfcec7f849dd2becf207841c45c0cf.zip
Prevent ill-formed instantiation of __invoke_of<...> during the evaluation of a bind expression. Fixes PR22003.
The SFINAE on the function __mu(Fn, Args...) that evaluates nested bind expressions always tries to deduce the return type for Fn(Args...) even when Fn is not a nested bind expression. This can cause hard compile errors when the instantation of Fn(Args...) is ill-formed. This patch prevents the instantation of __invoke_of<Fn, Args...> unless Fn is actually a bind expression. Bug reportand patch from Michel Morin. http://llvm.org/bugs/show_bug.cgi?id=22003 llvm-svn: 224753
Diffstat (limited to 'libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind')
-rw-r--r--libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp49
1 files changed, 49 insertions, 0 deletions
diff --git a/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp b/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
new file mode 100644
index 00000000000..33bf0185590
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+// template<CopyConstructible Fn, CopyConstructible... Types>
+// unspecified bind(Fn, Types...);
+// template<Returnable R, CopyConstructible Fn, CopyConstructible... Types>
+// unspecified bind(Fn, Types...);
+
+// http://llvm.org/bugs/show_bug.cgi?id=22003
+
+#include <functional>
+
+struct DummyUnaryFunction
+{
+ template <typename S>
+ int operator()(S const & s) const { return 0; }
+};
+
+struct BadUnaryFunction
+{
+ template <typename S>
+ constexpr int operator()(S const & s) const
+ {
+ // Trigger a compile error if this function is instantiated.
+ // The constexpr is needed so that it is instantiated while checking
+ // __invoke_of<BadUnaryFunction &, ...>.
+ static_assert(!std::is_same<S, S>::value, "Shit");
+ return 0;
+ }
+};
+
+int main(int argc, char* argv[])
+{
+ // Check that BadUnaryFunction::operator()(S const &) is not
+ // instantiated when checking if BadUnaryFunction is a nested bind
+ // expression during b(0). See PR22003.
+ auto b = std::bind(DummyUnaryFunction(), BadUnaryFunction());
+ b(0);
+ auto b2 = std::bind<long>(DummyUnaryFunction(), BadUnaryFunction());
+ b2(0);
+}
OpenPOWER on IntegriCloud