From 62d870df1b9614b28b9bd656a28104259a59ac21 Mon Sep 17 00:00:00 2001 From: Michael Weghorn Date: Thu, 7 Dec 2023 17:52:53 +0100 Subject: [PATCH] QmltcVisitor: Fix sort order of array used with std::binary_search Using std::binary_search has the requirement that the passed range fulfils ordering requirements, which was not the case for the cppKeywords array here. As the QString doc says [1]: > QStrings can be compared using overloaded operators such as operator<(), > operator<=(), operator==(), operator>=(), and so on. Note that > the comparison is based exclusively on the numeric Unicode > values of the characters. It is very fast, but is not what a > human would expect; (...) Therefore, sort the array accordingly and add an assert to ensure it will remain sorted. Fixes an crash/assert when building qtdeclarative with CXXFLAGS='-D_GLIBCXX_DEBUG': /usr/include/c++/13/bits/stl_algo.h:2243: In function: bool std::binary_search(_FIter, _FIter, const _Tp&) [with _FIter = const QString*; _Tp = QStringView] Error: elements in iterator range [first, last) are not partitioned by the value __val. Objects involved in the operation: iterator "first" @ 0x7ffc4a2c4f18 { type = QString const* (constant iterator); } iterator "last" @ 0x7ffc4a2c4f10 { type = QString const* (constant iterator); } Aborted (core dumped) ninja: build stopped: subcommand failed. GDB backtrace: Program terminated with signal SIGABRT, Aborted. #0 __pthread_kill_implementation (threadid=, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 44 ./nptl/pthread_kill.c: No such file or directory. (gdb) bt #0 __pthread_kill_implementation (threadid=, signo=signo@entry=6, no_tid=no_tid@entry=0) at ./nptl/pthread_kill.c:44 #1 0x00007f307e0a815f in __pthread_kill_internal (signo=6, threadid=) at ./nptl/pthread_kill.c:78 #2 0x00007f307e05a472 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26 #3 0x00007f307e0444b2 in __GI_abort () at ./stdlib/abort.c:79 #4 0x00007f307e2a300d in ?? () from /lib/x86_64-linux-gnu/libstdc++.so.6 #5 0x00005639ff90471d in std::binary_search (__first=0x5639ffa1a9c0 const&)::cppKeywords>, __last=0x5639ffa1b2c0 const&)::cppKeywords>, __val=...) at /usr/include/c++/13/bits/stl_algo.h:2243 #6 0x00005639ff8fb837 in operator() (__closure=0x7ffc4a2c52bf, word=...) at /home/michi/development/git/qt5/qtdeclarative/tools/qmltc/qmltcvisitor.cpp:764 #7 0x00005639ff8fb89e in operator() (__closure=0x7ffc4a2c52a0, name=..., errorPrefix=...) at /home/michi/development/git/qt5/qtdeclarative/tools/qmltc/qmltcvisitor.cpp:768 #8 0x00005639ff8fc99b in QmltcVisitor::checkForNamingCollisionsWithCpp (this=0x7ffc4a2c6070, type=...) at /home/michi/development/git/qt5/qtdeclarative/tools/qmltc/qmltcvisitor.cpp:787 #9 0x00005639ff8f9dea in QmltcVisitor::endVisit (this=0x7ffc4a2c6070, program=0x563a002e0628) at /home/michi/development/git/qt5/qtdeclarative/tools/qmltc/qmltcvisitor.cpp:341 #10 0x00007f307f6636fa in QQmlJS::AST::UiProgram::accept0 (this=0x563a002e0628, visitor=0x7ffc4a2c6070) at /home/michi/development/git/qt5/qtdeclarative/src/qml/parser/qqmljsast.cpp:1193 #11 0x00007f3080159b8f in QQmlJS::AST::Node::accept (this=0x563a002e0628, visitor=0x7ffc4a2c6070) at /home/michi/development/git/qt5/qtbase/include/QtQml/6.7.0/QtQml/private/../../../../../../qtdeclarative/src/qml/parser/qqmljsast_p.h:272 #12 0x00007f3080212f4b in QQmlJSTypeResolver::init (this=0x7ffc4a2c5b50, visitor=0x7ffc4a2c6070, program=0x563a002e0628) at /home/michi/development/git/qt5/qtdeclarative/src/qmlcompiler/qqmljstyperesolver.cpp:173 #13 0x00005639ff8f0bd3 in QmltcTypeResolver::init (this=0x7ffc4a2c5b50, visitor=0x7ffc4a2c6070, program=0x563a002e0628) at /home/michi/development/git/qt5/qtdeclarative/tools/qmltc/qmltctyperesolver.cpp:19 #14 0x00005639ff8c02d4 in main (argc=23, argv=0x7ffc4a2c7a68) at /home/michi/development/git/qt5/qtdeclarative/tools/qmltc/main.cpp:269 [1] https://doc.qt.io/qt-6/qstring.html#comparing-strings Change-Id: I82ebbcdca4ab90155b935f9af24b3a3821134563 Reviewed-by: Sami Shalayel Reviewed-by: Ulf Hermann --- tools/qmltc/qmltcvisitor.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/qmltc/qmltcvisitor.cpp b/tools/qmltc/qmltcvisitor.cpp index b15c9cdae85..88ec4518913 100644 --- a/tools/qmltc/qmltcvisitor.cpp +++ b/tools/qmltc/qmltcvisitor.cpp @@ -674,20 +674,20 @@ void QmltcVisitor::checkForNamingCollisionsWithCpp(const QQmlJSScope::ConstPtr & u"case"_s, u"catch"_s, u"char"_s, - u"char8_t"_s, u"char16_t"_s, u"char32_t"_s, + u"char8_t"_s, u"class"_s, + u"co_await"_s, + u"co_return"_s, + u"co_yield"_s, u"compl"_s, u"concept"_s, u"const"_s, + u"const_cast"_s, u"consteval"_s, u"constexpr"_s, - u"const_cast"_s, u"continue"_s, - u"co_await"_s, - u"co_return"_s, - u"co_yield"_s, u"decltype"_s, u"default"_s, u"delete"_s, @@ -755,6 +755,7 @@ void QmltcVisitor::checkForNamingCollisionsWithCpp(const QQmlJSScope::ConstPtr & u"xor"_s, u"xor_eq"_s, }; + Q_ASSERT(std::is_sorted(std::begin(cppKeywords), std::end(cppKeywords))); const auto isReserved = [&](QStringView word) { if (word.startsWith(QChar(u'_')) && word.size() >= 2