Skip to content

Fix "outside the valid range of a QString" runtime warnings

This warning will become an assertion failure and possibly undefined behavior in Qt 6.

Steps to reproduce:

  1. Clear the data-repository for ktexteditor project and open it (or open it for the first time).
  2. Wait for several seconds => 4 identical warnings are printed:

Using QCharRef with an index pointing outside the valid range of a QString. The corresponding behavior is deprecated, and will be changed in a future version of Qt.

The 4 call stacks obtained by placing a breakpoint at the std::cerr << "------------ " << qPrintable(msg) << std::endl; line added in the second commit are the same:

#0 (anonymous namespace)::messageOutput(QtMsgType, QMessageLogContext const&, QString const&) (type=QtWarningMsg, context=..., msg="Using QCharRef with an index pointing outside the valid range of a QString. The corresponding behavior is deprecated, and will be changed in a future version of Qt.") at /home/Fast_storage/kdevelop/app/main.cpp:75
#1 0x00007ff7a96e0aa8 in () at /usr/lib/libQt5Core.so.5
#2 0x00007ff7a96d9bc9 in () at /usr/lib/libQt5Core.so.5
#3 0x00007ff7a96a0101 in QMessageLogger::warning(char const*, ...) const () at /usr/lib/libQt5Core.so.5
#4 0x00007ff7a96a4a27 in QtPrivate::DeprecatedRefClassBehavior::warn(QtPrivate::DeprecatedRefClassBehavior::WarningType, QtPrivate::DeprecatedRefClassBehavior::EmittingClass) () at /usr/lib/libQt5Core.so.5
#5 0x00007ff7ac786df1 in QCharRef::operator QChar() const (this=0x7ff70bffae20) at /usr/include/qt/QtCore/qstring.h:1205
#6 0x00007ff7ac786390 in KDevelop::ParamIterator::operator++() (this=0x7ff70bffae98) at /home/Fast_storage/kdevelop/kdevplatform/language/duchain/stringhelpers.cpp:602
#7 0x00007ff7ac7667e6 in KDevelop::Identifier::Identifier(QString const&, unsigned int, unsigned int*) (this=0x7ff70bffafd0, id="__not_overloaded2<_Tp, _Up, __void_t<decltype(std::declval<_Tp>().operator<(std::declval<_Up>()))>>", start=0, takenRange=0x0) at /home/Fast_storage/kdevelop/kdevplatform/language/duchain/identifier.cpp:406
#8 0x00007ff7317db6b3 in (anonymous namespace)::makeId(CXCursor) (cursor=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:114
#9 0x00007ff731808811 in (anonymous namespace)::Visitor::buildDeclaration<(CXCursorKind)32, KDevelop::ClassDeclaration, true>(CXCursor) (this=0x7ff70bffd110, cursor=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1184
#10 0x00007ff7317f80a3 in (anonymous namespace)::Visitor::dispatchCursor<(CXCursorKind)32, (Decision)0, (Decision)0>(CXCursor, CXCursor) (this=0x7ff70bffd110, cursor=..., parent=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:984
#11 0x00007ff7317ee1d9 in (anonymous namespace)::Visitor::dispatchCursor<(CXCursorKind)32, (Decision)0, (Decision)2>(CXCursor, CXCursor) (this=0x7ff70bffd110, cursor=..., parent=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:959
#12 0x00007ff7317e4983 in (anonymous namespace)::Visitor::dispatchCursor<(CXCursorKind)32>(CXCursor, CXCursor) (this=0x7ff70bffd110, cursor=..., parent=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:947
#13 0x00007ff7317df9d2 in (anonymous namespace)::visitCursor(CXCursor, CXCursor, CXClientData) (cursor=..., parent=..., data=0x7ff70bffd110) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1571
#14 0x00007ff72694ac2e in () at /usr/lib/libclang.so.13
#15 0x00007ff72694b7e6 in () at /usr/lib/libclang.so.13
#16 0x00007ff72694ba18 in () at /usr/lib/libclang.so.13
#17 0x00007ff72694a5b2 in () at /usr/lib/libclang.so.13
#18 0x00007ff72694cca0 in clang_visitChildren () at /usr/lib/libclang.so.13
#19 0x00007ff7317fc89a in (anonymous namespace)::Visitor::buildDeclaration<(CXCursorKind)2, KDevelop::ClassDeclaration, true>(CXCursor) (this=0x7ff70bffd110, cursor=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1214
#20 0x00007ff7317f2119 in (anonymous namespace)::Visitor::dispatchCursor<(CXCursorKind)2, (Decision)1, (Decision)0>(CXCursor, CXCursor) (this=0x7ff70bffd110, cursor=..., parent=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:984
#21 0x00007ff7317eb381 in (anonymous namespace)::Visitor::dispatchCursor<(CXCursorKind)2, (Decision)1, (Decision)2>(CXCursor, CXCursor) (this=0x7ff70bffd110, cursor=..., parent=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:959
#22 0x00007ff7317e3611 in (anonymous namespace)::Visitor::dispatchCursor<(CXCursorKind)2>(CXCursor, CXCursor) (this=0x7ff70bffd110, cursor=..., parent=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:948
#23 0x00007ff7317df1dd in (anonymous namespace)::visitCursor(CXCursor, CXCursor, CXClientData) (cursor=..., parent=..., data=0x7ff70bffd110) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1550
#24 0x00007ff72694ac2e in () at /usr/lib/libclang.so.13
#25 0x00007ff72694b7e6 in () at /usr/lib/libclang.so.13
#26 0x00007ff72694ba18 in () at /usr/lib/libclang.so.13
#27 0x00007ff726949931 in () at /usr/lib/libclang.so.13
#28 0x00007ff72694cca0 in clang_visitChildren () at /usr/lib/libclang.so.13
#29 0x00007ff7317eca8e in (anonymous namespace)::Visitor::buildDeclaration<(CXCursorKind)22, KDevelop::Declaration, true>(CXCursor) (this=0x7ff70bffd110, cursor=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1214
#30 0x00007ff7317e40ab in (anonymous namespace)::Visitor::dispatchCursor<(CXCursorKind)22>(CXCursor, CXCursor) (this=0x7ff70bffd110, cursor=..., parent=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:984
#31 0x00007ff7317df608 in (anonymous namespace)::visitCursor(CXCursor, CXCursor, CXClientData) (cursor=..., parent=..., data=0x7ff70bffd110) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1561
#32 0x00007ff72694ac2e in () at /usr/lib/libclang.so.13
#33 0x00007ff72694b7e6 in () at /usr/lib/libclang.so.13
#34 0x00007ff72694ba18 in () at /usr/lib/libclang.so.13
#35 0x00007ff726949f4e in () at /usr/lib/libclang.so.13
#36 0x00007ff72694cca0 in clang_visitChildren () at /usr/lib/libclang.so.13
#37 0x00007ff7317de908 in (anonymous namespace)::Visitor::Visitor(CXTranslationUnit, CXFile, IncludeFileContexts const&, bool) (this=0x7ff70bffd110, tu=0x55614dfdada0, file=0x55614dfd6e70, includes=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, update=false) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1471
#38 0x00007ff7317e0073 in Builder::visit(CXTranslationUnitImpl*, void*, QHash<void*, KDevelop::ReferencedTopDUContext> const&, bool) (tu=0x55614dfdada0, file=0x55614dfd6e70, includes=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, update=false) at /home/Fast_storage/kdevelop/plugins/clang/duchain/builder.cpp:1618
#39 0x00007ff73184c146 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x55614dfd6e70, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:207
#40 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x55614edc6410, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#41 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x556150a54670, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#42 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x556150f67b50, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#43 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x556150f67ab0, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#44 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x55614f7d3f50, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#45 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x55614e2d06c0, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#46 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x556146da07d0, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#47 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x55615079a250, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#48 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x55615079aa40, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#49 0x00007ff73184b934 in ClangHelpers::buildDUChain(void*, QMultiHash<void*, Import> const&, ParseSession const&, QFlags<KDevelop::TopDUContext::Feature>, QHash<void*, KDevelop::ReferencedTopDUContext>&, QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> const&, KDevelop::IndexedString const&, ClangIndex*, std::function<bool ()> const&) (file=0x556150138250, imports=QMultiHash<void *, Import> (size = 1297) = {...}, session=..., features=..., includedFiles=QHash<void *, KDevelop::ReferencedTopDUContext> (size = 160) = {...}, unsavedRevisions=QHash<KDevelop::IndexedString, KDevelop::ModificationRevision> (size = 39) = {...}, parseDocument=..., index=0x5561483c4f00, abortFunction=...) at /home/Fast_storage/kdevelop/plugins/clang/duchain/clanghelpers.cpp:121
#50 0x00007ff7319052ce in ClangParseJob::run(QSharedPointer<ThreadWeaver::JobInterface>, ThreadWeaver::Thread*) (this=0x55614df5b150) at /home/Fast_storage/kdevelop/plugins/clang/clangparsejob.cpp:322
#51 0x00007ff7ae55b36c in ThreadWeaver::IdDecorator::run(QSharedPointer<ThreadWeaver::JobInterface>, ThreadWeaver::Thread*) () at /usr/lib/libKF5ThreadWeaver.so.5
#52 0x00007ff7ae55b14e in ThreadWeaver::Executor::run(QSharedPointer<ThreadWeaver::JobInterface> const&, ThreadWeaver::Thread*) () at /usr/lib/libKF5ThreadWeaver.so.5
#53 0x00007ff7ae55c096 in ThreadWeaver::Job::execute(QSharedPointer<ThreadWeaver::JobInterface> const&, ThreadWeaver::Thread*) () at /usr/lib/libKF5ThreadWeaver.so.5
#54 0x00007ff7ae55fde2 in ThreadWeaver::Thread::run() () at /usr/lib/libKF5ThreadWeaver.so.5
#55 0x00007ff7a96e42ca in () at /usr/lib/libQt5Core.so.5
#56 0x00007ff7a909f78d in () at /usr/lib/libc.so.6
#57 0x00007ff7a91208e4 in clone () at /usr/lib/libc.so.6

Variable values for the four warnings at the time the breakpoint is hit in KDevelop::ParamIterator::operator++() (#6):

m_cur = 27
m_curEnd = 99
m_end = 99
m_parens = "<>:"
m_prefix = "__not_overloaded2"
m_source="__not_overloaded2<_Tp, _Up, __void_t<decltype(std::declval<_Tp>().operator<(std::declval<_Up>()))>>"
m_source.size() == 99
m_cur = 26
m_curEnd = 99
m_end = 99
m_parens = "<>:"
m_prefix = "__not_overloaded"
m_source="__not_overloaded<_Tp, _Up, __void_t<decltype(operator<(std::declval<_Tp>(), std::declval<_Up>()))>>"
m_source.size() == 99
m_cur = 27
m_curEnd = 100
m_end = 100
m_parens = "<>:"
m_prefix = "__not_overloaded2"
m_source ="__not_overloaded2<_Tp, _Up, __void_t<decltype(std::declval<_Tp>().operator<=(std::declval<_Up>()))>>"
m_source.size() = 100
m_cur = 26
m_curEnd = 100
m_end = 100
m_parens = "<>:"
m_prefix = "__not_overloaded"
m_source="__not_overloaded<_Tp, _Up, __void_t<decltype(operator<=(std::declval<_Tp>(), std::declval<_Up>()))>>"
m_source.size() = 100

There is a possibly relevant comment in ParamIterator::ParamIterator():

//The paren was not closed. It might be an identifier like "operator<", so count everything as prefix.

But apparently ParamIterator cannot parse operator(<[<]|>[>]) correctly. Ideally libclang API should provide the necessary info. Otherwise, we'd need a regex to detect such operators and exclude them somehow. Or we could just work the warning around and keep parsing such operators incorrectly.

Edited by Milian Wolff

Merge request reports