diff --git a/src/corelib/CMakeLists.txt b/src/corelib/CMakeLists.txt index f44af721e5a..9be1fde7873 100644 --- a/src/corelib/CMakeLists.txt +++ b/src/corelib/CMakeLists.txt @@ -35,8 +35,10 @@ qt_internal_add_module(Core NO_GENERATE_METATYPES # metatypes are extracted manually below EXCEPTIONS SOURCES - # Keep qsimd.cpp first so its global static runs first + # Keep these .cpp files in the first and in the order they are so their + # static initialization order is retained global/qsimd.cpp global/qsimd.h global/qsimd_p.h + tools/qhash.cpp tools/qhash.h # Keep the rest alphabetical compat/removed_api.cpp @@ -226,7 +228,6 @@ qt_internal_add_module(Core tools/qduplicatetracker_p.h tools/qflatmap_p.h tools/qfreelist.cpp tools/qfreelist_p.h - tools/qhash.cpp tools/qhash.h tools/qhashfunctions.h tools/qiterator.h tools/qline.cpp tools/qline.h diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 5bea0bf9f00..9264ae53a3f 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -66,11 +66,17 @@ #ifndef QT_BOOTSTRAPPED #include #include +#include #endif // QT_BOOTSTRAPPED #include #include +#if defined(QT_NO_DEBUG) && !defined(NDEBUG) +# define NDEBUG +#endif +#include + #ifdef Q_CC_GNU # define Q_DECL_HOT_FUNCTION __attribute__((hot)) #else @@ -89,7 +95,11 @@ struct HashSeedStorage static constexpr int SeedCount = 2; QBasicAtomicInteger seeds[SeedCount] = { Q_BASIC_ATOMIC_INITIALIZER(0), Q_BASIC_ATOMIC_INITIALIZER(0) }; +#if !QT_SUPPORTS_INIT_PRIORITY || defined(QT_BOOTSTRAPPED) constexpr HashSeedStorage() = default; +#else + HashSeedStorage() { initialize(0); } +#endif enum State { OverriddenByEnvironment = -1, @@ -126,19 +136,24 @@ struct HashSeedStorage private: Q_DECL_COLD_FUNCTION Q_NEVER_INLINE StateResult initialize(int which) noexcept; - [[maybe_unused]] static void ensureConstexprConstructibility() - { - static_assert(std::is_trivially_destructible_v); - static constexpr HashSeedStorage dummy {}; - Q_UNUSED(dummy); - } }; [[maybe_unused]] HashSeedStorage::StateResult HashSeedStorage::initialize(int which) noexcept { StateResult result = { 0, OverriddenByEnvironment }; - bool ok; - int seed = qEnvironmentVariableIntValue("QT_HASH_SEED", &ok); +#ifdef QT_BOOTSTRAPPED + Q_UNUSED(which); + Q_UNREACHABLE(); +#else + // can't use qEnvironmentVariableIntValue (reentrancy) + const char *seedstr = getenv("QT_HASH_SEED"); + const char *endptr = nullptr; + bool ok = false; + int seed; + if (seedstr) + seed = qstrntoll(seedstr, strlen(seedstr), &endptr, 10, &ok); + if (ok && endptr != seedstr + strlen(seedstr)) + ok = false; if (ok) { if (seed) { // can't use qWarning here (reentrancy) @@ -158,6 +173,7 @@ private: result.requestedSeed = x.data[i]; } result.state = JustInitialized; +#endif return result; } @@ -166,14 +182,15 @@ inline HashSeedStorage::StateResult HashSeedStorage::state(int which) constexpr quintptr BadSeed = quintptr(Q_UINT64_C(0x5555'5555'5555'5555)); StateResult result = { BadSeed, AlreadyInitialized }; -#ifndef QT_BOOTSTRAPPED +#if defined(QT_BOOTSTRAPPED) + result = { 0, OverriddenByEnvironment }; +#elif !QT_SUPPORTS_INIT_PRIORITY + // dynamic initialization static auto once = [&]() { result = initialize(which); return true; }(); Q_UNUSED(once); -#else - result = { 0, OverriddenByEnvironment }; #endif if (result.state == AlreadyInitialized && which >= 0) @@ -185,6 +202,9 @@ inline HashSeedStorage::StateResult HashSeedStorage::state(int which) /* The QHash seed itself. */ +#ifdef Q_DECL_INIT_PRIORITY +Q_DECL_INIT_PRIORITY(05) +#endif static HashSeedStorage qt_qhash_seed; /*