From 279663c1b4bfcec7f849dd2becf207841c45c0cf Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Tue, 23 Dec 2014 05:54:34 +0000 Subject: 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 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 --- .../func.bind.bind/invoke_function_object.pass.cpp | 49 ++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind/invoke_function_object.pass.cpp (limited to 'libcxx/test/std/utilities/function.objects/bind/func.bind/func.bind.bind') 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. +// +//===----------------------------------------------------------------------===// + +// + +// template +// unspecified bind(Fn, Types...); +// template +// unspecified bind(Fn, Types...); + +// http://llvm.org/bugs/show_bug.cgi?id=22003 + +#include + +struct DummyUnaryFunction +{ + template + int operator()(S const & s) const { return 0; } +}; + +struct BadUnaryFunction +{ + template + 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. + static_assert(!std::is_same::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(DummyUnaryFunction(), BadUnaryFunction()); + b2(0); +} -- cgit v1.2.3