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
|
#endif
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <charconv>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <climits>
|
#include <climits>
|
||||||
@@ -603,19 +604,31 @@ public:
|
|||||||
static
|
static
|
||||||
BasicSmallString number(int number)
|
BasicSmallString number(int number)
|
||||||
{
|
{
|
||||||
char buffer[12];
|
#ifdef __cpp_lib_to_chars
|
||||||
std::size_t size = itoa(number, buffer, 10);
|
// +1 for the sign, +1 for the extra digit
|
||||||
|
char buffer[std::numeric_limits<int>::digits10 + 2];
|
||||||
return BasicSmallString(buffer, size);
|
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
|
static
|
||||||
BasicSmallString number(long long int number)
|
BasicSmallString number(long long int number)
|
||||||
{
|
{
|
||||||
char buffer[22];
|
#ifdef __cpp_lib_to_chars
|
||||||
std::size_t size = itoa(number, buffer, 10);
|
// +1 for the sign, +1 for the extra digit
|
||||||
|
char buffer[std::numeric_limits<long long int>::digits10 + 2];
|
||||||
return BasicSmallString(buffer, size);
|
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
|
static
|
||||||
@@ -913,51 +926,6 @@ private:
|
|||||||
m_data.allocated.data.size = size;
|
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:
|
private:
|
||||||
Internal::StringDataLayout<Size> m_data;
|
Internal::StringDataLayout<Size> m_data;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user