forked from qt-creator/qt-creator
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 <tobias.hunger@qt.io> Reviewed-by: Ralf Nolden <nolden@kde.org> Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -89,7 +89,8 @@ SOURCES += \
|
|||||||
avddialog.cpp \
|
avddialog.cpp \
|
||||||
androidbuildapkstep.cpp \
|
androidbuildapkstep.cpp \
|
||||||
androidbuildapkwidget.cpp \
|
androidbuildapkwidget.cpp \
|
||||||
androidqtsupport.cpp
|
androidqtsupport.cpp \
|
||||||
|
androidrunnable.cpp
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
androidsettingswidget.ui \
|
androidsettingswidget.ui \
|
||||||
|
@@ -76,6 +76,7 @@ QtcPlugin {
|
|||||||
"androidruncontrol.h",
|
"androidruncontrol.h",
|
||||||
"androidrunfactories.cpp",
|
"androidrunfactories.cpp",
|
||||||
"androidrunfactories.h",
|
"androidrunfactories.h",
|
||||||
|
"androidrunnable.cpp",
|
||||||
"androidrunnable.h",
|
"androidrunnable.h",
|
||||||
"androidrunner.cpp",
|
"androidrunner.cpp",
|
||||||
"androidrunner.h",
|
"androidrunner.h",
|
||||||
|
@@ -27,6 +27,8 @@
|
|||||||
#include "androidconstants.h"
|
#include "androidconstants.h"
|
||||||
#include "androidsignaloperation.h"
|
#include "androidsignaloperation.h"
|
||||||
|
|
||||||
|
#include <projectexplorer/runnables.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
|
32
src/plugins/android/androidrunnable.cpp
Normal file
32
src/plugins/android/androidrunnable.cpp
Normal file
@@ -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
|
@@ -40,6 +40,8 @@ struct ANDROID_EXPORT AndroidRunnable
|
|||||||
QVector<QStringList> beforeStartADBCommands;
|
QVector<QStringList> beforeStartADBCommands;
|
||||||
QVector<QStringList> afterFinishADBCommands;
|
QVector<QStringList> afterFinishADBCommands;
|
||||||
QString deviceSerialNumber;
|
QString deviceSerialNumber;
|
||||||
|
|
||||||
|
static void *staticTypeId;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const AndroidRunnable &r1, const AndroidRunnable &r2)
|
inline bool operator==(const AndroidRunnable &r1, const AndroidRunnable &r2)
|
||||||
|
@@ -42,6 +42,8 @@ public:
|
|||||||
QString analyzerHost;
|
QString analyzerHost;
|
||||||
QString analyzerSocket;
|
QString analyzerSocket;
|
||||||
quint16 analyzerPort = 0;
|
quint16 analyzerPort = 0;
|
||||||
|
|
||||||
|
static void *staticTypeId;
|
||||||
};
|
};
|
||||||
|
|
||||||
DEBUGGER_EXPORT bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2);
|
DEBUGGER_EXPORT bool operator==(const AnalyzerConnection &c1, const AnalyzerConnection &c2);
|
||||||
|
@@ -3834,6 +3834,9 @@ QList<QObject *> DebuggerPlugin::createTestObjects() const
|
|||||||
#endif // if WITH_TESTS
|
#endif // if WITH_TESTS
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
|
void *AnalyzerConnection::staticTypeId = &AnalyzerConnection::staticTypeId;
|
||||||
|
|
||||||
} // namespace Debugger
|
} // namespace Debugger
|
||||||
|
|
||||||
#include "debuggerplugin.moc"
|
#include "debuggerplugin.moc"
|
||||||
|
@@ -28,8 +28,9 @@
|
|||||||
#include "customwizardpage.h"
|
#include "customwizardpage.h"
|
||||||
#include "customwizardscriptgenerator.h"
|
#include "customwizardscriptgenerator.h"
|
||||||
|
|
||||||
#include <projectexplorer/projectexplorer.h>
|
|
||||||
#include <projectexplorer/baseprojectwizarddialog.h>
|
#include <projectexplorer/baseprojectwizarddialog.h>
|
||||||
|
#include <projectexplorer/projectexplorer.h>
|
||||||
|
#include <projectexplorer/runconfiguration.h>
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
#include <coreplugin/messagemanager.h>
|
#include <coreplugin/messagemanager.h>
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "desktopdeviceconfigurationwidget.h"
|
#include "desktopdeviceconfigurationwidget.h"
|
||||||
#include "desktopprocesssignaloperation.h"
|
#include "desktopprocesssignaloperation.h"
|
||||||
#include <projectexplorer/projectexplorerconstants.h>
|
#include <projectexplorer/projectexplorerconstants.h>
|
||||||
|
#include <projectexplorer/runnables.h>
|
||||||
|
|
||||||
#include <ssh/sshconnection.h>
|
#include <ssh/sshconnection.h>
|
||||||
|
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include "../kit.h"
|
#include "../kit.h"
|
||||||
#include "../kitinformation.h"
|
#include "../kitinformation.h"
|
||||||
|
#include "../runnables.h"
|
||||||
|
|
||||||
#include <ssh/sshconnection.h>
|
#include <ssh/sshconnection.h>
|
||||||
#include <utils/portlist.h>
|
#include <utils/portlist.h>
|
||||||
@@ -466,4 +467,6 @@ DeviceEnvironmentFetcher::DeviceEnvironmentFetcher()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *HostName::staticTypeId = &HostName::staticTypeId;
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -159,6 +159,7 @@ public:
|
|||||||
virtual ~ClonableConcept() = default;
|
virtual ~ClonableConcept() = default;
|
||||||
virtual ClonableConcept *clone() const = 0;
|
virtual ClonableConcept *clone() const = 0;
|
||||||
virtual bool equals(const std::unique_ptr<ClonableConcept> &other) const = 0;
|
virtual bool equals(const std::unique_ptr<ClonableConcept> &other) const = 0;
|
||||||
|
virtual void *typeId() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -168,11 +169,14 @@ public:
|
|||||||
ClonableModel(const T &data) : m_data(data) { }
|
ClonableModel(const T &data) : m_data(data) { }
|
||||||
~ClonableModel() Q_DECL_NOEXCEPT { } // gcc 4.7.3
|
~ClonableModel() Q_DECL_NOEXCEPT { } // gcc 4.7.3
|
||||||
ClonableConcept *clone() const override { return new ClonableModel(*this); }
|
ClonableConcept *clone() const override { return new ClonableModel(*this); }
|
||||||
|
void *typeId() const { return T::staticTypeId; }
|
||||||
|
|
||||||
bool equals(const std::unique_ptr<ClonableConcept> &other) const override
|
bool equals(const std::unique_ptr<ClonableConcept> &other) const override
|
||||||
{
|
{
|
||||||
auto that = dynamic_cast<const ClonableModel<T> *>(other.get());
|
if (other->typeId() != typeId())
|
||||||
return that && m_data == that->m_data;
|
return false;
|
||||||
|
auto that = static_cast<const ClonableModel<T> *>(other.get());
|
||||||
|
return m_data == that->m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
T m_data;
|
T m_data;
|
||||||
@@ -189,7 +193,7 @@ public:
|
|||||||
void operator=(Runnable other) { d = std::move(other.d); }
|
void operator=(Runnable other) { d = std::move(other.d); }
|
||||||
|
|
||||||
template <class T> bool is() const {
|
template <class T> bool is() const {
|
||||||
return dynamic_cast<ClonableModel<T> *>(d.get()) != 0;
|
return d.get()->typeId() == T::staticTypeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> const T &as() const {
|
template <class T> const T &as() const {
|
||||||
@@ -213,7 +217,7 @@ public:
|
|||||||
void operator=(Connection other) { d = std::move(other.d); }
|
void operator=(Connection other) { d = std::move(other.d); }
|
||||||
|
|
||||||
template <class T> bool is() const {
|
template <class T> bool is() const {
|
||||||
return dynamic_cast<ClonableModel<T> *>(d.get()) != 0;
|
return d.get()->typeId() == T::staticTypeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T> const T &as() const {
|
template <class T> const T &as() const {
|
||||||
|
@@ -35,4 +35,6 @@ bool operator==(const StandardRunnable &r1, const StandardRunnable &r2)
|
|||||||
&& r1.environment == r2.environment;
|
&& r1.environment == r2.environment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *StandardRunnable::staticTypeId = &StandardRunnable::staticTypeId;
|
||||||
|
|
||||||
} // namespace ProjectExplorer
|
} // namespace ProjectExplorer
|
||||||
|
@@ -43,8 +43,22 @@ public:
|
|||||||
Utils::Environment environment;
|
Utils::Environment environment;
|
||||||
ApplicationLauncher::Mode runMode = ApplicationLauncher::Gui;
|
ApplicationLauncher::Mode runMode = ApplicationLauncher::Gui;
|
||||||
IDevice::ConstPtr device; // Override the kit's device. Keep unset by default.
|
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);
|
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
|
} // namespace ProjectExplorer
|
||||||
|
Reference in New Issue
Block a user