diff options
author | Qt Continuous Integration System <qt-info@nokia.com> | 2010-04-07 08:57:12 (GMT) |
---|---|---|
committer | Qt Continuous Integration System <qt-info@nokia.com> | 2010-04-07 08:57:12 (GMT) |
commit | a113de78774cebb53d0571b9e567ddee10acee78 (patch) | |
tree | 5a52362a3db8d94b9f65a0af0a2511e28adffc2c | |
parent | 7327d31b4e20bd4b3e3bad95c2fba3eb7a548dbb (diff) | |
parent | 71df6edab122730c38ac238e168a4cc35b6f4857 (diff) | |
download | Qt-a113de78774cebb53d0571b9e567ddee10acee78.zip Qt-a113de78774cebb53d0571b9e567ddee10acee78.tar.gz Qt-a113de78774cebb53d0571b9e567ddee10acee78.tar.bz2 |
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/qt-s60-public into 4.6-integration
* '4.6' of scm.dev.nokia.troll.no:qt/qt-s60-public:
QTBUG-4887 and other exception safety fixes
-rw-r--r-- | src/gui/image/qimage.cpp | 6 | ||||
-rw-r--r-- | src/gui/kernel/qapplication_s60.cpp | 9 | ||||
-rw-r--r-- | src/gui/kernel/qwidget.cpp | 8 | ||||
-rw-r--r-- | src/gui/widgets/qmenu.cpp | 14 | ||||
-rw-r--r-- | tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp | 19 |
5 files changed, 45 insertions, 11 deletions
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 4f5efa1..5d2b4c0 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -5667,7 +5667,11 @@ void QImage::setAlphaChannel(const QImage &alphaChannel) detach(); - *this = convertToFormat(QImage::Format_ARGB32_Premultiplied); + QImage converted = convertToFormat(QImage::Format_ARGB32_Premultiplied); + if (!converted.isNull()) + *this = converted; + else + return; // Slight optimization since alphachannels are returned as 8-bit grays. if (alphaChannel.d->depth == 8 && alphaChannel.isGrayscale()) { diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 37d1b62..e986ce9 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -372,8 +372,13 @@ QSymbianControl::~QSymbianControl() { if (S60->curWin == this) S60->curWin = 0; - if (!QApplicationPrivate::is_app_closing) - setFocusSafely(false); + if (!QApplicationPrivate::is_app_closing) { + QT_TRY { + setFocusSafely(false); + } QT_CATCH(const std::exception&) { + // ignore exceptions, nothing can be done + } + } S60->appUi()->RemoveFromStack(this); delete m_longTapDetector; } diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index cd943cd..e180001 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1487,8 +1487,12 @@ QWidget::~QWidget() if (QWidgetPrivate::allWidgets) // might have been deleted by ~QApplication QWidgetPrivate::allWidgets->remove(this); - QEvent e(QEvent::Destroy); - QCoreApplication::sendEvent(this, &e); + QT_TRY { + QEvent e(QEvent::Destroy); + QCoreApplication::sendEvent(this, &e); + } QT_CATCH(const std::exception&) { + // if this fails we can't do anything about it but at least we are not allowed to throw. + } } int QWidgetPrivate::instanceCounter = 0; // Current number of widget instances diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index a9978f9..c7573bf 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1406,12 +1406,14 @@ QMenu::QMenu(QMenuPrivate &dd, QWidget *parent) QMenu::~QMenu() { Q_D(QMenu); - QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin(); - for (; it != d->widgetItems.end(); ++it) { - if (QWidget *widget = it.value()) { - QWidgetAction *action = static_cast<QWidgetAction *>(it.key()); - action->releaseWidget(widget); - *it = 0; + if (!d->widgetItems.isEmpty()) { // avoid detach on shared null hash + QHash<QAction *, QWidget *>::iterator it = d->widgetItems.begin(); + for (; it != d->widgetItems.end(); ++it) { + if (QWidget *widget = it.value()) { + QWidgetAction *action = static_cast<QWidgetAction *>(it.key()); + action->releaseWidget(widget); + *it = 0; + } } } diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index 4433c7a..91d1a44 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -43,6 +43,7 @@ #include <QtTest/QtTest> #include <stddef.h> +#include <exception> QT_USE_NAMESPACE @@ -285,8 +286,26 @@ void tst_ExceptionSafetyObjects::safeMessageHandler(QtMsgType type, const char * allocFailer.reactivateAt(currentIndex); } +typedef void (*PVF)(); +PVF defaultTerminate; +void debugTerminate() +{ + // you can detect uncaught exceptions with a breakpoint in here + (*defaultTerminate)(); +} + +PVF defaultUnexpected; +void debugUnexpected() +{ + // you can detect unexpected exceptions with a breakpoint in here + (*defaultUnexpected)(); +} + void tst_ExceptionSafetyObjects::initTestCase() { + // set handlers for bad exception cases, you might want to step in and breakpoint the default handlers too + defaultTerminate = std::set_terminate(&debugTerminate); + defaultUnexpected = std::set_unexpected(&debugUnexpected); testMessageHandler = qInstallMsgHandler(safeMessageHandler); QVERIFY(AllocFailer::initialize()); |