From 3e986578980f1c37e282ee15068fa250a763209d Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Tue, 20 May 2025 20:38:38 +0200 Subject: [PATCH] QPainter: make Private::d_ptrs a QVLA This way, we remove the impedance mismatch between QPainter::d_ptr (which already is a unique_ptr) and Private::d_ptrs, which still dealt in raw pointers, simplifying the code. Since we're now owning the objects in d_ptrs, add an assertion that d_ptrs is empty on QPainter destruction. Coverity-Id: 425479 Change-Id: I849e80752b4bc5a71aef8d47663c6ffc9fdca9f7 Reviewed-by: Matthias Rauter Reviewed-by: Axel Spoerl --- src/gui/painting/qpainter.cpp | 13 +++++-------- src/gui/painting/qpainter_p.h | 2 +- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 2982f05f2a3..b800952ae39 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -247,11 +247,7 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) // the current d_ptr to the shared painter's d_ptr. sp->save(); ++sp->d_ptr->refcount; - { - // ensure realloc happens before the unique_ptr::release(): - auto &p = sp->d_ptr->d_ptrs.emplace_back(); - p = q->d_ptr.release(); - } + sp->d_ptr->d_ptrs.push_back(std::move(q->d_ptr)); q->d_ptr.reset(sp->d_ptr.get()); Q_ASSERT(q->d_ptr->state); @@ -296,19 +292,19 @@ void QPainterPrivate::detachPainterPrivate(QPainter *q) Q_ASSERT(q); --refcount; - QPainterPrivate *original = d_ptrs.back(); + auto original = std::move(d_ptrs.back()); d_ptrs.pop_back(); if (inDestructor) { inDestructor = false; if (original) original->inDestructor = true; } else if (!original) { - original = new QPainterPrivate(q); + original = std::make_unique(q); } q->restore(); Q_UNUSED(q->d_ptr.release()); - q->d_ptr.reset(original); + q->d_ptr = std::move(original); if (emulationEngine) { extended = emulationEngine->real_engine; @@ -1488,6 +1484,7 @@ QPainter::~QPainter() Q_ASSERT(d_ptr->inDestructor); d_ptr->inDestructor = false; Q_ASSERT(d_ptr->refcount == 1); + Q_ASSERT(d_ptr->d_ptrs.empty()); } } diff --git a/src/gui/painting/qpainter_p.h b/src/gui/painting/qpainter_p.h index 0ddd78fb2a4..dd4653a5788 100644 --- a/src/gui/painting/qpainter_p.h +++ b/src/gui/painting/qpainter_p.h @@ -166,7 +166,7 @@ public: // redirections within the same paintEvent(), which should be enough // in 99% of all cases). E.g: A renders B which renders C which renders D. static constexpr qsizetype NDPtrs = 4; - QVarLengthArray d_ptrs; + QVarLengthArray, NDPtrs> d_ptrs; std::unique_ptr state; template