From bd40bc8ea3f1eff8c2f211000dd9062f1785a5e4 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 4 Apr 2018 12:42:44 -0400 Subject: [PATCH] PR c++/85118 - wrong error with generic lambda and std::bind. * call.c (add_template_conv_candidate): Disable if there are any call operators. From-SVN: r259090 --- gcc/cp/ChangeLog | 4 + gcc/cp/call.c | 6 +- .../g++.dg/cpp1y/lambda-generic-variadic17.C | 125 ++++++++++++++++++ 3 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 8ab7cce4732..f0927e82b36 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2018-04-04 Jason Merrill + PR c++/85118 - wrong error with generic lambda and std::bind. + * call.c (add_template_conv_candidate): Disable if there are any + call operators. + PR c++/85141 - ICE with compound assignment and static member fn. * typeck.c (cp_build_modify_expr): Call decay_conversion for RHS of compound assignment. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 901f18c43e6..f81773157b6 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -3274,10 +3274,10 @@ add_template_conv_candidate (struct z_candidate **candidates, tree tmpl, tree return_type, tree access_path, tree conversion_path, tsubst_flags_t complain) { - /* Making this work broke PR 71117, so until the committee resolves core - issue 2189, let's disable this candidate if there are any viable call + /* Making this work broke PR 71117 and 85118, so until the committee resolves + core issue 2189, let's disable this candidate if there are any call operators. */ - if (any_strictly_viable (*candidates)) + if (*candidates) return NULL; return diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C new file mode 100644 index 00000000000..4a7392f93bc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C @@ -0,0 +1,125 @@ +// PR c++/85118 +// { dg-do compile { target c++14 } } + +namespace std +{ + template + struct remove_const + { typedef _Tp type; }; + + template + struct remove_const<_Tp const> + { typedef _Tp type; }; + + + template + struct remove_volatile + { typedef _Tp type; }; + + template + struct remove_volatile<_Tp volatile> + { typedef _Tp type; }; + + + template + struct remove_cv + { + typedef typename + remove_const::type>::type type; + }; + + template + struct remove_reference + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&> + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&&> + { typedef _Tp type; }; + + template + struct decay + { + using type = typename remove_reference::type>::type; + }; + + template + _Tp&& + declval() noexcept; + + template + constexpr _Tp&& + forward(typename std::remove_reference<_Tp>::type& __t) noexcept + { return static_cast<_Tp&&>(__t); } + + + template + struct _Mu + { + template + _CVArg&& + operator()(_CVArg&& __arg, _Tuple&) const volatile + { return std::forward<_CVArg>(__arg); } + }; + + template + struct _Bind + { + _Functor _M_f; + _Bound_args _M_bound_args; + + template()( + _Mu<_Bound_args>()( std::declval<_Bound_args&>(), + std::declval<_Args&>() ) ) )> + _Result + operator()(_Args&& __args) { return {}; } + + template()( + _Mu<_Bound_args>()( std::declval(), + std::declval<_Args&>() ) ) )> + _Result + operator()(_Args&& __args) volatile; + + }; + + template + _Bind::type, typename decay<_BoundArgs>::type> + bind(_Func&& __f, _BoundArgs&& __args) + { + return { + std::forward<_Func>(__f), + std::forward<_BoundArgs>(__args) + }; + } + +} // namespace std + + +template +bool isOneOf(const T& ) +{ + return false; +} + +template +bool isOneOf(const T& t, const FirstType& firstValue, const Tail&... tail) +{ + return t == firstValue || isOneOf(t, tail...); +} + +int main() +{ + const auto isOneOfHelper = [](auto&&... params) + { + return isOneOf(std::forward(params)...); + }; + + auto isO = std::bind(isOneOfHelper, 'o'); + + isO('o'); +} -- 2.30.2