Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.15.0
-
None
-
MSVC 19.26.28806
-
-
61ccfefb25d61da95a1a1cdf0313da1448dc23c6 (qt/qtbase/dev) 8585263843147e8092ff5bbc2e13d10a1b7be0de (qt/qtbase/5.15)
Description
When compiling a program using Qt on MSVC at /W3 warning level, I get the following error:
C:\Qt\5.15.0\msvc2019_64\include\QtCore/qstringview.h(262): warning C4244: 'return': conversion from 'qsizetype' to 'int', possible loss of data
The line in question is https://github.com/qt/qtbase/blob/1b72f9676f13fc527d26a5b012ef2322414eaa25/src/corelib/text/qstringview.h#L306-L307 (qtbase git master).
class QStringView { ... Q_REQUIRED_RESULT Q_DECL_CONSTEXPR int compare(QChar c) const noexcept { return empty() || front() == c ? size() - 1 : *utf16() - c.unicode() ; }
This code was only added in Qt 5.15 commit b2f79cc, which explains why I didn't see the warning before. "#include <QWidget>" is sufficient to reproduce this error.
This code is heavily code-golfed. I believe the intent is that "size() - 1" is:
- negative if empty() (aka size() == 0)
- zero if this is a length-1 string equal to c
- positive if it's a long string starting with c.
But if size() is over 2 billion (an extreme edge case), casting qsizetype to int will overflow (which is UB, and may return the wrong value, or return a 64-bit value in a register expected to be 32 bits, or miscompile some other way).
Maybe it should be rewritten and expanded to three if/else statements. If empty(), return -1. If front() == c, return size() > 1. Otherwise return *utf16() - c.unicode().