[libcxx] r263036 - Implement LWG#2583: There is no way to supply an allocator for basic_string(str, pos)

Duncan Exon Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 11 07:52:20 PST 2016


There's a longer term fix involving availability attributes.   My patch to the test system for deployment targets is holding up a series of patches that tell the compiler when API was introduced (with a 'strict' flag).  This moves link time errors (and load time errors when back deploying) to compile time.  (I also have patches to get the test suite green for all Apple deployment targets.)

That doesn't handle this case explicitly, but I have an idea for new support in clang via a new flag:
- extern=10.10: only respect extern template for this function for dylibs 10.10 and later, otherwise leave as linkonce. 

This would allow libc++ to add new basic_string functions to the dylib over time. 

-- dpnes

> On Mar 11, 2016, at 7:32 AM, Nico Weber <thakis at chromium.org> wrote:
> 
> I reverted this in 263246 for now. I think the right fix is just to add _LIBCPP_INLINE_VISIBILITY to the new constructor, but I'm not 100% sure.
> 
>> On Thu, Mar 10, 2016 at 10:21 AM, Nico Weber <thakis at chromium.org> wrote:
>> I think this is ABI-breaking. On OS X, new libc++ headers must work with old system libc++.dylibs. When I build in this setup with this change, I get
>> 
>> Undefined symbols for architecture x86_64:
>>   "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, std::__1::allocator<char> const&)", referenced from:
>>      
>> The new function probably needs that always_inline treatment that many other functions have?
>> 
>> 
>>> On Wed, Mar 9, 2016 at 12:51 PM, Marshall Clow via cfe-commits <cfe-commits at lists.llvm.org> wrote:
>>> Author: marshall
>>> Date: Wed Mar  9 11:51:43 2016
>>> New Revision: 263036
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=263036&view=rev
>>> Log:
>>> Implement LWG#2583: There is no way to supply an allocator for basic_string(str, pos)
>>> 
>>> Modified:
>>>     libcxx/trunk/include/string
>>>     libcxx/trunk/test/std/strings/basic.string/string.cons/substr.pass.cpp
>>>     libcxx/trunk/www/cxx1z_status.html
>>> 
>>> Modified: libcxx/trunk/include/string
>>> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/string?rev=263036&r1=263035&r2=263036&view=diff
>>> ==============================================================================
>>> --- libcxx/trunk/include/string (original)
>>> +++ libcxx/trunk/include/string Wed Mar  9 11:51:43 2016
>>> @@ -98,8 +98,10 @@ public:
>>>      basic_string(const basic_string& str);
>>>      basic_string(basic_string&& str)
>>>          noexcept(is_nothrow_move_constructible<allocator_type>::value);
>>> -    basic_string(const basic_string& str, size_type pos, size_type n = npos,
>>> +    basic_string(const basic_string& str, size_type pos,                 // LWG#2583
>>>                   const allocator_type& a = allocator_type());
>>> +    basic_string(const basic_string& str, size_type pos, size_type n,    // LWG#2583
>>> +                 const Allocator& a = Allocator());
>>>      basic_string(const value_type* s, const allocator_type& a = allocator_type());
>>>      basic_string(const value_type* s, size_type n, const allocator_type& a = allocator_type());
>>>      basic_string(size_type n, value_type c, const allocator_type& a = allocator_type());
>>> @@ -1397,7 +1399,9 @@ public:
>>>      basic_string(size_type __n, value_type __c);
>>>      _LIBCPP_INLINE_VISIBILITY
>>>      basic_string(size_type __n, value_type __c, const allocator_type& __a);
>>> -    basic_string(const basic_string& __str, size_type __pos, size_type __n = npos,
>>> +    basic_string(const basic_string& __str, size_type __pos, size_type __n,
>>> +                 const allocator_type& __a = allocator_type());
>>> +    basic_string(const basic_string& __str, size_type __pos,
>>>                   const allocator_type& __a = allocator_type());
>>>      template<class _InputIterator>
>>>          _LIBCPP_INLINE_VISIBILITY
>>> @@ -2220,6 +2224,20 @@ basic_string<_CharT, _Traits, _Allocator
>>>  #if _LIBCPP_DEBUG_LEVEL >= 2
>>>      __get_db()->__insert_c(this);
>>>  #endif
>>> +}
>>> +
>>> +template <class _CharT, class _Traits, class _Allocator>
>>> +basic_string<_CharT, _Traits, _Allocator>::basic_string(const basic_string& __str, size_type __pos,
>>> +                                                        const allocator_type& __a)
>>> +    : __r_(__a)
>>> +{
>>> +    size_type __str_sz = __str.size();
>>> +    if (__pos > __str_sz)
>>> +        this->__throw_out_of_range();
>>> +    __init(__str.data() + __pos, __str_sz - __pos);
>>> +#if _LIBCPP_DEBUG_LEVEL >= 2
>>> +    __get_db()->__insert_c(this);
>>> +#endif
>>>  }
>>> 
>>>  template <class _CharT, class _Traits, class _Allocator>
>>> 
>>> Modified: libcxx/trunk/test/std/strings/basic.string/string.cons/substr.pass.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/strings/basic.string/string.cons/substr.pass.cpp?rev=263036&r1=263035&r2=263036&view=diff
>>> ==============================================================================
>>> --- libcxx/trunk/test/std/strings/basic.string/string.cons/substr.pass.cpp (original)
>>> +++ libcxx/trunk/test/std/strings/basic.string/string.cons/substr.pass.cpp Wed Mar  9 11:51:43 2016
>>> @@ -11,14 +11,21 @@
>>>  // <string>
>>> 
>>>  // basic_string(const basic_string<charT,traits,Allocator>& str,
>>> -//              size_type pos, size_type n = npos,
>>> +//              size_type pos, size_type n,
>>> +//              const Allocator& a = Allocator());
>>> +//
>>> +// basic_string(const basic_string<charT,traits,Allocator>& str,
>>> +//              size_type pos,
>>>  //              const Allocator& a = Allocator());
>>> 
>>>  #include <string>
>>>  #include <stdexcept>
>>>  #include <algorithm>
>>> +#include <vector>
>>> +#include <scoped_allocator>
>>>  #include <cassert>
>>> 
>>> +#include "test_macros.h"
>>>  #include "test_allocator.h"
>>>  #include "min_allocator.h"
>>> 
>>> @@ -91,6 +98,20 @@ test(S str, unsigned pos, unsigned n, co
>>>      }
>>>  }
>>> 
>>> +#if TEST_STD_VER >= 11
>>> +void test2583()
>>> +{   // LWG #2583
>>> +    typedef std::basic_string<char, std::char_traits<char>, test_allocator<char> > StringA;
>>> +    std::vector<StringA, std::scoped_allocator_adaptor<test_allocator<StringA>>> vs;
>>> +    StringA s{"1234"};
>>> +    vs.emplace_back(s, 2);
>>> +
>>> +    try { vs.emplace_back(s, 5); }
>>> +    catch (const std::out_of_range&) { return; }
>>> +    assert(false);
>>> +}
>>> +#endif
>>> +
>>>  int main()
>>>  {
>>>      {
>>> @@ -131,7 +152,7 @@ int main()
>>>      test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 10, A(8));
>>>      test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A(7)), 50, 100, A(8));
>>>      }
>>> -#if __cplusplus >= 201103L
>>> +#if TEST_STD_VER >= 11
>>>      {
>>>      typedef min_allocator<char> A;
>>>      typedef std::basic_string<char, std::char_traits<char>, A> S;
>>> @@ -170,5 +191,7 @@ int main()
>>>      test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 10, A());
>>>      test(S("1234567890123456789012345678901234567890123456789012345678901234567890", A()), 50, 100, A());
>>>      }
>>> +
>>> +    test2583();
>>>  #endif
>>>  }
>>> 
>>> Modified: libcxx/trunk/www/cxx1z_status.html
>>> URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=263036&r1=263035&r2=263036&view=diff
>>> ==============================================================================
>>> --- libcxx/trunk/www/cxx1z_status.html (original)
>>> +++ libcxx/trunk/www/cxx1z_status.html Wed Mar  9 11:51:43 2016
>>> @@ -227,7 +227,7 @@
>>>         <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2579">2579</a></td><td>Inconsistency wrt Allocators in <tt>basic_string</tt> assignment vs. <tt>basic_string::assign</tt></td><td>Jacksonville</td><td><i></i></td></tr>
>>>         <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2581">2581</a></td><td>Specialization of <tt><type_traits></tt> variable templates should be prohibited</td><td>Jacksonville</td><td>Complete</td></tr>
>>>         <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2582">2582</a></td><td>§[res.on.functions]/2's prohibition against incomplete types shouldn't apply to type traits</td><td>Jacksonville</td><td></td></tr>
>>> -       <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2583">2583</a></td><td>There is no way to supply an allocator for <tt>basic_string(str, pos)</tt></td><td>Jacksonville</td><td><i></i></td></tr>
>>> +       <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2583">2583</a></td><td>There is no way to supply an allocator for <tt>basic_string(str, pos)</tt></td><td>Jacksonville</td><td>Complete</td></tr>
>>>         <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2585">2585</a></td><td><tt>forward_list::resize(size_type, const value_type&)</tt> effects incorrect</td><td>Jacksonville</td><td></td></tr>
>>>         <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2586">2586</a></td><td>Wrong value category used in <tt>scoped_allocator_adaptor::construct()</tt></td><td>Jacksonville</td><td></td></tr>
>>>         <tr><td><a href="http://cplusplus.github.io/LWG/lwg-defects.html#2590">2590</a></td><td>Aggregate initialization for <tt>std::array</tt></td><td>Jacksonville</td><td>Complete</td></tr>
>>> 
>>> 
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160311/25ebd102/attachment-0001.html>


More information about the cfe-commits mailing list