diff options
author | Harald Fernengel <harald@trolltech.com> | 2009-08-03 13:12:46 (GMT) |
---|---|---|
committer | Harald Fernengel <harald@trolltech.com> | 2009-08-03 13:12:46 (GMT) |
commit | 41a83e1ff19ad1396e6001e6b0ac003c701ba55a (patch) | |
tree | 609e40eda10418bbf925002c36552074796b96b6 /src/corelib | |
parent | d1f3b9df2bc5c57d414da73a7d4f9ed7b25df3db (diff) | |
download | Qt-41a83e1ff19ad1396e6001e6b0ac003c701ba55a.zip Qt-41a83e1ff19ad1396e6001e6b0ac003c701ba55a.tar.gz Qt-41a83e1ff19ad1396e6001e6b0ac003c701ba55a.tar.bz2 |
Squashed commit of the topic/exceptions branch.
Contains some smaller fixes and renaming of macros. Looks big,
but isn't scary at all ;)
Diffstat (limited to 'src/corelib')
79 files changed, 500 insertions, 254 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 b2d52d5..0afe80f 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..9bec0f5 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" 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 76ffb6a..818e555 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1910,6 +1910,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> @@ -2162,7 +2171,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); @@ -2464,7 +2473,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 } @@ -3231,7 +3244,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 @@ -3251,14 +3264,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 @@ -3278,7 +3291,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); @@ -3286,10 +3299,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 @@ -3309,11 +3322,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> @@ -3336,15 +3349,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); } @@ -3357,11 +3376,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> @@ -3371,9 +3390,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; @@ -3382,19 +3401,22 @@ 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; } #endif diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index e6508a8..257e3db 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1662,6 +1662,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) # 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; @@ -2378,33 +2386,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..9787566 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; } } 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 84394fe..2421282 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -1003,11 +1003,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 b324441..1650526 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -217,6 +217,11 @@ QConfFile::QConfFile(const QString &fileName, bool _userPerms) usedHashFunc()->insert(name, this); } +QConfFile::~QConfFile() +{ + usedHashFunc()->remove(name); +} + ParsedSettingsMap QConfFile::mergedKeyMap() const { ParsedSettingsMap result = originalKeys; @@ -263,7 +268,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))) { @@ -1232,12 +1237,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 2d5bea6..f7120e1 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) 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 dc7d7bd..90d04cd 100644 --- a/src/corelib/kernel/qabstractitemmodel.h +++ b/src/corelib/kernel/qabstractitemmodel.h @@ -283,7 +283,7 @@ protected: QModelIndexList persistentIndexList() const; 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 c07a6e9..90d8f2f 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -1114,6 +1114,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 @@ -1128,6 +1131,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..3293d47 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(); } @@ -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 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 e0ac5da..c52965a 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -181,7 +181,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 215f6ae..0b9f841 100644 --- a/src/corelib/kernel/qmetaobject.cpp +++ b/src/corelib/kernel/qmetaobject.cpp @@ -1535,7 +1535,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/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index 91266db..02338fe 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -434,8 +434,8 @@ int QMetaType::registerType(const char *typeName, Destructor destructor, int idx = qMetaTypeType_unlocked(normalizedTypeName); if (!idx) { - idx = currentIdx++; ct->resize(ct->count() + 1); + idx = currentIdx++; QCustomTypeInfo &inf = (*ct)[idx - User]; inf.typeName = normalizedTypeName; inf.constr = constructor; 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 85e0ed1..cc2df0c 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('*')) @@ -401,6 +402,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); @@ -417,10 +422,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 @@ -665,12 +666,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 @@ -700,20 +707,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); } /*! @@ -765,11 +778,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) @@ -2658,8 +2686,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; @@ -2671,8 +2705,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; @@ -2831,14 +2872,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) sender->d_func()->connectedSignals = ~0u; else if (signal_index < 32) @@ -3024,7 +3071,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 74a5904..e725c82 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -117,7 +117,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/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/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/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 9ba1f11..a87af39 100644 --- a/src/corelib/statemachine/qabstracttransition.h +++ b/src/corelib/statemachine/qabstracttransition.h @@ -109,7 +109,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 b05ffef..c227ab1 100644 --- a/src/corelib/statemachine/qeventtransition.h +++ b/src/corelib/statemachine/qeventtransition.h @@ -88,7 +88,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 69060ae..d6c2324 100644 --- a/src/corelib/statemachine/qsignaltransition.h +++ b/src/corelib/statemachine/qsignaltransition.h @@ -81,7 +81,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 41d32be..be37591 100644 --- a/src/corelib/statemachine/qstate.h +++ b/src/corelib/statemachine/qstate.h @@ -105,7 +105,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 30d0e3a..1f0d5b0 100644 --- a/src/corelib/statemachine/qstatemachine.h +++ b/src/corelib/statemachine/qstatemachine.h @@ -153,7 +153,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.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..51de0be 100644 --- a/src/corelib/thread/qthread_p.h +++ b/src/corelib/thread/qthread_p.h @@ -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/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..fc6a1e3a 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -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); 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 17634c1..a8fac2d 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -3943,7 +3943,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 @@ -6786,8 +6792,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/qregexp.cpp b/src/corelib/tools/qregexp.cpp index d7d347f..d980a9b 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -1216,7 +1216,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? @@ -1303,8 +1303,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 @@ -2795,7 +2794,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(); @@ -2989,8 +2988,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 d8ca658..16368e9 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 38b6f58..ca2fd1a 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1023,6 +1023,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; @@ -1236,11 +1237,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 f1614ea..e6c914f 100644 --- a/src/corelib/xml/qxmlstream_p.h +++ b/src/corelib/xml/qxmlstream_p.h @@ -648,6 +648,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); } } |