Details
-
Bug
-
Resolution: Fixed
-
P1: Critical
-
5.13.0 Alpha 1, 5.13.2, 5.14.2, 5.15.0
Description
When a simple value type with Q_GADGET is passed from C++ side to QML, and from there to another signal the value type object gets destroyed and the signal receives a null object.
Here's a sample log:
cpp: void __cdecl PointFactory::create(const class QString &) cpp: __cdecl Point::Point(void) 0xf0c66f73e8 this.index: 1 cpp: __cdecl Point::Point(const class Point &) this: 0xf0c66f73f8 this.index: 2 other: 0xf0c66f73e8 other.index 1 cpp: __cdecl Point::Point(const class Point &) this: 0x294c6612410 this.index: 3 other: 0xf0c66f73f8 other.index 2 cpp: __cdecl Point::Point(const class Point &) this: 0x294c6e31d10 this.index: 4 other: 0x294c6612410 other.index 3 cpp: __cdecl Point::~Point(void) 0x294c6612410 this.index: 3 qml: onPointCreated Before signal1: Point(Test, 4) cpp: __cdecl Point::Point(const class Point &) this: 0x294c6611390 this.index: 5 other: 0x294c6e31d10 other.index 4 cpp: __cdecl Point::~Point(void) 0x294c6611390 this.index: 5 qml: onSignal1: null qml: onSignal2: null qml: func: Point(Test, 4) qml: onPointCreated After signal1: Point(Test, 4) cpp: __cdecl Point::~Point(void) 0xf0c66f73f8 this.index: 2 cpp: __cdecl Point::~Point(void) 0xf0c66f73e8 this.index: 1 ---- Quit App cpp: __cdecl Point::~Point(void) 0x294c6e31d10 this.index: 4
In the example, a `Point` object is created on the stack and passed to the QML side with a signal. `Point` is successfully copied during that transfer and the signal handler `onPointCreated` properly receives the `Point`.
But when the signal handler `onPointCreated` passes the `Point` to another signal, the `Point` gets copied but then immediately destroyed. Then `onSignal1` receives a null object.
If I pass the first `Point` object to a JavaScript function, it works as expected. But you'll notice that in that case the `Point` object is not actually copied but passed as a reference.
Also, If you look at the log, the `Point` object with index 4 is only destroyed when I close the app. If I click on the button multiple times, there will be a pool of `Point` objects that are not destroyed until I close the app. For instance, try clicking the button 10 times and then clear the output, then close the app. You'll see logs for 10 `Point` objects being destroyed.