[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
This commit is contained in:
Logan Smith 2020-02-20 12:20:21 -05:00 committed by Louis Dionne
parent 3543ac9ab5
commit e442f38395
3 changed files with 26 additions and 2 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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));