[libcxx-commits] [PATCH] D115598: [libc++][NFC] Remove goto from std::string

Arthur O'Dwyer via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Sun Dec 12 12:29:36 PST 2021


Quuxplusone accepted this revision as: Quuxplusone.
Quuxplusone added a comment.

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.



================
Comment at: libcxx/include/string:2361
     traits_type::move(__p, __s, __n);
-    traits_type::assign(__p[__n], value_type());
-    __set_size(__n);
-    __invalidate_iterators_past(__n);
+    __null_terminate_at(__p, __n);
   } else {
----------------
This can `return __null_terminate_at(__p, __n)` too. Tail-call for the win.


================
Comment at: libcxx/include/string:3001
                     traits_type::move(__p + __pos + __n2, __p + __pos + __n1, __n_move);
-                    goto __finish;
+                    return __null_terminate_at(__p, __n2 - __n1);
                 }
----------------
Here and below: `__sz + __n2 - __n1`, right? I hope this caused some test failures! :)


================
Comment at: libcxx/include/string:3223
     _LIBCPP_ASSERT(!empty(), "string::pop_back(): string is already empty");
-    size_type __sz;
-    if (__is_long())
-    {
-        __sz = __get_long_size() - 1;
-        __set_long_size(__sz);
-        traits_type::assign(*(__get_long_pointer() + __sz), value_type());
-    }
-    else
-    {
-        __sz = __get_short_size() - 1;
-        __set_short_size(__sz);
-        traits_type::assign(*(__get_short_pointer() + __sz), value_type());
-    }
-    __invalidate_iterators_past(__sz);
+    __null_terminate_at(__get_pointer(), size() - 1);
 }
----------------
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.


================
Comment at: libcxx/include/string:1698-1699
+    void __finish_replace(size_type& __sz, size_type& __n1, size_type& __n2, value_type*& __p) {
+      // __sz += __n2 - __n1; in this and the below function below can cause unsigned
+      // integer overflow, but this is a safe operation, so we disable the check.
+      __sz += __n2 - __n1;
----------------
nilayvaish wrote:
> Quuxplusone wrote:
> > This comment seems obsolete; I have no idea what "check" it's talking about. Let's remove the comment.
> 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?
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.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115598/new/

https://reviews.llvm.org/D115598



More information about the libcxx-commits mailing list