diff --git a/ctl/string.cc b/ctl/string.cc index ae5692b0f..f1bf28a50 100644 --- a/ctl/string.cc +++ b/ctl/string.cc @@ -47,27 +47,27 @@ string::~string() /* noexcept */ } } -string::string(const char* s) noexcept +string::string(const char* s) noexcept : string() { append(s, strlen(s)); } -string::string(const string& s) noexcept +string::string(const string& s) noexcept : string() { append(s.data(), s.size()); } -string::string(const string_view s) noexcept +string::string(const string_view s) noexcept : string() { append(s.p, s.n); } -string::string(size_t size, char ch) noexcept +string::string(size_t size, char ch) noexcept : string() { resize(size, ch); } -string::string(const char* s, size_t size) noexcept +string::string(const char* s, size_t size) noexcept : string() { append(s, size); } @@ -75,6 +75,8 @@ string::string(const char* s, size_t size) noexcept const char* string::c_str() const noexcept { + if (!size()) + return ""; if (size() >= capacity()) __builtin_trap(); if (data()[size()]) @@ -86,8 +88,9 @@ void string::reserve(size_t c2) noexcept { char* p2; - if (c2 < size()) - c2 = size(); + size_t n = size(); + if (c2 < n) + c2 = n; if (ckd_add(&c2, c2, 15)) __builtin_trap(); c2 &= -16; @@ -101,7 +104,6 @@ string::reserve(size_t c2) noexcept if (!(p2 = (char *)realloc(big()->p, c2))) __builtin_trap(); } - size_t n = size(); std::atomic_signal_fence(std::memory_order_seq_cst); set_big_capacity(c2); big()->n = n; diff --git a/ctl/string.h b/ctl/string.h index e2cb4d16b..e96ff71c0 100644 --- a/ctl/string.h +++ b/ctl/string.h @@ -84,7 +84,9 @@ class string string() noexcept { set_small_size(0); - small()->buf[0] = 0; +#if 0 + s.small()->buf[0] = 0; +#endif } void swap(string& s) noexcept @@ -100,9 +102,9 @@ class string { __builtin_memcpy(blob, __builtin_launder(s.blob), sizeof(blob)); s.set_small_size(0); - /* shouldn't be necessary, but the spec says s should be left in a valid - state and our c_str() depends on this */ +#if 0 s.small()->buf[0] = 0; +#endif } void clear() noexcept @@ -304,6 +306,7 @@ class string if (c2 > __::big_mask) __builtin_trap(); *(__builtin_launder(blob) + __::sso_max) = 0x80; + big()->c &= ~__::big_mask; big()->c |= c2; } diff --git a/test/ctl/string_test.cc b/test/ctl/string_test.cc index 218b1b5ef..264edbbbc 100644 --- a/test/ctl/string_test.cc +++ b/test/ctl/string_test.cc @@ -308,6 +308,12 @@ main() s.append(" world"); if (s != "hello world") return 63; + for (int i = 0; i < 4; ++i) { + s.append(" world"); + } + if (s != "hello world world world world world") { + return 64; + } } // {