Eliminate the C++0x-only is_convertible testing function that accepts
a cv-qualifier rvalue reference to the type, e.g., template <class _Tp> char __test(const volatile typename remove_reference<_Tp>::type&&); The use of this function signature rather than the more straightforward one used in C++98/03 mode, e.g., template <class _Tp> char __test(_Tp); is broken in two ways: 1) An rvalue reference cannot bind to lvalues, so is_convertible<X&, X&>::value would be false. This breaks two of the unique_ptr tests on Clang and GCC >= 4.5. Prior GCC's seem to have allowed rvalue references to bind to lvalues, allowing this bug to slip in. 2) By adding cv-qualifiers to the type we're converting to, we get some incorrect "true" results for, e.g., is_convertible<const X&, X&>::value. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@124166 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f83417b823
commit
f9e1c7e367
@ -600,11 +600,7 @@ template <class _Tp> struct _LIBCPP_VISIBLE is_abstract : public __libcpp_abstra
|
|||||||
|
|
||||||
namespace __is_convertible_imp
|
namespace __is_convertible_imp
|
||||||
{
|
{
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
|
||||||
template <class _Tp> char __test(const volatile typename remove_reference<_Tp>::type&&);
|
|
||||||
#else
|
|
||||||
template <class _Tp> char __test(_Tp);
|
template <class _Tp> char __test(_Tp);
|
||||||
#endif
|
|
||||||
template <class _Tp> __two __test(...);
|
template <class _Tp> __two __test(...);
|
||||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||||
template <class _Tp> _Tp&& __source();
|
template <class _Tp> _Tp&& __source();
|
||||||
|
@ -16,6 +16,10 @@
|
|||||||
typedef void Function();
|
typedef void Function();
|
||||||
typedef char Array[1];
|
typedef char Array[1];
|
||||||
|
|
||||||
|
class NonCopyable {
|
||||||
|
NonCopyable(NonCopyable&);
|
||||||
|
};
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@ -366,4 +370,15 @@ int main()
|
|||||||
static_assert((!std::is_convertible<const char*, char*>::value), "");
|
static_assert((!std::is_convertible<const char*, char*>::value), "");
|
||||||
static_assert(( std::is_convertible<const char*, const char*>::value), "");
|
static_assert(( std::is_convertible<const char*, const char*>::value), "");
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
static_assert((std::is_convertible<NonCopyable&, NonCopyable&>::value), "");
|
||||||
|
static_assert((std::is_convertible<NonCopyable&, const NonCopyable&>::value), "");
|
||||||
|
static_assert((std::is_convertible<NonCopyable&, const volatile NonCopyable&>::value), "");
|
||||||
|
static_assert((std::is_convertible<NonCopyable&, volatile NonCopyable&>::value), "");
|
||||||
|
static_assert((std::is_convertible<const NonCopyable&, const NonCopyable&>::value), "");
|
||||||
|
static_assert((std::is_convertible<const NonCopyable&, const volatile NonCopyable&>::value), "");
|
||||||
|
static_assert((std::is_convertible<volatile NonCopyable&, const volatile NonCopyable&>::value), "");
|
||||||
|
static_assert((std::is_convertible<const volatile NonCopyable&, const volatile NonCopyable&>::value), "");
|
||||||
|
static_assert((!std::is_convertible<const NonCopyable&, NonCopyable&>::value), "");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user