From 3f11ef92167ba4622a5326eb7ef1fc67b61866eb Mon Sep 17 00:00:00 2001 From: hjk Date: Tue, 21 Jun 2016 14:06:24 +0200 Subject: [PATCH] Avoid using dynamic_cast<> dynamic_cast<> breaks in cross-library situations. In the past the issue was witnessed on Mac, this time on FreeBSD in various configurations. The workaround deployed here is to manually create unique type ids in form of (addresses of) global variables. Task-id: QTCREATORBUG-16462 Change-Id: Ie28fbb3d31d06c1a722a3d9ea808831191298e71 Reviewed-by: Tobias Hunger Reviewed-by: Ralf Nolden Reviewed-by: Eike Ziller --- src/plugins/android/android.pro | 3 +- src/plugins/android/android.qbs | 1 + src/plugins/android/androiddevice.cpp | 2 ++ src/plugins/android/androidrunnable.cpp | 32 +++++++++++++++++++ src/plugins/android/androidrunnable.h | 2 ++ .../analyzer/analyzerstartparameters.h | 2 ++ src/plugins/debugger/debuggerplugin.cpp | 3 ++ .../customwizard/customwizard.cpp | 3 +- .../devicesupport/desktopdevice.cpp | 1 + .../projectexplorer/devicesupport/idevice.cpp | 3 ++ .../projectexplorer/runconfiguration.h | 12 ++++--- src/plugins/projectexplorer/runnables.cpp | 2 ++ src/plugins/projectexplorer/runnables.h | 14 ++++++++ 13 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 src/plugins/android/androidrunnable.cpp diff --git a/src/plugins/android/android.pro b/src/plugins/android/android.pro index 6fffdcc081a..00deb37e067 100644 --- a/src/plugins/android/android.pro +++ b/src/plugins/android/android.pro @@ -89,7 +89,8 @@ SOURCES += \ avddialog.cpp \ androidbuildapkstep.cpp \ androidbuildapkwidget.cpp \ - androidqtsupport.cpp + androidqtsupport.cpp \ + androidrunnable.cpp FORMS += \ androidsettingswidget.ui \ diff --git a/src/plugins/android/android.qbs b/src/plugins/android/android.qbs index 4251bd023b8..df9c12c5daa 100644 --- a/src/plugins/android/android.qbs +++ b/src/plugins/android/android.qbs @@ -76,6 +76,7 @@ QtcPlugin { "androidruncontrol.h", "androidrunfactories.cpp", "androidrunfactories.h", + "androidrunnable.cpp", "androidrunnable.h", "androidrunner.cpp", "androidrunner.h", diff --git a/src/plugins/android/androiddevice.cpp b/src/plugins/android/androiddevice.cpp index 6f9b11ba1d3..83ced224e8a 100644 --- a/src/plugins/android/androiddevice.cpp +++ b/src/plugins/android/androiddevice.cpp @@ -27,6 +27,8 @@ #include "androidconstants.h" #include "androidsignaloperation.h" +#include + #include using namespace ProjectExplorer; diff --git a/src/plugins/android/androidrunnable.cpp b/src/plugins/android/androidrunnable.cpp new file mode 100644 index 00000000000..f91d7cf63e1 --- /dev/null +++ b/src/plugins/android/androidrunnable.cpp @@ -0,0 +1,32 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "androidrunnable.h" + +namespace Android { + +void *AndroidRunnable::staticTypeId = &AndroidRunnable::staticTypeId; + +} // namespace Android diff --git a/src/plugins/android/androidrunnable.h b/src/plugins/android/androidrunnable.h index 453807c359e..7ad339a45b2 100644 --- a/src/plugins/android/androidrunnable.h +++ b/src/plugins/android/androidrunnable.h @@ -40,6 +40,8 @@ struct ANDROID_EXPORT AndroidRunnable QVector beforeStartADBCommands; QVector afterFinishADBCommands; QString deviceSerialNumber; + + static void *staticTypeId; }; inline bool operator==(const AndroidRunnable &r1, const AndroidRunnable &r2) diff --git a/src/plugins/debugger/analyzer/analyzerstartparameters.h b/src/plugins/debugger/analyzer/analyzerstartparameters.h index 73226c0e33e..ad385965601 100644 --- a/src/plugins/debugger/analyzer/analyzerstartparameters.h +++ b/src/plugins/debugger/analyzer/analyzerstartparameters.h @@ -42,6 +42,8 @@ public: QString analyzerHost; QString analyzerSocket; quint16 analyzerPort = 0; + + static void *staticTypeId; }; DEBUGGER_EXPORT bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index c44d53ba42e..63ce6b56ff2 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -3834,6 +3834,9 @@ QList DebuggerPlugin::createTestObjects() const #endif // if WITH_TESTS } // namespace Internal + +void *AnalyzerConnection::staticTypeId = &AnalyzerConnection::staticTypeId; + } // namespace Debugger #include "debuggerplugin.moc" diff --git a/src/plugins/projectexplorer/customwizard/customwizard.cpp b/src/plugins/projectexplorer/customwizard/customwizard.cpp index 0471a53cc4c..1156fdd82d2 100644 --- a/src/plugins/projectexplorer/customwizard/customwizard.cpp +++ b/src/plugins/projectexplorer/customwizard/customwizard.cpp @@ -28,8 +28,9 @@ #include "customwizardpage.h" #include "customwizardscriptgenerator.h" -#include #include +#include +#include #include #include diff --git a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp index 71ecf037d54..19d89a17099 100644 --- a/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/desktopdevice.cpp @@ -30,6 +30,7 @@ #include "desktopdeviceconfigurationwidget.h" #include "desktopprocesssignaloperation.h" #include +#include #include diff --git a/src/plugins/projectexplorer/devicesupport/idevice.cpp b/src/plugins/projectexplorer/devicesupport/idevice.cpp index b48a6b51eca..72d4df110a6 100644 --- a/src/plugins/projectexplorer/devicesupport/idevice.cpp +++ b/src/plugins/projectexplorer/devicesupport/idevice.cpp @@ -30,6 +30,7 @@ #include "../kit.h" #include "../kitinformation.h" +#include "../runnables.h" #include #include @@ -466,4 +467,6 @@ DeviceEnvironmentFetcher::DeviceEnvironmentFetcher() { } +void *HostName::staticTypeId = &HostName::staticTypeId; + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/runconfiguration.h b/src/plugins/projectexplorer/runconfiguration.h index c5b6e2f82f2..01fe5b9af4b 100644 --- a/src/plugins/projectexplorer/runconfiguration.h +++ b/src/plugins/projectexplorer/runconfiguration.h @@ -159,6 +159,7 @@ public: virtual ~ClonableConcept() = default; virtual ClonableConcept *clone() const = 0; virtual bool equals(const std::unique_ptr &other) const = 0; + virtual void *typeId() const = 0; }; template @@ -168,11 +169,14 @@ public: ClonableModel(const T &data) : m_data(data) { } ~ClonableModel() Q_DECL_NOEXCEPT { } // gcc 4.7.3 ClonableConcept *clone() const override { return new ClonableModel(*this); } + void *typeId() const { return T::staticTypeId; } bool equals(const std::unique_ptr &other) const override { - auto that = dynamic_cast *>(other.get()); - return that && m_data == that->m_data; + if (other->typeId() != typeId()) + return false; + auto that = static_cast *>(other.get()); + return m_data == that->m_data; } T m_data; @@ -189,7 +193,7 @@ public: void operator=(Runnable other) { d = std::move(other.d); } template bool is() const { - return dynamic_cast *>(d.get()) != 0; + return d.get()->typeId() == T::staticTypeId; } template const T &as() const { @@ -213,7 +217,7 @@ public: void operator=(Connection other) { d = std::move(other.d); } template bool is() const { - return dynamic_cast *>(d.get()) != 0; + return d.get()->typeId() == T::staticTypeId; } template const T &as() const { diff --git a/src/plugins/projectexplorer/runnables.cpp b/src/plugins/projectexplorer/runnables.cpp index c05b0a4c12e..a8c9be4aad2 100644 --- a/src/plugins/projectexplorer/runnables.cpp +++ b/src/plugins/projectexplorer/runnables.cpp @@ -35,4 +35,6 @@ bool operator==(const StandardRunnable &r1, const StandardRunnable &r2) && r1.environment == r2.environment; } +void *StandardRunnable::staticTypeId = &StandardRunnable::staticTypeId; + } // namespace ProjectExplorer diff --git a/src/plugins/projectexplorer/runnables.h b/src/plugins/projectexplorer/runnables.h index 3949b80a0b5..258b45ea797 100644 --- a/src/plugins/projectexplorer/runnables.h +++ b/src/plugins/projectexplorer/runnables.h @@ -43,8 +43,22 @@ public: Utils::Environment environment; ApplicationLauncher::Mode runMode = ApplicationLauncher::Gui; IDevice::ConstPtr device; // Override the kit's device. Keep unset by default. + + static void *staticTypeId; }; PROJECTEXPLORER_EXPORT bool operator==(const StandardRunnable &r1, const StandardRunnable &r2); +class PROJECTEXPLORER_EXPORT HostName +{ +public: + explicit HostName(const QString &host) : m_host(host) {} + QString host() const { return m_host; } + + static void *staticTypeId; + +private: + QString m_host; +}; + } // namespace ProjectExplorer