diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h index d1d660dfc7..289473514e 100644 --- a/src/corelib/tools/qsharedpointer_impl.h +++ b/src/corelib/tools/qsharedpointer_impl.h @@ -185,9 +185,7 @@ namespace QtSharedPointer { virtual inline ~ExternalRefCountData() { Q_ASSERT(!weakref.load()); Q_ASSERT(strongref.load() <= 0); } // overridden by derived classes - // returns false to indicate caller should delete the pointer - // returns true in case it has already done so - virtual inline bool destroy() { return false; } + virtual inline void destroy() { } #ifndef QT_NO_QOBJECT Q_CORE_EXPORT static ExternalRefCountData *getAndRef(const QObject *); @@ -210,7 +208,7 @@ namespace QtSharedPointer { : destroyer(d) { } - inline bool destroy() { destroyer(this); return true; } + inline void destroy() { destroyer(this); } inline void operator delete(void *ptr) { ::operator delete(ptr); } inline void operator delete(void *, void *) { } }; @@ -327,31 +325,17 @@ namespace QtSharedPointer { typedef ExternalRefCountData Data; inline void deref() - { deref(d, this->value); } - static inline void deref(Data *d, T *value) + { deref(d); } + static inline void deref(Data *d) { if (!d) return; if (!d->strongref.deref()) { - if (!d->destroy()) - delete value; + d->destroy(); } if (!d->weakref.deref()) delete d; } - inline void internalConstruct(T *ptr) - { -#ifdef QT_SHAREDPOINTER_TRACK_POINTERS - internalConstruct(ptr, normalDeleter); -#else - if (ptr) - d = new Data; - else - d = 0; - internalFinishConstruction(ptr); -#endif - } - template inline void internalConstruct(T *ptr, Deleter deleter) { @@ -381,8 +365,6 @@ namespace QtSharedPointer { inline ExternalRefCount() : d(0) { } inline ExternalRefCount(Qt::Initialization i) : Basic(i) { } - inline ExternalRefCount(T *ptr) : Basic(Qt::Uninitialized) // throws - { internalConstruct(ptr); } template inline ExternalRefCount(T *ptr, Deleter deleter) : Basic(Qt::Uninitialized) // throws { internalConstruct(ptr, deleter); } @@ -403,7 +385,7 @@ namespace QtSharedPointer { other.ref(); qSwap(d, o); qSwap(this->value, actual); - deref(o, actual); + deref(o); } inline void internalSwap(ExternalRefCount &other) @@ -448,7 +430,7 @@ namespace QtSharedPointer { this->value = 0; // dereference saved data - deref(o, actual); + deref(o); } Data *d; @@ -463,7 +445,7 @@ public: inline QSharedPointer() { } // inline ~QSharedPointer() { } - inline explicit QSharedPointer(T *ptr) : BaseClass(ptr) // throws + inline explicit QSharedPointer(T *ptr) : BaseClass(ptr, &QtSharedPointer::normalDeleter) // throws { } template diff --git a/tests/auto/corelib/tools/qsharedpointer/forwarddeclaration.cpp b/tests/auto/corelib/tools/qsharedpointer/forwarddeclaration.cpp deleted file mode 100644 index 6fb01c6aa2..0000000000 --- a/tests/auto/corelib/tools/qsharedpointer/forwarddeclaration.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#define QT_SHAREDPOINTER_TRACK_POINTERS -#include "qsharedpointer.h" - -class ForwardDeclared; -ForwardDeclared *forwardPointer(); - -void externalForwardDeclaration() -{ - struct Wrapper { QSharedPointer pointer; }; -} - diff --git a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp index b10b7e53ba..cb244040d8 100644 --- a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Intel Corporation. ** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -40,10 +41,17 @@ ****************************************************************************/ #include "forwarddeclared.h" +#include "qsharedpointer.h" -ForwardDeclared *forwardPointer() +class ForwardDeclared { - return new ForwardDeclared; +public: + ~ForwardDeclared(); +}; + +QSharedPointer *forwardPointer() +{ + return new QSharedPointer(new ForwardDeclared); } int forwardDeclaredDestructorRunCount; diff --git a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h index 23f6dbf24c..604e7fd70d 100644 --- a/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h +++ b/tests/auto/corelib/tools/qsharedpointer/forwarddeclared.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Intel Corporation. ** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -43,12 +44,17 @@ #define FORWARDDECLARED_H extern int forwardDeclaredDestructorRunCount; -class ForwardDeclared -{ -public: - ~ForwardDeclared(); -}; +class ForwardDeclared; -ForwardDeclared *forwardPointer(); +#ifdef QT_NAMESPACE +namespace QT_NAMESPACE { +#endif +template class QSharedPointer; +#ifdef QT_NAMESPACE +} +using namespace QT_NAMESPACE; +#endif + +QSharedPointer *forwardPointer(); #endif // FORWARDDECLARED_H diff --git a/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro b/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro index eaea328ac8..e63ef1a261 100644 --- a/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro +++ b/tests/auto/corelib/tools/qsharedpointer/qsharedpointer.pro @@ -4,7 +4,6 @@ TARGET = tst_qsharedpointer QT = core testlib SOURCES = tst_qsharedpointer.cpp \ - forwarddeclaration.cpp \ forwarddeclared.cpp \ wrapper.cpp diff --git a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp index 7c3f0e5415..b8cf0a7b78 100644 --- a/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/corelib/tools/qsharedpointer/tst_qsharedpointer.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies). +** Copyright (C) 2012 Intel Corporation. ** Contact: http://www.qt-project.org/ ** ** This file is part of the test suite of the Qt Toolkit. @@ -48,6 +49,7 @@ #include #include "externaltests.h" +#include "forwarddeclared.h" #include "wrapper.h" #include @@ -68,9 +70,9 @@ private slots: void basics(); void operators(); void swap(); - void forwardDeclaration1(); - void forwardDeclaration2(); + void useOfForwardDeclared(); void memoryManagement(); + void dropLastReferenceOfForwardDeclared(); void downCast(); void functionCallDownCast(); void upCast(); @@ -341,43 +343,12 @@ void tst_QSharedPointer::swap() QVERIFY(*p1 == 42); } -class ForwardDeclared; -ForwardDeclared *forwardPointer(); -void externalForwardDeclaration(); -extern int forwardDeclaredDestructorRunCount; - -void tst_QSharedPointer::forwardDeclaration1() +void tst_QSharedPointer::useOfForwardDeclared() { -#if defined(Q_CC_SUN) || defined(Q_CC_WINSCW) || defined(Q_CC_RVCT) - QSKIP("This type of forward declaration is not valid with this compiler"); -#else - externalForwardDeclaration(); - - struct Wrapper { QSharedPointer pointer; }; - - forwardDeclaredDestructorRunCount = 0; - { - Wrapper w; - w.pointer = QSharedPointer(forwardPointer()); - QVERIFY(!w.pointer.isNull()); - } - QCOMPARE(forwardDeclaredDestructorRunCount, 1); -#endif + // this just a compile test: use the forward-declared class + QSharedPointer sp; } -#include "forwarddeclared.h" - -void tst_QSharedPointer::forwardDeclaration2() -{ - forwardDeclaredDestructorRunCount = 0; - { - struct Wrapper { QSharedPointer pointer; }; - Wrapper w1, w2; - w1.pointer = QSharedPointer(forwardPointer()); - QVERIFY(!w1.pointer.isNull()); - } - QCOMPARE(forwardDeclaredDestructorRunCount, 1); -} void tst_QSharedPointer::memoryManagement() { @@ -444,6 +415,15 @@ void tst_QSharedPointer::memoryManagement() QCOMPARE(ptr.data(), (Data*)0); } +void tst_QSharedPointer::dropLastReferenceOfForwardDeclared() +{ + // pointer to shared-pointer is weird, but we need to do it so that + // we can drop the last reference in a different .cpp than where it was created + forwardDeclaredDestructorRunCount = 0; + delete forwardPointer(); + QCOMPARE(forwardDeclaredDestructorRunCount, 1); +} + class DerivedData: public Data { public: @@ -1715,17 +1695,6 @@ void tst_QSharedPointer::invalidConstructs_data() "ptr = new Data;"; // use of forward-declared class - QTest::newRow("forward-declaration") -#ifdef Q_CC_CLANG - // Deleting a forward declaration is undefined, which results in a linker error with clang - << &QTest::QExternalTest::tryLinkFail -#else - // Other compilers accept the code, but do not call the destructor at run-time - << &QTest::QExternalTest::tryRun -#endif - << "forwardDeclaredDestructorRunCount = 0;\n" - "{ QSharedPointer ptr = QSharedPointer(forwardPointer()); }\n" - "exit(forwardDeclaredDestructorRunCount);"; QTest::newRow("creating-forward-declaration") << &QTest::QExternalTest::tryCompileFail << "QSharedPointer::create();"; @@ -1839,7 +1808,6 @@ void tst_QSharedPointer::invalidConstructs() QTest::QExternalTest test; test.setQtModules(QTest::QExternalTest::QtCore); - test.setExtraProgramSources(QStringList() << QFINDTESTDATA("forwarddeclared.cpp")); test.setProgramHeader( "#define QT_SHAREDPOINTER_TRACK_POINTERS\n" "#define QT_DEBUG\n" @@ -1849,9 +1817,7 @@ void tst_QSharedPointer::invalidConstructs() "struct Data { int i; };\n" "struct DerivedData: public Data { int j; };\n" "\n" - "extern int forwardDeclaredDestructorRunCount;\n" "class ForwardDeclared;\n" - "ForwardDeclared *forwardPointer();\n" ); QFETCH(QString, code);