Don't SFINAE pair's copy assignment operator in C++03 mode.

In C++03 mode evaluating the SFINAE can cause a hard error due to
access control violations. This is a problem because the SFINAE
is evaluated as soon as the class is instantiated, and not later.

llvm-svn: 276594
This commit is contained in:
Eric Fiselier 2016-07-25 00:48:36 +00:00
parent 141b2881d7
commit 4e91ea50a0
2 changed files with 40 additions and 0 deletions

View File

@ -351,9 +351,13 @@ struct _LIBCPP_TYPE_VIS_ONLY pair
typedef typename remove_reference<_T1>::type _T1Unref;
typedef typename remove_reference<_T2>::type _T2Unref;
#if !defined(_LIBCPP_CXX03_LANG)
typedef integral_constant<bool,
is_copy_assignable<_T1>::value
&& is_copy_assignable<_T2>::value> _CanCopyAssign;
#else
typedef true_type _CanCopyAssign;
#endif
_LIBCPP_INLINE_VISIBILITY
pair& operator=(typename conditional<_CanCopyAssign::value, pair, __nat>::type const& __p)

View File

@ -0,0 +1,36 @@
//===----------------------------------------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
// REQUIRES-ANY: c++98, c++03
// <utility>
// template <class T1, class T2> struct pair
// pair& operator=(pair const& p);
#include <utility>
#include <memory>
#include <cassert>
struct NonAssignable {
NonAssignable() {}
private:
NonAssignable& operator=(NonAssignable const&);
};
int main()
{
// Test that we don't constrain the assignment operator in C++03 mode.
// Since we don't have access control SFINAE having pair evaluate SFINAE
// may cause a hard error.
typedef std::pair<int, NonAssignable> P;
static_assert(std::is_copy_assignable<P>::value, "");
}