Remove goto from std::string
Details
- Reviewers
• Quuxplusone ldionne nilayvaish - Group Reviewers
Restricted Project - Commits
- rGf2eab339b9af: [libc++][NFC] Remove goto from std::string
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libcxx/include/string | ||
---|---|---|
1697–1704 | We could make this basic_string<_CharT, _Traits, _Allocator>& __null_terminate_at(value_type *__p, size_type __newsz) { __set_size(__newsz); __invalidate_iterators_past(__newsz); traits_type::assign(__p[__newsz], value_type()); return *this; } and then change about 10 callers to the appropriate choice out of return __null_terminate_at(__p, __n); __null_terminate_at(__get_pointer(), __n); __null_terminate_at(__p, __sz + __n); return __null_terminate_at(__p, __sz + (__n2 - __n1)); etc. The only friction I see to that is that some of these callers, e.g. append and insert, are currently skipping the call to __invalidate_iterators_past(__sz) because they know there aren't any valid iterators past the new size. So either we pessimize them in debug mode, or more likely we just leave them as-is and don't upgrade them to this new helper function. | |
1698–1699 | This comment seems obsolete; I have no idea what "check" it's talking about. Let's remove the comment. |
libcxx/include/string | ||
---|---|---|
1698–1699 | Maybe the UBSAN annotation on line 2988 and 3038. I am guessing this will get sanitizer's attention now. Should we annotate this function with _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK? |
libcxx/include/string | ||
---|---|---|
1697 | The first param should be value_type* and update places where pointer is being to passed to pass value_type*. |
LGTM now, although it'd be nice to find the answer to my question about pop_back and __erase_to_end's history, just in case it matters.
libcxx/include/string | ||
---|---|---|
1698–1699 | Thanks, that's definitely it! Instead of keeping the ubsan macro at all, though, I believe we could just change new line 3020 to avoid the overflow: return __null_terminate_at(__p, __sz - (__n1 - __n2)); because at that point __n1 >= __n2, unless I'm mistaken. | |
2365 | This can return __null_terminate_at(__p, __n) too. Tail-call for the win. | |
3008–3009 | Here and below: __sz + __n2 - __n1, right? I hope this caused some test failures! :) | |
3251 | Huh. Anyone got any idea why the left-hand code was so... hand-inlined? Anything in the git log that sheds light on this? Ditto __erase_to_end below. |
- Replaced null_terminate_at() with erase_to_end() in pop_back()
- Added _LIBCPP_HIDE_FROM_ABI
- Fixed bugs
libcxx/include/string | ||
---|---|---|
3251 | I think we want to avoid checking whether the string is long or short again and again. Would likely save a few cycles. |
libcxx/include/string | ||
---|---|---|
3251 | This code is part of the initial libc++ commit. Unless you know where to get any (svn?) log, I think this question can't be answered. The only thing I could guess is some sort of compiler limitation 12+ years ago. |
LGTM with comment. Thanks for the refactoring, and happy this gets us closer to being constexpr friendly.
libcxx/include/string | ||
---|---|---|
3028 |
libcxx/include/string | ||
---|---|---|
3008–3009 | Same issue as line 3020: either __sz + (__n2 - __n1) or __sz - __n1 + __n2. | |
3028 | Or "match line 3023" should also work, I think: __sz - __n1 + __n2 |
The first param should be value_type* and update places where pointer is being to passed to pass value_type*.