diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2023-05-03 12:28:23 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2023-05-15 18:18:01 -0700 |
commit | 5f5daae04a93f3d522565ab57d7ed8faa239adf1 (patch) | |
tree | 457eaa757fe17f1dbf85273206906a984ca65950 | |
parent | 1acbcc318ad536ab25ffde3f7c786a3c0706311f (diff) | |
download | qtbase-5f5daae04a93f3d522565ab57d7ed8faa239adf1.tar.gz |
QHash: suppress GCC 12 & 13 warning that QHash could overflow
It can't unless you really have so many elements that it should
overflow. When growing, we call bucketsForCapacity(), which won't
overflow; when copying/detaching, we allocate the exact same amount of
memory that we've previously allocated, so that has to be good too.
There was nothing wrong with the previous code. The warning was showing
how the compiler had detected a possible overflow and caused a call to
operator new(-1) to force std::bad_alloc to be thrown. Disabling the
warning did not work in LTO mode. So we mimic it: Q_CHECK_PTR will call
qBadAlloc() for us if exceptions are enabled, or qt_check_pointer() if
not but assertions are (if neither are, then we have no means of
reporting the error, so let's just assume that it can't happen).
In function ‘allocateSpans’,
inlined from ‘__ct ’ at qhash.h:581:48,
inlined from ‘detached’ at qhash.h:596:20,
[...]
qhash.h:551:19: warning: argument 1 value ‘18446744073709551615’ exceeds maximum object size 9223372036854775807 [-Walloc-size-larger-than=]
Commit 1d167b515ef81ba71f3f47863e66d36ed6d06c1c is the likely source of
this warning.
Fixes: QTBUG-113335
Pick-to: 6.5
Change-Id: Ieab617d69f3b4b54ab30fffd175bb8d36228209c
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
-rw-r--r-- | src/corelib/tools/qhash.h | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index b7d3a85e56..9b29429591 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -538,6 +538,14 @@ struct Data size_t nSpans; }; + constexpr qptrdiff MaxSpanCount = (std::numeric_limits<qptrdiff>::max)() / sizeof(Span); + constexpr size_t MaxBucketCount = MaxSpanCount << SpanConstants::SpanShift; + + if (numBuckets > MaxBucketCount) { + Q_CHECK_PTR(false); + Q_UNREACHABLE(); // no exceptions and no assertions -> no error reporting + } + size_t nSpans = numBuckets >> SpanConstants::SpanShift; return R{ new Span[nSpans], nSpans }; } |