From aa5d2eaf134c8654bddf90983191f5577e85b68e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 1 Jun 2022 11:16:20 -0700 Subject: [PATCH] SmallString: Replace manual itoa implementation with std::to_chars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC 12 was producing a huge warning log about this, thinking we were overflowing the buffer. I don't see how. In function ‘std::_Require >, std::is_move_constructible<_Tp>, std::is_move_assignable<_Tp> > std::swap(_Tp&, _Tp&) [with _Tp = char]’, inlined from ‘void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = char*; _ForwardIterator2 = char*]’ at /usr/include/c++/12/bits/stl_algobase.h:182:11, inlined from ‘void std::__reverse(_RandomAccessIterator, _RandomAccessIterator, random_access_iterator_tag) [with _RandomAccessIterator = char*]’ at /usr/include/c++/12/bits/stl_algo.h:1107:18, inlined from ‘void std::reverse(_BIter, _BIter) [with _BIter = char*]’ at /usr/include/c++/12/bits/stl_algo.h:1134:21, inlined from ‘static std::size_t Utils::BasicSmallString::itoa(long long int, char*, uint) [with unsigned int Size = 31]’ at smallstring.h:956:21, [... many more frames ...] move.h:205:11: warning: writing 1 byte into a region of size 0 [-Wstringop-overflow=] smallstring.h:615:14: note: at offset 46 into destination object ‘buffer’ of size 22 615 | char buffer[22]; | ^~~~~~ smallstring.h:615:14: note: at offset [14, 22] into destination object ‘buffer’ of size 22 smallstring.h:615:14: note: at offset 46 into destination object ‘buffer’ of size 22 Change-Id: Iba16e8ea451b444ab213fffd16f491e608ee713a Reviewed-by: Qt CI Bot Reviewed-by: Thiago Macieira Reviewed-by: Marc Mutz --- src/libs/utils/smallstring.h | 74 ++++++++++-------------------------- 1 file changed, 21 insertions(+), 53 deletions(-) diff --git a/src/libs/utils/smallstring.h b/src/libs/utils/smallstring.h index f1a95d3a78d..35c01030fcb 100644 --- a/src/libs/utils/smallstring.h +++ b/src/libs/utils/smallstring.h @@ -39,6 +39,7 @@ #endif #include +#include #include #include #include @@ -603,19 +604,31 @@ public: static BasicSmallString number(int number) { - char buffer[12]; - std::size_t size = itoa(number, buffer, 10); - - return BasicSmallString(buffer, size); +#ifdef __cpp_lib_to_chars + // +1 for the sign, +1 for the extra digit + char buffer[std::numeric_limits::digits10 + 2]; + auto result = std::to_chars(buffer, buffer + sizeof(buffer), number, 10); + Q_ASSERT(result.ec == std::errc{}); + auto endOfConversionString = result.ptr; + return BasicSmallString(buffer, endOfConversionString); +#else + return std::to_string(number); +#endif } static BasicSmallString number(long long int number) { - char buffer[22]; - std::size_t size = itoa(number, buffer, 10); - - return BasicSmallString(buffer, size); +#ifdef __cpp_lib_to_chars + // +1 for the sign, +1 for the extra digit + char buffer[std::numeric_limits::digits10 + 2]; + auto result = std::to_chars(buffer, buffer + sizeof(buffer), number, 10); + Q_ASSERT(result.ec == std::errc{}); + auto endOfConversionString = result.ptr; + return BasicSmallString(buffer, endOfConversionString); +#else + return std::to_string(number); +#endif } static @@ -913,51 +926,6 @@ private: m_data.allocated.data.size = size; } - static - std::size_t itoa(long long int number, char* string, uint base) - { - using llint = long long int; - using lluint = long long unsigned int; - std::size_t size = 0; - bool isNegative = false; - lluint unsignedNumber = 0; - - if (number == 0) - { - string[size] = '0'; - string[++size] = '\0'; - - return size; - } - - if (number < 0 && base == 10) - { - isNegative = true; - if (number == std::numeric_limits::min()) - unsignedNumber = lluint(std::numeric_limits::max()) + 1; - else - unsignedNumber = lluint(-number); - } else { - unsignedNumber = lluint(number); - } - - while (unsignedNumber != 0) - { - int remainder = int(unsignedNumber % base); - string[size++] = (remainder > 9) ? char((remainder - 10) + 'a') : char(remainder + '0'); - unsignedNumber /= base; - } - - if (isNegative) - string[size++] = '-'; - - string[size] = '\0'; - - std::reverse(string, string+size); - - return size; - } - private: Internal::StringDataLayout m_data; };