[libcxx-commits] [libcxx] 3c8e31e - [libc++] ADL-proof <functional> by adding _VSTD:: qualification on calls.

Arthur O'Dwyer via libcxx-commits libcxx-commits at lists.llvm.org
Mon Dec 14 09:09:27 PST 2020


Author: Arthur O'Dwyer
Date: 2020-12-14T12:08:34-05:00
New Revision: 3c8e31e17b85c3d24ade9053d56c1998b4dd28cd

URL: https://github.com/llvm/llvm-project/commit/3c8e31e17b85c3d24ade9053d56c1998b4dd28cd
DIFF: https://github.com/llvm/llvm-project/commit/3c8e31e17b85c3d24ade9053d56c1998b4dd28cd.diff

LOG: [libc++] ADL-proof <functional> by adding _VSTD:: qualification on calls.

- std::reference_wrapper
- std::function
- std::mem_fn

While I'm here, remove _VSTD:: qualification from calls to `declval`
because it takes no arguments and thus isn't susceptible to ADL.

Differential Revision: https://reviews.llvm.org/D92884

Added: 
    libcxx/test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp
    libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp
    libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp

Modified: 
    libcxx/include/__functional_base
    libcxx/include/__functional_base_03
    libcxx/include/functional

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base
index f591bf5a9dce..c84e7eb11567 100644
--- a/libcxx/include/__functional_base
+++ b/libcxx/include/__functional_base
@@ -298,7 +298,7 @@ struct __weak_result_type<_Rp (_Cp::*)(_A1, _A2, _A3...) const volatile>
 template <class _Tp, class ..._Args>
 struct __invoke_return
 {
-    typedef decltype(__invoke(_VSTD::declval<_Tp>(), _VSTD::declval<_Args>()...)) type;
+    typedef decltype(_VSTD::__invoke(declval<_Tp>(), declval<_Args>()...)) type;
 };
 
 #else // defined(_LIBCPP_CXX03_LANG)
@@ -314,27 +314,27 @@ struct __invoke_void_return_wrapper
 #ifndef _LIBCPP_CXX03_LANG
     template <class ..._Args>
     static _Ret __call(_Args&&... __args) {
-        return __invoke(_VSTD::forward<_Args>(__args)...);
+        return _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
     }
 #else
     template <class _Fn>
     static _Ret __call(_Fn __f) {
-        return __invoke(__f);
+        return _VSTD::__invoke(__f);
     }
 
     template <class _Fn, class _A0>
     static _Ret __call(_Fn __f, _A0& __a0) {
-        return __invoke(__f, __a0);
+        return _VSTD::__invoke(__f, __a0);
     }
 
     template <class _Fn, class _A0, class _A1>
     static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1) {
-        return __invoke(__f, __a0, __a1);
+        return _VSTD::__invoke(__f, __a0, __a1);
     }
 
     template <class _Fn, class _A0, class _A1, class _A2>
     static _Ret __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2){
-        return __invoke(__f, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f, __a0, __a1, __a2);
     }
 #endif
 };
@@ -345,27 +345,27 @@ struct __invoke_void_return_wrapper<void>
 #ifndef _LIBCPP_CXX03_LANG
     template <class ..._Args>
     static void __call(_Args&&... __args) {
-        __invoke(_VSTD::forward<_Args>(__args)...);
+        _VSTD::__invoke(_VSTD::forward<_Args>(__args)...);
     }
 #else
     template <class _Fn>
     static void __call(_Fn __f) {
-        __invoke(__f);
+        _VSTD::__invoke(__f);
     }
 
     template <class _Fn, class _A0>
     static void __call(_Fn __f, _A0& __a0) {
-        __invoke(__f, __a0);
+        _VSTD::__invoke(__f, __a0);
     }
 
     template <class _Fn, class _A0, class _A1>
     static void __call(_Fn __f, _A0& __a0, _A1& __a1) {
-        __invoke(__f, __a0, __a1);
+        _VSTD::__invoke(__f, __a0, __a1);
     }
 
     template <class _Fn, class _A0, class _A1, class _A2>
     static void __call(_Fn __f, _A0& __a0, _A1& __a1, _A2& __a2) {
-        __invoke(__f, __a0, __a1, __a2);
+        _VSTD::__invoke(__f, __a0, __a1, __a2);
     }
 #endif
 };
@@ -398,112 +398,112 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_of<type&, _ArgTypes...>::type
     operator() (_ArgTypes&&... __args) const {
-        return __invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
+        return _VSTD::__invoke(get(), _VSTD::forward<_ArgTypes>(__args)...);
     }
 #else
 
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return<type>::type
     operator() () const {
-        return __invoke(get());
+        return _VSTD::__invoke(get());
     }
 
     template <class _A0>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return0<type, _A0>::type
     operator() (_A0& __a0) const {
-        return __invoke(get(), __a0);
+        return _VSTD::__invoke(get(), __a0);
     }
 
     template <class _A0>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return0<type, _A0 const>::type
     operator() (_A0 const& __a0) const {
-        return __invoke(get(), __a0);
+        return _VSTD::__invoke(get(), __a0);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0, _A1>::type
     operator() (_A0& __a0, _A1& __a1) const {
-        return __invoke(get(), __a0, __a1);
+        return _VSTD::__invoke(get(), __a0, __a1);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0 const, _A1>::type
     operator() (_A0 const& __a0, _A1& __a1) const {
-        return __invoke(get(), __a0, __a1);
+        return _VSTD::__invoke(get(), __a0, __a1);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0, _A1 const>::type
     operator() (_A0& __a0, _A1 const& __a1) const {
-        return __invoke(get(), __a0, __a1);
+        return _VSTD::__invoke(get(), __a0, __a1);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0 const, _A1 const>::type
     operator() (_A0 const& __a0, _A1 const& __a1) const {
-        return __invoke(get(), __a0, __a1);
+        return _VSTD::__invoke(get(), __a0, __a1);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1, _A2>::type
     operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1, _A2>::type
     operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1 const, _A2>::type
     operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1, _A2 const>::type
     operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
     operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
     operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
     operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
     operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
-        return __invoke(get(), __a0, __a1, __a2);
+        return _VSTD::__invoke(get(), __a0, __a1, __a2);
     }
 #endif // _LIBCPP_CXX03_LANG
 };

diff  --git a/libcxx/include/__functional_base_03 b/libcxx/include/__functional_base_03
index e6dac90c84f7..9b08bd26a8fd 100644
--- a/libcxx/include/__functional_base_03
+++ b/libcxx/include/__functional_base_03
@@ -40,7 +40,7 @@ struct __enable_invoke_imp<_Ret, _T1, false, true>  {
 template <class _Ret, class _T1>
 struct __enable_invoke_imp<_Ret, _T1, false, false>  {
     typedef typename add_lvalue_reference<
-                typename __apply_cv<decltype(*_VSTD::declval<_T1>()), _Ret>::type
+                typename __apply_cv<decltype(*declval<_T1>()), _Ret>::type
             >::type _Bullet4;
     typedef _Bullet4 type;
 };
@@ -142,7 +142,7 @@ __invoke(_Fn __f, _T1& __t1) {
 
 template <class _Fp>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(_VSTD::declval<_Fp&>()())
+decltype(declval<_Fp&>()())
 __invoke(_Fp& __f)
 {
     return __f();
@@ -150,7 +150,7 @@ __invoke(_Fp& __f)
 
 template <class _Fp, class _A0>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>()))
+decltype(declval<_Fp&>()(declval<_A0&>()))
 __invoke(_Fp& __f, _A0& __a0)
 {
     return __f(__a0);
@@ -158,7 +158,7 @@ __invoke(_Fp& __f, _A0& __a0)
 
 template <class _Fp, class _A0, class _A1>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>()))
+decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>()))
 __invoke(_Fp& __f, _A0& __a0, _A1& __a1)
 {
     return __f(__a0, __a1);
@@ -166,7 +166,7 @@ __invoke(_Fp& __f, _A0& __a0, _A1& __a1)
 
 template <class _Fp, class _A0, class _A1, class _A2>
 inline _LIBCPP_INLINE_VISIBILITY
-decltype(_VSTD::declval<_Fp&>()(_VSTD::declval<_A0&>(), _VSTD::declval<_A1&>(), _VSTD::declval<_A2&>()))
+decltype(declval<_Fp&>()(declval<_A0&>(), declval<_A1&>(), declval<_A2&>()))
 __invoke(_Fp& __f, _A0& __a0, _A1& __a1, _A2& __a2)
 {
     return __f(__a0, __a1, __a2);
@@ -181,13 +181,13 @@ struct __invoke_return
 template <class _Fp>
 struct __invoke_return<_Fp, false>
 {
-    typedef decltype(__invoke(_VSTD::declval<_Fp&>())) type;
+    typedef decltype(_VSTD::__invoke(declval<_Fp&>())) type;
 };
 
 template <class _Tp, class _A0>
 struct __invoke_return0
 {
-    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>())) type;
+    typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>())) type;
 };
 
 template <class _Rp, class _Tp, class _A0>
@@ -199,8 +199,8 @@ struct __invoke_return0<_Rp _Tp::*, _A0>
 template <class _Tp, class _A0, class _A1>
 struct __invoke_return1
 {
-    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
-                                                      _VSTD::declval<_A1&>())) type;
+    typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
+                                                      declval<_A1&>())) type;
 };
 
 template <class _Rp, class _Class, class _A0, class _A1>
@@ -211,9 +211,9 @@ struct __invoke_return1<_Rp _Class::*, _A0, _A1> {
 template <class _Tp, class _A0, class _A1, class _A2>
 struct __invoke_return2
 {
-    typedef decltype(__invoke(_VSTD::declval<_Tp&>(), _VSTD::declval<_A0&>(),
-                                                      _VSTD::declval<_A1&>(),
-                                                      _VSTD::declval<_A2&>())) type;
+    typedef decltype(_VSTD::__invoke(declval<_Tp&>(), declval<_A0&>(),
+                                                      declval<_A1&>(),
+                                                      declval<_A2&>())) type;
 };
 
 template <class _Ret, class _Class, class _A0, class _A1, class _A2>

diff  --git a/libcxx/include/functional b/libcxx/include/functional
index 6d3d905e6754..a54868e82220 100644
--- a/libcxx/include/functional
+++ b/libcxx/include/functional
@@ -1296,7 +1296,7 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return<type, _ArgTypes...>::type
     operator() (_ArgTypes&&... __args) const {
-        return __invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
+        return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__args)...);
     }
 #else
 
@@ -1304,98 +1304,98 @@ public:
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return0<type, _A0>::type
     operator() (_A0& __a0) const {
-        return __invoke(__f_, __a0);
+        return _VSTD::__invoke(__f_, __a0);
     }
 
     template <class _A0>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return0<type, _A0 const>::type
     operator() (_A0 const& __a0) const {
-        return __invoke(__f_, __a0);
+        return _VSTD::__invoke(__f_, __a0);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0, _A1>::type
     operator() (_A0& __a0, _A1& __a1) const {
-        return __invoke(__f_, __a0, __a1);
+        return _VSTD::__invoke(__f_, __a0, __a1);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0 const, _A1>::type
     operator() (_A0 const& __a0, _A1& __a1) const {
-        return __invoke(__f_, __a0, __a1);
+        return _VSTD::__invoke(__f_, __a0, __a1);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0, _A1 const>::type
     operator() (_A0& __a0, _A1 const& __a1) const {
-        return __invoke(__f_, __a0, __a1);
+        return _VSTD::__invoke(__f_, __a0, __a1);
     }
 
     template <class _A0, class _A1>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return1<type, _A0 const, _A1 const>::type
     operator() (_A0 const& __a0, _A1 const& __a1) const {
-        return __invoke(__f_, __a0, __a1);
+        return _VSTD::__invoke(__f_, __a0, __a1);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1, _A2>::type
     operator() (_A0& __a0, _A1& __a1, _A2& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1, _A2>::type
     operator() (_A0 const& __a0, _A1& __a1, _A2& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1 const, _A2>::type
     operator() (_A0& __a0, _A1 const& __a1, _A2& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1, _A2 const>::type
     operator() (_A0& __a0, _A1& __a1, _A2 const& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1 const, _A2>::type
     operator() (_A0 const& __a0, _A1 const& __a1, _A2& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1, _A2 const>::type
     operator() (_A0 const& __a0, _A1& __a1, _A2 const& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0, _A1 const, _A2 const>::type
     operator() (_A0& __a0, _A1 const& __a1, _A2 const& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 
     template <class _A0, class _A1, class _A2>
     _LIBCPP_INLINE_VISIBILITY
     typename __invoke_return2<type, _A0 const, _A1 const, _A2 const>::type
     operator() (_A0 const& __a0, _A1 const& __a1, _A2 const& __a2) const {
-        return __invoke(__f_, __a0, __a1, __a2);
+        return _VSTD::__invoke(__f_, __a0, __a1, __a2);
     }
 #endif
 };
@@ -2303,7 +2303,7 @@ public:
     }
 
     virtual _Rp operator()(_ArgTypes&& ... __arg) {
-        return __invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
+        return _VSTD::__invoke(__f_, _VSTD::forward<_ArgTypes>(__arg)...);
     }
 
 #ifndef _LIBCPP_NO_RTTI

diff  --git a/libcxx/test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp
new file mode 100644
index 000000000000..2bb8e9f49209
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/func.memfn/robust_against_adl.pass.cpp
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+#include <functional>
+
+#include "test_macros.h"
+
+struct Incomplete;
+template<class T> struct Holder { T t; };
+typedef Holder<Incomplete> *Ptr;
+
+struct A {
+    Ptr no_args() const { return nullptr; }
+    Ptr one_arg(Ptr p) const { return p; }
+    void one_arg_void(Ptr) const { }
+};
+
+int main(int, char**)
+{
+    A a;
+    A *pa = &a;
+    const A *cpa = &a;
+    Ptr x = nullptr;
+    const Ptr cx = nullptr;
+    std::mem_fn(&A::no_args)(a);
+    std::mem_fn(&A::no_args)(pa);
+    std::mem_fn(&A::no_args)(*cpa);
+    std::mem_fn(&A::no_args)(cpa);
+    std::mem_fn(&A::one_arg)(a, x);
+    std::mem_fn(&A::one_arg)(pa, x);
+    std::mem_fn(&A::one_arg)(a, cx);
+    std::mem_fn(&A::one_arg)(pa, cx);
+    std::mem_fn(&A::one_arg)(*cpa, x);
+    std::mem_fn(&A::one_arg)(cpa, x);
+    std::mem_fn(&A::one_arg)(*cpa, cx);
+    std::mem_fn(&A::one_arg)(cpa, cx);
+    std::mem_fn(&A::one_arg_void)(a, x);
+    std::mem_fn(&A::one_arg_void)(pa, x);
+    std::mem_fn(&A::one_arg_void)(a, cx);
+    std::mem_fn(&A::one_arg_void)(pa, cx);
+    std::mem_fn(&A::one_arg_void)(*cpa, x);
+    std::mem_fn(&A::one_arg_void)(cpa, x);
+    std::mem_fn(&A::one_arg_void)(*cpa, cx);
+    std::mem_fn(&A::one_arg_void)(cpa, cx);
+    return 0;
+}

diff  --git a/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp
new file mode 100644
index 000000000000..f831ec7986c5
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/func.wrap/func.wrap.func/robust_against_adl.pass.cpp
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03
+
+// <functional>
+
+#include <functional>
+
+#include "test_macros.h"
+
+struct Incomplete;
+template<class T> struct Holder { T t; };
+typedef Holder<Incomplete> *Ptr;
+
+Ptr no_args() { return nullptr; }
+Ptr one_arg(Ptr p) { return p; }
+Ptr two_args(Ptr p, Ptr) { return p; }
+Ptr three_args(Ptr p, Ptr, Ptr) { return p; }
+Ptr four_args(Ptr p, Ptr, Ptr, Ptr) { return p; }
+
+void one_arg_void(Ptr) { }
+
+int main(int, char**)
+{
+    Ptr x = nullptr;
+    std::function<Ptr()> f(no_args); f();
+    std::function<Ptr(Ptr)> g(one_arg); g(x);
+    std::function<void(Ptr)> h(one_arg_void); h(x);
+    return 0;
+}

diff  --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
new file mode 100644
index 000000000000..2774401b052b
--- /dev/null
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.invoke/robust_against_adl.pass.cpp
@@ -0,0 +1,49 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// <functional>
+
+#include <functional>
+
+#include "test_macros.h"
+
+struct Incomplete;
+template<class T> struct Holder { T t; };
+typedef Holder<Incomplete> *Ptr;
+
+Ptr no_args() { return nullptr; }
+Ptr one_arg(Ptr p) { return p; }
+Ptr two_args(Ptr p, Ptr) { return p; }
+Ptr three_args(Ptr p, Ptr, Ptr) { return p; }
+
+void one_arg_void(Ptr) { }
+
+int main(int, char**)
+{
+    Ptr x = nullptr;
+    const Ptr cx = nullptr;
+    std::ref(no_args)();
+    std::ref(one_arg)(x);
+    std::ref(one_arg)(cx);
+    std::ref(two_args)(x, x);
+    std::ref(two_args)(x, cx);
+    std::ref(two_args)(cx, x);
+    std::ref(two_args)(cx, cx);
+    std::ref(three_args)(x, x, x);
+    std::ref(three_args)(x, x, cx);
+    std::ref(three_args)(x, cx, x);
+    std::ref(three_args)(cx, x, x);
+    std::ref(three_args)(x, cx, cx);
+    std::ref(three_args)(cx, x, cx);
+    std::ref(three_args)(cx, cx, x);
+    std::ref(three_args)(cx, cx, cx);
+    std::ref(one_arg_void)(x);
+    std::ref(one_arg_void)(cx);
+
+    return 0;
+}


        


More information about the libcxx-commits mailing list