From b56b6a9538f50ac4d4424bc7ad37d2f462245182 Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Thu, 21 Apr 2022 08:49:53 +0200 Subject: Workaround MSVC2022 ICE in constexpr functions It happens around initialization of STL containers in a constexpr function. In this case, aggregate initialization of std::array with double braces seems to cause the crash. For some reason it doesn't seem to happen in 98-based. This workaround can be reverted after Microsoft fixes the issue: https://developercommunity.visualstudio.com/t/fatal-error-C1001:-Internal-compiler-err/1669485 Change-Id: I6bc2c71d328691cc74bc53c6d62f3d5df519b81e Fixes: QTBUG-101917 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit 0ce5e91bdfa2cd7cac247911b9e8c4404c114937) Reviewed-by: Qt Cherry-pick Bot --- chromium/base/hash/md5_constexpr_internal.h | 62 +++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 7 deletions(-) diff --git a/chromium/base/hash/md5_constexpr_internal.h b/chromium/base/hash/md5_constexpr_internal.h index b705bc8ad05..5c9c004455e 100644 --- a/chromium/base/hash/md5_constexpr_internal.h +++ b/chromium/base/hash/md5_constexpr_internal.h @@ -281,15 +281,63 @@ struct MD5CE { return IntermediateDataToMD5Digest(ProcessMessage(data, n)); } - static constexpr uint64_t Hash64(const char* data, uint32_t n) { - IntermediateData intermediate = ProcessMessage(data, n); - return (static_cast(SwapEndian(intermediate.a)) << 32) | - static_cast(SwapEndian(intermediate.b)); + static constexpr uint64_t Hash64(const char* message, uint32_t n) { + const uint32_t m = GetPaddedMessageLength(n); + IntermediateData intermediate0 = kInitialIntermediateData; + for (uint32_t offset = 0; offset < m; offset += 64) { + RoundData data = { + GetPaddedMessageWord(message, n, m, offset), + GetPaddedMessageWord(message, n, m, offset + 4), + GetPaddedMessageWord(message, n, m, offset + 8), + GetPaddedMessageWord(message, n, m, offset + 12), + GetPaddedMessageWord(message, n, m, offset + 16), + GetPaddedMessageWord(message, n, m, offset + 20), + GetPaddedMessageWord(message, n, m, offset + 24), + GetPaddedMessageWord(message, n, m, offset + 28), + GetPaddedMessageWord(message, n, m, offset + 32), + GetPaddedMessageWord(message, n, m, offset + 36), + GetPaddedMessageWord(message, n, m, offset + 40), + GetPaddedMessageWord(message, n, m, offset + 44), + GetPaddedMessageWord(message, n, m, offset + 48), + GetPaddedMessageWord(message, n, m, offset + 52), + GetPaddedMessageWord(message, n, m, offset + 56), + GetPaddedMessageWord(message, n, m, offset + 60)}; + IntermediateData intermediate1 = intermediate0; + for (uint32_t i = 0; i < 64; ++i) + intermediate1 = ApplyStep(i, data, intermediate1); + intermediate0 = Add(intermediate0, intermediate1); + } + return (static_cast(SwapEndian(intermediate0.a)) << 32) | + static_cast(SwapEndian(intermediate0.b)); } - static constexpr uint32_t Hash32(const char* data, uint32_t n) { - IntermediateData intermediate = ProcessMessage(data, n); - return SwapEndian(intermediate.a); + static constexpr uint32_t Hash32(const char* message, uint32_t n) { + const uint32_t m = GetPaddedMessageLength(n); + IntermediateData intermediate0 = kInitialIntermediateData; + for (uint32_t offset = 0; offset < m; offset += 64) { + RoundData data = { + GetPaddedMessageWord(message, n, m, offset), + GetPaddedMessageWord(message, n, m, offset + 4), + GetPaddedMessageWord(message, n, m, offset + 8), + GetPaddedMessageWord(message, n, m, offset + 12), + GetPaddedMessageWord(message, n, m, offset + 16), + GetPaddedMessageWord(message, n, m, offset + 20), + GetPaddedMessageWord(message, n, m, offset + 24), + GetPaddedMessageWord(message, n, m, offset + 28), + GetPaddedMessageWord(message, n, m, offset + 32), + GetPaddedMessageWord(message, n, m, offset + 36), + GetPaddedMessageWord(message, n, m, offset + 40), + GetPaddedMessageWord(message, n, m, offset + 44), + GetPaddedMessageWord(message, n, m, offset + 48), + GetPaddedMessageWord(message, n, m, offset + 52), + GetPaddedMessageWord(message, n, m, offset + 56), + GetPaddedMessageWord(message, n, m, offset + 60)}; + IntermediateData intermediate1 = intermediate0; + for (uint32_t i = 0; i < 64; ++i) + intermediate1 = ApplyStep(i, data, intermediate1); + intermediate0 = Add(intermediate0, intermediate1); + } + return SwapEndian(intermediate0.a); } }; -- cgit v1.2.1