On Mon, 14 Apr 2025 at 07:37, Tomasz Kaminski <tkami...@redhat.com> wrote:
>
>
>
> On Sat, Apr 12, 2025 at 4:01 PM Jonathan Wakely <jwak...@redhat.com> wrote:
>>
>> My recent r15-9381-g648d5c26e25497 change assumes that a contiguous
>> iterator with the correct value_type can be converted to a const charT*
>> but that's not true for volatile charT*. The optimization should only be
>> done if it can be converted to the right pointer type.
>>
>> Additionally, the generic loop for non-contiguous iterators needs an
>> explicit cast to deal with iterators that have a reference type that is
>> not explicitly convertible to charT.
>>
>> libstdc++-v3/ChangeLog:
>>
>>         PR libstdc++/119748
>>         * include/bits/basic_string.h (_S_copy_chars): Only optimize for
>>         contiguous iterators that are convertible to const charT*. Use
>>         explicit conversion to charT after dereferencing iterator.
>>         (_S_copy_range): Likewise for contiguous ranges.
>>         * include/bits/cow_string.h (_S_copy_chars): Likewise.
>>         (basic_string(from_range_t, R&&, const Alloc&)): Likewise.
>>         * testsuite/21_strings/basic_string/cons/char/119748.cc: New
>>         test.
>>         * testsuite/21_strings/basic_string/cons/wchar_t/119748.cc:
>>         New test.
>> ---
>>
>> Tested x86_64-linux.
>>
>> The static_cast<_CharT>(*__k1) bit in _S_copy_chars is relevant for the
>> branches too. Thinking about it now, I should probably add another
>> test with iterators that have a value_type with 'explicit operator char()'
>> because volatile char* isn't the only case that fails.
>
> The range constructor is constrained by container-compatible-range
> (https://eel.is/c++draft/containers#concept:container-compatible-range),
> that requires conversion to value type to be implicit.
> Similar requirement exists for iterator-pair algorithms:
> https://eel.is/c++draft/containers#sequence.reqmts-2.5

Ah yes, thanks. So we only have a problem when iter_reference_t<I> or
range_reference_t<R> is volatile-qualified. Those are the only cases
where const charT& won't bind to the iterator's reference type, or
where a contiguous iterator can't be converted to const charT*.

The new tests are still incomplete though, as volatile char* only
tests the contiguous iterator path. We also need to test forward
iterators and input iterators that return volatile references.

New patch incoming ...

Reply via email to