forked from qt-creator/qt-creator
SmallString: Replace manual itoa implementation with std::to_chars
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::__not_<std::__is_tuple_like<_Tp> >, 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<Size>::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 <qt_ci_bot@qt-project.org>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
This commit is contained in:
committed by
Marco Bubke
parent
d7ba5a84b0
commit
aa5d2eaf13
@@ -39,6 +39,7 @@
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <charconv>
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <climits>
|
||||
@@ -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<int>::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<long long int>::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<llint>::min())
|
||||
unsignedNumber = lluint(std::numeric_limits<llint>::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<Size> m_data;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user