From b0a7ace47d97dd173bf53d671c908f6f66b1d03d Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Wed, 24 Apr 2024 16:35:01 +0200 Subject: [PATCH] MSVC: improve QASV(const char(&str)[N]) compilation time The lengthHelperContainer() implementation for sizeof(Char) == 1 case is using qstrnlen() for the non-constexpr case. qstrnlen() is an inline function which is effectively a nullptr check and a memchr() call. For some reason, on MSVC this combination resulted in very slow compilation for the user projects, where each call to QObject::setObjectName() was hitting this codepath. Fix it by replacing the qstrnlen() call with strnlen_s() for MSVC. It seems that for now all versions of MSVC are affected. However, introduce a new Q_COMPILER_SLOW_QSTRNLEN_COMPILATION definition, which will allow us to check for the compiler version later on. For now this definition is set for all MSVC versions unconditionally. Fixes: QTBUG-124376 Change-Id: Id769bef1e950ffa756acf7af39d362fd8b112019 Reviewed-by: Oliver Wolff Reviewed-by: Marc Mutz (cherry picked from commit d849cb80a4ba468e2c6097ebfcab384ddaec8e67) Reviewed-by: Qt Cherry-pick Bot (cherry picked from commit 7faabcce1ad66e51a0f8ebbbe722591d6b220f70) --- src/corelib/global/qcompilerdetection.h | 2 ++ src/corelib/text/qstringalgorithms.h | 11 ++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 9c46ea0efbc..0230b5a7844 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -857,6 +857,8 @@ # if _MSC_VER < 1936 # define Q_COMPILER_LACKS_THREE_WAY_COMPARE_SYMMETRY # endif +// QTBUG-124376: MSVC is slow at compiling qstrnlen() +# define Q_COMPILER_SLOW_QSTRNLEN_COMPILATION # endif /* __cplusplus */ #endif // defined(Q_CC_MSVC) && !defined(Q_CC_CLANG) diff --git a/src/corelib/text/qstringalgorithms.h b/src/corelib/text/qstringalgorithms.h index 3b9d8f3ccaf..41c607b857e 100644 --- a/src/corelib/text/qstringalgorithms.h +++ b/src/corelib/text/qstringalgorithms.h @@ -174,12 +174,21 @@ lengthHelperContainer(const Char (&str)[N]) return lengthHelperContainerLoop(str); } +inline qsizetype qstrnlen_helper(const char *str, size_t maxlen) +{ +#if !defined(Q_COMPILER_SLOW_QSTRNLEN_COMPILATION) + return qstrnlen(str, maxlen); +#else + return strnlen_s(str, maxlen); +#endif +} + template [[nodiscard]] constexpr inline std::enable_if_t lengthHelperContainer(const Char (&str)[N]) { #ifdef QT_SUPPORTS_IS_CONSTANT_EVALUATED if (!q20::is_constant_evaluated()) - return qstrnlen(reinterpret_cast(str), N); + return qstrnlen_helper(reinterpret_cast(str), N); #endif return lengthHelperContainerLoop(str);