QSimplex: split QConcreteSimplexVariable from QSimplexVariable
The latter was used both as a concrete type as well as a base class, driving Coverity nuts because it couldn't prove that we weren't deleting derived classes (AnchorData) through a QSimplexVariable pointer. This is the same issue that Coverity took with QBrushData (CIDs 218724, 11772), and the solution is the same (cf. 3bbc9e29ef59683351cf35c19a8bd4a030615c64): Split the Janus-headed class into one that acts only as the base class (and has a protected dtor) and one that only acts as a concrete class (and we can mark it final). The protected dtor in the former now statically ensures we don't delete a derived class object through a QSimplexVariable pointer. We don't need to modify AnchorData subclasses, because AnchorData introduces a virtual destructor. Coverity-Id: 390828 Pick-to: 6.8 6.5 Change-Id: I981c02e69af44ebacd4ba3aec76792e14eb15836 Reviewed-by: Mate Barany <mate.barany@qt.io> (cherry picked from commit a405834ae694ef791d0b648b9a6bb65b67904731) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
5ed1dcd1cc
commit
ef60ea194e
@ -2764,11 +2764,11 @@ enum slackType { Grower = -1, Shrinker = 1 };
|
||||
static auto createSlack(QSimplexConstraint *sizeConstraint, qreal interval, slackType type)
|
||||
{
|
||||
struct R {
|
||||
QSimplexVariable *slack;
|
||||
QConcreteSimplexVariable *slack;
|
||||
QSimplexConstraint *limit;
|
||||
};
|
||||
|
||||
QSimplexVariable *slack = new QSimplexVariable;
|
||||
auto slack = new QConcreteSimplexVariable;
|
||||
sizeConstraint->variables.insert(slack, type);
|
||||
|
||||
QSimplexConstraint *limit = new QSimplexConstraint;
|
||||
@ -2783,7 +2783,7 @@ bool QGraphicsAnchorLayoutPrivate::solvePreferred(const QList<QSimplexConstraint
|
||||
const QList<AnchorData *> &variables)
|
||||
{
|
||||
QList<QSimplexConstraint *> preferredConstraints;
|
||||
QList<QSimplexVariable *> preferredVariables;
|
||||
QList<QConcreteSimplexVariable *> preferredVariables;
|
||||
QSimplexConstraint objective;
|
||||
|
||||
// Fill the objective coefficients for this variable. In the
|
||||
|
@ -156,28 +156,28 @@ bool QSimplex::setConstraints(const QList<QSimplexConstraint *> &newConstraints)
|
||||
QList <QSimplexVariable *> artificialList;
|
||||
|
||||
for (int i = 0; i < constraints.size(); ++i) {
|
||||
QSimplexVariable *slack;
|
||||
QSimplexVariable *surplus;
|
||||
QSimplexVariable *artificial;
|
||||
QConcreteSimplexVariable *slack;
|
||||
QConcreteSimplexVariable *surplus;
|
||||
QConcreteSimplexVariable *artificial;
|
||||
|
||||
Q_ASSERT(constraints[i]->helper.first == 0);
|
||||
Q_ASSERT(constraints[i]->artificial == nullptr);
|
||||
|
||||
switch(constraints[i]->ratio) {
|
||||
case QSimplexConstraint::LessOrEqual:
|
||||
slack = new QSimplexVariable;
|
||||
slack = new QConcreteSimplexVariable;
|
||||
slack->index = ++variableIndex;
|
||||
constraints[i]->helper.first = slack;
|
||||
constraints[i]->helper.second = 1.0;
|
||||
break;
|
||||
case QSimplexConstraint::MoreOrEqual:
|
||||
surplus = new QSimplexVariable;
|
||||
surplus = new QConcreteSimplexVariable;
|
||||
surplus->index = ++variableIndex;
|
||||
constraints[i]->helper.first = surplus;
|
||||
constraints[i]->helper.second = -1.0;
|
||||
Q_FALLTHROUGH();
|
||||
case QSimplexConstraint::Equal:
|
||||
artificial = new QSimplexVariable;
|
||||
artificial = new QConcreteSimplexVariable;
|
||||
constraints[i]->artificial = artificial;
|
||||
artificialList += constraints[i]->artificial;
|
||||
break;
|
||||
|
@ -29,8 +29,14 @@ struct QSimplexVariable
|
||||
|
||||
qreal result;
|
||||
int index;
|
||||
protected:
|
||||
QT_DECLARE_RO5_SMF_AS_DEFAULTED(QSimplexVariable)
|
||||
};
|
||||
|
||||
// "pure" QSimplexVariable without the protected destructor
|
||||
struct QConcreteSimplexVariable final : QSimplexVariable
|
||||
{
|
||||
};
|
||||
|
||||
/*!
|
||||
\internal
|
||||
@ -59,8 +65,8 @@ struct QSimplexConstraint final
|
||||
qreal constant;
|
||||
Ratio ratio;
|
||||
|
||||
std::pair<QSimplexVariable *, qreal> helper;
|
||||
QSimplexVariable * artificial;
|
||||
std::pair<QConcreteSimplexVariable *, qreal> helper;
|
||||
QConcreteSimplexVariable *artificial;
|
||||
|
||||
void invert();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user