[libc++] Fix PR 31938 - std::basic_string constructors use non-deductible parameter types.

Summary:
This patch fixes http://llvm.org/PR31938. The description below is copy/pasted from the bug:

The standard says:

template<class charT, class traits = char_traits<charT>,
         class Allocator = allocator<charT>>
class basic_string {
  using value_type = typename traits::char_type;
  // ...
  basic_string(const charT* s, const Allocator& a = Allocator());
};

libc++ actually chooses to declare the constructor as

  basic_string(const value_type* s, const Allocator& a = Allocator());

The implicit deduction guides from class template argument deduction make what was previously an implementation detail visible:

std::basic_string s = "foo"; // error, can't deduce charT.

The constructor in question is in the libc++ DSO, but fortunately it looks like fixing this will not result in an ABI break.


@rsmith How does this look? I did more than just the constructors mentioned in the PR, but IDK how far to take it.


Reviewers: mclow.lists, rsmith

Reviewed By: rsmith

Subscribers: cfe-commits, rsmith

Differential Revision: https://reviews.llvm.org/D29863

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@295393 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Eric Fiselier
2017-02-17 01:17:10 +00:00
parent 4203bfb5d3
commit 0eaf2e8474
4 changed files with 336 additions and 27 deletions

View File

@@ -775,30 +775,30 @@ public:
_LIBCPP_INLINE_VISIBILITY
basic_string(basic_string&& __str, const allocator_type& __a);
#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES
_LIBCPP_INLINE_VISIBILITY basic_string(const value_type* __s);
_LIBCPP_INLINE_VISIBILITY basic_string(const _CharT* __s);
_LIBCPP_INLINE_VISIBILITY
basic_string(const value_type* __s, const allocator_type& __a);
basic_string(const _CharT* __s, const _Allocator& __a);
_LIBCPP_INLINE_VISIBILITY
basic_string(const value_type* __s, size_type __n);
basic_string(const _CharT* __s, size_type __n);
_LIBCPP_INLINE_VISIBILITY
basic_string(const value_type* __s, size_type __n, const allocator_type& __a);
basic_string(const _CharT* __s, size_type __n, const _Allocator& __a);
_LIBCPP_INLINE_VISIBILITY
basic_string(size_type __n, value_type __c);
basic_string(size_type __n, _CharT __c);
_LIBCPP_INLINE_VISIBILITY
basic_string(size_type __n, value_type __c, const allocator_type& __a);
basic_string(size_type __n, _CharT __c, const _Allocator& __a);
basic_string(const basic_string& __str, size_type __pos, size_type __n,
const allocator_type& __a = allocator_type());
const _Allocator& __a = _Allocator());
_LIBCPP_INLINE_VISIBILITY
basic_string(const basic_string& __str, size_type __pos,
const allocator_type& __a = allocator_type());
const _Allocator& __a = _Allocator());
template<class _Tp>
basic_string(const _Tp& __t, size_type __pos, size_type __n,
basic_string(const _Tp& __t, size_type __pos, size_type __n,
const allocator_type& __a = allocator_type(),
typename enable_if<__can_be_converted_to_string_view<_CharT, _Traits, _Tp>::value, void>::type* = 0);
_LIBCPP_INLINE_VISIBILITY explicit
basic_string(__self_view __sv);
_LIBCPP_INLINE_VISIBILITY
basic_string(__self_view __sv, const allocator_type& __a);
basic_string(__self_view __sv, const _Allocator& __a);
template<class _InputIterator>
_LIBCPP_INLINE_VISIBILITY
basic_string(_InputIterator __first, _InputIterator __last);
@@ -807,9 +807,9 @@ public:
basic_string(_InputIterator __first, _InputIterator __last, const allocator_type& __a);
#ifndef _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
_LIBCPP_INLINE_VISIBILITY
basic_string(initializer_list<value_type> __il);
basic_string(initializer_list<_CharT> __il);
_LIBCPP_INLINE_VISIBILITY
basic_string(initializer_list<value_type> __il, const allocator_type& __a);
basic_string(initializer_list<_CharT> __il, const _Allocator& __a);
#endif // _LIBCPP_HAS_NO_GENERALIZED_INITIALIZERS
inline ~basic_string();
@@ -1557,7 +1557,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(const value_type* __s, size_ty
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s)
{
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*) detected nullptr");
__init(__s, traits_type::length(__s));
@@ -1568,7 +1568,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s)
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, const allocator_type& __a)
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, const _Allocator& __a)
: __r_(__a)
{
_LIBCPP_ASSERT(__s != nullptr, "basic_string(const char*, allocator) detected nullptr");
@@ -1580,7 +1580,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, c
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n)
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n) detected nullptr");
__init(__s, __n);
@@ -1591,7 +1591,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, s
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const value_type* __s, size_type __n, const allocator_type& __a)
basic_string<_CharT, _Traits, _Allocator>::basic_string(const _CharT* __s, size_type __n, const _Allocator& __a)
: __r_(__a)
{
_LIBCPP_ASSERT(__n == 0 || __s != nullptr, "basic_string(const char*, n, allocator) detected nullptr");
@@ -1615,7 +1615,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
}
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, const allocator_type& __a)
basic_string<_CharT, _Traits, _Allocator>::basic_string(
const basic_string& __str, const allocator_type& __a)
: __r_(__a)
{
if (!__str.__is_long())
@@ -1694,7 +1695,7 @@ basic_string<_CharT, _Traits, _Allocator>::__init(size_type __n, value_type __c)
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c)
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c)
{
__init(__n, __c);
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1704,7 +1705,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_typ
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_type __c, const allocator_type& __a)
basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, _CharT __c, const _Allocator& __a)
: __r_(__a)
{
__init(__n, __c);
@@ -1714,8 +1715,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(size_type __n, value_typ
}
template <class _CharT, class _Traits, class _Allocator>
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos, size_type __n,
const allocator_type& __a)
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str,
size_type __pos, size_type __n,
const _Allocator& __a)
: __r_(__a)
{
size_type __str_sz = __str.size();
@@ -1730,7 +1732,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __st
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
const allocator_type& __a)
const _Allocator& __a)
: __r_(__a)
{
size_type __str_sz = __str.size();
@@ -1753,7 +1755,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(
__init(__sv.data(), __sv.size());
#if _LIBCPP_DEBUG_LEVEL >= 2
__get_db()->__insert_c(this);
#endif
#endif
}
template <class _CharT, class _Traits, class _Allocator>
@@ -1768,7 +1770,7 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv)
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const allocator_type& __a)
basic_string<_CharT, _Traits, _Allocator>::basic_string(__self_view __sv, const _Allocator& __a)
: __r_(__a)
{
__init(__sv.data(), __sv.size());
@@ -1863,7 +1865,8 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(_InputIterator __first,
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il)
basic_string<_CharT, _Traits, _Allocator>::basic_string(
initializer_list<_CharT> __il)
{
__init(__il.begin(), __il.end());
#if _LIBCPP_DEBUG_LEVEL >= 2
@@ -1873,7 +1876,9 @@ basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_t
template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
basic_string<_CharT, _Traits, _Allocator>::basic_string(initializer_list<value_type> __il, const allocator_type& __a)
basic_string<_CharT, _Traits, _Allocator>::basic_string(
initializer_list<_CharT> __il, const _Allocator& __a)
: __r_(__a)
{
__init(__il.begin(), __il.end());