diff options
authorMarc Mutz <>2016-01-06 17:46:11 +0100
committerMarc Mutz <>2016-01-09 15:18:50 +0000
commit1e2b42523f3a04fc3403ef6864bbcba447e4362c (patch)
parent889fcfbf2b97c71146d182277068e7fbdb06587f (diff)
Fix UB in tst_QObject::disconnectDoesNotLeakFunctor()
If CountedStruct is passed a GetSenderObject object, it will attempt to call a member on it from within its own destructor. That works usually quite well, but in this test case, which tests for function object leaks when a connection is torn down because the sender object is destroyed, the destruction of the CountedStruct happens when all connections are severed in ~QObject. At that point, what used to be a GetSenderObject instance no longer is one and the call into one of its member functions invokes undefined behavior. Fix by making QObject::sender() public by a using declaration instead of a wrapper function. Found by UBSan: tests/auto/corelib/kernel/qobject/tst_qobject.cpp:6007:104: runtime error: member call on address 0x7ffc6e7538b0 which does not point to an object of type 'GetSenderObject' 0x7ffc6e7538b0: note: object is of type 'QObject' Change-Id: Ia973140037b3c1b5a670a8a3949d09b956f40349 Reviewed-by: Olivier Goffart (Woboq GmbH) <>
1 files changed, 3 insertions, 3 deletions
diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
index aa6ab31065..5b1dad78cf 100644
--- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
+++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp
@@ -5987,7 +5987,7 @@ class GetSenderObject : public QObject
- QObject *accessSender() { return sender(); }
+ using QObject::sender; // make public
public Q_SLOTS:
void triggerSignal() { Q_EMIT aSignal(); }
@@ -6003,8 +6003,8 @@ struct CountedStruct
CountedStruct(GetSenderObject *sender) : sender(sender) { ++countedStructObjectsCount; }
CountedStruct(const CountedStruct &o) : sender(o.sender) { ++countedStructObjectsCount; }
CountedStruct &operator=(const CountedStruct &) { return *this; }
- // accessSender here allows us to check if there's a deadlock
- ~CountedStruct() { --countedStructObjectsCount; if (sender != Q_NULLPTR) (void)sender->accessSender(); }
+ // calling sender() here allows us to check if there's a deadlock
+ ~CountedStruct() { --countedStructObjectsCount; if (sender) (void)sender->sender(); }
void operator()() const { }
GetSenderObject *sender;