aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2018-04-04 12:42:44 -0400
committerJason Merrill <jason@gcc.gnu.org>2018-04-04 12:42:44 -0400
commitbd40bc8ea3f1eff8c2f211000dd9062f1785a5e4 (patch)
tree9a7e43dc75fb6ef34094a6d4ff75ab17e6525bcd
parent7447f1d7e21fbebd7ddaf9865bf05104592f3049 (diff)
downloadgcc-bd40bc8ea3f1eff8c2f211000dd9062f1785a5e4.zip
gcc-bd40bc8ea3f1eff8c2f211000dd9062f1785a5e4.tar.gz
gcc-bd40bc8ea3f1eff8c2f211000dd9062f1785a5e4.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/call.c6
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic17.C125
3 files changed, 132 insertions, 3 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8ab7cce..f0927e8 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2018-04-04 Jason Merrill <jason@redhat.com>
+ 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 901f18c..f817731 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 0000000..4a7392f
--- /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<typename _Tp>
+ struct remove_const
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_const<_Tp const>
+ { typedef _Tp type; };
+
+
+ template<typename _Tp>
+ struct remove_volatile
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_volatile<_Tp volatile>
+ { typedef _Tp type; };
+
+
+ template<typename _Tp>
+ struct remove_cv
+ {
+ typedef typename
+ remove_const<typename remove_volatile<_Tp>::type>::type type;
+ };
+
+ template<typename _Tp>
+ struct remove_reference
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&&>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct decay
+ {
+ using type = typename remove_reference<typename remove_const<_Tp>::type>::type;
+ };
+
+ template<typename _Tp>
+ _Tp&&
+ declval() noexcept;
+
+ template<typename _Tp>
+ constexpr _Tp&&
+ forward(typename std::remove_reference<_Tp>::type& __t) noexcept
+ { return static_cast<_Tp&&>(__t); }
+
+
+ template<typename _Arg>
+ struct _Mu
+ {
+ template<typename _CVArg, typename _Tuple>
+ _CVArg&&
+ operator()(_CVArg&& __arg, _Tuple&) const volatile
+ { return std::forward<_CVArg>(__arg); }
+ };
+
+ template<typename _Functor, typename _Bound_args>
+ struct _Bind
+ {
+ _Functor _M_f;
+ _Bound_args _M_bound_args;
+
+ template<typename _Args, typename _Result
+ = decltype( std::declval<_Functor&>()(
+ _Mu<_Bound_args>()( std::declval<_Bound_args&>(),
+ std::declval<_Args&>() ) ) )>
+ _Result
+ operator()(_Args&& __args) { return {}; }
+
+ template<typename _Args, typename _Result
+ = decltype( std::declval<volatile _Functor&>()(
+ _Mu<_Bound_args>()( std::declval<volatile _Bound_args&>(),
+ std::declval<_Args&>() ) ) )>
+ _Result
+ operator()(_Args&& __args) volatile;
+
+ };
+
+ template<typename _Func, typename _BoundArgs>
+ _Bind<typename decay<_Func>::type, typename decay<_BoundArgs>::type>
+ bind(_Func&& __f, _BoundArgs&& __args)
+ {
+ return {
+ std::forward<_Func>(__f),
+ std::forward<_BoundArgs>(__args)
+ };
+ }
+
+} // namespace std
+
+
+template <typename T>
+bool isOneOf(const T& )
+{
+ return false;
+}
+
+template <typename T, typename FirstType, typename... Tail>
+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<decltype(params)>(params)...);
+ };
+
+ auto isO = std::bind(isOneOfHelper, 'o');
+
+ isO('o');
+}