diff options
-rw-r--r-- | libcxx/include/functional | 4 | ||||
-rw-r--r-- | libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp | 49 |
2 files changed, 51 insertions, 2 deletions
diff --git a/libcxx/include/functional b/libcxx/include/functional index 416a9a97f71..d14b46bb76a 100644 --- a/libcxx/include/functional +++ b/libcxx/include/functional @@ -1863,10 +1863,10 @@ __mu_expand(_Ti& __ti, tuple<_Uj...>& __uj, __tuple_indices<_Indx...>) template <class _Ti, class ..._Uj> inline _LIBCPP_INLINE_VISIBILITY -typename enable_if +typename __lazy_enable_if < is_bind_expression<_Ti>::value, - typename __invoke_of<_Ti&, _Uj...>::type + __invoke_of<_Ti&, _Uj...> >::type __mu(_Ti& __ti, tuple<_Uj...>& __uj) { 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); +} |