As reported in https://sourceforge.net/p/cppcheck/discussion/general/thread/fa43fb8ab1/ removeContradiction() minValue/maxValue.remove(..) can access free'd memory as it removes all matching values by iterating over the complete list. Creating a full copy instead of a reference avoids this issue. Signed-off-by: Dirk Müller <dirk@dmllr.de>
This commit is contained in:
parent
49da3e3821
commit
76695f6be2
|
@ -240,21 +240,25 @@ static void addInlineSuppressions(const simplecpp::TokenList &tokens, const Sett
|
||||||
if (!inlineSuppressionsBlockBegin.empty()) {
|
if (!inlineSuppressionsBlockBegin.empty()) {
|
||||||
const Suppressions::Suppression lastBeginSuppression = inlineSuppressionsBlockBegin.back();
|
const Suppressions::Suppression lastBeginSuppression = inlineSuppressionsBlockBegin.back();
|
||||||
|
|
||||||
for (const Suppressions::Suppression &supprBegin : inlineSuppressionsBlockBegin)
|
auto supprBegin = inlineSuppressionsBlockBegin.begin();
|
||||||
|
while (supprBegin != inlineSuppressionsBlockBegin.end())
|
||||||
{
|
{
|
||||||
if (lastBeginSuppression.lineNumber != supprBegin.lineNumber)
|
if (lastBeginSuppression.lineNumber != supprBegin->lineNumber) {
|
||||||
|
++supprBegin;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (suppr.symbolName == supprBegin.symbolName && suppr.lineNumber > supprBegin.lineNumber) {
|
if (suppr.symbolName == supprBegin->symbolName && suppr.lineNumber > supprBegin->lineNumber) {
|
||||||
suppr.lineBegin = supprBegin.lineNumber;
|
suppr.lineBegin = supprBegin->lineNumber;
|
||||||
suppr.lineEnd = suppr.lineNumber;
|
suppr.lineEnd = suppr.lineNumber;
|
||||||
suppr.lineNumber = supprBegin.lineNumber;
|
suppr.lineNumber = supprBegin->lineNumber;
|
||||||
suppr.type = Suppressions::Type::block;
|
suppr.type = Suppressions::Type::block;
|
||||||
inlineSuppressionsBlockBegin.remove(supprBegin);
|
inlineSuppressionsBlockBegin.erase(supprBegin);
|
||||||
suppressions.addSuppression(std::move(suppr));
|
suppressions.addSuppression(std::move(suppr));
|
||||||
throwError = false;
|
throwError = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
++supprBegin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2052,64 +2052,68 @@ static bool isAdjacent(const ValueFlow::Value& x, const ValueFlow::Value& y)
|
||||||
return std::abs(x.intvalue - y.intvalue) == 1;
|
return std::abs(x.intvalue - y.intvalue) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool removePointValue(std::list<ValueFlow::Value>& values, ValueFlow::Value& x)
|
static bool removePointValue(std::list<ValueFlow::Value>& values, std::list<ValueFlow::Value>::iterator& x)
|
||||||
{
|
{
|
||||||
const bool isPoint = x.bound == ValueFlow::Value::Bound::Point;
|
const bool isPoint = x->bound == ValueFlow::Value::Bound::Point;
|
||||||
if (!isPoint)
|
if (!isPoint)
|
||||||
x.decreaseRange();
|
x->decreaseRange();
|
||||||
else
|
else
|
||||||
values.remove(x);
|
x = values.erase(x);
|
||||||
return isPoint;
|
return isPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool removeContradiction(std::list<ValueFlow::Value>& values)
|
static bool removeContradiction(std::list<ValueFlow::Value>& values)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
for (ValueFlow::Value& x : values) {
|
for (auto itx = values.begin(); itx != values.end(); ++itx) {
|
||||||
if (x.isNonValue())
|
if (itx->isNonValue())
|
||||||
continue;
|
continue;
|
||||||
for (ValueFlow::Value& y : values) {
|
|
||||||
if (y.isNonValue())
|
auto ity = itx;
|
||||||
|
++ity;
|
||||||
|
for (; ity != values.end(); ++ity) {
|
||||||
|
if (ity->isNonValue())
|
||||||
continue;
|
continue;
|
||||||
if (x == y)
|
if (*itx == *ity)
|
||||||
continue;
|
continue;
|
||||||
if (x.valueType != y.valueType)
|
if (itx->valueType != ity->valueType)
|
||||||
continue;
|
continue;
|
||||||
if (x.isImpossible() == y.isImpossible())
|
if (itx->isImpossible() == ity->isImpossible())
|
||||||
continue;
|
continue;
|
||||||
if (x.isSymbolicValue() && !ValueFlow::Value::sameToken(x.tokvalue, y.tokvalue))
|
if (itx->isSymbolicValue() && !ValueFlow::Value::sameToken(itx->tokvalue, ity->tokvalue))
|
||||||
continue;
|
continue;
|
||||||
if (!x.equalValue(y)) {
|
if (!itx->equalValue(*ity)) {
|
||||||
auto compare = [](const ValueFlow::Value& x, const ValueFlow::Value& y) {
|
auto compare = [](const std::list<ValueFlow::Value>::const_iterator& x, const std::list<ValueFlow::Value>::const_iterator& y) {
|
||||||
return x.compareValue(y, less{});
|
return x->compareValue(*y, less{});
|
||||||
};
|
};
|
||||||
const ValueFlow::Value& maxValue = std::max(x, y, compare);
|
auto itMax = std::max(itx, ity, compare);
|
||||||
const ValueFlow::Value& minValue = std::min(x, y, compare);
|
auto itMin = std::min(itx, ity, compare);
|
||||||
// TODO: Adjust non-points instead of removing them
|
// TODO: Adjust non-points instead of removing them
|
||||||
if (maxValue.isImpossible() && maxValue.bound == ValueFlow::Value::Bound::Upper) {
|
if (itMax->isImpossible() && itMax->bound == ValueFlow::Value::Bound::Upper) {
|
||||||
values.remove(minValue);
|
values.erase(itMin);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (minValue.isImpossible() && minValue.bound == ValueFlow::Value::Bound::Lower) {
|
if (itMin->isImpossible() && itMin->bound == ValueFlow::Value::Bound::Lower) {
|
||||||
values.remove(maxValue);
|
values.erase(itMax);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const bool removex = !x.isImpossible() || y.isKnown();
|
const bool removex = !itx->isImpossible() || ity->isKnown();
|
||||||
const bool removey = !y.isImpossible() || x.isKnown();
|
const bool removey = !ity->isImpossible() || itx->isKnown();
|
||||||
if (x.bound == y.bound) {
|
if (itx->bound == ity->bound) {
|
||||||
if (removex)
|
if (removex)
|
||||||
values.remove(x);
|
values.erase(itx);
|
||||||
if (removey)
|
if (removey)
|
||||||
values.remove(y);
|
values.erase(ity);
|
||||||
|
// itx and ity are invalidated
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
result = removex || removey;
|
result = removex || removey;
|
||||||
bool bail = false;
|
bool bail = false;
|
||||||
if (removex && removePointValue(values, x))
|
if (removex && removePointValue(values, itx))
|
||||||
bail = true;
|
bail = true;
|
||||||
if (removey && removePointValue(values, y))
|
if (removey && removePointValue(values, ity))
|
||||||
bail = true;
|
bail = true;
|
||||||
if (bail)
|
if (bail)
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue