mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-22 01:00:12 +08:00
libstdc++: Fix use of make_pair that used ADL
_Rb_tree::_M_equal_range calls make_pair unqualified, which means it uses ADL. As the new testcase shows, this can find something other than std::make_pair. Rather than just changing it to use a qualified call, remove the use of make_pair entirely. We don't need to deduce any types here, we know exactly what type of std::pair we want to construct, so do that explicitly. libstdc++-v3/ChangeLog: * include/bits/stl_tree.h (_Rb_tree::_M_equal_range): Replace unqualified call to make_pair with explicit construction of std::pair. * testsuite/23_containers/set/operations/equal_range_adl.cc: New test.
This commit is contained in:
parent
5ced917508
commit
d5fb86cbec
@ -2633,6 +2633,8 @@ namespace __rb_tree
|
||||
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
|
||||
equal_range(const _Key& __k)
|
||||
{
|
||||
typedef pair<iterator, iterator> _Ret;
|
||||
|
||||
_Base_ptr __x = _M_begin();
|
||||
_Base_ptr __y = _M_end();
|
||||
while (__x)
|
||||
@ -2647,12 +2649,11 @@ namespace __rb_tree
|
||||
_Base_ptr __yu(__y);
|
||||
__y = __x, __x = _S_left(__x);
|
||||
__xu = _S_right(__xu);
|
||||
return make_pair(iterator(_M_lower_bound(__x, __y, __k)),
|
||||
iterator(_M_upper_bound(__xu, __yu, __k)));
|
||||
return _Ret(iterator(_M_lower_bound(__x, __y, __k)),
|
||||
iterator(_M_upper_bound(__xu, __yu, __k)));
|
||||
}
|
||||
}
|
||||
return pair<iterator, iterator>(iterator(__y),
|
||||
iterator(__y));
|
||||
return _Ret(iterator(__y), iterator(__y));
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Val, typename _KeyOfValue,
|
||||
@ -2664,6 +2665,8 @@ namespace __rb_tree
|
||||
_Rb_tree<_Key, _Val, _KeyOfValue, _Compare, _Alloc>::
|
||||
equal_range(const _Key& __k) const
|
||||
{
|
||||
typedef pair<const_iterator, const_iterator> _Ret;
|
||||
|
||||
_Base_ptr __x = _M_begin();
|
||||
_Base_ptr __y = _M_end();
|
||||
while (__x)
|
||||
@ -2678,12 +2681,11 @@ namespace __rb_tree
|
||||
_Base_ptr __yu(__y);
|
||||
__y = __x, __x = _S_left(__x);
|
||||
__xu = _S_right(__xu);
|
||||
return make_pair(const_iterator(_M_lower_bound(__x, __y, __k)),
|
||||
const_iterator(_M_upper_bound(__xu, __yu, __k)));
|
||||
return _Ret(const_iterator(_M_lower_bound(__x, __y, __k)),
|
||||
const_iterator(_M_upper_bound(__xu, __yu, __k)));
|
||||
}
|
||||
}
|
||||
return pair<const_iterator, const_iterator>(const_iterator(__y),
|
||||
const_iterator(__y));
|
||||
return _Ret(const_iterator(__y), const_iterator(__y));
|
||||
}
|
||||
|
||||
template<typename _Key, typename _Val, typename _KeyOfValue,
|
||||
|
@ -0,0 +1,26 @@
|
||||
// { dg-do compile }
|
||||
|
||||
#include <set>
|
||||
|
||||
namespace adl
|
||||
{
|
||||
#if __cplusplus < 201103L
|
||||
template<typename T> void make_pair(const T&, const T&) { }
|
||||
#else
|
||||
template<typename T> void make_pair(T&&, T&&) { }
|
||||
#endif
|
||||
|
||||
struct X { bool operator<(const X&) const { return false; } };
|
||||
}
|
||||
|
||||
typedef std::set<adl::X> Set;
|
||||
|
||||
void
|
||||
test_equal_range(Set& s, const adl::X& x)
|
||||
{
|
||||
// _Rb_tree::_M_equal_range was using make_pair unqualified.
|
||||
(void) s.equal_range(x);
|
||||
const Set& cs = s;
|
||||
// Similarly for the const overload.
|
||||
(void) cs.equal_range(x);
|
||||
}
|
Loading…
Reference in New Issue
Block a user