diff options
author | Jason Barron <jbarron@trolltech.com> | 2009-08-04 11:17:47 (GMT) |
---|---|---|
committer | Jason Barron <jbarron@trolltech.com> | 2009-08-04 11:17:47 (GMT) |
commit | be212bf108e71ba3b5b75802b1f4de6613ba315c (patch) | |
tree | c541ad12e8698f04e8fe386c2e1b94e8baca6c1b /src/corelib | |
parent | 67ae1b0dac175f48875507f3187ed49276a29ddf (diff) | |
parent | e6bb00250b321b149dd80259dc4f479088d5949b (diff) | |
download | Qt-be212bf108e71ba3b5b75802b1f4de6613ba315c.zip Qt-be212bf108e71ba3b5b75802b1f4de6613ba315c.tar.gz Qt-be212bf108e71ba3b5b75802b1f4de6613ba315c.tar.bz2 |
Merge commit 'origin/master'
Conflicts:
src/corelib/global/qglobal.h
src/corelib/kernel/qmetatype.cpp
src/corelib/kernel/qobject.cpp
src/corelib/thread/qthread_unix.cpp
src/gui/graphicsview/qgraphicssceneevent.h
src/gui/itemviews/qheaderview.h
src/gui/kernel/qapplication_qws.cpp
src/gui/kernel/qgesture.h
src/gui/kernel/qgesturerecognizer.h
src/gui/painting/qpaintengine_raster.cpp
src/network/access/qhttpnetworkreply.cpp
src/network/access/qnetworkcookie.h
src/network/socket/qnativesocketengine_unix.cpp
Diffstat (limited to 'src/corelib')
84 files changed, 536 insertions, 292 deletions
diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index e4b1fcc..8da0935 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -125,7 +125,7 @@ protected: private: Q_DISABLE_COPY(QAbstractAnimation) - Q_DECLARE_PRIVATE(QAbstractAnimation) + Q_DECLARE_SCOPED_PRIVATE(QAbstractAnimation) }; #endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qanimationgroup.h b/src/corelib/animation/qanimationgroup.h index 93c6fb1..5b07524 100644 --- a/src/corelib/animation/qanimationgroup.h +++ b/src/corelib/animation/qanimationgroup.h @@ -76,7 +76,7 @@ protected: private: Q_DISABLE_COPY(QAnimationGroup) - Q_DECLARE_PRIVATE(QAnimationGroup) + Q_DECLARE_SCOPED_PRIVATE(QAnimationGroup) }; #endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qparallelanimationgroup.h b/src/corelib/animation/qparallelanimationgroup.h index 07808f1..8422102 100644 --- a/src/corelib/animation/qparallelanimationgroup.h +++ b/src/corelib/animation/qparallelanimationgroup.h @@ -73,7 +73,7 @@ protected: private: Q_DISABLE_COPY(QParallelAnimationGroup) - Q_DECLARE_PRIVATE(QParallelAnimationGroup) + Q_DECLARE_SCOPED_PRIVATE(QParallelAnimationGroup) Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) }; diff --git a/src/corelib/animation/qpauseanimation.h b/src/corelib/animation/qpauseanimation.h index 6907d0a..b84e940 100644 --- a/src/corelib/animation/qpauseanimation.h +++ b/src/corelib/animation/qpauseanimation.h @@ -72,7 +72,7 @@ protected: private: Q_DISABLE_COPY(QPauseAnimation) - Q_DECLARE_PRIVATE(QPauseAnimation) + Q_DECLARE_SCOPED_PRIVATE(QPauseAnimation) }; #endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qpropertyanimation.h b/src/corelib/animation/qpropertyanimation.h index e07444c..6631f67 100644 --- a/src/corelib/animation/qpropertyanimation.h +++ b/src/corelib/animation/qpropertyanimation.h @@ -78,7 +78,7 @@ protected: private: Q_PRIVATE_SLOT(d_func(), void _q_targetDestroyed()) Q_DISABLE_COPY(QPropertyAnimation) - Q_DECLARE_PRIVATE(QPropertyAnimation) + Q_DECLARE_SCOPED_PRIVATE(QPropertyAnimation) }; #endif //QT_NO_ANIMATION diff --git a/src/corelib/animation/qsequentialanimationgroup.h b/src/corelib/animation/qsequentialanimationgroup.h index 5d43356..81a7ff5 100644 --- a/src/corelib/animation/qsequentialanimationgroup.h +++ b/src/corelib/animation/qsequentialanimationgroup.h @@ -83,7 +83,7 @@ protected: private: Q_DISABLE_COPY(QSequentialAnimationGroup) - Q_DECLARE_PRIVATE(QSequentialAnimationGroup) + Q_DECLARE_SCOPED_PRIVATE(QSequentialAnimationGroup) Q_PRIVATE_SLOT(d_func(), void _q_uncontrolledAnimationFinished()) }; diff --git a/src/corelib/animation/qvariantanimation.h b/src/corelib/animation/qvariantanimation.h index 3e397ca..8c75fc1 100644 --- a/src/corelib/animation/qvariantanimation.h +++ b/src/corelib/animation/qvariantanimation.h @@ -113,7 +113,7 @@ private: static void registerInterpolator(Interpolator func, int interpolationType); Q_DISABLE_COPY(QVariantAnimation) - Q_DECLARE_PRIVATE(QVariantAnimation) + Q_DECLARE_SCOPED_PRIVATE(QVariantAnimation) }; template <typename T> diff --git a/src/corelib/arch/symbian/qatomic_symbian.cpp b/src/corelib/arch/symbian/qatomic_symbian.cpp index 170b737..a228696 100644 --- a/src/corelib/arch/symbian/qatomic_symbian.cpp +++ b/src/corelib/arch/symbian/qatomic_symbian.cpp @@ -42,6 +42,37 @@ #include <QtCore/qglobal.h> #include <QtCore/qatomic.h> +#include <e32debug.h> + +// Heap and handle info printer. This code is placed here as it happens to make it the very last static to be destroyed in a Qt app. +// This way we can report on heap cells and handles that are really not owned by anything which still exists. +// This information can be used to detect whether memory leaks are happening, particularly if these numbers grow as the app is used more. +struct SPrintExitInfo +{ + SPrintExitInfo() + { + RThread().HandleCount(initProcessHandleCount,initThreadHandleCount); + initCells = User::CountAllocCells(); + } + ~SPrintExitInfo() + { + RProcess myProc; + TFullName fullName = myProc.FileName(); + TInt cells = User::CountAllocCells(); + TInt processHandleCount=0; + TInt threadHandleCount=0; + RThread().HandleCount(processHandleCount,threadHandleCount); + RDebug::Print(_L("%S exiting with %d allocated cells, %d handles"), + &fullName, + cells - initCells, + (processHandleCount + threadHandleCount) - (initProcessHandleCount + initThreadHandleCount)); + } + TInt initCells; + TInt initProcessHandleCount; + TInt initThreadHandleCount; +} printExitInfo; + + #if defined(Q_CC_RVCT) #include "../arm/qatomic_arm.cpp" @@ -76,4 +107,3 @@ __declspec(dllexport) __asm int QBasicAtomicInt::fetchAndStoreOrdered(int newVal QT_END_NAMESPACE #endif // Q_CC_RVCT - diff --git a/src/corelib/concurrent/qfuturewatcher.h b/src/corelib/concurrent/qfuturewatcher.h index 04d5680..948ecca 100644 --- a/src/corelib/concurrent/qfuturewatcher.h +++ b/src/corelib/concurrent/qfuturewatcher.h @@ -59,7 +59,7 @@ class QFutureWatcherBasePrivate; class Q_CORE_EXPORT QFutureWatcherBase : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QFutureWatcherBase) + Q_DECLARE_SCOPED_PRIVATE(QFutureWatcherBase) public: QFutureWatcherBase(QObject *parent = 0); diff --git a/src/corelib/concurrent/qthreadpool.h b/src/corelib/concurrent/qthreadpool.h index 0ddefd1..dddf962 100644 --- a/src/corelib/concurrent/qthreadpool.h +++ b/src/corelib/concurrent/qthreadpool.h @@ -58,7 +58,7 @@ class QThreadPoolPrivate; class Q_CORE_EXPORT QThreadPool : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QThreadPool) + Q_DECLARE_SCOPED_PRIVATE(QThreadPool) Q_PROPERTY(int expiryTimeout READ expiryTimeout WRITE setExpiryTimeout) Q_PROPERTY(int maxThreadCount READ maxThreadCount WRITE setMaxThreadCount) Q_PROPERTY(int activeThreadCount READ activeThreadCount) diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 375f4aa..a6901d9 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1903,6 +1903,15 @@ QSysInfo::SymVersion QSysInfo::symbianVersion() */ /*! + T *q_check_ptr(T *pointer) + \relates <QtGlobal> + + Users Q_CHECK_PTR on \a pointer, then returns \a pointer. + + This can be used as an inline version of Q_CHECK_PTR. +*/ + +/*! \macro const char* Q_FUNC_INFO() \relates <QtGlobal> @@ -2086,8 +2095,8 @@ QString qt_error_string(int errorCode) warnings, critical and fatal error messages. The Qt library (debug mode) contains hundreds of warning messages that are printed when internal errors (usually invalid function arguments) - occur. Qt built in release mode also contains such warnings unless - QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during + occur. Qt built in release mode also contains such warnings unless + QT_NO_WARNING_OUTPUT and/or QT_NO_DEBUG_OUTPUT have been set during compilation. If you implement your own message handler, you get total control of these messages. @@ -2142,7 +2151,7 @@ void qt_message_output(QtMsgType msgType, const char *buf) _LIT(format, "[Qt Message] %S"); const int maxBlockSize = 256 - ((const TDesC &)format).Length(); const TPtrC8 ptr(reinterpret_cast<const TUint8*>(buf)); - HBufC* hbuffer = HBufC::NewL(qMin(maxBlockSize, ptr.Length())); + HBufC* hbuffer = q_check_ptr(HBufC::New(qMin(maxBlockSize, ptr.Length()))); for (int i = 0; i < ptr.Length(); i += hbuffer->Length()) { hbuffer->Des().Copy(ptr.Mid(i, qMin(maxBlockSize, ptr.Length()-i))); RDebug::Print(format, hbuffer); @@ -2444,7 +2453,11 @@ bool qputenv(const char *varName, const QByteArray& value) QByteArray buffer(varName); buffer += '='; buffer += value; - return putenv(qstrdup(buffer.constData())) == 0; + char* envVar = qstrdup(buffer.constData()); + int result = putenv(envVar); + if (result != 0) // error. we have to delete the string. + delete[] envVar; + return result == 0; #endif } @@ -2483,7 +2496,7 @@ Q_GLOBAL_STATIC(SeedStorage, randTLS) // Thread Local Storage for seed value */ void qsrand(uint seed) { -#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN) +#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN) SeedStorageType *pseed = randTLS()->localData(); if (!pseed) randTLS()->setLocalData(pseed = new SeedStorageType); @@ -3202,7 +3215,7 @@ bool QInternal::callFunction(InternalFunction func, void **args) Compares the floating point value \a p1 and \a p2 and returns \c true if they are considered equal, otherwise \c false. - Note that comparing values where either \a p1 or \a p2 is 0.0 will not work. + Note that comparing values where either \a p1 or \a p2 is 0.0 will not work. The solution to this is to compare against values greater than or equal to 1.0. \snippet doc/src/snippets/code/src_corelib_global_qglobal.cpp 46 @@ -3267,7 +3280,7 @@ bool QInternal::callFunction(InternalFunction func, void **args) #include <typeinfo> -/*! \macro QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION(function) +/*! \macro QT_TRAP_THROWING(function) \relates <QtGlobal> \ingroup qts60 @@ -3287,14 +3300,14 @@ bool QInternal::callFunction(InternalFunction func, void **args) CAknTitlePane* titlePane = S60->titlePane(); if (titlePane) { TPtrC captionPtr(qt_QString2TPtrC(caption)); - QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION(titlePane->SetTextL(captionPtr)); + QT_TRAP_THROWING(titlePane->SetTextL(captionPtr)); } \endcode - \sa QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(), QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE() + \sa QT_TRYCATCH_ERROR(), QT_TRYCATCH_LEAVING() */ -/*! \macro QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(error, function) +/*! \macro QT_TRYCATCH_ERROR(error, function) \relates <QtGlobal> \ingroup qts60 @@ -3314,7 +3327,7 @@ bool QInternal::callFunction(InternalFunction func, void **args) { TPtrC name; TInt err; - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(err, name.Set(qt_QString2TPtrC(serverName))); + QT_TRYCATCH_ERROR(err, name.Set(qt_QString2TPtrC(serverName))); if (err != KErrNone) return err; return iServer.Connect(name); @@ -3322,10 +3335,10 @@ bool QInternal::callFunction(InternalFunction func, void **args) \endcode } - \sa QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(), QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION() + \sa QT_TRYCATCH_LEAVING(), QT_TRAP_THROWING() */ -/*! \macro QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(function) +/*! \macro QT_TRYCATCH_LEAVING(function) \relates <QtGlobal> \ingroup qts60 @@ -3345,11 +3358,11 @@ bool QInternal::callFunction(InternalFunction func, void **args) { iStatus = KRequestPending; SetActive(); - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(m_dispatcher->wakeUpWasCalled()); + QT_TRYCATCH_LEAVING(m_dispatcher->wakeUpWasCalled()); } \endcode - \sa QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION(), QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR() + \sa QT_TRAP_THROWING(), QT_TRYCATCH_ERROR() */ #include <stdexcept> @@ -3372,15 +3385,21 @@ public: \warning This function is only available on Symbian. - \sa qt_translateExceptionToSymbianErrorL(), qt_translateExceptionToSymbianError() + \sa qt_exception2SymbianLeaveL(), qt_exception2SymbianError() */ -void qt_translateSymbianErrorToException(int error) +void qt_throwIfError(int error) { if (error >= KErrNone) return; // do nothing - not an exception switch (error) { case KErrNoMemory: throw std::bad_alloc(); + case KErrArgument: + throw std::invalid_argument("from Symbian error"); + case KErrOverflow: + throw std::overflow_error("from Symbian error"); + case KErrUnderflow: + throw std::underflow_error("from Symbian error"); default: throw QSymbianLeaveException(error); } @@ -3393,11 +3412,11 @@ void qt_translateSymbianErrorToException(int error) \warning This function is only available on Symbian. - \sa qt_translateSymbianErrorToException(), qt_translateExceptionToSymbianError() + \sa qt_throwIfError(), qt_exception2SymbianError() */ -void qt_translateExceptionToSymbianErrorL(const std::exception& aThrow) +void qt_exception2SymbianLeaveL(const std::exception& aThrow) { - User::Leave(qt_translateExceptionToSymbianError(aThrow)); + User::Leave(qt_exception2SymbianError(aThrow)); } /*! \relates <QtGlobal> @@ -3407,9 +3426,9 @@ void qt_translateExceptionToSymbianErrorL(const std::exception& aThrow) \warning This function is only available on Symbian. - \sa qt_translateSymbianErrorToException(), qt_translateExceptionToSymbianErrorL() + \sa qt_throwIfError(), qt_exception2SymbianLeaveL() */ -int qt_translateExceptionToSymbianError(const std::exception& aThrow) +int qt_exception2SymbianError(const std::exception& aThrow) { const std::type_info& atype = typeid(aThrow); int err = KErrGeneral; @@ -3418,18 +3437,21 @@ int qt_translateExceptionToSymbianError(const std::exception& aThrow) err = KErrNoMemory; else if(atype == typeid(QSymbianLeaveException)) err = static_cast<const QSymbianLeaveException&>(aThrow).error; - else if(atype == typeid(std::invalid_argument)) - err = KErrArgument; - else if(atype == typeid(std::out_of_range)) - // std::out_of_range is of type logic_error which by definition means that it is - // "presumably detectable before the program executes". - // std::out_of_range is used to report an argument is not within the expected range. - // The description of KErrArgument says an argument is out of range. Hence the mapping. - err = KErrArgument; - else if(atype == typeid(std::overflow_error)) - err = KErrOverflow; - else if(atype == typeid(std::underflow_error)) - err = KErrUnderflow; + else { + if(atype == typeid(std::invalid_argument)) + err = KErrArgument; + else if(atype == typeid(std::out_of_range)) + // std::out_of_range is of type logic_error which by definition means that it is + // "presumably detectable before the program executes". + // std::out_of_range is used to report an argument is not within the expected range. + // The description of KErrArgument says an argument is out of range. Hence the mapping. + err = KErrArgument; + else if(atype == typeid(std::overflow_error)) + err = KErrOverflow; + else if(atype == typeid(std::underflow_error)) + err = KErrUnderflow; + qWarning("translation from std exception \"%s\" to %d", aThrow.what(), err); + } return err; } diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 9013416..dc3667b 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -906,9 +906,9 @@ QT_END_INCLUDE_NAMESPACE */ #ifndef QT_LINUXBASE /* the LSB defines TRUE and FALSE for us */ -/* Symbian OS defines TRUE = 1 and FALSE = 0, +/* Symbian OS defines TRUE = 1 and FALSE = 0, redefine to built-in booleans to make autotests work properly */ -#ifdef Q_OS_SYMBIAN +#ifdef Q_OS_SYMBIAN #undef TRUE #undef FALSE #endif @@ -1651,6 +1651,9 @@ Q_CORE_EXPORT void qBadAlloc(); # define Q_CHECK_PTR(p) do { if (!(p)) qBadAlloc(); } while (0) #endif +template <typename T> +inline T *q_check_ptr(T *p) { Q_CHECK_PTR(p); return p; } + #if (defined(Q_CC_GNU) && !defined(Q_OS_SOLARIS)) || defined(Q_CC_HPACC) || defined(Q_CC_DIAB) # define Q_FUNC_INFO __PRETTY_FUNCTION__ #elif defined(_MSC_VER) @@ -2283,6 +2286,11 @@ inline const QForeachContainer<T> *qForeachContainer(const QForeachContainerBase #endif #define Q_DECLARE_PRIVATE(Class) \ + inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } \ + inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr); } \ + friend class Class##Private; + +#define Q_DECLARE_SCOPED_PRIVATE(Class) \ inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr.data()); } \ inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr.data()); } \ friend class Class##Private; @@ -2390,33 +2398,32 @@ QT_END_NAMESPACE namespace std { class exception; } #endif QT_BEGIN_NAMESPACE -Q_CORE_EXPORT void qt_translateSymbianErrorToException(int error); -Q_CORE_EXPORT void qt_translateExceptionToSymbianErrorL(const std::exception& ex); -Q_CORE_EXPORT int qt_translateExceptionToSymbianError(const std::exception& ex); +Q_CORE_EXPORT void qt_throwIfError(int error); +Q_CORE_EXPORT void qt_exception2SymbianLeaveL(const std::exception& ex); +Q_CORE_EXPORT int qt_exception2SymbianError(const std::exception& ex); -#define QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION(f) \ +#define QT_TRAP_THROWING(_f) \ { \ - TInt error; \ - TRAP(error, f); \ - if (error) \ - qt_translateSymbianErrorToException(error); \ + TInt ____error; \ + TRAP(____error, _f); \ + qt_throwIfError(____error); \ } -#define QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(err, f) \ +#define QT_TRYCATCH_ERROR(_err, _f) \ { \ - err = KErrNone; \ + _err = KErrNone; \ try { \ - f; \ - } catch (const std::exception &ex) { \ - err = qt_translateExceptionToSymbianError(ex); \ + _f; \ + } catch (const std::exception &____ex) { \ + _err = qt_exception2SymbianError(____ex); \ } \ } -#define QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(f) \ +#define QT_TRYCATCH_LEAVING(_f) \ { \ - TInt err; \ - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(err, f) \ - User::LeaveIfError(err); \ + TInt ____err; \ + QT_TRYCATCH_ERROR(____err, _f) \ + User::LeaveIfError(____err); \ } #endif diff --git a/src/corelib/io/qabstractfileengine.h b/src/corelib/io/qabstractfileengine.h index 54eb6de..07c92d2 100644 --- a/src/corelib/io/qabstractfileengine.h +++ b/src/corelib/io/qabstractfileengine.h @@ -196,7 +196,7 @@ protected: QScopedPointer<QAbstractFileEnginePrivate> d_ptr; private: - Q_DECLARE_PRIVATE(QAbstractFileEngine) + Q_DECLARE_SCOPED_PRIVATE(QAbstractFileEngine) Q_DISABLE_COPY(QAbstractFileEngine) }; diff --git a/src/corelib/io/qbuffer.h b/src/corelib/io/qbuffer.h index e078d05..ce5f605 100644 --- a/src/corelib/io/qbuffer.h +++ b/src/corelib/io/qbuffer.h @@ -96,7 +96,7 @@ protected: qint64 writeData(const char *data, qint64 len); private: - Q_DECLARE_PRIVATE(QBuffer) + Q_DECLARE_SCOPED_PRIVATE(QBuffer) Q_DISABLE_COPY(QBuffer) Q_PRIVATE_SLOT(d_func(), void _q_emitSignals()) diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index edbe5f0..836fa44 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -86,7 +86,7 @@ class QDirPrivate QDir *q_ptr; Q_DECLARE_PUBLIC(QDir) - friend class QScopedPointer<QDirPrivate>; + friend class QScopedPointerDeleter<QDirPrivate>; protected: QDirPrivate(QDir*, const QDir *copy=0); ~QDirPrivate(); @@ -288,10 +288,10 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, names->append(l.at(i).fileName()); } } else { - QDirSortItem *si = new QDirSortItem[n]; + QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]); for (int i = 0; i < n; ++i) si[i].item = l.at(i); - qSort(si, si+n, QDirSortItemComparator(sort)); + qSort(si.data(), si.data()+n, QDirSortItemComparator(sort)); // put them back in the list(s) if(infos) { for (int i = 0; i < n; ++i) @@ -301,7 +301,6 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l, for (int i = 0; i < n; ++i) names->append(si[i].item.fileName()); } - delete [] si; } } } @@ -334,8 +333,9 @@ void QDirPrivate::detach(bool createFileEngine) { qAtomicDetach(data); if (createFileEngine) { + QAbstractFileEngine *newFileEngine = QAbstractFileEngine::create(data->path); delete data->fileEngine; - data->fileEngine = QAbstractFileEngine::create(data->path); + data->fileEngine = newFileEngine; } } @@ -1824,7 +1824,7 @@ QChar QDir::separator() { #if defined (Q_FS_FAT) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN) return QLatin1Char('\\'); -#elif defined(Q_OS_UNIX) +#elif defined(Q_OS_UNIX) return QLatin1Char('/'); #elif defined (Q_OS_MAC) return QLatin1Char(':'); diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index f54fbdc..5ef4356 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -60,7 +60,7 @@ class Q_CORE_EXPORT QDir protected: QScopedPointer<QDirPrivate> d_ptr; private: - Q_DECLARE_PRIVATE(QDir) + Q_DECLARE_SCOPED_PRIVATE(QDir) public: enum Filter { Dirs = 0x001, Files = 0x002, diff --git a/src/corelib/io/qfile.h b/src/corelib/io/qfile.h index f448609..24ce617 100644 --- a/src/corelib/io/qfile.h +++ b/src/corelib/io/qfile.h @@ -64,7 +64,7 @@ class Q_CORE_EXPORT QFile : public QIODevice #ifndef QT_NO_QOBJECT Q_OBJECT #endif - Q_DECLARE_PRIVATE(QFile) + Q_DECLARE_SCOPED_PRIVATE(QFile) public: diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 5295b16..c73823a 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -168,7 +168,7 @@ public: protected: QScopedPointer<QFileInfoPrivate> d_ptr; private: - Q_DECLARE_PRIVATE(QFileInfo) + Q_DECLARE_SCOPED_PRIVATE(QFileInfo) }; Q_DECLARE_TYPEINFO(QFileInfo, Q_MOVABLE_TYPE); diff --git a/src/corelib/io/qfilesystemwatcher.h b/src/corelib/io/qfilesystemwatcher.h index 60458e5..76a6c60 100644 --- a/src/corelib/io/qfilesystemwatcher.h +++ b/src/corelib/io/qfilesystemwatcher.h @@ -57,7 +57,7 @@ class QFileSystemWatcherPrivate; class Q_CORE_EXPORT QFileSystemWatcher : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QFileSystemWatcher) + Q_DECLARE_SCOPED_PRIVATE(QFileSystemWatcher) public: QFileSystemWatcher(QObject *parent = 0); diff --git a/src/corelib/io/qfilesystemwatcher_symbian.cpp b/src/corelib/io/qfilesystemwatcher_symbian.cpp index aeb19db..c8c1d82 100644 --- a/src/corelib/io/qfilesystemwatcher_symbian.cpp +++ b/src/corelib/io/qfilesystemwatcher_symbian.cpp @@ -80,7 +80,7 @@ void CNotifyChangeEvent::RunL() if (iStatus.Int() == KErrNone){ fsSession.NotifyChange(ENotifyAll, iStatus, watchedPath); SetActive(); - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(engine->emitPathChanged(this)); + QT_TRYCATCH_LEAVING(engine->emitPathChanged(this)); } else { qWarning("CNotifyChangeEvent::RunL() - Failed to order change notifications: %d", iStatus.Int()); } diff --git a/src/corelib/io/qfsfileengine.h b/src/corelib/io/qfsfileengine.h index feca09b..0fd87a4 100644 --- a/src/corelib/io/qfsfileengine.h +++ b/src/corelib/io/qfsfileengine.h @@ -56,7 +56,7 @@ class QFSFileEnginePrivate; class Q_CORE_EXPORT QFSFileEngine : public QAbstractFileEngine { - Q_DECLARE_PRIVATE(QFSFileEngine) + Q_DECLARE_SCOPED_PRIVATE(QFSFileEngine) public: QFSFileEngine(); explicit QFSFileEngine(const QString &file); diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 6c5db5f..fa2aaf7 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -999,11 +999,7 @@ QString QFSFileEngine::fileName(FileName file) const int size = PATH_CHUNK_SIZE; while (1) { - s = (char *) ::realloc(s, size); - if (s == 0) { - len = -1; - break; - } + s = q_check_ptr((char *) ::realloc(s, size)); len = ::readlink(d->nativeFilePath.constData(), s, size); if (len < 0) { ::free(s); diff --git a/src/corelib/io/qiodevice.h b/src/corelib/io/qiodevice.h index 866fa72..d8237a7 100644 --- a/src/corelib/io/qiodevice.h +++ b/src/corelib/io/qiodevice.h @@ -165,7 +165,7 @@ protected: #endif private: - Q_DECLARE_PRIVATE(QIODevice) + Q_DECLARE_SCOPED_PRIVATE(QIODevice) Q_DISABLE_COPY(QIODevice) #ifdef QT3_SUPPORT diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index bff5f7e..a4025a1 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -191,7 +191,7 @@ protected: qint64 writeData(const char *data, qint64 len); private: - Q_DECLARE_PRIVATE(QProcess) + Q_DECLARE_SCOPED_PRIVATE(QProcess) Q_DISABLE_COPY(QProcess) Q_PRIVATE_SLOT(d_func(), bool _q_canReadStandardOutput()) diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index 0bf9660..49dacea 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -94,7 +94,7 @@ protected: QScopedPointer<QResourcePrivate> d_ptr; private: - Q_DECLARE_PRIVATE(QResource) + Q_DECLARE_SCOPED_PRIVATE(QResource) }; QT_END_NAMESPACE diff --git a/src/corelib/io/qresource_p.h b/src/corelib/io/qresource_p.h index f58f9a2..452d8e1 100644 --- a/src/corelib/io/qresource_p.h +++ b/src/corelib/io/qresource_p.h @@ -61,7 +61,7 @@ class QResourceFileEnginePrivate; class QResourceFileEngine : public QAbstractFileEngine { private: - Q_DECLARE_PRIVATE(QResourceFileEngine) + Q_DECLARE_SCOPED_PRIVATE(QResourceFileEngine) public: explicit QResourceFileEngine(const QString &path); ~QResourceFileEngine(); diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 20cd8a7..7df6eee 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -221,6 +221,11 @@ QConfFile::QConfFile(const QString &fileName, bool _userPerms) usedHashFunc()->insert(name, this); } +QConfFile::~QConfFile() +{ + usedHashFunc()->remove(name); +} + ParsedSettingsMap QConfFile::mergedKeyMap() const { ParsedSettingsMap result = originalKeys; @@ -267,7 +272,7 @@ QConfFile *QConfFile::fromName(const QString &fileName, bool _userPerms) ConfFileHash *usedHash = usedHashFunc(); ConfFileCache *unusedCache = unusedCacheFunc(); - QConfFile *confFile; + QConfFile *confFile = 0; QMutexLocker locker(globalMutex()); if (!(confFile = usedHash->value(absPath))) { @@ -1219,12 +1224,11 @@ QConfFileSettingsPrivate::~QConfFileSettingsPrivate() for (int i = 0; i < NumConfFiles; ++i) { if (confFiles[i] && !confFiles[i]->ref.deref()) { - if (usedHash) - usedHash->remove(confFiles[i]->name); - if (confFiles[i]->size == 0) { delete confFiles[i].take(); } else if (unusedCache) { + if (usedHash) + usedHash->remove(confFiles[i]->name); QT_TRY { // compute a better size? unusedCache->insert(confFiles[i]->name, confFiles[i].data(), diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index 0d382b66..a082d6a 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -80,7 +80,7 @@ class Q_CORE_EXPORT QSettings #else QScopedPointer<QSettingsPrivate> d_ptr; #endif - Q_DECLARE_PRIVATE(QSettings) + Q_DECLARE_SCOPED_PRIVATE(QSettings) public: enum Status { diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h index a49a063..883e2fe 100644 --- a/src/corelib/io/qsettings_p.h +++ b/src/corelib/io/qsettings_p.h @@ -149,6 +149,8 @@ inline QString QSettingsGroup::toString() const class Q_AUTOTEST_EXPORT QConfFile { public: + ~QConfFile(); + ParsedSettingsMap mergedKeyMap() const; bool isWritable() const; diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 5dc30c5..235b4f5 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -289,7 +289,7 @@ static int qt_mkstemps(char *path, int slen) //************* QTemporaryFileEngine class QTemporaryFileEngine : public QFSFileEngine { - Q_DECLARE_PRIVATE(QFSFileEngine) + Q_DECLARE_SCOPED_PRIVATE(QFSFileEngine) public: QTemporaryFileEngine(const QString &file, bool fileIsTemplate = true) : QFSFileEngine(file), filePathIsTemplate(fileIsTemplate) @@ -517,7 +517,7 @@ QTemporaryFile::QTemporaryFile() #ifdef Q_OS_SYMBIAN //Just for verify that folder really exist on hardware fileEngine()->mkdir( QDir::tempPath(), true ); -#endif +#endif } /*! diff --git a/src/corelib/io/qtemporaryfile.h b/src/corelib/io/qtemporaryfile.h index a597a93..c0b41bb 100644 --- a/src/corelib/io/qtemporaryfile.h +++ b/src/corelib/io/qtemporaryfile.h @@ -64,7 +64,7 @@ class Q_CORE_EXPORT QTemporaryFile : public QFile #ifndef QT_NO_QOBJECT Q_OBJECT #endif - Q_DECLARE_PRIVATE(QTemporaryFile) + Q_DECLARE_SCOPED_PRIVATE(QTemporaryFile) public: QTemporaryFile(); diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h index fc4794e..9d4b3d0 100644 --- a/src/corelib/io/qtextstream.h +++ b/src/corelib/io/qtextstream.h @@ -72,7 +72,7 @@ class QTextDecoder; class QTextStreamPrivate; class Q_CORE_EXPORT QTextStream // text stream class { - Q_DECLARE_PRIVATE(QTextStream) + Q_DECLARE_SCOPED_PRIVATE(QTextStream) public: enum RealNumberNotation { diff --git a/src/corelib/kernel/qabstracteventdispatcher.h b/src/corelib/kernel/qabstracteventdispatcher.h index 0550dde..93815f6 100644 --- a/src/corelib/kernel/qabstracteventdispatcher.h +++ b/src/corelib/kernel/qabstracteventdispatcher.h @@ -58,7 +58,7 @@ template <typename T1, typename T2> struct QPair; class Q_CORE_EXPORT QAbstractEventDispatcher : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QAbstractEventDispatcher) + Q_DECLARE_SCOPED_PRIVATE(QAbstractEventDispatcher) public: typedef QPair<int, int> TimerInfo; diff --git a/src/corelib/kernel/qabstractitemmodel.h b/src/corelib/kernel/qabstractitemmodel.h index a6bbff4..2503393 100644 --- a/src/corelib/kernel/qabstractitemmodel.h +++ b/src/corelib/kernel/qabstractitemmodel.h @@ -287,7 +287,7 @@ protected: void setRoleNames(const QHash<int,QByteArray> &roleNames); private: - Q_DECLARE_PRIVATE(QAbstractItemModel) + Q_DECLARE_SCOPED_PRIVATE(QAbstractItemModel) Q_DISABLE_COPY(QAbstractItemModel) }; diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp index a3a85b0..c681b1f 100644 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ b/src/corelib/kernel/qcore_symbian_p.cpp @@ -61,13 +61,12 @@ Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString) #else TPtrC16 ptr(qt_QString2TPtrC(aString)); #endif - buffer = HBufC::New(ptr.Length()); - Q_CHECK_PTR(buffer); + buffer = q_check_ptr(HBufC::New(ptr.Length())); buffer->Des().Copy(ptr); return buffer; } -Q_CORE_EXPORT QString qt_TDesC2QStringL(const TDesC& aDescriptor) +Q_CORE_EXPORT QString qt_TDesC2QString(const TDesC& aDescriptor) { #ifdef QT_NO_UNICODE return QString::fromLocal8Bit(aDescriptor.Ptr(), aDescriptor.Length()); @@ -82,9 +81,8 @@ QHBufC::QHBufC() } QHBufC::QHBufC(const QHBufC &src) + : m_hBufC(q_check_ptr(src.m_hBufC->Alloc())) { - m_hBufC = src.m_hBufC->Alloc(); - Q_CHECK_PTR(m_hBufC); } /*! diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index bd8f304..453c3d3 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -65,8 +65,8 @@ QT_BEGIN_NAMESPACE Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString); -Q_CORE_EXPORT QString qt_TDesC2QStringL(const TDesC& aDescriptor); -inline QString qt_TDes2QStringL(const TDes& aDescriptor) { return qt_TDesC2QStringL(aDescriptor); } +Q_CORE_EXPORT QString qt_TDesC2QString(const TDesC& aDescriptor); +inline QString qt_TDes2QString(const TDes& aDescriptor) { return qt_TDesC2QString(aDescriptor); } static inline QSize qt_TSize2QSize(const TSize& ts) { diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index b84ad53..4a1da35 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1119,6 +1119,9 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) event->d = reinterpret_cast<QEventPrivate *>(quintptr(data->loopLevel)); } + // delete the event on exceptions to protect against memory leaks till the event is + // properly owned in the postEventList + QScopedPointer<QEvent> eventDeleter(event); if (data->postEventList.isEmpty() || data->postEventList.last().priority >= priority) { // optimization: we can simply append if the last event in // the queue has higher or equal priority @@ -1133,6 +1136,7 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) QPostEventList::iterator at = qUpperBound(begin, end, priority); data->postEventList.insert(at, QPostEvent(receiver, event, priority)); } + eventDeleter.take(); event->posted = true; ++receiver->d_func()->postedEvents; data->canWait = false; diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 48e65a7..60b0882 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -76,7 +76,7 @@ class Q_CORE_EXPORT QCoreApplication : public QObject Q_PROPERTY(QString organizationName READ organizationName WRITE setOrganizationName) Q_PROPERTY(QString organizationDomain READ organizationDomain WRITE setOrganizationDomain) - Q_DECLARE_PRIVATE(QCoreApplication) + Q_DECLARE_SCOPED_PRIVATE(QCoreApplication) public: QCoreApplication(int &argc, char **argv); ~QCoreApplication(); diff --git a/src/corelib/kernel/qeventdispatcher_glib_p.h b/src/corelib/kernel/qeventdispatcher_glib_p.h index 80ec9fa..bcb655b 100644 --- a/src/corelib/kernel/qeventdispatcher_glib_p.h +++ b/src/corelib/kernel/qeventdispatcher_glib_p.h @@ -67,7 +67,7 @@ class QEventDispatcherGlibPrivate; class Q_CORE_EXPORT QEventDispatcherGlib : public QAbstractEventDispatcher { Q_OBJECT - Q_DECLARE_PRIVATE(QEventDispatcherGlib) + Q_DECLARE_SCOPED_PRIVATE(QEventDispatcherGlib) public: explicit QEventDispatcherGlib(QObject *parent = 0); diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 34a20da..e876843 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -194,7 +194,7 @@ void QWakeUpActiveObject::RunL() { iStatus = KRequestPending; SetActive(); - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(m_dispatcher->wakeUpWasCalled()); + QT_TRYCATCH_LEAVING(m_dispatcher->wakeUpWasCalled()); } QTimerActiveObject::QTimerActiveObject(QEventDispatcherSymbian *dispatcher, SymbianTimerInfo *timerInfo) @@ -224,7 +224,7 @@ void QTimerActiveObject::DoCancel() void QTimerActiveObject::RunL() { int error; - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(error, Run()); + QT_TRYCATCH_ERROR(error, Run()); if (error < 0) { CActiveScheduler::Current()->Error(error); // stop and report here, as this timer will be deleted on scope exit } @@ -274,6 +274,11 @@ void QTimerActiveObject::Start() } } +SymbianTimerInfo::SymbianTimerInfo() +: timerAO(0) +{ +} + SymbianTimerInfo::~SymbianTimerInfo() { delete timerAO; @@ -314,7 +319,7 @@ void QCompleteDeferredAOs::RunL() iStatus = KRequestPending; SetActive(); - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(m_dispatcher->reactivateDeferredActiveObjects()); + QT_TRYCATCH_LEAVING(m_dispatcher->reactivateDeferredActiveObjects()); } QSelectThread::QSelectThread() @@ -587,7 +592,7 @@ void QSocketActiveObject::RunL() if (!okToRun()) return; - QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(m_dispatcher->socketFired(this)); + QT_TRYCATCH_LEAVING(m_dispatcher->socketFired(this)); } void QSocketActiveObject::deleteLater() @@ -619,11 +624,11 @@ QEventDispatcherSymbian::~QEventDispatcherSymbian() void QEventDispatcherSymbian::startingUp() { if( !CActiveScheduler::Current() ) { - m_activeScheduler = new(ELeave)CQtActiveScheduler(); + m_activeScheduler = q_check_ptr(new CQtActiveScheduler()); // CBase derived class needs to be checked on new CActiveScheduler::Install(m_activeScheduler); } - m_wakeUpAO = new(ELeave) QWakeUpActiveObject(this); - m_completeDeferredAOs = new(ELeave) QCompleteDeferredAOs(this); + m_wakeUpAO = q_check_ptr(new QWakeUpActiveObject(this)); + m_completeDeferredAOs = q_check_ptr(new QCompleteDeferredAOs(this)); // We already might have posted events, wakeup once to process them wakeUp(); } @@ -647,7 +652,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla QT_TRY { Q_D(QAbstractEventDispatcher); - + // It is safe if this counter overflows. The main importance is that each // iteration count is different from the last. m_iterationCount++; @@ -742,7 +747,7 @@ bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags fla m_noSocketEvents = oldNoSocketEventsValue; } QT_CATCH (const std::exception& ex) { #ifndef QT_NO_EXCEPTIONS - CActiveScheduler::Current()->Error(qt_translateExceptionToSymbianError(ex)); + CActiveScheduler::Current()->Error(qt_exception2SymbianError(ex)); #endif } @@ -896,7 +901,7 @@ bool QEventDispatcherSymbian::hasPendingEvents() void QEventDispatcherSymbian::registerSocketNotifier ( QSocketNotifier * notifier ) { - QSocketActiveObject *socketAO = new (ELeave) QSocketActiveObject(this, notifier); + QSocketActiveObject *socketAO = q_check_ptr(new QSocketActiveObject(this, notifier)); m_notifiers.insert(notifier, socketAO); m_selectThread.requestSocketEvents(notifier, &socketAO->iStatus); } @@ -930,7 +935,7 @@ void QEventDispatcherSymbian::registerTimer ( int timerId, int interval, QObject timer->inTimerEvent = false; timer->receiver = object; timer->dispatcher = this; - timer->timerAO = new(ELeave) QTimerActiveObject(this, timer.data()); + timer->timerAO = q_check_ptr(new QTimerActiveObject(this, timer.data())); m_timerList.insert(timerId, timer); timer->timerAO->Start(); @@ -952,16 +957,20 @@ bool QEventDispatcherSymbian::unregisterTimer ( int timerId ) bool QEventDispatcherSymbian::unregisterTimers ( QObject * object ) { - QList<TimerInfo> idsToRemove = registeredTimers(object); - - if (idsToRemove.isEmpty()) + if (m_timerList.isEmpty()) return false; - for (int c = 0; c < idsToRemove.size(); ++c) { - unregisterTimer(idsToRemove[c].first); + bool unregistered = false; + for (QHash<int, SymbianTimerInfoPtr>::iterator i = m_timerList.begin(); i != m_timerList.end(); ) { + if ((*i)->receiver == object) { + i = m_timerList.erase(i); + unregistered = true; + } else { + ++i; + } } - return true; + return unregistered; } QList<QEventDispatcherSymbian::TimerInfo> QEventDispatcherSymbian::registeredTimers ( QObject * object ) const @@ -993,4 +1002,3 @@ void CQtActiveScheduler::Error(TInt aError) const } QT_END_NAMESPACE - diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index b39d6df..310d74d 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -112,6 +112,7 @@ private: struct SymbianTimerInfo : public QSharedData { + SymbianTimerInfo(); ~SymbianTimerInfo(); int timerId; @@ -183,7 +184,7 @@ private: class QSelectThread : public QThread { - Q_DECLARE_PRIVATE(QThread) + Q_DECLARE_SCOPED_PRIVATE(QThread) public: QSelectThread(); @@ -217,7 +218,7 @@ public: // from CActiveScheduler class Q_CORE_EXPORT QEventDispatcherSymbian : public QAbstractEventDispatcher { - Q_DECLARE_PRIVATE(QAbstractEventDispatcher) + Q_DECLARE_SCOPED_PRIVATE(QAbstractEventDispatcher) public: QEventDispatcherSymbian(QObject *parent = 0); diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index a52af00..70c287f 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -142,7 +142,7 @@ class QEventDispatcherUNIXPrivate; class Q_CORE_EXPORT QEventDispatcherUNIX : public QAbstractEventDispatcher { Q_OBJECT - Q_DECLARE_PRIVATE(QEventDispatcherUNIX) + Q_DECLARE_SCOPED_PRIVATE(QEventDispatcherUNIX) public: explicit QEventDispatcherUNIX(QObject *parent = 0); diff --git a/src/corelib/kernel/qeventdispatcher_win_p.h b/src/corelib/kernel/qeventdispatcher_win_p.h index ca5dbf8..37578a0 100644 --- a/src/corelib/kernel/qeventdispatcher_win_p.h +++ b/src/corelib/kernel/qeventdispatcher_win_p.h @@ -67,7 +67,7 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp) class Q_CORE_EXPORT QEventDispatcherWin32 : public QAbstractEventDispatcher { Q_OBJECT - Q_DECLARE_PRIVATE(QEventDispatcherWin32) + Q_DECLARE_SCOPED_PRIVATE(QEventDispatcherWin32) void createInternalHwnd(); friend class QGuiEventDispatcherWin32; diff --git a/src/corelib/kernel/qeventloop.h b/src/corelib/kernel/qeventloop.h index 60d00df..e14e352 100644 --- a/src/corelib/kernel/qeventloop.h +++ b/src/corelib/kernel/qeventloop.h @@ -55,7 +55,7 @@ class QEventLoopPrivate; class Q_CORE_EXPORT QEventLoop : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QEventLoop) + Q_DECLARE_SCOPED_PRIVATE(QEventLoop) public: explicit QEventLoop(QObject *parent = 0); diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp index 9ff0bc1..7f8d2e8 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1571,7 +1571,9 @@ bool QMetaMethod::invoke(QObject *object, int nargs = 1; // include return type void **args = (void **) qMalloc(paramCount * sizeof(void *)); + Q_CHECK_PTR(args); int *types = (int *) qMalloc(paramCount * sizeof(int)); + Q_CHECK_PTR(types); types[0] = 0; // return type args[0] = 0; diff --git a/src/corelib/kernel/qmimedata.h b/src/corelib/kernel/qmimedata.h index 609528a..9366c5d 100644 --- a/src/corelib/kernel/qmimedata.h +++ b/src/corelib/kernel/qmimedata.h @@ -94,7 +94,7 @@ protected: QVariant::Type preferredType) const; private: Q_DISABLE_COPY(QMimeData) - Q_DECLARE_PRIVATE(QMimeData) + Q_DECLARE_SCOPED_PRIVATE(QMimeData) }; QT_END_NAMESPACE diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index e849227..2630b63 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -72,6 +72,7 @@ static int DIRECT_CONNECTION_ONLY = 0; static int *queuedConnectionTypes(const QList<QByteArray> &typeNames) { int *types = new int [typeNames.count() + 1]; + Q_CHECK_PTR(types); for (int i = 0; i < typeNames.count(); ++i) { const QByteArray typeName = typeNames.at(i); if (typeName.endsWith('*')) @@ -405,6 +406,10 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o) return; } QMutexLocker locker(guardHashLock()); + if (o) { + hash->insert(o, ptr); + QObjectPrivate::get(o)->hasGuards = true; + } if (*ptr) { bool more = false; //if the QObject has more pointer attached to it. GuardHash::iterator it = hash->find(*ptr); @@ -421,10 +426,6 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o) QObjectPrivate::get(*ptr)->hasGuards = false; } *ptr = o; - if (*ptr) { - hash->insert(*ptr, ptr); - QObjectPrivate::get(*ptr)->hasGuards = true; - } } /*! \internal @@ -685,12 +686,18 @@ QObject::QObject(QObject *parent) : d_ptr(new QObjectPrivate) { Q_D(QObject); - qt_addObject(d_ptr->q_ptr = this); + d_ptr->q_ptr = this; d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current(); d->threadData->ref(); - if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData)) - parent = 0; - setParent(parent); + QT_TRY { + if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData)) + parent = 0; + setParent(parent); + } QT_CATCH(...) { + d->threadData->deref(); + QT_RETHROW; + } + qt_addObject(this); } #ifdef QT3_SUPPORT @@ -720,20 +727,26 @@ QObject::QObject(QObjectPrivate &dd, QObject *parent) : d_ptr(&dd) { Q_D(QObject); - qt_addObject(d_ptr->q_ptr = this); + d_ptr->q_ptr = this; d->threadData = (parent && !parent->thread()) ? parent->d_func()->threadData : QThreadData::current(); d->threadData->ref(); - if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData)) - parent = 0; - if (d->isWidget) { - if (parent) { - d->parent = parent; - d->parent->d_func()->children.append(this); + QT_TRY { + if (!check_parent_thread(parent, parent ? parent->d_func()->threadData : 0, d->threadData)) + parent = 0; + if (d->isWidget) { + if (parent) { + d->parent = parent; + d->parent->d_func()->children.append(this); + } + // no events sent here, this is done at the end of the QWidget constructor + } else { + setParent(parent); } - // no events sent here, this is done at the end of the QWidget constructor - } else { - setParent(parent); + } QT_CATCH(...) { + d->threadData->deref(); + QT_RETHROW; } + qt_addObject(this); } /*! @@ -785,11 +798,26 @@ QObject::~QObject() // all the signal/slots connections are still in place - if we don't // quit now, we will crash pretty soon. qWarning("Detected an unexpected exception in ~QObject while emitting destroyed()."); +#if defined(Q_AUTOTEST_EXPORT) && !defined(QT_NO_EXCEPTIONS) + struct AutotestException : public std::exception + { + const char *what() const throw() { return "autotest swallow"; } + } autotestException; + // throw autotestException; + +#else QT_RETHROW; +#endif } { - QMutexLocker locker(signalSlotLock(this)); + QMutex *signalSlotMutex = 0; + QT_TRY { + signalSlotMutex = signalSlotLock(this); + } QT_CATCH(const std::bad_alloc &) { + // out of memory - swallow to prevent a crash + } + QMutexLocker locker(signalSlotMutex); // set ref to zero to indicate that this object has been deleted if (d->currentSender != 0) @@ -2709,8 +2737,14 @@ bool QObject::disconnect(const QObject *sender, const char *signal, QByteArray signal_name; bool signal_found = false; if (signal) { - signal_name = QMetaObject::normalizedSignature(signal); - signal = signal_name; + QT_TRY { + signal_name = QMetaObject::normalizedSignature(signal); + signal = signal_name.constData(); + } QT_CATCH (const std::bad_alloc &) { + // if the signal is already normalized, we can continue. + if (sender->metaObject()->indexOfSignal(signal + 1) == -1) + QT_RETHROW; + } if (!check_signal_macro(sender, signal, "disconnect", "unbind")) return false; @@ -2722,8 +2756,15 @@ bool QObject::disconnect(const QObject *sender, const char *signal, int membcode = -1; bool method_found = false; if (method) { - method_name = QMetaObject::normalizedSignature(method); - method = method_name; + QT_TRY { + method_name = QMetaObject::normalizedSignature(method); + method = method_name.constData(); + } QT_CATCH(const std::bad_alloc &) { + // if the method is already normalized, we can continue. + if (receiver->metaObject()->indexOfMethod(method + 1) == -1) + QT_RETHROW; + } + membcode = extract_code(method); if (!check_method_code(membcode, receiver, method, "disconnect")) return false; @@ -2882,14 +2923,20 @@ bool QMetaObject::connect(const QObject *sender, int signal_index, c->method = method_index; c->connectionType = type; c->argumentTypes = types; + + QT_TRY { + s->d_func()->addConnection(signal_index, c); + } QT_CATCH(...) { + delete c; + QT_RETHROW; + } + c->prev = &r->d_func()->senders; c->next = *c->prev; *c->prev = c; if (c->next) c->next->prev = &c->next; - s->d_func()->addConnection(signal_index, c); - if (signal_index < 0) { for (uint i = 0; i < (sizeof sender->d_func()->connectedSignals / sizeof sender->d_func()->connectedSignals[0] ); ++i) @@ -3081,7 +3128,9 @@ static void queued_activate(QObject *sender, int signal, QObjectPrivate::Connect while (c->argumentTypes[nargs-1]) ++nargs; int *types = (int *) qMalloc(nargs*sizeof(int)); + Q_CHECK_PTR(types); void **args = (void **) qMalloc(nargs*sizeof(void *)); + Q_CHECK_PTR(args); types[0] = 0; // return type args[0] = 0; // return value for (int n = 1; n < nargs; ++n) diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index a9f005b..200c97d 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -118,7 +118,7 @@ class Q_CORE_EXPORT QObject { Q_OBJECT Q_PROPERTY(QString objectName READ objectName WRITE setObjectName) - Q_DECLARE_PRIVATE(QObject) + Q_DECLARE_SCOPED_PRIVATE(QObject) public: Q_INVOKABLE explicit QObject(QObject *parent=0); diff --git a/src/corelib/kernel/qsharedmemory.h b/src/corelib/kernel/qsharedmemory.h index 4957c3e..0e15ebe 100644 --- a/src/corelib/kernel/qsharedmemory.h +++ b/src/corelib/kernel/qsharedmemory.h @@ -57,7 +57,7 @@ class QSharedMemoryPrivate; class Q_CORE_EXPORT QSharedMemory : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QSharedMemory) + Q_DECLARE_SCOPED_PRIVATE(QSharedMemory) public: enum AccessMode diff --git a/src/corelib/kernel/qsignalmapper.h b/src/corelib/kernel/qsignalmapper.h index 7bc5035..8c1f663 100644 --- a/src/corelib/kernel/qsignalmapper.h +++ b/src/corelib/kernel/qsignalmapper.h @@ -56,7 +56,7 @@ class QSignalMapperPrivate; class Q_CORE_EXPORT QSignalMapper : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QSignalMapper) + Q_DECLARE_SCOPED_PRIVATE(QSignalMapper) public: explicit QSignalMapper(QObject *parent = 0); ~QSignalMapper(); diff --git a/src/corelib/kernel/qsocketnotifier.h b/src/corelib/kernel/qsocketnotifier.h index 96dda35..bc5d97d 100644 --- a/src/corelib/kernel/qsocketnotifier.h +++ b/src/corelib/kernel/qsocketnotifier.h @@ -53,7 +53,7 @@ QT_MODULE(Core) class Q_CORE_EXPORT QSocketNotifier : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QObject) + Q_DECLARE_SCOPED_PRIVATE(QObject) public: enum Type { Read, Write, Exception }; diff --git a/src/corelib/kernel/qsystemsemaphore_symbian.cpp b/src/corelib/kernel/qsystemsemaphore_symbian.cpp index 8179046..1516841 100644 --- a/src/corelib/kernel/qsystemsemaphore_symbian.cpp +++ b/src/corelib/kernel/qsystemsemaphore_symbian.cpp @@ -47,7 +47,7 @@ #include <qcore_symbian_p.h> #include <e32cmn.h> QT_BEGIN_NAMESPACE - + #ifndef QT_NO_SYSTEMSEMAPHORE QSystemSemaphorePrivate::QSystemSemaphorePrivate() : @@ -65,7 +65,7 @@ void QSystemSemaphorePrivate::setErrorString(const QString &function, int err) errorString = QCoreApplication::tr("%1: already exists", "QSystemSemaphore").arg(function); error = QSystemSemaphore::AlreadyExists; break; - case KErrNotFound: + case KErrNotFound: errorString = QCoreApplication::tr("%1: doesn't exists", "QSystemSemaphore").arg(function); error = QSystemSemaphore::NotFound; break; diff --git a/src/corelib/kernel/qtranslator.h b/src/corelib/kernel/qtranslator.h index b4cea18..1f94210 100644 --- a/src/corelib/kernel/qtranslator.h +++ b/src/corelib/kernel/qtranslator.h @@ -86,7 +86,7 @@ public: private: Q_DISABLE_COPY(QTranslator) - Q_DECLARE_PRIVATE(QTranslator) + Q_DECLARE_SCOPED_PRIVATE(QTranslator) }; #endif // QT_NO_TRANSLATION diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp index b487615..5016d3b 100644 --- a/src/corelib/kernel/qvariant.cpp +++ b/src/corelib/kernel/qvariant.cpp @@ -156,7 +156,7 @@ static void construct(QVariant::Private *x, const void *copy) x->data.b = copy ? *static_cast<const bool *>(copy) : false; break; case QVariant::Double: -#if defined(Q_CC_RVCT) +#if defined(Q_CC_RVCT) // Using trinary operator with 64bit constants crashes when ran on Symbian device if (copy){ x->data.d = *static_cast<const double*>(copy); @@ -165,13 +165,13 @@ static void construct(QVariant::Private *x, const void *copy) } #else x->data.d = copy ? *static_cast<const double*>(copy) : 0.0; -#endif +#endif break; case QMetaType::Float: x->data.f = copy ? *static_cast<const float*>(copy) : 0.0f; break; case QVariant::LongLong: -#if defined(Q_CC_RVCT) +#if defined(Q_CC_RVCT) // Using trinary operator with 64bit constants crashes when ran on Symbian device if (copy){ x->data.ll = *static_cast<const qlonglong *>(copy); @@ -180,10 +180,10 @@ static void construct(QVariant::Private *x, const void *copy) } #else x->data.ll = copy ? *static_cast<const qlonglong *>(copy) : Q_INT64_C(0); -#endif +#endif break; case QVariant::ULongLong: -#if defined(Q_CC_RVCT) +#if defined(Q_CC_RVCT) // Using trinary operator with 64bit constants crashes when ran on Symbian device if (copy){ x->data.ull = *static_cast<const qulonglong *>(copy); @@ -192,7 +192,7 @@ static void construct(QVariant::Private *x, const void *copy) } #else x->data.ull = copy ? *static_cast<const qulonglong *>(copy) : Q_UINT64_C(0); -#endif +#endif break; case QVariant::Invalid: case QVariant::UserType: @@ -618,7 +618,7 @@ static bool convert(const QVariant::Private *d, QVariant::Type t, void *result, ok = &dummy; switch (uint(t)) { - case QVariant::Url: + case QVariant::Url: switch (d->type) { case QVariant::String: *static_cast<QUrl *>(result) = QUrl(*v_cast<QString>(d)); @@ -1214,8 +1214,8 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler; and versatile, but may prove less memory and speed efficient than storing specific types in standard data structures. - QVariant also supports the notion of null values, where you can - have a defined type with no value set. However, note that QVariant + QVariant also supports the notion of null values, where you can + have a defined type with no value set. However, note that QVariant types can only be cast when they have had a value set. \snippet doc/src/snippets/code/src_corelib_kernel_qvariant.cpp 1 diff --git a/src/corelib/kernel/qwineventnotifier_p.h b/src/corelib/kernel/qwineventnotifier_p.h index 07aa0ae..2c8934f 100644 --- a/src/corelib/kernel/qwineventnotifier_p.h +++ b/src/corelib/kernel/qwineventnotifier_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE class Q_CORE_EXPORT QWinEventNotifier : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QObject) + Q_DECLARE_SCOPED_PRIVATE(QObject) public: explicit QWinEventNotifier(QObject *parent = 0); diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h index 1717ac0..b646b4d 100644 --- a/src/corelib/plugin/qfactoryloader_p.h +++ b/src/corelib/plugin/qfactoryloader_p.h @@ -66,7 +66,7 @@ class QFactoryLoaderPrivate; class Q_CORE_EXPORT QFactoryLoader : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QFactoryLoader) + Q_DECLARE_SCOPED_PRIVATE(QFactoryLoader) public: QFactoryLoader(const char *iid, diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp index 5364190..d7692b0 100644 --- a/src/corelib/plugin/qpluginloader.cpp +++ b/src/corelib/plugin/qpluginloader.cpp @@ -311,7 +311,7 @@ void QPluginLoader::setFileName(const QString &fileName) QFileInfoList driveList(QDir::drives()); foreach(const QFileInfo& drive, driveList) { QString testFilePath(drive.absolutePath() + stubPath); - testFilePath = QDir::cleanPath(testFilePath); + testFilePath = QDir::cleanPath(testFilePath); if (QFile::exists(testFilePath)) { fn = testFilePath; break; @@ -319,7 +319,7 @@ void QPluginLoader::setFileName(const QString &fileName) } } } - + #else QString fn = QFileInfo(fileName).canonicalFilePath(); #endif diff --git a/src/corelib/statemachine/qabstractstate.h b/src/corelib/statemachine/qabstractstate.h index 5355ac2..3229ab7 100644 --- a/src/corelib/statemachine/qabstractstate.h +++ b/src/corelib/statemachine/qabstractstate.h @@ -85,7 +85,7 @@ protected: private: Q_DISABLE_COPY(QAbstractState) - Q_DECLARE_PRIVATE(QAbstractState) + Q_DECLARE_SCOPED_PRIVATE(QAbstractState) }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qabstracttransition.h b/src/corelib/statemachine/qabstracttransition.h index 8ff3a6e..bfd2849 100644 --- a/src/corelib/statemachine/qabstracttransition.h +++ b/src/corelib/statemachine/qabstracttransition.h @@ -106,7 +106,7 @@ protected: private: Q_DISABLE_COPY(QAbstractTransition) - Q_DECLARE_PRIVATE(QAbstractTransition) + Q_DECLARE_SCOPED_PRIVATE(QAbstractTransition) }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qeventtransition.h b/src/corelib/statemachine/qeventtransition.h index 0ebca19..08887f0 100644 --- a/src/corelib/statemachine/qeventtransition.h +++ b/src/corelib/statemachine/qeventtransition.h @@ -83,7 +83,7 @@ protected: private: Q_DISABLE_COPY(QEventTransition) - Q_DECLARE_PRIVATE(QEventTransition) + Q_DECLARE_SCOPED_PRIVATE(QEventTransition) }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qfinalstate.h b/src/corelib/statemachine/qfinalstate.h index e37ef36..7b77b2b 100644 --- a/src/corelib/statemachine/qfinalstate.h +++ b/src/corelib/statemachine/qfinalstate.h @@ -68,7 +68,7 @@ protected: private: Q_DISABLE_COPY(QFinalState) - Q_DECLARE_PRIVATE(QFinalState) + Q_DECLARE_SCOPED_PRIVATE(QFinalState) }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qhistorystate.h b/src/corelib/statemachine/qhistorystate.h index 395bb98..889308d 100644 --- a/src/corelib/statemachine/qhistorystate.h +++ b/src/corelib/statemachine/qhistorystate.h @@ -83,7 +83,7 @@ protected: private: Q_DISABLE_COPY(QHistoryState) - Q_DECLARE_PRIVATE(QHistoryState) + Q_DECLARE_SCOPED_PRIVATE(QHistoryState) }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qsignaltransition.h b/src/corelib/statemachine/qsignaltransition.h index 415751e..c823c2b 100644 --- a/src/corelib/statemachine/qsignaltransition.h +++ b/src/corelib/statemachine/qsignaltransition.h @@ -78,7 +78,7 @@ protected: private: Q_DISABLE_COPY(QSignalTransition) - Q_DECLARE_PRIVATE(QSignalTransition) + Q_DECLARE_SCOPED_PRIVATE(QSignalTransition) }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qstate.h b/src/corelib/statemachine/qstate.h index ce88b25..05d394b 100644 --- a/src/corelib/statemachine/qstate.h +++ b/src/corelib/statemachine/qstate.h @@ -107,7 +107,7 @@ protected: private: Q_DISABLE_COPY(QState) - Q_DECLARE_PRIVATE(QState) + Q_DECLARE_SCOPED_PRIVATE(QState) }; #endif //QT_NO_STATEMACHINE diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h index 230d852..1b1caa1 100644 --- a/src/corelib/statemachine/qstatemachine.h +++ b/src/corelib/statemachine/qstatemachine.h @@ -141,7 +141,7 @@ protected: private: Q_DISABLE_COPY(QStateMachine) - Q_DECLARE_PRIVATE(QStateMachine) + Q_DECLARE_SCOPED_PRIVATE(QStateMachine) Q_PRIVATE_SLOT(d_func(), void _q_start()) Q_PRIVATE_SLOT(d_func(), void _q_process()) #ifndef QT_NO_ANIMATION diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index 1cf4bc9..6eaa55a 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -183,7 +183,7 @@ QThreadPrivate::QThreadPrivate(QThreadData *d) id = 0; waiters = 0; #endif -#if defined (Q_WS_WIN) || defined (Q_OS_SYMBIAN) +#if defined (Q_WS_WIN) || defined (Q_OS_SYMBIAN) terminationEnabled = true; terminatePending = false; #endif diff --git a/src/corelib/thread/qthread.h b/src/corelib/thread/qthread.h index c784352..0d8aa8b 100644 --- a/src/corelib/thread/qthread.h +++ b/src/corelib/thread/qthread.h @@ -127,7 +127,7 @@ protected: private: Q_OBJECT - Q_DECLARE_PRIVATE(QThread) + Q_DECLARE_SCOPED_PRIVATE(QThread) static void initialize(); static void cleanup(); @@ -154,7 +154,7 @@ private: friend class QCoreApplication; friend class QThreadData; friend class QAdoptedThread; - Q_DECLARE_PRIVATE(QThread) + Q_DECLARE_SCOPED_PRIVATE(QThread) }; #endif // QT_NO_THREAD diff --git a/src/corelib/thread/qthread_p.h b/src/corelib/thread/qthread_p.h index 31b5090..752796b 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -152,7 +152,7 @@ public: static void finish(void *, bool lockAnyway=true); #endif // Q_OS_WIN32 -#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined (Q_OS_SYMBIAN) +#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE) || defined (Q_OS_SYMBIAN) bool terminationEnabled, terminatePending; # endif QThreadData *data; @@ -214,7 +214,7 @@ public: // thread wrapper for the main() thread class QAdoptedThread : public QThread { - Q_DECLARE_PRIVATE(QThread) + Q_DECLARE_SCOPED_PRIVATE(QThread) public: QAdoptedThread(QThreadData *data = 0); diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 1be9048..de0575c 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -197,7 +197,7 @@ void QThreadPrivate::createEventDispatcher(QThreadData *data) else #endif #ifdef Q_OS_SYMBIAN - data->eventDispatcher = new QEventDispatcherSymbian; + data->eventDispatcher = new QEventDispatcherSymbian; #else data->eventDispatcher = new QEventDispatcherUNIX; #endif @@ -212,7 +212,7 @@ void *QThreadPrivate::start(void *arg) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); pthread_cleanup_push(QThreadPrivate::finish, arg); #endif - + QThread *thr = reinterpret_cast<QThread *>(arg); QThreadData *data = QThreadData::get2(thr); @@ -245,7 +245,7 @@ void *QThreadPrivate::start(void *arg) #ifndef Q_OS_SYMBIAN pthread_cleanup_pop(1); #else - QThreadPrivate::finish(arg); + QThreadPrivate::finish(arg); #endif return 0; @@ -285,7 +285,7 @@ void QThreadPrivate::finish(void *arg) d->thread_id = 0; #ifdef Q_OS_SYMBIAN if (closeNativeHandle) - d->data->symbian_thread_handle.Close(); + d->data->symbian_thread_handle.Close(); #endif d->thread_done.wakeAll(); #ifdef Q_OS_SYMBIAN @@ -582,10 +582,10 @@ void QThread::terminate() d->terminatePending = true; return; } - + d->terminated = true; QThreadPrivate::finish(this, false, false); - d->data->symbian_thread_handle.Terminate(KErrNone); + d->data->symbian_thread_handle.Terminate(KErrNone); d->data->symbian_thread_handle.Close(); #endif @@ -629,7 +629,7 @@ void QThread::setTerminationEnabled(bool enabled) d->terminated = true; QThreadPrivate::finish(thr, false); locker.unlock(); // don't leave the mutex locked! - pthread_exit(NULL); + pthread_exit(NULL); } #endif } diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 22cee0e..97f437f 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1307,6 +1307,7 @@ QByteArray::QByteArray(int size, char ch) QByteArray::QByteArray(int size, Qt::Initialization) { d = static_cast<Data *>(qMalloc(sizeof(Data)+size)); + Q_CHECK_PTR(d); d->ref = 1; d->alloc = d->size = size; d->data = d->array; diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index d1a3386..a57fec7 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -150,10 +150,10 @@ struct Q_CORE_EXPORT QHashData }; inline void QHashData::mightGrow() // ### Qt 5: eliminate -{ +{ if (size >= numBuckets) rehash(numBits + 1); -} +} inline bool QHashData::willGrow() { @@ -167,8 +167,13 @@ inline bool QHashData::willGrow() inline void QHashData::hasShrunk() { - if (size <= (numBuckets >> 3) && numBits > userNumBits) - rehash(qMax(int(numBits) - 2, int(userNumBits))); + if (size <= (numBuckets >> 3) && numBits > userNumBits) { + QT_TRY { + rehash(qMax(int(numBits) - 2, int(userNumBits))); + } QT_CATCH(const std::bad_alloc &) { + // ignore bad allocs - shrinking shouldn't throw. rehash is exception safe. + } + } } inline QHashData::Node *QHashData::firstNode() @@ -761,6 +766,8 @@ Q_INLINE_TEMPLATE typename QHash<Key, T>::iterator QHash<Key, T>::insertMulti(co template <class Key, class T> Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::remove(const Key &akey) { + if (isEmpty()) // prevents detaching shared null + return 0; detach(); int oldSize = d->size; @@ -782,6 +789,8 @@ Q_OUTOFLINE_TEMPLATE int QHash<Key, T>::remove(const Key &akey) template <class Key, class T> Q_OUTOFLINE_TEMPLATE T QHash<Key, T>::take(const Key &akey) { + if (isEmpty()) // prevents detaching shared null + return T(); detach(); Node **node = findNode(akey); @@ -983,12 +992,12 @@ Q_INLINE_TEMPLATE int QMultiHash<Key, T>::remove(const Key &key, const T &value) typename QHash<Key, T>::iterator end(QHash<Key, T>::end()); while (i != end && i.key() == key) { if (i.value() == value) { -#if defined(Q_CC_RVCT) - // RVCT has problems with scoping, apparently. +#if defined(Q_CC_RVCT) + // RVCT has problems with scoping, apparently. i = QHash<Key, T>::erase(i); #else i = erase(i); -#endif +#endif ++n; } else { ++i; diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index a56518b..c6c898d 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -363,15 +363,16 @@ Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src) Node *current = from; if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { QT_TRY { - while(current != to) + while(current != to) { (current++)->v = new T(*reinterpret_cast<T*>((src++)->v)); + } } QT_CATCH(...) { while (current != from) delete reinterpret_cast<T*>(current--); QT_RETHROW; } - } - else if (QTypeInfo<T>::isComplex) { + + } else if (QTypeInfo<T>::isComplex) { QT_TRY { while(current != to) new (current++) T(*reinterpret_cast<T*>(src++)); @@ -380,6 +381,9 @@ Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src) (reinterpret_cast<T*>(current--))->~T(); QT_RETHROW; } + } else { + if (src != from && to - from > 0) + memcpy(from, src, (to - from) * sizeof(Node *)); } } @@ -408,11 +412,12 @@ Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l) template <typename T> inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t) { - Node *n = reinterpret_cast<Node *>(p.insert(before.i - reinterpret_cast<Node *>(p.begin()))); + int iBefore = before.i - reinterpret_cast<Node *>(p.begin()); + Node *n = reinterpret_cast<Node *>(p.insert(iBefore)); QT_TRY { node_construct(n, t); } QT_CATCH(...) { - p.remove(before.i - reinterpret_cast<Node *>(p.begin())); + p.remove(iBefore); QT_RETHROW; } return n; @@ -689,7 +694,13 @@ Q_OUTOFLINE_TEMPLATE QList<T> &QList<T>::operator+=(const QList<T> &l) { detach(); Node *n = reinterpret_cast<Node *>(p.append(l.p)); - node_copy(n, reinterpret_cast<Node *>(p.end()), reinterpret_cast<Node *>(l.p.begin())); + QT_TRY{ + node_copy(n, reinterpret_cast<Node *>(p.end()), reinterpret_cast<Node *>(l.p.begin())); + } QT_CATCH(...) { + // restore the old end + d->end -= (reinterpret_cast<Node *>(p.end()) - n); + QT_RETHROW; + } return *this; } diff --git a/src/corelib/tools/qlistdata.cpp b/src/corelib/tools/qlistdata.cpp index 3c45bed..c67af7a 100644 --- a/src/corelib/tools/qlistdata.cpp +++ b/src/corelib/tools/qlistdata.cpp @@ -74,12 +74,16 @@ QListData::Data *QListData::detach() Data *x = static_cast<Data *>(qMalloc(DataHeaderSize + d->alloc * sizeof(void *))); Q_CHECK_PTR(x); - ::memcpy(x, d, DataHeaderSize + d->alloc * sizeof(void *)); - x->alloc = d->alloc; x->ref = 1; x->sharable = true; - if (!x->alloc) - x->begin = x->end = 0; + x->alloc = d->alloc; + if (!x->alloc) { + x->begin = 0; + x->end = 0; + } else { + x->begin = d->begin; + x->end = d->end; + } qSwap(d, x); if (!x->ref.deref()) @@ -87,20 +91,30 @@ QListData::Data *QListData::detach() return 0; } -// Returns the old (shared) data, it is up to the caller to deref() and free() +/*! + * Detaches the QListData by reallocating new memory. + * Returns the old (shared) data, it is up to the caller to deref() and free() + * For the new data node_copy needs to be called. + * + * \internal + */ QListData::Data *QListData::detach2() { Data *x = d; Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *))); Q_CHECK_PTR(t); + t->ref = 1; + t->sharable = true; + t->alloc = x->alloc; + if (!t->alloc) { + t->begin = 0; + t->end = 0; + } else { + t->begin = x->begin; + t->end = x->end; + } d = t; - ::memcpy(d, x, DataHeaderSize + x->alloc * sizeof(void *)); - d->alloc = x->alloc; - d->ref = 1; - d->sharable = true; - if (!d->alloc) - d->begin = d->end = 0; return x; } @@ -117,12 +131,14 @@ void QListData::realloc(int alloc) d->begin = d->end = 0; } +// ensures that enough space is available to append one element void **QListData::append() { Q_ASSERT(d->ref == 1); if (d->end == d->alloc) { int n = d->end - d->begin; if (d->begin > 2 * d->alloc / 3) { + // we have enough space. Just not at the end -> move it. ::memcpy(d->array + n, d->array + d->begin, n * sizeof(void *)); d->begin = n; d->end = n * 2; @@ -133,6 +149,7 @@ void **QListData::append() return d->array + d->end++; } +// ensures that enough space is available to append the list void **QListData::append(const QListData& l) { Q_ASSERT(d->ref == 1); @@ -141,7 +158,6 @@ void **QListData::append(const QListData& l) if (n) { if (e + n > d->alloc) realloc(grow(e + l.d->end - l.d->begin)); - ::memcpy(d->array + d->end, l.d->array + l.d->begin, n * sizeof(void*)); d->end += n; } return d->array + e; diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index e66f533..18e608d 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -3884,7 +3884,13 @@ QString QLocalePrivate::doubleToString(double d, char *rve = 0; char *buff = 0; - digits = QLatin1String(qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff)); + QT_TRY { + digits = QLatin1String(qdtoa(d, mode, pr, &decpt, &sign, &rve, &buff)); + } QT_CATCH(...) { + if (buff != 0) + free(buff); + QT_RETHROW; + } if (buff != 0) free(buff); #endif // QT_QLOCALE_USES_FCVT @@ -6734,8 +6740,13 @@ static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, if (i <= 0) i = 1; } - *resultp = static_cast<char *>(malloc(i + 1)); - Q_CHECK_PTR(resultp); + QT_TRY { + *resultp = static_cast<char *>(malloc(i + 1)); + Q_CHECK_PTR(*resultp); + } QT_CATCH(...) { + Bfree(b); + QT_RETHROW; + } s = s0 = *resultp; if (ilim >= 0 && ilim <= Quick_max && try_quick) { diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp index 976227d..95d4edf 100644 --- a/src/corelib/tools/qlocale_symbian.cpp +++ b/src/corelib/tools/qlocale_symbian.cpp @@ -637,9 +637,9 @@ static QString symbianDayName(int day, bool short_format) return QString(); if (short_format) { - return qt_TDes2QStringL(TDayNameAbb(TDay(day))); + return qt_TDes2QString(TDayNameAbb(TDay(day))); } else { - return qt_TDes2QStringL(TDayName(TDay(day))); + return qt_TDes2QString(TDayName(TDay(day))); } } @@ -655,9 +655,9 @@ static QString symbianMonthName(int month, bool short_format) return QString(); if (short_format) { - return qt_TDes2QStringL(TMonthNameAbb(TMonth(month))); + return qt_TDes2QString(TMonthNameAbb(TMonth(month))); } else { - return qt_TDes2QStringL(TMonthName(TMonth(month))); + return qt_TDes2QString(TMonthName(TMonth(month))); } } @@ -678,7 +678,7 @@ static QString symbianDateFormat(bool short_format) dateFormat.Set(ptrGetLongDateFormatSpec(_s60Locale)); } - return s60ToQtFormat(qt_TDesC2QStringL(dateFormat)); + return s60ToQtFormat(qt_TDesC2QString(dateFormat)); } /*! @@ -687,7 +687,7 @@ static QString symbianDateFormat(bool short_format) */ static QString symbianTimeFormat() { - return s60ToQtFormat(qt_TDesC2QStringL(ptrGetTimeFormatSpec(_s60Locale))); + return s60ToQtFormat(qt_TDesC2QString(ptrGetTimeFormatSpec(_s60Locale))); } /*! @@ -719,7 +719,7 @@ static QString symbianDateToString(const QDate &date, bool short_format) TRAPD(err, ptrTimeFormatL(timeStr, buffer, dateFormat, *_s60Locale.GetLocale());) if (err == KErrNone) - return qt_TDes2QStringL(buffer); + return qt_TDes2QString(buffer); else return QString(); } @@ -749,7 +749,7 @@ static QString symbianTimeToString(const QTime &time) ) if (err == KErrNone) - return qt_TDes2QStringL(buffer); + return qt_TDes2QString(buffer); else return QString(); } diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index be80e75..70a2896 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -1019,12 +1019,12 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::remove(const Key &key, const T &value) typename QMap<Key, T>::iterator end(QMap<Key, T>::end()); while (i != end && !qMapLessThanKey<Key>(key, i.key())) { if (i.value() == value) { -#if defined(Q_CC_RVCT) - // RVCT has problems with scoping, apparently. +#if defined(Q_CC_RVCT) + // RVCT has problems with scoping, apparently. i = QMap<Key, T>::erase(i); #else i = erase(i); -#endif +#endif ++n; } else { ++i; diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index 8bda634..0ac4fa2 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -1225,7 +1225,7 @@ private: int yyPos; // the position of the next character to read int yyLen; // the length of yyIn int yyCh; // the last character read - QRegExpCharClass *yyCharClass; // attribute for Tok_CharClass tokens + QScopedPointer<QRegExpCharClass> yyCharClass; // attribute for Tok_CharClass tokens int yyMinRep; // attribute for Tok_Quantifier int yyMaxRep; // ditto QString yyError; // syntax error or overflow during parsing? @@ -1316,8 +1316,7 @@ void QRegExpMatchState::prepareForMatch(QRegExpEngine *eng) #endif int numCaptures = eng->numCaptures(); int newCapturedSize = 2 + 2 * numCaptures; - bigArray = (int *)realloc(bigArray, ((3 + 4 * ncap) * ns + 4 * ncap + newSlideTabSize + newCapturedSize)*sizeof(int)); - Q_CHECK_PTR(bigArray); + bigArray = q_check_ptr((int *)realloc(bigArray, ((3 + 4 * ncap) * ns + 4 * ncap + newSlideTabSize + newCapturedSize)*sizeof(int))); // set all internal variables only _after_ bigArray is realloc'ed // to prevent a broken regexp in oom case @@ -3124,7 +3123,7 @@ void QRegExpEngine::startTokenizer(const QChar *rx, int len) yyPos = 0; yyLen = len; yyCh = getChar(); - yyCharClass = new QRegExpCharClass; + yyCharClass.reset(new QRegExpCharClass); yyMinRep = 0; yyMaxRep = 0; yyError = QString(); @@ -3318,8 +3317,7 @@ int QRegExpEngine::parse(const QChar *pattern, int len) #endif box.cat(middleBox); box.cat(rightBox); - delete yyCharClass; - yyCharClass = 0; + yyCharClass.reset(0); #ifndef QT_NO_REGEXP_CAPTURE for (int i = 0; i < nf; ++i) { diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index 7cfca0e..a0d6943 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -245,12 +245,7 @@ public: inline void clear() { if(!buffers.isEmpty()) { - QByteArray tmp = buffers[0]; - buffers.clear(); - buffers << tmp; - //TODO merge this optimization ? - //buffers.erase(buffers.begin() + 1, buffers.end()); - //>>>>>>> 08ae7ee1fb930e7d4b4039e2294cba69f9380964:src/corelib/tools/qringbuffer_p.h + buffers.erase(buffers.begin() + 1, buffers.end()); if (buffers.at(0).size() != basicBlockSize) buffers[0].resize(basicBlockSize); } diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 912edb6..cf24381 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -39,6 +39,10 @@ ** ****************************************************************************/ +#include "qscopedpointer.h" + +QT_BEGIN_NAMESPACE + /*! \class QScopedPointer \brief The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon destruction. @@ -53,9 +57,7 @@ called resource acquisition is initialization(RAII). QScopedPointer guarantees that the object pointed to will get deleted when - the current scope dissapears, and it also has no way of releasing - ownership, hence clearly communicating the lifetime and ownership of the - object. These guarantees are convenient when reading the code. + the current scope dissapears. Consider this function which does heap allocations, and have various exit points: @@ -68,7 +70,7 @@ The code the compiler generates for QScopedPointer is the same as when writing it manually. Code that makes use of \a delete are candidates for - QScopedPointer usage(and if not, possibly another type of smart pointer + QScopedPointer usage (and if not, possibly another type of smart pointer such as QSharedPointer). QScopedPointer intentionally has no copy constructor or assignment operator, such that ownership and lifetime is clearly communicated. @@ -78,7 +80,26 @@ \snippet doc/src/snippets/code/src_corelib_tools_qscopedpointer.cpp 2 - \note QScopedPointer does not work with arrays. + \section1 Custom cleanup handlers + + Arrays as well as pointers that have been allocated with \c malloc must + not be deleted using \c delete. QScopedPointer's second template parameter + can be used for custom cleanup handlers. + + The following custom cleanup handlers exist: + + \list + \i QScopedPointerDeleter - the default, deletes the pointer using \c delete + \i QScopedPointerArrayDeleter - deletes the pointer using \c{delete []}. Use + this handler for pointers that were allocated with \c{new []}. + \i QScopedPointerPodDeleter - deletes the pointer using \c{free()}. Use this + handler for pointers that were allocated with \c{malloc()}. + \endlist + + You can pass your own classes as handlers, provided that they have a public + static function \c{void cleanup(T *pointer)}. + + \snippet doc/src/snippets/code/src_corelib_tools_qscopedpointer.cpp 5 \section1 Forward Declared Pointers @@ -175,9 +196,6 @@ Deletes the existing object it is pointing to if any, and sets its pointer to \a other. QScopedPointer now owns \a other and will delete it in its destructor. - - If \a other is equal to the value returned by data(), behavior is - undefined. */ /*! @@ -185,8 +203,8 @@ Returns the value of the pointer referenced by this object. The pointer of this QScopedPointer object will be reset to \c null. + + Callers of this function take ownership of the pointer. */ QT_END_NAMESPACE - -#endif diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h index fc8f9e2..62daacb 100644 --- a/src/corelib/tools/qscopedpointer.h +++ b/src/corelib/tools/qscopedpointer.h @@ -49,8 +49,46 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) template <typename T> +struct QScopedPointerDeleter +{ + static inline void cleanup(T *pointer) + { + // Enforce a complete type. + // If you get a compile error here, read the secion on forward declared + // classes in the QScopedPointer documentation. + typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; + (void) sizeof(IsIncompleteType); + + delete pointer; + } +}; + +template <typename T> +struct QScopedPointerArrayDeleter +{ + static inline void cleanup(T *pointer) + { + // Enforce a complete type. + // If you get a compile error here, read the secion on forward declared + // classes in the QScopedPointer documentation. + typedef char IsIncompleteType[ sizeof(T) ? 1 : -1 ]; + (void) sizeof(IsIncompleteType); + + delete [] pointer; + } +}; + +struct QScopedPointerPodDeleter +{ + static inline void cleanup(void *pointer) { if (pointer) qFree(pointer); } +}; + +template <typename T, typename Cleanup = QScopedPointerDeleter<T> > class QScopedPointer { +#ifndef Q_CC_NOKIAX86 + typedef T *QScopedPointer:: *RestrictedBool; +#endif public: explicit inline QScopedPointer(T *p = 0) : d(p) { @@ -58,16 +96,20 @@ public: inline ~QScopedPointer() { - delete d; + T *oldD = this->d; + Cleanup::cleanup(oldD); + this->d = 0; } inline T &operator*() const { + Q_ASSERT(d); return *d; } inline T *operator->() const { + Q_ASSERT(d); return d; } @@ -81,10 +123,17 @@ public: return d != other.d; } +#if defined(Q_CC_NOKIAX86) || defined(Q_QDOC) inline operator bool() const { - return d; + return isNull() ? 0 : &QScopedPointer::d; + } +#else + inline operator RestrictedBool() const + { + return isNull() ? 0 : &QScopedPointer::d; } +#endif inline T *data() const { @@ -98,9 +147,11 @@ public: inline void reset(T *other = 0) { + if (d == other) + return; T *oldD = d; d = other; - delete oldD; + Cleanup::cleanup(oldD); } inline T *take() @@ -117,37 +168,52 @@ private: Q_DISABLE_COPY(QScopedPointer) }; -/* internal class - allows special handling for resetting and cleaning the pointer */ -template <typename T, typename CustomHandler> -class QScopedCustomPointer : public QScopedPointer<T> +template <typename T, typename Cleanup = QScopedPointerArrayDeleter<T> > +class QScopedArrayPointer : public QScopedPointer<T, Cleanup> { public: - inline QScopedCustomPointer(T *p = 0) - : QScopedPointer<T>(p) + explicit inline QScopedArrayPointer(T *p = 0) + : QScopedPointer<T, Cleanup>(p) { } - inline ~QScopedCustomPointer() + inline T &operator[](int i) { - T *oldD = this->d; - this->d = 0; - CustomHandler::cleanup(oldD); + return this->d[i]; } - inline void reset(T *other = 0) + inline const T &operator[](int i) const + { + return this->d[i]; + } + +private: + Q_DISABLE_COPY(QScopedArrayPointer) +}; + +/* Internal helper class - exposes the data through data_ptr (legacy from QShared). + Required for some internal Qt classes, do not use otherwise. */ +template <typename T, typename Cleanup = QScopedPointerDeleter<T> > +class QCustomScopedPointer : public QScopedPointer<T, Cleanup> +{ +public: + explicit inline QCustomScopedPointer(T *p = 0) + : QScopedPointer<T, Cleanup>(p) { - CustomHandler::reset(this->d, other); } inline T *&data_ptr() { return this->d; } + +private: + Q_DISABLE_COPY(QCustomScopedPointer) }; -/* Internal helper class - a handler for QShared* classes, to be used in QScopedCustomPointer */ +/* Internal helper class - a handler for QShared* classes, to be used in QCustomScopedPointer */ template <typename T> -class QScopedSharedPointerHandler +class QScopedPointerSharedDeleter { public: static inline void cleanup(T *d) @@ -155,24 +221,17 @@ public: if (d && !d->ref.deref()) delete d; } - - static inline void reset(T *&d, T *other) - { - T *oldD = d; - d = other; - cleanup(oldD); - } }; -/* Internal. This should really have been a typedef, but you can't have a templated typedef :) +/* Internal. This class is basically a scoped pointer pointing to a ref-counted object */ template <typename T> -class QScopedSharedPointer : public QScopedCustomPointer<T, QScopedSharedPointerHandler<T> > +class QScopedSharedPointer : public QCustomScopedPointer<T, QScopedPointerSharedDeleter<T> > { public: - inline QScopedSharedPointer(T *p = 0) - : QScopedCustomPointer<T, QScopedSharedPointerHandler<T> >(p) + explicit inline QScopedSharedPointer(T *p = 0) + : QCustomScopedPointer<T, QScopedPointerSharedDeleter<T> >(p) { } @@ -189,8 +248,11 @@ public: other->ref.ref(); T *oldD = this->d; this->d = other; - QScopedSharedPointerHandler<T>::cleanup(oldD); + QScopedPointerSharedDeleter<T>::cleanup(oldD); } + +private: + Q_DISABLE_COPY(QScopedSharedPointer) }; QT_END_NAMESPACE diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index f3c773b..87e812f 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1025,6 +1025,7 @@ QString::QString(int size, QChar ch) QString::QString(int size, Qt::Initialization) { d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar)); + Q_CHECK_PTR(d); d->ref = 1; d->alloc = d->size = size; d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0; @@ -1238,11 +1239,9 @@ void QString::realloc(int alloc) asciiCache->remove(d); } #endif - Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar))); - Q_CHECK_PTR(x); - x->alloc = alloc; - x->data = x->array; - d = x; + d = static_cast<Data *>(q_check_ptr(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar)))); + d->alloc = alloc; + d->data = d->array; } } diff --git a/src/corelib/tools/qtimeline.h b/src/corelib/tools/qtimeline.h index 2d1ad42..2a1c2c2 100644 --- a/src/corelib/tools/qtimeline.h +++ b/src/corelib/tools/qtimeline.h @@ -136,7 +136,7 @@ protected: private: Q_DISABLE_COPY(QTimeLine) - Q_DECLARE_PRIVATE(QTimeLine) + Q_DECLARE_SCOPED_PRIVATE(QTimeLine) }; QT_END_NAMESPACE diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h index 7be7138..3215624 100644 --- a/src/corelib/xml/qxmlstream.h +++ b/src/corelib/xml/qxmlstream.h @@ -392,7 +392,7 @@ public: private: Q_DISABLE_COPY(QXmlStreamReader) - Q_DECLARE_PRIVATE(QXmlStreamReader) + Q_DECLARE_SCOPED_PRIVATE(QXmlStreamReader) QScopedPointer<QXmlStreamReaderPrivate> d_ptr; }; @@ -465,7 +465,7 @@ public: private: Q_DISABLE_COPY(QXmlStreamWriter) - Q_DECLARE_PRIVATE(QXmlStreamWriter) + Q_DECLARE_SCOPED_PRIVATE(QXmlStreamWriter) QScopedPointer<QXmlStreamWriterPrivate> d_ptr; }; #endif // QT_NO_XMLSTREAMWRITER diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h index 7a4d2a8..68477af 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -652,6 +652,7 @@ public: if (tos + extraCapacity + 1 > cap) { cap = qMax(tos + extraCapacity + 1, cap << 1 ); data = reinterpret_cast<T *>(qRealloc(data, cap * sizeof(T))); + Q_CHECK_PTR(data); } } |