forked from OSchip/llvm-project
This fixes a very subtle ABI problem concerning the copy constructor of
pair, and a couple of pair-like implementation detail types. The C++98/03 and 11 standards all specify that the copy constructor of pair<int, int> is trivial. However as libc++ tracked the draft C++11 standard over the years, this copy constructor became non-trivial, and then just recently was corrected back to trivial for C++11. Unfortunately (for libc++1) the Itanium ABI specifies different calling conventions for trivial and non-trivial copy constructors. Therefore currently the C++03 libc++ copy constructor for pair<int, int> is ABI incompatible with the C++11 libc++ copy constructor for pair<int, int>. This is Bad(tm). This patch corrects the situation by making this copy constructor trivial in C++03 mode as well. Just in case it is needed for an incomplete C++11 compiler, libc++ retains the ability to support pair with rvalue references, but without defaulted special members. However the pair needs non-trivial special members to implement this special case, (as it did when clang was in this place a couple of years ago). During this work a bug was also found and fixed in is_trivially_constructible. And there is a minor drive-by fix in <__config> regarding __type_visibility__. A test is updated to ensure that the copy constructor of pair<int, int> is trivial in both C++03 and C++11. This test will necessarily fail for a compiler that implements rvalue references but not defaulted special members. llvm-svn: 194536
This commit is contained in:
parent
4337e97029
commit
ccad8c32e0
|
@ -174,7 +174,7 @@
|
|||
#endif
|
||||
|
||||
#ifndef _LIBCPP_TYPE_VIS
|
||||
# if __has_attribute(type_visibility)
|
||||
# if __has_attribute(__type_visibility__)
|
||||
# define _LIBCPP_TYPE_VIS __attribute__ ((__type_visibility__("default")))
|
||||
# else
|
||||
# define _LIBCPP_TYPE_VIS __attribute__ ((__visibility__("default")))
|
||||
|
|
|
@ -1954,7 +1954,7 @@ public:
|
|||
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
|
||||
: __first_(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
|
||||
|
@ -1973,8 +1973,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
|
||||
|
@ -1992,9 +1990,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
|
@ -2051,7 +2047,7 @@ public:
|
|||
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
|
||||
: _T1(_VSTD::forward<_T1_param>(__t1)), __second_(_VSTD::forward<_T2_param>(__t2)) {}
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
|
||||
|
@ -2069,8 +2065,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
|
||||
|
@ -2087,9 +2081,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
|
@ -2147,7 +2139,7 @@ public:
|
|||
is_nothrow_move_constructible<_T2>::value)
|
||||
: _T2(_VSTD::forward<_T2_param>(__t2)), __first_(_VSTD::forward<_T1_param>(__t1)) {}
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
|
||||
|
@ -2165,8 +2157,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
|
||||
|
@ -2183,9 +2173,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
|
@ -2241,7 +2229,7 @@ public:
|
|||
_LIBCPP_INLINE_VISIBILITY __libcpp_compressed_pair_imp(_T1_param __t1, _T2_param __t2)
|
||||
: _T1(_VSTD::forward<_T1_param>(__t1)), _T2(_VSTD::forward<_T2_param>(__t2)) {}
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(const __libcpp_compressed_pair_imp& __p)
|
||||
|
@ -2259,8 +2247,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__libcpp_compressed_pair_imp(__libcpp_compressed_pair_imp&& __p)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
|
||||
|
@ -2277,9 +2263,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
|
@ -2332,7 +2316,7 @@ public:
|
|||
_LIBCPP_INLINE_VISIBILITY __compressed_pair(_T1_param __t1, _T2_param __t2)
|
||||
: base(_VSTD::forward<_T1_param>(__t1), _VSTD::forward<_T2_param>(__t2)) {}
|
||||
|
||||
#ifdef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#if defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__compressed_pair(const __compressed_pair& __p)
|
||||
|
@ -2349,7 +2333,6 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
__compressed_pair(__compressed_pair&& __p)
|
||||
_NOEXCEPT_(is_nothrow_move_constructible<_T1>::value &&
|
||||
|
@ -2365,9 +2348,7 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
|
||||
|
||||
#endif // _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
#endif // defined(_LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS) && !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES)
|
||||
|
||||
#ifndef _LIBCPP_HAS_NO_VARIADICS
|
||||
|
||||
|
|
|
@ -2437,7 +2437,7 @@ template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_default_construct
|
|||
// is_trivially_copy_constructible
|
||||
|
||||
template <class _Tp> struct _LIBCPP_TYPE_VIS_ONLY is_trivially_copy_constructible
|
||||
: public is_trivially_constructible<_Tp, const typename add_lvalue_reference<_Tp>::type>
|
||||
: public is_trivially_constructible<_Tp, typename add_lvalue_reference<const _Tp>::type>
|
||||
{};
|
||||
|
||||
// is_trivially_move_constructible
|
||||
|
|
|
@ -275,7 +275,7 @@ struct _LIBCPP_TYPE_VIS_ONLY pair
|
|||
#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pair(const pair& __p) = default;
|
||||
#else
|
||||
#elif !defined(_LIBCPP_HAS_NO_RVALUE_REFERENCES) // default the copy ctor in C++03
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
pair(const pair& __p)
|
||||
_NOEXCEPT_(is_nothrow_copy_constructible<first_type>::value &&
|
||||
|
|
|
@ -26,6 +26,8 @@ int main()
|
|||
assert(p2.second == 4);
|
||||
}
|
||||
|
||||
static_assert((std::is_trivially_copy_constructible<std::pair<int, int> >::value), "");
|
||||
|
||||
#if _LIBCPP_STD_VER > 11
|
||||
{
|
||||
typedef std::pair<int, short> P1;
|
||||
|
|
Loading…
Reference in New Issue