[libcxx-commits] [libcxx] e442f38 - [libc++] Fix unintended ADL inside ref(reference_wrapper<T>) and cref(reference_wrapper<T>)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Feb 20 09:22:55 PST 2020


Author: Logan Smith
Date: 2020-02-20T12:22:21-05:00
New Revision: e442f38395f71b680bc1174568e461b5ff1f7ebf

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

LOG: [libc++] Fix unintended ADL inside ref(reference_wrapper<T>) and cref(reference_wrapper<T>)

This patch qualifies calls to ref and cref inside ref(reference_wrapper<T>)
and cref(reference_wrapper<T>), respectively. These previously unqualified
calls could break in the presence of user functions called ref/cref inside
associated namespaces: https://gcc.godbolt.org/z/8VfprT

Fixes PR44398.

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

Added: 
    

Modified: 
    libcxx/include/__functional_base
    libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp
    libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__functional_base b/libcxx/include/__functional_base
index ca761c409b62..f591bf5a9dce 100644
--- a/libcxx/include/__functional_base
+++ b/libcxx/include/__functional_base
@@ -522,7 +522,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 reference_wrapper<_Tp>
 ref(reference_wrapper<_Tp> __t) _NOEXCEPT
 {
-    return ref(__t.get());
+    return _VSTD::ref(__t.get());
 }
 
 template <class _Tp>
@@ -538,7 +538,7 @@ inline _LIBCPP_INLINE_VISIBILITY
 reference_wrapper<const _Tp>
 cref(reference_wrapper<_Tp> __t) _NOEXCEPT
 {
-    return cref(__t.get());
+    return _VSTD::cref(__t.get());
 }
 
 #ifndef _LIBCPP_CXX03_LANG

diff  --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp
index b4707f4e4bc3..d76bcf9245c0 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/cref_2.pass.cpp
@@ -17,6 +17,11 @@
 
 #include "test_macros.h"
 
+namespace adl {
+  struct A {};
+  void cref(A) {}
+}
+
 int main(int, char**)
 {
     const int i = 0;
@@ -24,5 +29,12 @@ int main(int, char**)
     std::reference_wrapper<const int> r2 = std::cref(r1);
     assert(&r2.get() == &i);
 
+    {
+    adl::A a;
+    std::reference_wrapper<const adl::A> a1 = std::cref(a);
+    std::reference_wrapper<const adl::A> a2 = std::cref(a1);
+    assert(&a2.get() == &a);
+    }
+
   return 0;
 }

diff  --git a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp
index 8761357eb82f..9ab62a20a873 100644
--- a/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp
+++ b/libcxx/test/std/utilities/function.objects/refwrap/refwrap.helpers/ref_2.pass.cpp
@@ -24,6 +24,11 @@ bool is5 ( int i ) { return i == 5; }
 template <typename T>
 bool call_pred ( T pred ) { return pred(5); }
 
+namespace adl {
+  struct A {};
+  void ref(A) {}
+}
+
 int main(int, char**)
 {
     {
@@ -32,6 +37,13 @@ int main(int, char**)
     std::reference_wrapper<int> r2 = std::ref(r1);
     assert(&r2.get() == &i);
     }
+    {
+    adl::A a;
+    std::reference_wrapper<adl::A> a1 = std::ref(a);
+    std::reference_wrapper<adl::A> a2 = std::ref(a1);
+    assert(&a2.get() == &a);
+    }
+
     {
     unary_counting_predicate<bool(*)(int), int> cp(is5);
     assert(!cp(6));


        


More information about the libcxx-commits mailing list