summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2023-05-03 12:28:23 -0700
committerThiago Macieira <thiago.macieira@intel.com>2023-05-15 18:18:01 -0700
commit5f5daae04a93f3d522565ab57d7ed8faa239adf1 (patch)
tree457eaa757fe17f1dbf85273206906a984ca65950
parent1acbcc318ad536ab25ffde3f7c786a3c0706311f (diff)
downloadqtbase-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.h8
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 };
}