From c3226bd5cc6bf009d2fb3c233a09f3ef5cf618e9 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 25 Mar 2019 12:40:36 +0100 Subject: configure: add linker flags for xkbcommon* when pkg-config not present Without this, xkbcommon feature would not be detected even if all xkbcommon dev libs are present. Change-Id: Ic247461dda9e7ddfed547708cccaad88f123903b Reviewed-by: Joerg Bornemann --- src/gui/configure.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gui/configure.json b/src/gui/configure.json index e4f25ab313..6fdcd562a7 100644 --- a/src/gui/configure.json +++ b/src/gui/configure.json @@ -764,7 +764,8 @@ }, "headers": [ "xkbcommon/xkbcommon.h" ], "sources": [ - { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" } + { "type": "pkgConfig", "args": "xkbcommon >= 0.5.0" }, + "-lxkbcommon" ] }, "xkbcommon_x11": { @@ -774,7 +775,8 @@ }, "headers": [ "xkbcommon/xkbcommon-x11.h" ], "sources": [ - { "type": "pkgConfig", "args": "xkbcommon-x11" } + { "type": "pkgConfig", "args": "xkbcommon-x11" }, + "-lxkbcommon -lxkbcommon-x11" ] }, "xrender": { -- cgit v1.2.3 From 243c8403903781a28832e0bf34ce962058300e99 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Tue, 26 Mar 2019 00:02:22 +0100 Subject: Drag'n'Drop: fix dnd regression DragEnter events always should start with the default state, which is accepted = false. This was a copy-and-paste error introduced by f8944a7f07112c85dc4f66848cabb490514cd28e. Fixes: QTBUG-73977 Change-Id: I34b3ea97c9b4f4fc040a9e6f1befd6124533361d Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidgetwindow.cpp | 2 - .../kernel/qwidget_window/tst_qwidget_window.cpp | 75 ++++++++++++++++++++++ 2 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index e9b749d7c2..fbc71cd0ea 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -878,8 +878,6 @@ void QWidgetWindow::handleDragEnterEvent(QDragEnterEvent *event, QWidget *widget const QPoint mapped = widget->mapFromGlobal(m_widget->mapToGlobal(event->pos())); QDragEnterEvent translated(mapped, event->possibleActions(), event->mimeData(), event->mouseButtons(), event->keyboardModifiers()); - translated.setDropAction(event->dropAction()); - translated.setAccepted(event->isAccepted()); QGuiApplication::forwardEvent(m_dragTarget, &translated, event); event->setAccepted(translated.isAccepted()); event->setDropAction(translated.dropAction()); diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 431d6ba960..8b558aa56f 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -46,6 +46,9 @@ #include #include #include +#include +#include +#include #include @@ -87,6 +90,7 @@ private slots: #if QT_CONFIG(draganddrop) void tst_dnd(); void tst_dnd_events(); + void tst_dnd_propagation(); #endif void tst_qtbug35600(); @@ -744,6 +748,77 @@ void tst_QWidget_window::tst_dnd_events() QCOMPARE(dndWidget._dndEvents, expectedDndEvents); } + +class DropTarget : public QWidget +{ +public: + explicit DropTarget() + { + setAcceptDrops(true); + + const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry(); + auto width = availableGeometry.width() / 6; + auto height = availableGeometry.height() / 4; + + setGeometry(availableGeometry.x() + 200, availableGeometry.y() + 200, width, height); + + QLabel *label = new QLabel(QStringLiteral("Test"), this); + label->setGeometry(40, 40, 60, 60); + label->setAcceptDrops(true); + } + + void dragEnterEvent(QDragEnterEvent *event) override + { + event->accept(); + mDndEvents.append("enter "); + } + + void dragMoveEvent(QDragMoveEvent *event) override + { + event->acceptProposedAction(); + } + + void dragLeaveEvent(QDragLeaveEvent *) override + { + mDndEvents.append("leave "); + } + + void dropEvent(QDropEvent *event) override + { + event->accept(); + mDndEvents.append("drop "); + } + + QString mDndEvents; +}; + +void tst_QWidget_window::tst_dnd_propagation() +{ + QMimeData mimeData; + mimeData.setText(QLatin1String("testmimetext")); + + DropTarget target; + target.show(); + QVERIFY(QTest::qWaitForWindowActive(&target)); + + Qt::DropActions supportedActions = Qt::DropAction::CopyAction; + QWindow *window = target.windowHandle(); + + auto posInsideDropTarget = QHighDpi::toNativePixels(QPoint(20, 20), window->screen()); + auto posInsideLabel = QHighDpi::toNativePixels(QPoint(60, 60), window->screen()); + + // Enter DropTarget. + QWindowSystemInterface::handleDrag(window, &mimeData, posInsideDropTarget, supportedActions, 0, 0); + // Enter QLabel. This will propagate because default QLabel does + // not accept the drop event in dragEnterEvent(). + QWindowSystemInterface::handleDrag(window, &mimeData, posInsideLabel, supportedActions, 0, 0); + // Drop on QLabel. DropTarget will get dropEvent(), because it accepted the event. + QWindowSystemInterface::handleDrop(window, &mimeData, posInsideLabel, supportedActions, 0, 0); + + QGuiApplication::processEvents(); + + QCOMPARE(target.mDndEvents, "enter leave enter drop "); +} #endif void tst_QWidget_window::tst_qtbug35600() -- cgit v1.2.3 From ae5db669e8989fe793949346d8061c67e5ec31cd Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 28 Mar 2019 10:12:12 +0100 Subject: Doc: Improve WinTab license information Do not categorize the license anymore as 'Public Domain', because the actual text is not explicit on whether it allows modifications. Instead show the original license text. Also remove the Homepage link, which now just displays (arguably outdated) information about patents. Finally, do not misuse the "Version" field for metadata information, use the newly introduced "PackageComment" field instead. [ChangeLog][Third-Party Code] Changed classification of the wintab license from Public Domain to Custom. Fixes: QTBUG-74453 Change-Id: Ibae36be1deee3b9c498c45d03ed741c3d5ff630c Reviewed-by: Alex Blasche Reviewed-by: Lars Knoll --- src/3rdparty/wintab/LICENSE.txt | 2 ++ src/3rdparty/wintab/qt_attribution.json | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 src/3rdparty/wintab/LICENSE.txt diff --git a/src/3rdparty/wintab/LICENSE.txt b/src/3rdparty/wintab/LICENSE.txt new file mode 100644 index 0000000000..6c03ad2aff --- /dev/null +++ b/src/3rdparty/wintab/LICENSE.txt @@ -0,0 +1,2 @@ +The text and information contained in this file may be freely used, +copied, or distributed without compensation or licensing restrictions. diff --git a/src/3rdparty/wintab/qt_attribution.json b/src/3rdparty/wintab/qt_attribution.json index f0c9b49841..1b9c55552e 100644 --- a/src/3rdparty/wintab/qt_attribution.json +++ b/src/3rdparty/wintab/qt_attribution.json @@ -5,9 +5,9 @@ "QtUsage": "Used in the Qt platform plugin for Windows. Configure with -no-feature-tabletevent to avoid.", "Description": "Wintab is a de facto API for pointing devices on Windows.", - "Version": "Upstream no longer offers updates; treat as final", - "Homepage": "http://www.pointing.com/Wintab.html", - "License": "Public Domain", + "PackageComment": "Upstream http://www.pointing.com/Wintab.html no longer offers updates; treat as final", + "License": "Custom License", + "LicenseFile": "LICENSE.txt", "LicenseId": "NONE", "Copyright": "Copyright 1991-1998 by LCS/Telegraphics." } -- cgit v1.2.3 From a0b5d6e60f96359d88352e0b1c000678cdc80988 Mon Sep 17 00:00:00 2001 From: Jani Heikkinen Date: Thu, 4 Apr 2019 15:05:16 +0300 Subject: Revert "Let "qmake -install qinstall" set default permissions 0644 and 0755" This reverts commit 3cdf46059a668f588fe237aa881c300dd76cbf9e. It seems change is causing regression & is reverted now to be able to proceed with releases Task-number: QTBUG-74912 Change-Id: Ib2365b96ee98fbbcc8853cc7f8726c157c1913a7 Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Joerg Bornemann --- qmake/main.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/qmake/main.cpp b/qmake/main.cpp index e5f7032554..a4ef79227b 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -260,25 +260,31 @@ static int installFile(const QString &source, const QString &target, bool exe = return 3; } - QFileDevice::Permissions targetPermissions = QFileDevice::ReadOwner | QFileDevice::WriteOwner - | QFileDevice::ReadUser | QFileDevice::WriteUser - | QFileDevice::ReadGroup | QFileDevice::ReadOther; if (exe) { - targetPermissions |= QFileDevice::ExeOwner | QFileDevice::ExeUser | - QFileDevice::ExeGroup | QFileDevice::ExeOther; - } - if (!targetFile.setPermissions(targetPermissions)) { - fprintf(stderr, "Error setting permissions on %s: %s\n", - qPrintable(target), qPrintable(targetFile.errorString())); - return 3; + if (!targetFile.setPermissions(sourceFile.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeUser | + QFileDevice::ExeGroup | QFileDevice::ExeOther)) { + fprintf(stderr, "Error setting execute permissions on %s: %s\n", + qPrintable(target), qPrintable(targetFile.errorString())); + return 3; + } } // Copy file times QString error; +#ifdef Q_OS_WIN + const QFile::Permissions permissions = targetFile.permissions(); + const bool readOnly = !(permissions & QFile::WriteUser); + if (readOnly) + targetFile.setPermissions(permissions | QFile::WriteUser); +#endif if (!IoUtils::touchFile(target, sourceFile.fileName(), &error)) { fprintf(stderr, "%s", qPrintable(error)); return 3; } +#ifdef Q_OS_WIN + if (readOnly) + targetFile.setPermissions(permissions); +#endif return 0; } -- cgit v1.2.3 From 7935d86e7dc4ad994455aba604c8a51b01470cd5 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Thu, 28 Mar 2019 13:43:50 +0100 Subject: Populate test data for reverse lookups using system tools Hardcoding IP addresses and their respective DNS records is fragile. We care about Qt producing the same result as other DNS querying tools, so testing that instead. Running a python script for this is easiest, and assumed to be quite reliable. In case where python fails/is not present, fall back to nslookup. That tool is available on Linux, macOS, and Windows, although the output it produces varies. This change implements very basic line-parsing that can interpret the various results encountered during testing on those platforms. This also reverts commit bbaceff253fae13d8e56691bc9de7e1981db5118, which blacklisted the tests that failed due to changes in DNS records. Use the opportunity to replace usage of gitorious.org. Change-Id: I967de226bd603c805df7fe3ed4e871d92d2d0750 Reviewed-by: Timur Pocheptsov --- tests/auto/network/kernel/qhostinfo/BLACKLIST | 2 - .../network/kernel/qhostinfo/tst_qhostinfo.cpp | 68 +++++++++++++++++++++- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/tests/auto/network/kernel/qhostinfo/BLACKLIST b/tests/auto/network/kernel/qhostinfo/BLACKLIST index cd4d4eb03c..87c5fe991f 100644 --- a/tests/auto/network/kernel/qhostinfo/BLACKLIST +++ b/tests/auto/network/kernel/qhostinfo/BLACKLIST @@ -4,5 +4,3 @@ windows ci [blockingLookup:a-plus-aaaa] windows ci -[reverseLookup:google-public-dns-a.google.com] -ci diff --git a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp index 82825f608c..0a130d363e 100644 --- a/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp +++ b/tests/auto/network/kernel/qhostinfo/tst_qhostinfo.cpp @@ -396,6 +396,68 @@ void tst_QHostInfo::lookupConnectToLambda() QCOMPARE(tmp.join(' '), expected.join(' ')); } +static QStringList reverseLookupHelper(const QString &ip) +{ + QStringList results; + + const QString pythonCode = + "import socket;" + "import sys;" + "print (socket.getnameinfo((sys.argv[1], 0), 0)[0]);"; + + QList lines; + QProcess python; + python.setProcessChannelMode(QProcess::ForwardedErrorChannel); + python.start("python", QStringList() << QString("-c") << pythonCode << ip); + if (python.waitForFinished()) { + if (python.exitStatus() == QProcess::NormalExit && python.exitCode() == 0) + lines = python.readAllStandardOutput().split('\n'); + for (QByteArray line : lines) { + if (!line.isEmpty()) + results << line.trimmed(); + } + if (!results.isEmpty()) + return results; + } + + qDebug() << "Python failed, falling back to nslookup"; + QProcess lookup; + lookup.setProcessChannelMode(QProcess::ForwardedErrorChannel); + lookup.start("nslookup", QStringList(ip)); + if (!lookup.waitForFinished()) { + results << "nslookup failure"; + qDebug() << "nslookup failure"; + return results; + } + lines = lookup.readAllStandardOutput().split('\n'); + + QByteArray name; + + const QByteArray nameMarkerNix("name ="); + const QByteArray nameMarkerWin("Name:"); + const QByteArray addressMarkerWin("Address:"); + + for (QByteArray line : lines) { + int index = -1; + if ((index = line.indexOf(nameMarkerNix)) != -1) { // Linux and macOS + name = line.mid(index + nameMarkerNix.length()).chopped(1).trimmed(); + results << name; + } else if (line.startsWith(nameMarkerWin)) { // Windows formatting + name = line.mid(line.lastIndexOf(" ")).trimmed(); + } else if (line.startsWith(addressMarkerWin)) { + QByteArray address = line.mid(addressMarkerWin.length()).trimmed(); + if (address == ip) { + results << name; + } + } + } + + if (results.isEmpty()) { + qDebug() << "Failure to parse nslookup output: " << lines; + } + return results; +} + void tst_QHostInfo::reverseLookup_data() { QTest::addColumn("address"); @@ -403,8 +465,8 @@ void tst_QHostInfo::reverseLookup_data() QTest::addColumn("err"); QTest::addColumn("ipv6"); - QTest::newRow("google-public-dns-a.google.com") << QString("8.8.8.8") << QStringList(QString("google-public-dns-a.google.com")) << 0 << false; - QTest::newRow("gitorious.org") << QString("87.238.52.168") << QStringList(QString("gitorious.org")) << 0 << false; + QTest::newRow("dns.google") << QString("8.8.8.8") << reverseLookupHelper("8.8.8.8") << 0 << false; + QTest::newRow("one.one.one.one") << QString("1.1.1.1") << reverseLookupHelper("1.1.1.1") << 0 << false; QTest::newRow("bogus-name") << QString("1::2::3::4") << QStringList() << 1 << true; } @@ -422,6 +484,8 @@ void tst_QHostInfo::reverseLookup() QHostInfo info = QHostInfo::fromName(address); if (err == 0) { + if (!hostNames.contains(info.hostName())) + qDebug() << "Failure: expecting" << hostNames << ",got " << info.hostName(); QVERIFY(hostNames.contains(info.hostName())); QCOMPARE(info.addresses().first(), QHostAddress(address)); } else { -- cgit v1.2.3 From 5a168507b1a3413d71cddfc5245adedcfe46b55d Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 4 Apr 2019 09:07:22 +0200 Subject: Manual dialog test: Output URLs when testing QFileDialog Change-Id: Icfaedcd68ff387cc888e41ec0b1db1810122b229 Reviewed-by: Joerg Bornemann --- tests/manual/dialogs/filedialogpanel.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/manual/dialogs/filedialogpanel.cpp b/tests/manual/dialogs/filedialogpanel.cpp index 9e3c761cff..62d03e735d 100644 --- a/tests/manual/dialogs/filedialogpanel.cpp +++ b/tests/manual/dialogs/filedialogpanel.cpp @@ -505,8 +505,15 @@ void FileDialogPanel::accepted() Q_ASSERT(d); m_result.clear(); QDebug(&m_result).nospace() +#if QT_VERSION >= 0x050000 + << "URLs: " << d->selectedUrls() << '\n' +#endif << "Files: " << d->selectedFiles() - << "\nDirectory: " << d->directory().absolutePath() + << "\nDirectory: " +#if QT_VERSION >= 0x050000 + << d->directoryUrl() << ", " +#endif + << d->directory().absolutePath() << "\nName filter: " << d->selectedNameFilter(); QTimer::singleShot(0, this, SLOT(showAcceptedResult())); // Avoid problems with the closing (modal) dialog as parent. } -- cgit v1.2.3 From b404cd930e32520f8ad62088c9ed31f33ce95933 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Thu, 4 Apr 2019 17:17:59 +0300 Subject: Make qt_is_ascii work properly on big endian systems Change-Id: Ia053fbc854a77e333edadb0be6c2e04826b8fbdb Reviewed-by: Thiago Macieira --- src/corelib/tools/qstring.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index d8bfb69a8b..4852d20082 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -501,7 +501,11 @@ bool qt_is_ascii(const char *&ptr, const char *end) Q_DECL_NOTHROW while (ptr + 4 <= end) { quint32 data = qFromUnaligned(ptr); if (data &= 0x80808080U) { +#if Q_BYTE_ORDER == Q_BIG_ENDIAN + uint idx = qCountLeadingZeroBits(data); +#else uint idx = qCountTrailingZeroBits(data); +#endif ptr += idx / 8; return false; } -- cgit v1.2.3 From 4e24bb24a234ee85fca25f9a117de7380083f593 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Fri, 5 Apr 2019 09:02:28 +0200 Subject: Remove noisy warning for undefined QGradient preset This runtime warning was recently introduced in the fix for an assert/crash when creating a brush with an invalid Preset value. However, that overlooked the usage where an unknown value is passed to QGradient constructor, and the code afterwards checks if the result is a NoGradient or not. It turns out that such usage is already established as legitimate, including in the Qt Quick Rectangle code, so this warning would be spit out continuously for perfectly legal qml code. Change-Id: Id60aed0817da0214b6cf17edd245f67e26470413 Reviewed-by: Allan Sandfeld Jensen --- src/gui/painting/qbrush.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index bcc23fa683..d071f665bb 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -1378,10 +1378,8 @@ QGradient::QGradient(Preset preset) }(); const QJsonValue presetData = jsonPresets[preset - 1]; - if (!presetData.isObject()) { - qWarning("QGradient: Undefined preset %i", preset); + if (!presetData.isObject()) return; - } m_type = LinearGradient; setCoordinateMode(ObjectMode); -- cgit v1.2.3 From 5f7b0e5ff4410a596168ee667b71afaa7b18eee8 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 4 Apr 2019 16:47:29 +0200 Subject: qmake: Remove dead code Silences a clang warning Change-Id: I5ade49326afcce964ffb5c24b5708977950d123e Reviewed-by: Joerg Bornemann --- qmake/generators/mac/pbuilder_pbx.cpp | 2 +- qmake/generators/makefile.cpp | 2 +- qmake/generators/unix/unixmake2.cpp | 2 +- qmake/meta.cpp | 7 ------- qmake/meta.h | 2 -- 5 files changed, 3 insertions(+), 12 deletions(-) diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 5407ed6c69..07832041a7 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -856,7 +856,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString lib_file = QMakeMetaInfo::checkLib(Option::normalizePath( (*lit) + Option::dir_sep + lib + Option::prl_ext)); if (!lib_file.isEmpty()) { - QMakeMetaInfo libinfo(project); + QMakeMetaInfo libinfo; if(libinfo.readLib(lib_file)) { if(!libinfo.isEmpty("QMAKE_PRL_TARGET")) { library = (*lit) + Option::dir_sep + libinfo.first("QMAKE_PRL_TARGET"); diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index ab261d02f1..e9dccf0c46 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -912,7 +912,7 @@ MakefileGenerator::processPrlFileCore(QString &origFile, const QStringRef &origN const QString meta_file = QMakeMetaInfo::checkLib(fixedFile); if (meta_file.isEmpty()) return false; - QMakeMetaInfo libinfo(project); + QMakeMetaInfo libinfo; debug_msg(1, "Processing PRL file: %s", meta_file.toLatin1().constData()); if (!libinfo.readLib(meta_file)) { fprintf(stderr, "Error processing meta file %s\n", meta_file.toLatin1().constData()); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 4b33713a75..24215ae7b0 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -407,7 +407,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) const ProStringList &l = project->values("QMAKE_PRL_INTERNAL_FILES"); ProStringList::ConstIterator it; for(it = l.begin(); it != l.end(); ++it) { - QMakeMetaInfo libinfo(project); + QMakeMetaInfo libinfo; if (libinfo.readLib((*it).toQString()) && !libinfo.isEmpty("QMAKE_PRL_BUILD_DIR")) { ProString dir; int slsh = (*it).lastIndexOf(Option::dir_sep); diff --git a/qmake/meta.cpp b/qmake/meta.cpp index 2e8759b8ba..c5c14d9b56 100644 --- a/qmake/meta.cpp +++ b/qmake/meta.cpp @@ -35,13 +35,6 @@ QT_BEGIN_NAMESPACE QHash QMakeMetaInfo::cache_vars; -QMakeMetaInfo::QMakeMetaInfo(QMakeProject *_conf) - : conf(_conf) -{ - -} - - bool QMakeMetaInfo::readLib(const QString &meta_file) { diff --git a/qmake/meta.h b/qmake/meta.h index 4721085fd2..5f41a37df0 100644 --- a/qmake/meta.h +++ b/qmake/meta.h @@ -41,11 +41,9 @@ class QMakeProject; class QMakeMetaInfo { - QMakeProject *conf; ProValueMap vars; static QHash cache_vars; public: - QMakeMetaInfo(QMakeProject *_conf); // These functions expect the path to be normalized static QString checkLib(const QString &lib); -- cgit v1.2.3 From 6d049ad63d1044da2287f5736b9863323be2be0c Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 4 Apr 2019 16:33:59 +0200 Subject: Remove unused static method The only use of this method got removed already in commit bebae3737624. Change-Id: I9757cbe34710efd9a9d31c74f81e01da40453ff9 Reviewed-by: Thiago Macieira Reviewed-by: Joerg Bornemann --- src/corelib/io/qstandardpaths_win.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp index 1809861fc6..c2c3b2702b 100644 --- a/src/corelib/io/qstandardpaths_win.cpp +++ b/src/corelib/io/qstandardpaths_win.cpp @@ -86,15 +86,6 @@ static void appendOrganizationAndApp(QString &path) // Courtesy qstandardpaths_u #endif } -static inline QString displayName(QStandardPaths::StandardLocation type) -{ -#ifndef QT_BOOTSTRAPPED - return QStandardPaths::displayName(type); -#else - return QString::number(type); -#endif -} - static inline void appendTestMode(QString &path) { if (QStandardPaths::isTestModeEnabled()) -- cgit v1.2.3 From bdee1189bf52a00fa89a8898e92bf75c36930666 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Wed, 3 Apr 2019 19:41:36 +0200 Subject: png handler: initialize all the variables passed to png_get_IHDR oss-fuzz found at least width is sometimes not initialized, and we're initializing almost all of them in most cases so be complete. the oss-fuzz instance was ==1==WARNING: MemorySanitizer: use-of-uninitialized-value #0 0x667c43 in operator!= /src/qtbase/src/corelib/tools/qsize.h:173:25 #1 0x667c43 in setup_qt /src/qtbase/src/gui/image/qpnghandler.cpp:403 Change-Id: Idb9aaf5ab85509d9c893beaf8d9118339ba46be7 Reviewed-by: Allan Sandfeld Jensen --- src/gui/image/qpnghandler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/image/qpnghandler.cpp b/src/gui/image/qpnghandler.cpp index 808037f434..801b30881d 100644 --- a/src/gui/image/qpnghandler.cpp +++ b/src/gui/image/qpnghandler.cpp @@ -231,8 +231,8 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal if (screen_gamma != 0.0 && file_gamma != 0.0) png_set_gamma(png_ptr, 1.0f / screen_gamma, file_gamma); - png_uint_32 width; - png_uint_32 height; + png_uint_32 width = 0; + png_uint_32 height = 0; int bit_depth = 0; int color_type = 0; png_bytep trans_alpha = 0; @@ -240,7 +240,7 @@ void setup_qt(QImage& image, png_structp png_ptr, png_infop info_ptr, QSize scal int num_trans; png_colorp palette = 0; int num_palette; - int interlace_method; + int interlace_method = PNG_INTERLACE_LAST; png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_method, 0, 0); png_set_interlace_handling(png_ptr); @@ -677,7 +677,7 @@ bool QPngHandlerPrivate::readPngImage(QImage *outImage) QImage::Format QPngHandlerPrivate::readImageFormat() { QImage::Format format = QImage::Format_Invalid; - png_uint_32 width, height; + png_uint_32 width = 0, height = 0; int bit_depth = 0, color_type = 0; png_colorp palette; int num_palette; -- cgit v1.2.3 From df7eec6bcb0b9fdee3888c9b4683dbb533eba300 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 3 Apr 2019 13:34:35 +0200 Subject: Windows QPA/File dialog: Refactor code copying non-file shell items Remove the canCopy() check which is not required and pass up the error message. Remove special characters and use the base name of the display name which can be an URL. Task-number: QTBUG-71785 Change-Id: I22966cb8d1f5bca0bbca71cf3ebe66e4ede1a747 Reviewed-by: Oliver Wolff Reviewed-by: Andre de la Rocha --- .../platforms/windows/qwindowsdialoghelpers.cpp | 88 ++++++++++++++++------ 1 file changed, 63 insertions(+), 25 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp index 1b17759b5f..ba441a1921 100644 --- a/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp +++ b/src/plugins/platforms/windows/qwindowsdialoghelpers.cpp @@ -569,12 +569,10 @@ public: bool isFileSystem() const { return (m_attributes & SFGAO_FILESYSTEM) != 0; } bool isDir() const { return (m_attributes & SFGAO_FOLDER) != 0; } - // Copy using IFileOperation - bool canCopy() const { return (m_attributes & SFGAO_CANCOPY) != 0; } // Supports IStream bool canStream() const { return (m_attributes & SFGAO_STREAM) != 0; } - bool copyData(QIODevice *out); + bool copyData(QIODevice *out, QString *errorMessage); static IShellItems itemsFromItemArray(IShellItemArray *items); @@ -666,14 +664,19 @@ QWindowsShellItem::IShellItems QWindowsShellItem::itemsFromItemArray(IShellItemA return result; } -bool QWindowsShellItem::copyData(QIODevice *out) +bool QWindowsShellItem::copyData(QIODevice *out, QString *errorMessage) { - if (!canCopy() || !canStream()) + if (!canStream()) { + *errorMessage = QLatin1String("Item not streamable"); return false; + } IStream *istream = nullptr; HRESULT hr = m_item->BindToHandler(nullptr, BHID_Stream, IID_PPV_ARGS(&istream)); - if (FAILED(hr)) + if (FAILED(hr)) { + *errorMessage = QLatin1String("BindToHandler() failed: ") + + QLatin1String(QWindowsContext::comErrorString(hr)); return false; + } enum : ULONG { bufSize = 102400 }; char buffer[bufSize]; ULONG bytesRead; @@ -686,7 +689,12 @@ bool QWindowsShellItem::copyData(QIODevice *out) break; } istream->Release(); - return hr == S_OK || hr == S_FALSE; + if (hr != S_OK && hr != S_FALSE) { + *errorMessage = QLatin1String("Read() failed: ") + + QLatin1String(QWindowsContext::comErrorString(hr)); + return false; + } + return true; } // Helper for "Libraries": collections of folders appearing from Windows 7 @@ -735,8 +743,6 @@ void QWindowsShellItem::format(QDebug &d) const d << " [dir]"; if (canStream()) d << " [stream]"; - if (canCopy()) - d << " [copyable]"; d << ", normalDisplay=\"" << normalDisplay() << "\", desktopAbsoluteParsing=\"" << desktopAbsoluteParsing() << "\", urlString=\"" << urlString() << "\", fileSysPath=\"" << fileSysPath() << '"'; @@ -1395,21 +1401,50 @@ static void cleanupTemporaryItemCopies() QFile::remove(file); } -static QString createTemporaryItemCopy(QWindowsShellItem &qItem) +// Determine temporary file pattern from a shell item's display +// name. This can be a URL. + +static bool validFileNameCharacter(QChar c) { - if (!qItem.canCopy() || !qItem.canStream()) + return c.isLetterOrNumber() || c == QLatin1Char('_') || c == QLatin1Char('-'); +} + +QString tempFilePattern(QString name) +{ + const int lastSlash = qMax(name.lastIndexOf(QLatin1Char('/')), + name.lastIndexOf(QLatin1Char('\\'))); + if (lastSlash != -1) + name.remove(0, lastSlash + 1); + + int lastDot = name.lastIndexOf(QLatin1Char('.')); + if (lastDot < 0) + lastDot = name.size(); + name.insert(lastDot, QStringLiteral("_XXXXXX")); + + for (int i = lastDot - 1; i >= 0; --i) { + if (!validFileNameCharacter(name.at(i))) + name[i] = QLatin1Char('_'); + } + + name.prepend(QDir::tempPath() + QLatin1Char('/')); + return name; +} + +static QString createTemporaryItemCopy(QWindowsShellItem &qItem, QString *errorMessage) +{ + if (!qItem.canStream()) { + *errorMessage = QLatin1String("Item not streamable"); return QString(); - QString pattern = qItem.normalDisplay(); - const int lastDot = pattern.lastIndexOf(QLatin1Char('.')); - const QString placeHolder = QStringLiteral("_XXXXXX"); - if (lastDot >= 0) - pattern.insert(lastDot, placeHolder); - else - pattern.append(placeHolder); - - QTemporaryFile targetFile(QDir::tempPath() + QLatin1Char('/') + pattern); + } + + QTemporaryFile targetFile(tempFilePattern(qItem.normalDisplay())); targetFile.setAutoRemove(false); - if (!targetFile.open() || !qItem.copyData(&targetFile)) + if (!targetFile.open()) { + *errorMessage = QLatin1String("Cannot create temporary file: ") + + targetFile.errorString(); + return QString(); + } + if (!qItem.copyData(&targetFile, errorMessage)) return QString(); const QString result = targetFile.fileName(); if (temporaryItemCopies()->isEmpty()) @@ -1427,11 +1462,14 @@ QList QWindowsNativeOpenFileDialog::dialogResult() const QWindowsShellItem qItem(item); const QString path = qItem.path(); if (path.isEmpty() && !qItem.isDir()) { - const QString temporaryCopy = createTemporaryItemCopy(qItem); - if (temporaryCopy.isEmpty()) - qWarning() << "Unable to create a local copy of" << qItem; - else + QString errorMessage; + const QString temporaryCopy = createTemporaryItemCopy(qItem, &errorMessage); + if (temporaryCopy.isEmpty()) { + qWarning().noquote() << "Unable to create a local copy of" << qItem + << ": " << errorMessage; + } else { result.append(QUrl::fromLocalFile(temporaryCopy)); + } } else { result.append(qItem.url()); } -- cgit v1.2.3 From 6ce2a87c23bbaacece7d32df276f64a0058e447d Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Tue, 26 Mar 2019 14:07:03 +0100 Subject: Forward declare all types required for compilation with `-trace` This patch fixes compilation with `-trace lttng` or `-trace etw`. We need to forward declare QEvent, QImageReader etc., otherwise the types will be unknown while compiling the trace points. In order to handle this generically, the tracegen utility is extended to support a 'prefix text' in the `*.tracepoints` input files. Any text within curly braces will be embedded as-is in the generated file. This can then be used to add forward declarations for the types we need, including potential namespaces and such. Change-Id: I5cb16763ce0fcb48ce3ea4577578d468ff3a4f4b Reviewed-by: Konstantin Tokarev --- src/corelib/qtcore.tracepoints | 6 ++++++ src/gui/qtgui.tracepoints | 6 ++++++ src/tools/tracegen/etw.cpp | 27 ++++++++++++++++----------- src/tools/tracegen/lttng.cpp | 17 +++++++++++------ src/tools/tracegen/provider.cpp | 19 +++++++++++++++++++ src/tools/tracegen/provider.h | 1 + src/widgets/qtwidgets.tracepoints | 6 ++++++ 7 files changed, 65 insertions(+), 17 deletions(-) diff --git a/src/corelib/qtcore.tracepoints b/src/corelib/qtcore.tracepoints index 33734a4274..a9a08071f3 100644 --- a/src/corelib/qtcore.tracepoints +++ b/src/corelib/qtcore.tracepoints @@ -1,3 +1,9 @@ +{ +QT_BEGIN_NAMESPACE +class QEvent; +QT_END_NAMESPACE +} + QCoreApplicationPrivate_init_entry() QCoreApplicationPrivate_init_exit() diff --git a/src/gui/qtgui.tracepoints b/src/gui/qtgui.tracepoints index aed6c35c03..0a96a589b1 100644 --- a/src/gui/qtgui.tracepoints +++ b/src/gui/qtgui.tracepoints @@ -1,3 +1,9 @@ +{ +QT_BEGIN_NAMESPACE +class QImageReader; +QT_END_NAMESPACE +} + QGuiApplicationPrivate_init_entry() QGuiApplicationPrivate_init_exit() diff --git a/src/tools/tracegen/etw.cpp b/src/tools/tracegen/etw.cpp index 8c065f93c9..e839137915 100644 --- a/src/tools/tracegen/etw.cpp +++ b/src/tools/tracegen/etw.cpp @@ -110,19 +110,21 @@ static QString createGuid(const QUuid &uuid) return guid; } -static void writePrologue(QTextStream &stream, const QString &fileName, const QString &providerName) +static void writePrologue(QTextStream &stream, const QString &fileName, const Provider &provider) { - QUuid uuid = QUuid::createUuidV5(QUuid(), providerName.toLocal8Bit()); + QUuid uuid = QUuid::createUuidV5(QUuid(), provider.name.toLocal8Bit()); - const QString provider = providerVar(providerName); + const QString providerV = providerVar(provider.name); const QString guard = includeGuard(fileName); const QString guid = createGuid(uuid); const QString guidString = uuid.toString(); stream << "#ifndef " << guard << "\n" << "#define " << guard << "\n" + << "\n" << "#include \n" - << "#include \n"; + << "#include \n" + << "\n"; /* TraceLogging API macros cannot deal with UTF8 * source files, so we work around it like this @@ -132,30 +134,33 @@ static void writePrologue(QTextStream &stream, const QString &fileName, const QS "#define _TlgPragmaUtf8Begin\n" "#define _TlgPragmaUtf8End\n"; + stream << "\n"; stream << qtHeaders(); - stream << "\n"; + if (!provider.prefixText.isEmpty()) + stream << provider.prefixText.join(QLatin1Char('\n')) << "\n\n"; + stream << "#ifdef TRACEPOINT_DEFINE\n" << "/* " << guidString << " */\n" - << "TRACELOGGING_DEFINE_PROVIDER(" << provider << ", \"" - << providerName <<"\", " << guid << ");\n\n"; + << "TRACELOGGING_DEFINE_PROVIDER(" << providerV << ", \"" + << provider.name <<"\", " << guid << ");\n\n"; stream << "static inline void registerProvider()\n" << "{\n" - << " TraceLoggingRegister(" << provider << ");\n" + << " TraceLoggingRegister(" << providerV << ");\n" << "}\n\n"; stream << "static inline void unregisterProvider()\n" << "{\n" - << " TraceLoggingUnregister(" << provider << ");\n" + << " TraceLoggingUnregister(" << providerV << ");\n" << "}\n"; stream << "Q_CONSTRUCTOR_FUNCTION(registerProvider)\n" << "Q_DESTRUCTOR_FUNCTION(unregisterProvider)\n\n"; stream << "#else\n" - << "TRACELOGGING_DECLARE_PROVIDER(" << provider << ");\n" + << "TRACELOGGING_DECLARE_PROVIDER(" << providerV << ");\n" << "#endif // TRACEPOINT_DEFINE\n\n"; } @@ -224,7 +229,7 @@ void writeEtw(QFile &file, const Provider &provider) const QString fileName = QFileInfo(file.fileName()).fileName(); - writePrologue(stream, fileName, provider.name); + writePrologue(stream, fileName, provider); writeTracepoints(stream, provider); writeEpilogue(stream, fileName); } diff --git a/src/tools/tracegen/lttng.cpp b/src/tools/tracegen/lttng.cpp index 5d41bf5f1f..f0fbca9e16 100644 --- a/src/tools/tracegen/lttng.cpp +++ b/src/tools/tracegen/lttng.cpp @@ -104,16 +104,21 @@ static void writeCtfMacro(QTextStream &stream, const Tracepoint::Field &field) } } -static void writePrologue(QTextStream &stream, const QString &fileName, const QString &providerName) +static void writePrologue(QTextStream &stream, const QString &fileName, const Provider &provider) { + const QString guard = includeGuard(fileName); + stream << "#undef TRACEPOINT_PROVIDER\n"; - stream << "#define TRACEPOINT_PROVIDER " << providerName << "\n\n"; + stream << "#define TRACEPOINT_PROVIDER " << provider.name << "\n"; + stream << "\n"; + // include prefix text or qt headers only once + stream << "#if !defined(" << guard << ")\n"; stream << qtHeaders(); - - const QString guard = includeGuard(fileName); - stream << "\n"; + if (!provider.prefixText.isEmpty()) + stream << provider.prefixText.join(QLatin1Char('\n')) << "\n\n"; + stream << "#endif\n\n"; /* the first guard is the usual one, the second is required * by LTTNG to force the re-evaluation of TRACEPOINT_* macros @@ -213,7 +218,7 @@ void writeLttng(QFile &file, const Provider &provider) const QString fileName = QFileInfo(file.fileName()).fileName(); - writePrologue(stream, fileName, provider.name); + writePrologue(stream, fileName, provider); writeTracepoints(stream, provider); writeEpilogue(stream, fileName); } diff --git a/src/tools/tracegen/provider.cpp b/src/tools/tracegen/provider.cpp index a6523a2e3d..39633efe5d 100644 --- a/src/tools/tracegen/provider.cpp +++ b/src/tools/tracegen/provider.cpp @@ -275,9 +275,21 @@ Provider parseProvider(const QString &filename) Provider provider; provider.name = QFileInfo(filename).baseName(); + bool parsingPrefixText = false; for (int lineNumber = 1; !s.atEnd(); ++lineNumber) { QString line = s.readLine().trimmed(); + if (line == QLatin1String("{")) { + parsingPrefixText = true; + continue; + } else if (parsingPrefixText && line == QLatin1String("}")) { + parsingPrefixText = false; + continue; + } else if (parsingPrefixText) { + provider.prefixText.append(line); + continue; + } + if (line.isEmpty() || line.startsWith(QLatin1Char('#'))) continue; @@ -296,7 +308,14 @@ Provider parseProvider(const QString &filename) } } + if (parsingPrefixText) { + panic("Syntax error while processing '%s': " + "no closing brace found for prefix text block", + qPrintable(filename)); + } + #ifdef TRACEGEN_DEBUG + qDebug() << provider.prefixText; for (auto i = provider.tracepoints.constBegin(); i != provider.tracepoints.constEnd(); ++i) dumpTracepoint(*i); #endif diff --git a/src/tools/tracegen/provider.h b/src/tools/tracegen/provider.h index 9771e62f4d..9be0c33d89 100644 --- a/src/tools/tracegen/provider.h +++ b/src/tools/tracegen/provider.h @@ -86,6 +86,7 @@ struct Provider { QString name; QVector tracepoints; + QStringList prefixText; }; Provider parseProvider(const QString &filename); diff --git a/src/widgets/qtwidgets.tracepoints b/src/widgets/qtwidgets.tracepoints index 01a1383670..bfaf87ffcc 100644 --- a/src/widgets/qtwidgets.tracepoints +++ b/src/widgets/qtwidgets.tracepoints @@ -1,3 +1,9 @@ +{ +QT_BEGIN_NAMESPACE +class QEvent; +QT_END_NAMESPACE +} + QApplication_notify_entry(QObject *receiver, QEvent *event, int type) QApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type) QApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type) -- cgit v1.2.3 From 5f62202e6c89269da3e9faaea4c88d0f19416cc1 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Tue, 26 Mar 2019 15:23:48 +0100 Subject: Add tracepoint to qt_message_print This allows us to deduce a lot about what a Qt application is doing, since the debug output usually contains a lot of information. Change-Id: I28a18afd151a1640a44ba8c7c9cd87d5d66c99b0 Reviewed-by: Christoph Sterz Reviewed-by: Thiago Macieira --- src/corelib/global/qlogging.cpp | 3 +++ src/corelib/qtcore.tracepoints | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 168934c202..30232170fb 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -57,6 +57,7 @@ #include "private/qloggingregistry_p.h" #include "private/qcoreapplication_p.h" #include "private/qsimd_p.h" +#include #endif #ifdef Q_OS_WIN #include @@ -1811,6 +1812,8 @@ static void ungrabMessageHandler() { } static void qt_message_print(QtMsgType msgType, const QMessageLogContext &context, const QString &message) { #ifndef QT_BOOTSTRAPPED + Q_TRACE(qt_message_print, msgType, context.category, context.function, context.file, context.line, message); + // qDebug, qWarning, ... macros do not check whether category is enabled if (isDefaultCategory(context.category)) { if (QLoggingCategory *defaultCategory = QLoggingCategory::defaultCategory()) { diff --git a/src/corelib/qtcore.tracepoints b/src/corelib/qtcore.tracepoints index a9a08071f3..f9018acdbf 100644 --- a/src/corelib/qtcore.tracepoints +++ b/src/corelib/qtcore.tracepoints @@ -38,3 +38,5 @@ QMetaObject_activate_begin_slot_functor(void *slotObject) QMetaObject_activate_end_slot_functor(void *slotObject) QMetaObject_activate_begin_declarative_signal(QObject *sender, int signalIndex) QMetaObject_activate_end_declarative_signal(QObject *sender, int signalIndex) + +qt_message_print(int type, const char *category, const char *function, const char *file, int line, const QString &message) -- cgit v1.2.3 From 127518deda5a05fda2ce24be98aaaeb7b975f163 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Wed, 27 Mar 2019 13:56:57 +0100 Subject: Introduce Q_TRACE_SCOPE to simplify tracing of a function entry/exit Additionally, we also add a Q_TRACE_EXIT which runs a trace point when the scope is exited, leveraging qScopeGuard behind the scenes. Q_TRACE_SCOPE uses Q_TRACE_EXIT internally - the difference is that the _SCOPE version enforces the naming scheme of _entry / _exit for the tracepoints, whereas Q_TRACE_EXIT can be used generically. Change-Id: I4a2f5ea09f451fcf664d07fd493b679f7527ac06 Reviewed-by: Thiago Macieira --- src/corelib/global/qtrace_p.h | 17 ++++++++++++++++- src/corelib/kernel/qcoreapplication.cpp | 4 +--- src/gui/kernel/qguiapplication.cpp | 8 ++------ 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/corelib/global/qtrace_p.h b/src/corelib/global/qtrace_p.h index 3d04a7311d..20f2beac98 100644 --- a/src/corelib/global/qtrace_p.h +++ b/src/corelib/global/qtrace_p.h @@ -52,11 +52,18 @@ // /* - * The Qt tracepoints API consists of only three macros: + * The Qt tracepoints API consists of only five macros: * * - Q_TRACE(tracepoint, args...) * Fires 'tracepoint' if it is enabled. * + * - Q_TRACE_EXIT(tracepoint, args...) + * Fires 'tracepoint' if it is enabled when the current scope exists. + * + * - Q_TRACE_SCOPE(tracepoint, args...) + * Wrapper around Q_TRACE/_EXIT to trace entry and exit. First it traces + * `${tracepoint}_entry` and then `${tracepoint}_exit` on scope exit. + * * - Q_UNCONDITIONAL_TRACE(tracepoint, args...) * Fires 'tracepoint' unconditionally: no check is performed to query * whether 'tracepoint' is enabled. @@ -110,15 +117,23 @@ */ #include +#include QT_BEGIN_NAMESPACE #if defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED) # define Q_TRACE(x, ...) QtPrivate::trace_ ## x(__VA_ARGS__) +# define Q_TRACE_EXIT(x, ...) \ + const auto qTraceExit_ ## x ## __COUNTER__ = qScopeGuard([&]() { Q_TRACE(x, __VA_ARGS__); }); +# define Q_TRACE_SCOPE(x, ...) \ + Q_TRACE(x ## _entry, __VA_ARGS__); \ + Q_TRACE_EXIT(x ## _exit, __VA_ARGS__); # define Q_UNCONDITIONAL_TRACE(x, ...) QtPrivate::do_trace_ ## x(__VA_ARGS__) # define Q_TRACE_ENABLED(x) QtPrivate::trace_ ## x ## _enabled() #else # define Q_TRACE(x, ...) +# define Q_TRACE_EXIT(x, ...) +# define Q_TRACE_SCOPE(x, ...) # define Q_UNCONDITIONAL_TRACE(x, ...) # define Q_TRACE_ENABLED(x) false #endif // defined(Q_TRACEPOINT) && !defined(QT_BOOTSTRAPPED) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 6d7985c91b..d173ec029b 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -778,7 +778,7 @@ QCoreApplication::QCoreApplication(int &argc, char **argv void QCoreApplicationPrivate::init() { - Q_TRACE(QCoreApplicationPrivate_init_entry); + Q_TRACE_SCOPE(QCoreApplicationPrivate_init); #if defined(Q_OS_MACOS) QMacAutoReleasePool pool; @@ -883,8 +883,6 @@ void QCoreApplicationPrivate::init() #ifndef QT_NO_QOBJECT is_app_running = true; // No longer starting up. #endif - - Q_TRACE(QCoreApplicationPrivate_init_exit); } /*! diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index fd01f8bb7b..424af20f26 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -1421,7 +1421,7 @@ void QGuiApplicationPrivate::eventDispatcherReady() void QGuiApplicationPrivate::init() { - Q_TRACE(QGuiApplicationPrivate_init_entry); + Q_TRACE_SCOPE(QGuiApplicationPrivate_init); #if defined(Q_OS_MACOS) QMacAutoReleasePool pool; @@ -1585,8 +1585,6 @@ void QGuiApplicationPrivate::init() if (!QGuiApplicationPrivate::displayName) QObject::connect(q, &QGuiApplication::applicationNameChanged, q, &QGuiApplication::applicationDisplayNameChanged); - - Q_TRACE(QGuiApplicationPrivate_init_exit); } extern void qt_cleanupFontDatabase(); @@ -1830,7 +1828,7 @@ bool QGuiApplicationPrivate::processNativeEvent(QWindow *window, const QByteArra void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *e) { - Q_TRACE(QGuiApplicationPrivate_processWindowSystemEvent_entry, e->type); + Q_TRACE_SCOPE(QGuiApplicationPrivate_processWindowSystemEvent, e->type); switch(e->type) { case QWindowSystemInterfacePrivate::Mouse: @@ -1940,8 +1938,6 @@ void QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePriv qWarning() << "Unknown user input event type:" << e->type; break; } - - Q_TRACE(QGuiApplicationPrivate_processWindowSystemEvent_exit, e->type); } /*! \internal -- cgit v1.2.3 From f4c41b9797f08f173049502fa7bd465cf5bde938 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Wed, 27 Mar 2019 14:00:21 +0100 Subject: Add missing _exit tracepoints for event handling This allows tools that look for matching `foo_entry/exit` pairs in the trace data to work properly. An unmatched `_entry` would otherwise confuse them, making them think that the call stack is continuously increasing. Change-Id: Idff7f587ea25c46ec86ad623cc82d503db34a194 Reviewed-by: Christoph Sterz Reviewed-by: Thiago Macieira --- src/corelib/kernel/qcoreapplication.cpp | 4 ++-- src/corelib/qtcore.tracepoints | 2 ++ src/widgets/kernel/qapplication.cpp | 2 +- src/widgets/qtwidgets.tracepoints | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index d173ec029b..596941b5a9 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1197,7 +1197,7 @@ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event) { // Note: when adjusting the tracepoints in here // consider adjusting QApplicationPrivate::notify_helper too. - Q_TRACE(QCoreApplication_notify_entry, receiver, event, event->type()); + Q_TRACE_SCOPE(QCoreApplication_notify, receiver, event, event->type()); // send to all application event filters (only does anything in the main thread) if (QCoreApplication::self @@ -1489,7 +1489,7 @@ bool QCoreApplication::sendSpontaneousEvent(QObject *receiver, QEvent *event) */ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) { - Q_TRACE(QCoreApplication_postEvent_entry, receiver, event, event->type()); + Q_TRACE_SCOPE(QCoreApplication_postEvent, receiver, event, event->type()); if (receiver == 0) { qWarning("QCoreApplication::postEvent: Unexpected null receiver"); diff --git a/src/corelib/qtcore.tracepoints b/src/corelib/qtcore.tracepoints index f9018acdbf..3a70136741 100644 --- a/src/corelib/qtcore.tracepoints +++ b/src/corelib/qtcore.tracepoints @@ -16,6 +16,7 @@ QEvent_ctor(QEvent *event, int type) QEvent_dtor(QEvent *event, int type) QCoreApplication_postEvent_entry(QObject *receiver, QEvent *event, int type) +QCoreApplication_postEvent_exit(QObject *receiver, QEvent *event, int type) QCoreApplication_postEvent_event_compressed(QObject *receiver, QEvent *event) QCoreApplication_postEvent_event_posted(QObject *receiver, QEvent *event, int type) @@ -23,6 +24,7 @@ QCoreApplication_sendEvent(QObject *receiver, QEvent *event, int type) QCoreApplication_sendSpontaneousEvent(QObject *receiver, QEvent *event, int type) QCoreApplication_notify_entry(QObject *receiver, QEvent *event, int type) +QCoreApplication_notify_exit(QObject *receiver, QEvent *event, int type) QCoreApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type) QCoreApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type) QCoreApplication_notify_after_delivery(QObject *receiver, QEvent *event, int type, bool consumed) diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index ebab87b193..fdece8414c 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -3697,7 +3697,7 @@ bool QApplicationPrivate::notify_helper(QObject *receiver, QEvent * e) // to the ones in QCoreApplicationPrivate::notify_helper; the reason for their // duplication is because tracepoint symbols are not exported by QtCore. // If you adjust the tracepoints here, consider adjusting QCoreApplicationPrivate too. - Q_TRACE(QApplication_notify_entry, receiver, e, e->type()); + Q_TRACE_SCOPE(QApplication_notify, receiver, e, e->type()); // send to all application event filters if (threadRequiresCoreApplication() diff --git a/src/widgets/qtwidgets.tracepoints b/src/widgets/qtwidgets.tracepoints index bfaf87ffcc..9c40cdb3e7 100644 --- a/src/widgets/qtwidgets.tracepoints +++ b/src/widgets/qtwidgets.tracepoints @@ -5,6 +5,7 @@ QT_END_NAMESPACE } QApplication_notify_entry(QObject *receiver, QEvent *event, int type) +QApplication_notify_exit(QObject *receiver, QEvent *event, int type) QApplication_notify_event_filtered(QObject *receiver, QEvent *event, int type) QApplication_notify_before_delivery(QObject *receiver, QEvent *event, int type) QApplication_notify_after_delivery(QObject *receiver, QEvent *event, int type, bool consumed) -- cgit v1.2.3 From 82ad4be4a2e0c2bccb6cd8ea2440aefee4ec48ec Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Wed, 27 Mar 2019 17:01:40 +0000 Subject: Fix various uncommon cases in QTzTimeZonePrivate backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Includes a fixup for 03fadc26e7617aece89949bc7d0acf50f6f050a9, which removed the check on empty transition list, needed when no data are available. Ensured that such a data-free zone would in fact be noticed as invalid during init(). Fixed handling of times before the epoch (we still want to consult a POSIX rule, if that's all that's available) while ensuring we (as documented) ignore DST for such times. Fixed handling of large times (milliseconds since epoch outside int range) when looking up POSIX rules. Gave QTimeZonePrivate a YearRange enum (to be moved to QTimeZone once this merges up to dev) so as to eliminate a magic number (and avoid adding another). Moved year-munging in POSIX rules after the one early return, which doesn't need the year range. Added test-cases for the distant past/future (just checking UTC's offsets; SLES has a minimal version of the UTC data-file that triggers the bugs fixed here for them). Fixes: QTBUG-74666 Fixes: QTBUG-74550 Change-Id: Ief7b7e55c62cf11064700934f404b2fc283614e1 Reviewed-by: Tony Sarajärvi Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime_p.h | 4 ++ src/corelib/tools/qtimezoneprivate_tz.cpp | 55 +++++++++++++--------- .../auto/corelib/tools/qtimezone/tst_qtimezone.cpp | 7 ++- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/corelib/tools/qdatetime_p.h b/src/corelib/tools/qdatetime_p.h index 4d30d4192b..b3d00745d0 100644 --- a/src/corelib/tools/qdatetime_p.h +++ b/src/corelib/tools/qdatetime_p.h @@ -140,6 +140,10 @@ public: // Inlined for its one caller in qdatetime.cpp inline void setUtcOffsetByTZ(qint64 atMSecsSinceEpoch); #endif // timezone + + // ### Qt 5.14: expose publicly in QDateTime + // The first and last years of which QDateTime can represent some part: + enum class YearRange : qint32 { First = -292275056, Last = +292278994 }; }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index f75a61977d..7d85bc077d 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -39,6 +39,7 @@ #include "qtimezone.h" #include "qtimezoneprivate_p.h" +#include "qdatetime_p.h" // ### Qt 5.14: remove once YearRange is on QDateTime #include #include @@ -520,19 +521,14 @@ PosixZone PosixZone::parse(const char *&pos, const char *end) static QVector calculatePosixTransitions(const QByteArray &posixRule, int startYear, int endYear, - int lastTranMSecs) + qint64 lastTranMSecs) { QVector result; - // Limit year by qint64 max size for msecs - if (startYear > 292278994) - startYear = 292278994; - if (endYear > 292278994) - endYear = 292278994; - // POSIX Format is like "TZ=CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00" // i.e. "std offset dst [offset],start[/time],end[/time]" - // See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html + // See the section about TZ at + // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html QList parts = posixRule.split(','); PosixZone stdZone, dstZone = PosixZone::invalid(); @@ -583,6 +579,13 @@ static QVector calculatePosixTransitions(const QByteArra else stdTime = QTime(2, 0, 0); + // Limit year to the range QDateTime can represent: + const int minYear = int(QDateTimePrivate::YearRange::First); + const int maxYear = int(QDateTimePrivate::YearRange::Last); + startYear = qBound(minYear, startYear, maxYear); + endYear = qBound(minYear, endYear, maxYear); + Q_ASSERT(startYear <= endYear); + for (int year = startYear; year <= endYear; ++year) { QTimeZonePrivate::Data dstData; QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC); @@ -598,13 +601,16 @@ static QVector calculatePosixTransitions(const QByteArra stdData.standardTimeOffset = stdZone.offset; stdData.daylightTimeOffset = 0; stdData.abbreviation = stdZone.name; - // Part of the high year will overflow - if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) { + // Part of maxYear will overflow (likewise for minYear, below): + if (year == maxYear && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) { if (dstData.atMSecsSinceEpoch > 0) { result << dstData; } else if (stdData.atMSecsSinceEpoch > 0) { result << stdData; } + } else if (year < 1970) { // We ignore DST before the epoch. + if (year > minYear || stdData.atMSecsSinceEpoch != QTimeZonePrivate::invalidMSecs()) + result << stdData; } else if (dst < std) { result << dstData << stdData; } else { @@ -794,6 +800,8 @@ void QTzTimeZonePrivate::init(const QByteArray &ianaId) tran.atMSecsSinceEpoch = tz_tran.tz_time * 1000; m_tranTimes.append(tran); } + if (m_tranTimes.isEmpty() && m_posixRule.isEmpty()) + return; // Invalid after all ! if (ianaId.isEmpty()) m_id = systemTimeZoneId(); @@ -954,22 +962,25 @@ QVector QTzTimeZonePrivate::getPosixTransitions(qint64 m QTimeZonePrivate::Data QTzTimeZonePrivate::data(qint64 forMSecsSinceEpoch) const { // If the required time is after the last transition (or there were none) - // and we have a POSIX rule then use it: - if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch) - && !m_posixRule.isEmpty() && forMSecsSinceEpoch >= 0) { + // and we have a POSIX rule, then use it: + if (!m_posixRule.isEmpty() + && (m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < forMSecsSinceEpoch)) { QVector posixTrans = getPosixTransitions(forMSecsSinceEpoch); auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(), [forMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) { return at.atMSecsSinceEpoch <= forMSecsSinceEpoch; }); - if (it > posixTrans.cbegin()) { - QTimeZonePrivate::Data data = *--it; + // Use most recent, if any in the past; or the first if we have no other rules: + if (it > posixTrans.cbegin() || (m_tranTimes.isEmpty() && it < posixTrans.cend())) { + QTimeZonePrivate::Data data = *(it > posixTrans.cbegin() ? it - 1 : it); data.atMSecsSinceEpoch = forMSecsSinceEpoch; return data; } } + if (m_tranTimes.isEmpty()) // Only possible if !isValid() + return invalidData(); - // Otherwise, if we can find a valid tran, then use its rule: + // Otherwise, use the rule for the most recent or first transition: auto last = std::partition_point(m_tranTimes.cbegin(), m_tranTimes.cend(), [forMSecsSinceEpoch] (const QTzTransitionTime &at) { return at.atMSecsSinceEpoch <= forMSecsSinceEpoch; @@ -989,9 +1000,9 @@ bool QTzTimeZonePrivate::hasTransitions() const QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSinceEpoch) const { // If the required time is after the last transition (or there were none) - // and we have a POSIX rule then use it: - if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch) - && !m_posixRule.isEmpty() && afterMSecsSinceEpoch >= 0) { + // and we have a POSIX rule, then use it: + if (!m_posixRule.isEmpty() + && (m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < afterMSecsSinceEpoch)) { QVector posixTrans = getPosixTransitions(afterMSecsSinceEpoch); auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(), [afterMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) { @@ -1012,9 +1023,9 @@ QTimeZonePrivate::Data QTzTimeZonePrivate::nextTransition(qint64 afterMSecsSince QTimeZonePrivate::Data QTzTimeZonePrivate::previousTransition(qint64 beforeMSecsSinceEpoch) const { // If the required time is after the last transition (or there were none) - // and we have a POSIX rule then use it: - if ((m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch) - && !m_posixRule.isEmpty() && beforeMSecsSinceEpoch > 0) { + // and we have a POSIX rule, then use it: + if (!m_posixRule.isEmpty() + && (m_tranTimes.isEmpty() || m_tranTimes.last().atMSecsSinceEpoch < beforeMSecsSinceEpoch)) { QVector posixTrans = getPosixTransitions(beforeMSecsSinceEpoch); auto it = std::partition_point(posixTrans.cbegin(), posixTrans.cend(), [beforeMSecsSinceEpoch] (const QTimeZonePrivate::Data &at) { diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp index eff9835776..bb6c48a2ed 100644 --- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp @@ -539,8 +539,13 @@ void tst_QTimeZone::checkOffset_data() int year, month, day, hour, min, sec; int std, dst; } table[] = { - // Zone with no transitions (QTBUG-74614, when TZ backend uses minimalist data) + // Zone with no transitions (QTBUG-74614, QTBUG-74666, when TZ backend uses minimal data) { "Etc/UTC", "epoch", 1970, 1, 1, 0, 0, 0, 0, 0 }, + { "Etc/UTC", "pre_int32", 1901, 12, 13, 20, 45, 51, 0, 0 }, + { "Etc/UTC", "post_int32", 2038, 1, 19, 3, 14, 9, 0, 0 }, + { "Etc/UTC", "post_uint32", 2106, 2, 7, 6, 28, 17, 0, 0 }, + { "Etc/UTC", "initial", -292275056, 5, 16, 16, 47, 5, 0, 0 }, + { "Etc/UTC", "final", 292278994, 8, 17, 7, 12, 55, 0, 0 }, // Kiev: regression test for QTBUG-64122 (on MS): { "Europe/Kiev", "summer", 2017, 10, 27, 12, 0, 0, 2 * 3600, 3600 }, { "Europe/Kiev", "winter", 2017, 10, 29, 12, 0, 0, 2 * 3600, 0 } -- cgit v1.2.3 From 8eeb5150ed99914e252a84f1637f179e3de04659 Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Fri, 5 Apr 2019 18:55:24 +0200 Subject: QDnsLookup: fix "Resolver functions not found" error on FreeBSD The current code only tries to load the required functions from LIBRESOLV_SO (if defined) and resolv, but on FreeBSD they are in libc: https://www.freebsd.org/cgi/man.cgi?query=res_query&sektion=3&apropos=0&manpath=freebsd This commit changes the code so that, after failing to load the non-existent libraries, it attempts to load the functions with dlsym() using the special handle RTLD_DEFAULT, which searches for the specified symbol in the loaded libraries. Task-number: QTBUG-74844 Change-Id: If97aaae233cabbfa01c30d26d9a7fb01ec3ff5c2 Reviewed-by: Joerg Bornemann Reviewed-by: Thiago Macieira --- src/network/kernel/kernel.pri | 6 ++++- src/network/kernel/qdnslookup_unix.cpp | 41 +++++++++++++++++++++++----------- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index 11b80d59d5..d7a92a12eb 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -38,7 +38,11 @@ qtConfig(dnslookup) { } unix { - !integrity:qtConfig(dnslookup): SOURCES += kernel/qdnslookup_unix.cpp + !integrity:qtConfig(dnslookup) { + SOURCES += kernel/qdnslookup_unix.cpp + qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl + } + SOURCES += kernel/qhostinfo_unix.cpp qtConfig(linux-netlink): SOURCES += kernel/qnetworkinterface_linux.cpp diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index ce1ec6442a..ee7484ab35 100644 --- a/src/network/kernel/qdnslookup_unix.cpp +++ b/src/network/kernel/qdnslookup_unix.cpp @@ -59,6 +59,10 @@ # include #endif +#if defined(Q_OS_FREEBSD) || QT_CONFIG(dlopen) +# include +#endif + #include QT_BEGIN_NAMESPACE @@ -87,6 +91,18 @@ struct QDnsLookupStateDeleter } }; +static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym) +{ + if (lib.isLoaded()) + return lib.resolve(sym); + +#if defined(RTLD_DEFAULT) && (defined(Q_OS_FREEBSD) || QT_CONFIG(dlopen)) + return reinterpret_cast(dlsym(RTLD_DEFAULT, sym)); +#else + return nullptr; +#endif +} + static bool resolveLibraryInternal() { QLibrary lib; @@ -96,31 +112,30 @@ static bool resolveLibraryInternal() #endif { lib.setFileName(QLatin1String("resolv")); - if (!lib.load()) - return false; + lib.load(); } - local_dn_expand = dn_expand_proto(lib.resolve("__dn_expand")); + local_dn_expand = dn_expand_proto(resolveSymbol(lib, "__dn_expand")); if (!local_dn_expand) - local_dn_expand = dn_expand_proto(lib.resolve("dn_expand")); + local_dn_expand = dn_expand_proto(resolveSymbol(lib, "dn_expand")); - local_res_nclose = res_nclose_proto(lib.resolve("__res_nclose")); + local_res_nclose = res_nclose_proto(resolveSymbol(lib, "__res_nclose")); if (!local_res_nclose) - local_res_nclose = res_nclose_proto(lib.resolve("res_9_nclose")); + local_res_nclose = res_nclose_proto(resolveSymbol(lib, "res_9_nclose")); if (!local_res_nclose) - local_res_nclose = res_nclose_proto(lib.resolve("res_nclose")); + local_res_nclose = res_nclose_proto(resolveSymbol(lib, "res_nclose")); - local_res_ninit = res_ninit_proto(lib.resolve("__res_ninit")); + local_res_ninit = res_ninit_proto(resolveSymbol(lib, "__res_ninit")); if (!local_res_ninit) - local_res_ninit = res_ninit_proto(lib.resolve("res_9_ninit")); + local_res_ninit = res_ninit_proto(resolveSymbol(lib, "res_9_ninit")); if (!local_res_ninit) - local_res_ninit = res_ninit_proto(lib.resolve("res_ninit")); + local_res_ninit = res_ninit_proto(resolveSymbol(lib, "res_ninit")); - local_res_nquery = res_nquery_proto(lib.resolve("__res_nquery")); + local_res_nquery = res_nquery_proto(resolveSymbol(lib, "__res_nquery")); if (!local_res_nquery) - local_res_nquery = res_nquery_proto(lib.resolve("res_9_nquery")); + local_res_nquery = res_nquery_proto(resolveSymbol(lib, "res_9_nquery")); if (!local_res_nquery) - local_res_nquery = res_nquery_proto(lib.resolve("res_nquery")); + local_res_nquery = res_nquery_proto(resolveSymbol(lib, "res_nquery")); return true; } -- cgit v1.2.3 From e199710d0ea804e4481042f41b91b5234540f5d5 Mon Sep 17 00:00:00 2001 From: Davide Beatrici Date: Sat, 6 Apr 2019 08:01:11 +0200 Subject: QHostInfo: use dlsym() with RTLD_DEFAULT in case libs cannot be loaded The current code only tries to load the required functions from LIBRESOLV_SO (if defined) and resolv, but on FreeBSD they are in libc: https://www.freebsd.org/cgi/man.cgi?query=res_query&sektion=3&apropos=0&manpath=freebsd This commit changes the code so that, after failing to load the non-existent libraries, it attempts to load the functions with dlsym() using the special handle RTLD_DEFAULT, which searches for the specified symbol in the loaded libraries. This is a follow-up to 8eeb5150ed99914e252a84f1637f179e3de04659. Change-Id: I19d90b0ca8703398bf4f5f4edd5ae31e346ef251 Reviewed-by: Thiago Macieira --- src/network/kernel/kernel.pri | 7 +++---- src/network/kernel/qhostinfo_unix.cpp | 33 ++++++++++++++++++++++++--------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/network/kernel/kernel.pri b/src/network/kernel/kernel.pri index d7a92a12eb..7074fcd5eb 100644 --- a/src/network/kernel/kernel.pri +++ b/src/network/kernel/kernel.pri @@ -38,13 +38,12 @@ qtConfig(dnslookup) { } unix { - !integrity:qtConfig(dnslookup) { - SOURCES += kernel/qdnslookup_unix.cpp - qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl - } + !integrity:qtConfig(dnslookup): SOURCES += kernel/qdnslookup_unix.cpp SOURCES += kernel/qhostinfo_unix.cpp + qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl + qtConfig(linux-netlink): SOURCES += kernel/qnetworkinterface_linux.cpp else: SOURCES += kernel/qnetworkinterface_unix.cpp } diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index d22608e22f..e4810d68ee 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -66,6 +66,10 @@ # include #endif +#if defined(Q_OS_FREEBSD) || QT_CONFIG(dlopen) +# include +#endif + QT_BEGIN_NAMESPACE // Almost always the same. If not, specify in qplatformdefs.h. @@ -115,6 +119,18 @@ struct LibResolv }; } +static QFunctionPointer resolveSymbol(QLibrary &lib, const char *sym) +{ + if (lib.isLoaded()) + return lib.resolve(sym); + +#if defined(RTLD_DEFAULT) && (defined(Q_OS_FREEBSD) || QT_CONFIG(dlopen)) + return reinterpret_cast(dlsym(RTLD_DEFAULT, sym)); +#else + return nullptr; +#endif +} + LibResolv::LibResolv() { QLibrary lib; @@ -124,31 +140,30 @@ LibResolv::LibResolv() #endif { lib.setFileName(QLatin1String("resolv")); - if (!lib.load()) - return; + lib.load(); } // res_ninit is required for localDomainName() - local_res_ninit = res_ninit_proto(lib.resolve("__res_ninit")); + local_res_ninit = res_ninit_proto(resolveSymbol(lib, "__res_ninit")); if (!local_res_ninit) - local_res_ninit = res_ninit_proto(lib.resolve("res_ninit")); + local_res_ninit = res_ninit_proto(resolveSymbol(lib, "res_ninit")); if (local_res_ninit) { // we must now find res_nclose - local_res_nclose = res_nclose_proto(lib.resolve("res_nclose")); + local_res_nclose = res_nclose_proto(resolveSymbol(lib, "res_nclose")); if (!local_res_nclose) - local_res_nclose = res_nclose_proto(lib.resolve("__res_nclose")); + local_res_nclose = res_nclose_proto(resolveSymbol(lib, "__res_nclose")); if (!local_res_nclose) local_res_ninit = nullptr; } if (ReinitNecessary || !local_res_ninit) { - local_res_init = res_init_proto(lib.resolve("__res_init")); + local_res_init = res_init_proto(resolveSymbol(lib, "__res_init")); if (!local_res_init) - local_res_init = res_init_proto(lib.resolve("res_init")); + local_res_init = res_init_proto(resolveSymbol(lib, "res_init")); if (local_res_init && !local_res_ninit) { // if we can't get a thread-safe context, we have to use the global _res state - local_res = res_state_ptr(lib.resolve("_res")); + local_res = res_state_ptr(resolveSymbol(lib, "_res")); } } } -- cgit v1.2.3 From 6863262dedea84435b0cee9a071e271ac759522c Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sat, 6 Apr 2019 11:46:35 +0200 Subject: QUdpSocket: Add missing \since to docs QNetworkDatagram was introduced together with these methods in Qt 5.8 (commit 4da2dda2aa) Change-Id: I454c26ebf6f94988cada8ac9315db1d43a31a595 Reviewed-by: Thiago Macieira --- src/network/socket/qudpsocket.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/network/socket/qudpsocket.cpp b/src/network/socket/qudpsocket.cpp index 85c4f4cbfd..0e3d516535 100644 --- a/src/network/socket/qudpsocket.cpp +++ b/src/network/socket/qudpsocket.cpp @@ -381,6 +381,7 @@ qint64 QUdpSocket::writeDatagram(const char *data, qint64 size, const QHostAddre */ /*! + \since 5.8 \overload Sends the datagram \a datagram to the host address and port numbers @@ -431,6 +432,8 @@ qint64 QUdpSocket::writeDatagram(const QNetworkDatagram &datagram) } /*! + \since 5.8 + Receives a datagram no larger than \a maxSize bytes and returns it in the QNetworkDatagram object, along with the sender's host address and port. If possible, this function will also try to determine the datagram's -- cgit v1.2.3 From a02a2a1e73206b3955438b38bb9311067ef04794 Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sat, 6 Apr 2019 11:54:24 +0200 Subject: QUdpSocket: Convert snippet to functor connect Change-Id: Ice210b979a1dd948cd8d95003bd50a4b71d91852 Reviewed-by: Thiago Macieira --- src/network/doc/snippets/code/src_network_socket_qudpsocket.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/doc/snippets/code/src_network_socket_qudpsocket.cpp b/src/network/doc/snippets/code/src_network_socket_qudpsocket.cpp index a98e31b10b..f6a28ce46c 100644 --- a/src/network/doc/snippets/code/src_network_socket_qudpsocket.cpp +++ b/src/network/doc/snippets/code/src_network_socket_qudpsocket.cpp @@ -54,8 +54,8 @@ void Server::initSocket() udpSocket = new QUdpSocket(this); udpSocket->bind(QHostAddress::LocalHost, 7755); - connect(udpSocket, SIGNAL(readyRead()), - this, SLOT(readPendingDatagrams())); + connect(udpSocket, &QUdpSocket::readyRead, + this, &Server::readPendingDatagrams); } void Server::readPendingDatagrams() -- cgit v1.2.3 From 8374b4016e730992ce72e69f81f183c518fdfe2c Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Tue, 2 Apr 2019 18:03:01 +0200 Subject: Be more precise in calculating start point of fast scaling We were using low precision dx/dy for calculating the starting point which meant we could be off when clipping at high scale factors. Fixes: QTBUG-60782 Change-Id: I883f9aed1346fdffae070b6316ea808b83519701 Reviewed-by: Eirik Aavitsland --- src/gui/painting/qblendfunctions_p.h | 119 +++++++++-------------------------- 1 file changed, 30 insertions(+), 89 deletions(-) diff --git a/src/gui/painting/qblendfunctions_p.h b/src/gui/painting/qblendfunctions_p.h index dc7a4dfe8c..5ea78cdde2 100644 --- a/src/gui/painting/qblendfunctions_p.h +++ b/src/gui/painting/qblendfunctions_p.h @@ -65,11 +65,11 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl, const QRect &clip, T blender) { - qreal sx = targetRect.width() / (qreal) srcRect.width(); - qreal sy = targetRect.height() / (qreal) srcRect.height(); + qreal sx = srcRect.width() / (qreal) targetRect.width(); + qreal sy = srcRect.height() / (qreal) targetRect.height(); - int ix = 0x00010000 / sx; - int iy = 0x00010000 / sy; + const int ix = 0x00010000 * sx; + const int iy = 0x00010000 * sy; // qDebug() << "scale:" << endl // << " - target" << targetRect << endl @@ -77,59 +77,30 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl, // << " - clip" << clip << endl // << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy; - int cx1 = clip.x(); - int cx2 = clip.x() + clip.width(); - int cy1 = clip.top(); - int cy2 = clip.y() + clip.height(); - - int tx1 = qRound(targetRect.left()); - int tx2 = qRound(targetRect.right()); - int ty1 = qRound(targetRect.top()); - int ty2 = qRound(targetRect.bottom()); - - if (tx2 < tx1) - qSwap(tx2, tx1); - - if (ty2 < ty1) - qSwap(ty2, ty1); - - if (tx1 < cx1) - tx1 = cx1; - - if (tx2 >= cx2) - tx2 = cx2; - - if (tx1 >= tx2) + QRect tr = targetRect.normalized().toRect(); + tr = tr.intersected(clip); + if (tr.isEmpty()) return; - - if (ty1 < cy1) - ty1 = cy1; - - if (ty2 >= cy2) - ty2 = cy2; - - if (ty1 >= ty2) - return; - - int h = ty2 - ty1; - int w = tx2 - tx1; - + const int tx1 = tr.left(); + const int ty1 = tr.top(); + int h = tr.height(); + int w = tr.width(); quint32 basex; quint32 srcy; if (sx < 0) { - int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; + int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * sx * 65536) + 1; basex = quint32(srcRect.right() * 65536) + dstx; } else { - int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; + int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * sx * 65536) - 1; basex = quint32(srcRect.left() * 65536) + dstx; } if (sy < 0) { - int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; + int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * sy * 65536) + 1; srcy = quint32(srcRect.bottom() * 65536) + dsty; } else { - int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; + int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * sy * 65536) - 1; srcy = quint32(srcRect.top() * 65536) + dsty; } @@ -185,11 +156,11 @@ template void qt_scale_image_32bit(uchar *destPixels, int dbpl, const QRect &clip, T blender) { - qreal sx = targetRect.width() / (qreal) srcRect.width(); - qreal sy = targetRect.height() / (qreal) srcRect.height(); + qreal sx = srcRect.width() / (qreal) targetRect.width(); + qreal sy = srcRect.height() / (qreal) targetRect.height(); - int ix = 0x00010000 / sx; - int iy = 0x00010000 / sy; + const int ix = 0x00010000 * sx; + const int iy = 0x00010000 * sy; // qDebug() << "scale:" << endl // << " - target" << targetRect << endl @@ -197,60 +168,30 @@ template void qt_scale_image_32bit(uchar *destPixels, int dbpl, // << " - clip" << clip << endl // << " - sx=" << sx << " sy=" << sy << " ix=" << ix << " iy=" << iy; - int cx1 = clip.x(); - int cx2 = clip.x() + clip.width(); - int cy1 = clip.top(); - int cy2 = clip.y() + clip.height(); - - int tx1 = qRound(targetRect.left()); - int tx2 = qRound(targetRect.right()); - int ty1 = qRound(targetRect.top()); - int ty2 = qRound(targetRect.bottom()); - - if (tx2 < tx1) - qSwap(tx2, tx1); - - if (ty2 < ty1) - qSwap(ty2, ty1); - - if (tx1 < cx1) - tx1 = cx1; - - if (tx2 >= cx2) - tx2 = cx2; - - if (tx1 >= tx2) - return; - - if (ty1 < cy1) - ty1 = cy1; - - if (ty2 >= cy2) - ty2 = cy2; - - if (ty1 >= ty2) - return; - - int h = ty2 - ty1; - int w = tx2 - tx1; - if (!w || !h) + QRect tr = targetRect.normalized().toRect(); + tr = tr.intersected(clip); + if (tr.isEmpty()) return; + const int tx1 = tr.left(); + const int ty1 = tr.top(); + int h = tr.height(); + int w = tr.width(); quint32 basex; quint32 srcy; if (sx < 0) { - int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * ix) + 1; + int dstx = qFloor((tx1 + qreal(0.5) - targetRect.right()) * sx * 65536) + 1; basex = quint32(srcRect.right() * 65536) + dstx; } else { - int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * ix) - 1; + int dstx = qCeil((tx1 + qreal(0.5) - targetRect.left()) * sx * 65536) - 1; basex = quint32(srcRect.left() * 65536) + dstx; } if (sy < 0) { - int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * iy) + 1; + int dsty = qFloor((ty1 + qreal(0.5) - targetRect.bottom()) * sy * 65536) + 1; srcy = quint32(srcRect.bottom() * 65536) + dsty; } else { - int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * iy) - 1; + int dsty = qCeil((ty1 + qreal(0.5) - targetRect.top()) * sy * 65536) - 1; srcy = quint32(srcRect.top() * 65536) + dsty; } -- cgit v1.2.3 From ffc71a977f4bef2872c5c93ddd4db7ebaee8e356 Mon Sep 17 00:00:00 2001 From: Samuel Gaist Date: Mon, 27 Aug 2018 00:16:58 +0200 Subject: QBenchmarkValgrindUtils: port to QRegularExpression This patch updates the code from the deprecated QRegExp class to QRegularExpression. Task-number: QTBUG-25485 Change-Id: I946790f50c6b14787bca31771de5e3a0d5fefe4c Reviewed-by: Edward Welbourne Reviewed-by: Thiago Macieira --- src/testlib/qbenchmarkvalgrind.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/testlib/qbenchmarkvalgrind.cpp b/src/testlib/qbenchmarkvalgrind.cpp index 1de149258d..7d24eb8293 100644 --- a/src/testlib/qbenchmarkvalgrind.cpp +++ b/src/testlib/qbenchmarkvalgrind.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -90,13 +91,13 @@ qint64 QBenchmarkValgrindUtils::extractResult(const QString &fileName) qint64 val = -1; bool valSeen = false; - QRegExp rxValue(QLatin1String("^summary: (\\d+)")); + QRegularExpression rxValue(QLatin1String("^summary: (\\d+)")); while (!file.atEnd()) { const QString line(QLatin1String(file.readLine())); - if (rxValue.indexIn(line) != -1) { - Q_ASSERT(rxValue.captureCount() == 1); + QRegularExpressionMatch match = rxValue.match(line); + if (match.hasMatch()) { bool ok; - val = rxValue.cap(1).toLongLong(&ok); + val = match.captured(1).toLongLong(&ok); Q_ASSERT(ok); valSeen = true; break; @@ -120,13 +121,12 @@ QString QBenchmarkValgrindUtils::getNewestFileName() int hiSuffix = -1; QFileInfo lastFileInfo; const QString pattern = QString::fromLatin1("%1.(\\d+)").arg(base); - QRegExp rx(pattern); + QRegularExpression rx(pattern); for (const QFileInfo &fileInfo : fiList) { - const int index = rx.indexIn(fileInfo.fileName()); - Q_ASSERT(index == 0); - Q_UNUSED(index); + QRegularExpressionMatch match = rx.match(fileInfo.fileName()); + Q_ASSERT(match.hasMatch()); bool ok; - const int suffix = rx.cap(1).toInt(&ok); + const int suffix = match.captured(1).toInt(&ok); Q_ASSERT(ok); Q_ASSERT(suffix >= 0); if (suffix > hiSuffix) { -- cgit v1.2.3 From 8cd0a39dd79a48697c181c3754cada4ffd832214 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Fri, 5 Apr 2019 09:53:22 +0200 Subject: qmake: Remove special-handling of cl.exe's -Gm option The comment hints that it's fixing an issue in Visual Studio 2013, which we don't support anymore. In all supported Visual Studio Versions -Gm is actually deprecated anyhow, and not set anymore by default. So I guess it's safe to remove the special handling here. Change-Id: I2e8ff85350ba651d9a763aabba7b6494ba88d82e Reviewed-by: Joerg Bornemann --- qmake/generators/win32/msvc_nmake.cpp | 8 -------- qmake/generators/win32/msvc_vcproj.cpp | 10 ---------- 2 files changed, 18 deletions(-) diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index f295705e2e..af6d3c5aff 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -171,15 +171,7 @@ QString NmakeMakefileGenerator::var(const ProKey &value) const .arg(precompH_f, precompH_f, escapeFilePath(isRunC ? precompPchC : precompPch)); QString p = MakefileGenerator::var(value); p.replace(QLatin1String("-c"), precompRule); - // Cannot use -Gm with -FI & -Yu, as this gives an - // internal compiler error, on the newer compilers - // ### work-around for a VS 2003 bug. Move to some prf file or remove completely. - p.remove("-Gm"); return p; - } else if (value == "QMAKE_CXXFLAGS") { - // Remove internal compiler error option - // ### work-around for a VS 2003 bug. Move to some prf file or remove completely. - return MakefileGenerator::var(value).remove("-Gm"); } } diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 06a96f7538..fd53ec2a6e 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1063,16 +1063,6 @@ void VcprojGenerator::initCompilerTool() conf.compiler.PrecompiledHeaderFile = "$(IntDir)\\" + precompPch; conf.compiler.PrecompiledHeaderThrough = project->first("PRECOMPILED_HEADER").toQString(); conf.compiler.ForcedIncludeFiles = project->values("PRECOMPILED_HEADER").toQStringList(); - - if (conf.CompilerVersion <= NET2003) { - // Minimal build option triggers an Internal Compiler Error - // when used in conjunction with /FI and /Yu, so remove it - // ### work-around for a VS 2003 bug. Move to some prf file or remove completely. - project->values("QMAKE_CFLAGS_DEBUG").removeAll("-Gm"); - project->values("QMAKE_CFLAGS_DEBUG").removeAll("/Gm"); - project->values("QMAKE_CXXFLAGS_DEBUG").removeAll("-Gm"); - project->values("QMAKE_CXXFLAGS_DEBUG").removeAll("/Gm"); - } } conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS")); -- cgit v1.2.3 From 7482602e857e0267a427d80fab73039696abe9b6 Mon Sep 17 00:00:00 2001 From: Kai Koehne Date: Thu, 4 Apr 2019 16:25:31 +0200 Subject: ANGLE: Remove superfluous -Gm- option /GM at one point apparently was set by default for debug builds. However, nowaways it's officially deprecated and even generates a warning in Visual Studio 2019; so we don't have to 'unset' it specifically anymore. Change-Id: I5b9b93c058c2ee8a5e025da43251d3859acbe061 Reviewed-by: Joerg Bornemann --- src/angle/src/config.pri | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/angle/src/config.pri b/src/angle/src/config.pri index 5c521281a6..cafae0e742 100644 --- a/src/angle/src/config.pri +++ b/src/angle/src/config.pri @@ -79,10 +79,9 @@ msvc { # /Oy: Omits frame pointer (x86 only). # /Gy: Enables function-level linking. # /GS: Buffers security check. - # /Gm-: Disable minimal rebuild. # /RTC1: Run time error checking - QMAKE_CFLAGS_RELEASE += -Oy- -Gy -GS -Gm- - QMAKE_CFLAGS_DEBUG += -Oy- -Gy -GS -Gm- -RTC1 + QMAKE_CFLAGS_RELEASE += -Oy- -Gy -GS + QMAKE_CFLAGS_DEBUG += -Oy- -Gy -GS -RTC1 QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO = -Zi $$QMAKE_CFLAGS_RELEASE QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -- cgit v1.2.3 From fe7a8d61d1428f4d316c2a6884d8dfb8190520f0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 3 Apr 2019 14:14:32 +0200 Subject: Update precompiled headers Include many headers that are commonly used now, and avoid listing them twice. Change-Id: I679dc24cff2cb3a3c9c18585ec78007ab3550743 Reviewed-by: Thiago Macieira --- src/corelib/global/qt_pch.h | 6 ++++++ src/gui/kernel/qt_gui_pch.h | 31 +++++++----------------------- src/widgets/kernel/qt_widgets_pch.h | 38 +++++++------------------------------ 3 files changed, 20 insertions(+), 55 deletions(-) diff --git a/src/corelib/global/qt_pch.h b/src/corelib/global/qt_pch.h index 76e46374c3..3972991618 100644 --- a/src/corelib/global/qt_pch.h +++ b/src/corelib/global/qt_pch.h @@ -60,12 +60,18 @@ # undef _POSIX_ #endif #include +#include +#include #include #include /* All moc genereated code has this include */ #include #include +#include +#include #include #include +#include +#include #if QT_CONFIG(textcodec) #include #endif diff --git a/src/gui/kernel/qt_gui_pch.h b/src/gui/kernel/qt_gui_pch.h index aa5d3f0572..5e07fa45e7 100644 --- a/src/gui/kernel/qt_gui_pch.h +++ b/src/gui/kernel/qt_gui_pch.h @@ -45,37 +45,20 @@ * UNSUPPORTED. */ -// from corelib/global/qt_pch.h +#include "../../corelib/global/qt_pch.h" + #if defined __cplusplus #include - - -#ifdef Q_OS_WIN -# define _POSIX_ -# include -# undef _POSIX_ -#endif - -#include -#include -#include // All moc genereated code has this include -#include -#include -#include -#include -#if QT_CONFIG(textcodec) -#include -#endif - #include #include +#include #include #include +#include #include #include #include -#include - -#include - +#include +#include +#include #endif diff --git a/src/widgets/kernel/qt_widgets_pch.h b/src/widgets/kernel/qt_widgets_pch.h index bec6536637..b70941950b 100644 --- a/src/widgets/kernel/qt_widgets_pch.h +++ b/src/widgets/kernel/qt_widgets_pch.h @@ -45,41 +45,17 @@ * UNSUPPORTED. */ -// from corelib/global/qt_pch.h +#include "../../gui/kernel/qt_gui_pch.h" + #if defined __cplusplus #include - - -#if 0 // Used to be included in Qt4 for Q_WS_WIN -# define _POSIX_ -# include -# undef _POSIX_ -#endif - -#include -#include -#include // All moc genereated code has this include -#include -#include -#include -#include -#if QT_CONFIG(textcodec) -#include -#endif - #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include -#include #include -#include #include - -#include - #endif -- cgit v1.2.3 From eaf20420f8a4d72c804a9d3725c3e294b34c78c8 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 3 Apr 2019 12:59:51 +0200 Subject: Fix precompiled headers with clang-cl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clang-cl couldn't find the header given to it by -FI when it isn't in any of the included directories. Additionally clang-cl 8 has a bug with exported templated classes with inline methods that causes it to have missing symbols at link time. We work around this. Fixes: QTBUG-74563 Change-Id: I7becf05fa8edb07bd4cefe12bee3737e5e1dfa14 Reviewed-by: Yuhang Zhao <2546789017@qq.com> Reviewed-by: Mårten Nordheim Reviewed-by: Kai Koehne --- mkspecs/win32-clang-msvc/qmake.conf | 3 --- qmake/generators/win32/msvc_nmake.cpp | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/mkspecs/win32-clang-msvc/qmake.conf b/mkspecs/win32-clang-msvc/qmake.conf index 4b9cac3e22..9a7f70454d 100644 --- a/mkspecs/win32-clang-msvc/qmake.conf +++ b/mkspecs/win32-clang-msvc/qmake.conf @@ -44,7 +44,4 @@ QMAKE_CXXFLAGS_LTCG = $$QMAKE_CFLAGS_LTCG # Leave QMAKE_LFLAGS_LTCG empty because lld-link doesn't need any additional parameters QMAKE_LFLAGS_LTCG = -# Precompiled headers are not supported yet by clang -CONFIG -= precompile_header - load(qt_config) diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index af6d3c5aff..63d89a5388 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -165,10 +165,14 @@ QString NmakeMakefileGenerator::var(const ProKey &value) const || value == "QMAKE_RUN_CXX_IMP" || value == "QMAKE_RUN_CXX"); if ((isRunCpp && usePCH) || (isRunC && usePCHC)) { - QFileInfo precompHInfo(fileInfo(precompH)); - QString precompH_f = escapeFilePath(precompHInfo.fileName()); + QString precompH_f = escapeFilePath(fileFixify(precompH, FileFixifyBackwards)); QString precompRule = QString("-c -FI%1 -Yu%2 -Fp%3") .arg(precompH_f, precompH_f, escapeFilePath(isRunC ? precompPchC : precompPch)); + // ### For clang_cl 8 we force inline methods to be compiled here instead + // linking them from a pch.o file. We do this by pretending we are also doing + // the pch.o generation step. + if (project->isActiveConfig("clang_cl")) + precompRule += QString(" -Xclang -building-pch-with-obj"); QString p = MakefileGenerator::var(value); p.replace(QLatin1String("-c"), precompRule); return p; @@ -230,7 +234,10 @@ void NmakeMakefileGenerator::init() precompObj = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch" + Option::obj_ext; precompPch = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch.pch"; // Add linking of precompObj (required for whole precompiled classes) - project->values("OBJECTS") += precompObj; + // ### For clang_cl we currently let inline methods be generated in the normal objects, + // since the PCH object is buggy (as of clang 8.0.0) + if (!project->isActiveConfig("clang_cl")) + project->values("OBJECTS") += precompObj; // Add pch file to cleanup project->values("QMAKE_CLEAN") += precompPch; // Return to variable pool @@ -240,7 +247,8 @@ void NmakeMakefileGenerator::init() if (usePCHC) { precompObjC = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch_c" + Option::obj_ext; precompPchC = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch_c.pch"; - project->values("OBJECTS") += precompObjC; + if (!project->isActiveConfig("clang_cl")) + project->values("OBJECTS") += precompObjC; project->values("QMAKE_CLEAN") += precompPchC; project->values("PRECOMPILED_OBJECT_C") = ProStringList(precompObjC); project->values("PRECOMPILED_PCH_C") = ProStringList(precompPchC); -- cgit v1.2.3