Refactorization: Allocate Token::_values (ValueFlow information) dynamically, reducing size of each token by around 10%

This commit is contained in:
PKEuS 2017-03-27 18:48:34 +02:00
parent 2938278f00
commit 3c8f5b85ae
17 changed files with 190 additions and 152 deletions

View File

@ -87,7 +87,7 @@ static bool match(const Token *tok, const std::string &rhs)
{ {
if (tok->str() == rhs) if (tok->str() == rhs)
return true; return true;
if (tok->isName() && !tok->varId() && tok->values.size() == 1U && tok->values.front().isKnown() && MathLib::toString(tok->values.front().intvalue) == rhs) if (tok->isName() && !tok->varId() && tok->values().size() == 1U && tok->values().front().isKnown() && MathLib::toString(tok->values().front().intvalue) == rhs)
return true; return true;
return false; return false;
} }

View File

@ -119,7 +119,7 @@ bool CheckAutoVariables::isAutoVarArray(const Token *tok)
// ValueFlow // ValueFlow
if (var->isPointer() && !var->isArgument()) { if (var->isPointer() && !var->isArgument()) {
for (std::list<ValueFlow::Value>::const_iterator it = tok->values.begin(); it != tok->values.end(); ++it) { for (std::list<ValueFlow::Value>::const_iterator it = tok->values().begin(); it != tok->values().end(); ++it) {
const ValueFlow::Value &val = *it; const ValueFlow::Value &val = *it;
if (val.isTokValue() && isAutoVarArray(val.tokvalue)) if (val.isTokValue() && isAutoVarArray(val.tokvalue))
return true; return true;

View File

@ -1132,7 +1132,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
if (!value) if (!value)
continue; continue;
for (std::list<ValueFlow::Value>::const_iterator it = tok->values.begin(); it != tok->values.end(); ++it) { for (std::list<ValueFlow::Value>::const_iterator it = tok->values().begin(); it != tok->values().end(); ++it) {
if (!it->isTokValue() || !it->tokvalue) if (!it->isTokValue() || !it->tokvalue)
continue; continue;
const Variable *var = it->tokvalue->variable(); const Variable *var = it->tokvalue->variable();

View File

@ -261,8 +261,8 @@ void CheckCondition::checkBadBitmaskCheck()
(parent->str() == "(" && Token::Match(parent->astOperand1(), "if|while")) || (parent->str() == "(" && Token::Match(parent->astOperand1(), "if|while")) ||
(parent->str() == "return" && parent->astOperand1() == tok && inBooleanFunction(tok)); (parent->str() == "return" && parent->astOperand1() == tok && inBooleanFunction(tok));
const bool isTrue = (tok->astOperand1()->values.size() == 1 && tok->astOperand1()->values.front().intvalue != 0 && tok->astOperand1()->values.front().isKnown()) || const bool isTrue = (tok->astOperand1()->values().size() == 1 && tok->astOperand1()->values().front().intvalue != 0 && tok->astOperand1()->values().front().isKnown()) ||
(tok->astOperand2()->values.size() == 1 && tok->astOperand2()->values.front().intvalue != 0 && tok->astOperand2()->values.front().isKnown()); (tok->astOperand2()->values().size() == 1 && tok->astOperand2()->values().front().intvalue != 0 && tok->astOperand2()->values().front().isKnown());
if (isBoolean && isTrue) if (isBoolean && isTrue)
badBitmaskCheckError(tok); badBitmaskCheckError(tok);
@ -1049,7 +1049,7 @@ void CheckCondition::alwaysTrueFalse()
if (isExpandedMacro) if (isExpandedMacro)
continue; continue;
alwaysTrueFalseError(tok, tok->values.front().intvalue != 0); alwaysTrueFalseError(tok, tok->values().front().intvalue != 0);
} }
} }
} }

View File

@ -474,8 +474,8 @@ static bool findFormat(unsigned int arg, const Token *firstArg,
argTok->variable()->dimensionKnown(0) && argTok->variable()->dimensionKnown(0) &&
argTok->variable()->dimension(0) != 0))) { argTok->variable()->dimension(0) != 0))) {
*formatArgTok = argTok->nextArgument(); *formatArgTok = argTok->nextArgument();
if (!argTok->values.empty() && argTok->values.front().isTokValue() && argTok->values.front().tokvalue && argTok->values.front().tokvalue->tokType() == Token::eString) if (!argTok->values().empty() && argTok->values().front().isTokValue() && argTok->values().front().tokvalue && argTok->values().front().tokvalue->tokType() == Token::eString)
*formatStringTok = argTok->values.front().tokvalue; *formatStringTok = argTok->values().front().tokvalue;
return true; return true;
} }
return false; return false;

View File

@ -547,7 +547,7 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const Va
if (arg->str() == "&") if (arg->str() == "&")
arg = arg->next(); arg = arg->next();
bool isnull = arg->hasKnownIntValue() && arg->values.front().intvalue == 0; bool isnull = arg->hasKnownIntValue() && arg->values().front().intvalue == 0;
// Is variable allocated? // Is variable allocated?
if (!isnull && (!af || af->arg == argNr)) if (!isnull && (!af || af->arg == argNr))

View File

@ -481,18 +481,18 @@ static bool alwaysTrue(const Token *tok)
{ {
if (!tok) if (!tok)
return false; return false;
if (tok->values.size() == 1U && if (tok->values().size() == 1U &&
tok->values.front().intvalue != 0 && tok->values().front().intvalue != 0 &&
tok->values.front().isKnown()) tok->values().front().isKnown())
return true; return true;
if (tok->str() == "||") if (tok->str() == "||")
return alwaysTrue(tok->astOperand1()) || alwaysTrue(tok->astOperand2()); return alwaysTrue(tok->astOperand1()) || alwaysTrue(tok->astOperand2());
if (tok->str() == "true") if (tok->str() == "true")
return true; return true;
return (tok->isComparisonOp() && return (tok->isComparisonOp() &&
tok->values.size() == 1U && tok->values().size() == 1U &&
tok->values.front().isKnown() && tok->values().front().isKnown() &&
tok->values.front().intvalue != 0); tok->values().front().intvalue != 0);
} }
bool CheckMemoryLeakInFunction::test_white_list(const std::string &funcname, const Settings *settings, bool cpp) bool CheckMemoryLeakInFunction::test_white_list(const std::string &funcname, const Settings *settings, bool cpp)

View File

@ -284,7 +284,7 @@ void CheckOther::warningOldStylePointerCast()
tok = tok->next(); tok = tok->next();
const Token *p = tok->tokAt(4); const Token *p = tok->tokAt(4);
if (p->hasKnownIntValue() && p->values.front().intvalue==0) // Casting nullpointers is safe if (p->hasKnownIntValue() && p->values().front().intvalue==0) // Casting nullpointers is safe
continue; continue;
// Is "type" a class? // Is "type" a class?

View File

@ -337,7 +337,7 @@ void CheckType::checkFloatToIntegerOverflow()
continue; continue;
const Token *op1 = tok->astOperand1(); const Token *op1 = tok->astOperand1();
for (std::list<ValueFlow::Value>::const_iterator it = op1->values.begin(); it != op1->values.end(); ++it) { for (std::list<ValueFlow::Value>::const_iterator it = op1->values().begin(); it != op1->values().end(); ++it) {
if (it->valueType != ValueFlow::Value::FLOAT) if (it->valueType != ValueFlow::Value::FLOAT)
continue; continue;
if (it->inconclusive && !_settings->inconclusive) if (it->inconclusive && !_settings->inconclusive)

View File

@ -219,8 +219,8 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<unsigned
} }
else if (tok->isComparisonOp()) { else if (tok->isComparisonOp()) {
if (tok->values.size() == 1U && tok->values.front().isKnown()) { if (tok->values().size() == 1U && tok->values().front().isKnown()) {
if (tok->values.front().intvalue) if (tok->values().front().intvalue)
*alwaysTrue = true; *alwaysTrue = true;
else else
*alwaysFalse = true; *alwaysFalse = true;

View File

@ -1016,7 +1016,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
Token::Match(tok, "%name% ;") && Token::Match(tok, "%name% ;") &&
tok->varId() == 0 && tok->varId() == 0 &&
tok->hasKnownIntValue() && tok->hasKnownIntValue() &&
tok->values.front().intvalue == 0) { tok->values().front().intvalue == 0) {
variables.use(varid1, tok); variables.use(varid1, tok);
} else { } else {
variables.write(varid1, tok); variables.write(varid1, tok);

View File

@ -1321,8 +1321,8 @@ void SymbolDatabase::createSymbolDatabaseEnums()
ValueFlow::valueFlowConstantFoldAST(rhs, _settings); ValueFlow::valueFlowConstantFoldAST(rhs, _settings);
// get constant folded value: // get constant folded value:
if (rhs && rhs->values.size() == 1U && rhs->values.front().isKnown()) { if (rhs && rhs->values().size() == 1U && rhs->values().front().isKnown()) {
enumerator.value = rhs->values.front().intvalue; enumerator.value = rhs->values().front().intvalue;
enumerator.value_known = true; enumerator.value_known = true;
value = enumerator.value + 1; value = enumerator.value + 1;
} }
@ -1425,8 +1425,8 @@ void SymbolDatabase::createSymbolDatabaseUnknownArrayDimensions()
ValueFlow::valueFlowConstantFoldAST(rhs, _settings); ValueFlow::valueFlowConstantFoldAST(rhs, _settings);
// get constant folded value: // get constant folded value:
if (rhs && rhs->values.size() == 1U && rhs->values.front().isKnown()) { if (rhs && rhs->values().size() == 1U && rhs->values().front().isKnown()) {
dimension.num = rhs->values.front().intvalue; dimension.num = rhs->values().front().intvalue;
dimension.known = true; dimension.known = true;
} }
} }

View File

@ -50,7 +50,8 @@ Token::Token(Token **t) :
_astOperand2(nullptr), _astOperand2(nullptr),
_astParent(nullptr), _astParent(nullptr),
_originalName(nullptr), _originalName(nullptr),
valuetype(nullptr) valuetype(nullptr),
_values(nullptr)
{ {
} }
@ -58,6 +59,7 @@ Token::~Token()
{ {
delete _originalName; delete _originalName;
delete valuetype; delete valuetype;
delete _values;
} }
void Token::update_property_info() void Token::update_property_info()
@ -213,7 +215,7 @@ void Token::swapWithNext()
std::swap(_scope, _next->_scope); std::swap(_scope, _next->_scope);
std::swap(_function, _next->_function); std::swap(_function, _next->_function);
std::swap(_originalName, _next->_originalName); std::swap(_originalName, _next->_originalName);
std::swap(values, _next->values); std::swap(_values, _next->_values);
std::swap(valuetype, _next->valuetype); std::swap(valuetype, _next->valuetype);
std::swap(_progressValue, _next->_progressValue); std::swap(_progressValue, _next->_progressValue);
} }
@ -236,7 +238,11 @@ void Token::deleteThis()
_originalName = _next->_originalName; _originalName = _next->_originalName;
_next->_originalName = nullptr; _next->_originalName = nullptr;
} }
values = _next->values; if (_next->_values) {
delete _values;
_values = _next->_values;
_next->_values = nullptr;
}
if (_next->valuetype) { if (_next->valuetype) {
delete valuetype; delete valuetype;
valuetype = _next->valuetype; valuetype = _next->valuetype;
@ -261,7 +267,11 @@ void Token::deleteThis()
_originalName = _previous->_originalName; _originalName = _previous->_originalName;
_previous->_originalName = nullptr; _previous->_originalName = nullptr;
} }
values = _previous->values; if (_previous->_values) {
delete _values;
_values = _previous->_values;
_previous->_values = nullptr;
}
if (_previous->valuetype) { if (_previous->valuetype) {
delete valuetype; delete valuetype;
valuetype = _previous->valuetype; valuetype = _previous->valuetype;
@ -1233,8 +1243,8 @@ static void astStringXml(const Token *tok, std::size_t indent, std::ostream &out
out << " variable=\"" << tok->variable() << '\"'; out << " variable=\"" << tok->variable() << '\"';
if (tok->function()) if (tok->function())
out << " function=\"" << tok->function() << '\"'; out << " function=\"" << tok->function() << '\"';
if (!tok->values.empty()) if (!tok->values().empty())
out << " values=\"" << &tok->values << '\"'; out << " values=\"" << &tok->values() << '\"';
if (!tok->astOperand1() && !tok->astOperand2()) { if (!tok->astOperand1() && !tok->astOperand2()) {
out << "/>" << std::endl; out << "/>" << std::endl;
@ -1318,19 +1328,19 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
else else
out << "\n\n##Value flow" << std::endl; out << "\n\n##Value flow" << std::endl;
for (const Token *tok = this; tok; tok = tok->next()) { for (const Token *tok = this; tok; tok = tok->next()) {
if (tok->values.empty()) if (!tok->_values)
continue; continue;
if (xml) if (xml)
out << " <values id=\"" << &tok->values << "\">" << std::endl; out << " <values id=\"" << tok->_values << "\">" << std::endl;
else if (line != tok->linenr()) else if (line != tok->linenr())
out << "Line " << tok->linenr() << std::endl; out << "Line " << tok->linenr() << std::endl;
line = tok->linenr(); line = tok->linenr();
if (!xml) { if (!xml) {
out << " " << tok->str() << (tok->values.front().isKnown() ? " always " : " possible "); out << " " << tok->str() << (tok->_values->front().isKnown() ? " always " : " possible ");
if (tok->values.size() > 1U) if (tok->_values->size() > 1U)
out << '{'; out << '{';
} }
for (std::list<ValueFlow::Value>::const_iterator it=tok->values.begin(); it!=tok->values.end(); ++it) { for (std::list<ValueFlow::Value>::const_iterator it=tok->_values->begin(); it!=tok->_values->end(); ++it) {
if (xml) { if (xml) {
out << " <value "; out << " <value ";
switch (it->valueType) { switch (it->valueType) {
@ -1357,7 +1367,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
} }
else { else {
if (it != tok->values.begin()) if (it != tok->_values->begin())
out << ","; out << ",";
switch (it->valueType) { switch (it->valueType) {
case ValueFlow::Value::INT: case ValueFlow::Value::INT:
@ -1377,7 +1387,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
} }
if (xml) if (xml)
out << " </values>" << std::endl; out << " </values>" << std::endl;
else if (tok->values.size() > 1U) else if (tok->_values->size() > 1U)
out << '}' << std::endl; out << '}' << std::endl;
else else
out << std::endl; out << std::endl;
@ -1388,9 +1398,11 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Settings *settings) const const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Settings *settings) const
{ {
if (!_values)
return nullptr;
const ValueFlow::Value *ret = nullptr; const ValueFlow::Value *ret = nullptr;
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) { for (it = _values->begin(); it != _values->end(); ++it) {
if (it->isIntValue() && it->intvalue <= val) { if (it->isIntValue() && it->intvalue <= val) {
if (!ret || ret->inconclusive || (ret->condition && !it->inconclusive)) if (!ret || ret->inconclusive || (ret->condition && !it->inconclusive))
ret = &(*it); ret = &(*it);
@ -1409,9 +1421,11 @@ const ValueFlow::Value * Token::getValueLE(const MathLib::bigint val, const Sett
const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Settings *settings) const const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Settings *settings) const
{ {
if (!_values)
return nullptr;
const ValueFlow::Value *ret = nullptr; const ValueFlow::Value *ret = nullptr;
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) { for (it = _values->begin(); it != _values->end(); ++it) {
if (it->isIntValue() && it->intvalue >= val) { if (it->isIntValue() && it->intvalue >= val) {
if (!ret || ret->inconclusive || (ret->condition && !it->inconclusive)) if (!ret || ret->inconclusive || (ret->condition && !it->inconclusive))
ret = &(*it); ret = &(*it);
@ -1430,10 +1444,12 @@ const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Sett
const Token *Token::getValueTokenMinStrSize() const const Token *Token::getValueTokenMinStrSize() const
{ {
if (!_values)
return nullptr;
const Token *ret = nullptr; const Token *ret = nullptr;
std::size_t minsize = ~0U; std::size_t minsize = ~0U;
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) { for (it = _values->begin(); it != _values->end(); ++it) {
if (it->isTokValue() && it->tokvalue && it->tokvalue->tokType() == Token::eString) { if (it->isTokValue() && it->tokvalue && it->tokvalue->tokType() == Token::eString) {
std::size_t size = getStrSize(it->tokvalue); std::size_t size = getStrSize(it->tokvalue);
if (!ret || size < minsize) { if (!ret || size < minsize) {
@ -1447,10 +1463,12 @@ const Token *Token::getValueTokenMinStrSize() const
const Token *Token::getValueTokenMaxStrLength() const const Token *Token::getValueTokenMaxStrLength() const
{ {
if (!_values)
return nullptr;
const Token *ret = nullptr; const Token *ret = nullptr;
std::size_t maxlength = 0U; std::size_t maxlength = 0U;
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) { for (it = _values->begin(); it != _values->end(); ++it) {
if (it->isTokValue() && it->tokvalue && it->tokvalue->tokType() == Token::eString) { if (it->isTokValue() && it->tokvalue && it->tokvalue->tokType() == Token::eString) {
std::size_t length = getStrLength(it->tokvalue); std::size_t length = getStrLength(it->tokvalue);
if (!ret || length > maxlength) { if (!ret || length > maxlength) {
@ -1474,7 +1492,7 @@ const Token *Token::getValueTokenDeadPointer() const
const Scope * const functionscope = getfunctionscope(this->scope()); const Scope * const functionscope = getfunctionscope(this->scope());
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) { for (it = values().begin(); it != values().end(); ++it) {
// Is this a pointer alias? // Is this a pointer alias?
if (!it->isTokValue() || (it->tokvalue && it->tokvalue->str() != "&")) if (!it->isTokValue() || (it->tokvalue && it->tokvalue->str() != "&"))
continue; continue;
@ -1502,6 +1520,61 @@ const Token *Token::getValueTokenDeadPointer() const
return nullptr; return nullptr;
} }
bool Token::addValue(const ValueFlow::Value &value)
{
if (value.isKnown() && _values) {
// Clear all other values since value is known
_values->clear();
}
if (_values) {
// Don't handle more than 10 values for performance reasons
// TODO: add setting?
if (_values->size() >= 10U)
return false;
// if value already exists, don't add it again
std::list<ValueFlow::Value>::iterator it;
for (it = _values->begin(); it != _values->end(); ++it) {
// different intvalue => continue
if (it->intvalue != value.intvalue)
continue;
// different types => continue
if (it->valueType != value.valueType)
continue;
if (value.isTokValue() && (it->tokvalue != value.tokvalue) && (it->tokvalue->str() != value.tokvalue->str()))
continue;
// same value, but old value is inconclusive so replace it
if (it->inconclusive && !value.inconclusive) {
*it = value;
if (it->varId == 0)
it->varId = _varId;
break;
}
// Same value already exists, don't add new value
return false;
}
// Add value
if (it == values().end()) {
ValueFlow::Value v(value);
if (v.varId == 0)
v.varId = _varId;
_values->push_back(v);
}
} else {
ValueFlow::Value v(value);
if (v.varId == 0)
v.varId = _varId;
_values = new std::list<ValueFlow::Value>(1, v);
}
return true;
}
void Token::assignProgressValues(Token *tok) void Token::assignProgressValues(Token *tok)
{ {
unsigned int total_count = 0; unsigned int total_count = 0;

View File

@ -736,6 +736,11 @@ public:
return _originalName ? *_originalName : emptyString; return _originalName ? *_originalName : emptyString;
} }
const std::list<ValueFlow::Value>& values() const {
static const std::list<ValueFlow::Value> emptyList;
return _values ? *_values : emptyList;
}
/** /**
* Sets the original name. * Sets the original name.
*/ */
@ -747,16 +752,14 @@ public:
*_originalName = name; *_originalName = name;
} }
/** Values of token */
std::list<ValueFlow::Value> values;
bool hasKnownIntValue() const { bool hasKnownIntValue() const {
return values.size() == 1U && values.front().isKnown() && values.front().isIntValue(); return _values && _values->size() == 1U && _values->front().isKnown() && _values->front().isIntValue();
} }
const ValueFlow::Value * getValue(const MathLib::bigint val) const { const ValueFlow::Value * getValue(const MathLib::bigint val) const {
std::list<ValueFlow::Value>::const_iterator it; if (!_values)
for (it = values.begin(); it != values.end(); ++it) { return nullptr;
for (std::list<ValueFlow::Value>::const_iterator it = _values->begin(); it != _values->end(); ++it) {
if (it->isIntValue() && it->intvalue == val) if (it->isIntValue() && it->intvalue == val)
return &(*it); return &(*it);
} }
@ -764,9 +767,10 @@ public:
} }
const ValueFlow::Value * getMaxValue(bool condition) const { const ValueFlow::Value * getMaxValue(bool condition) const {
if (!_values)
return nullptr;
const ValueFlow::Value *ret = nullptr; const ValueFlow::Value *ret = nullptr;
std::list<ValueFlow::Value>::const_iterator it; for (std::list<ValueFlow::Value>::const_iterator it = _values->begin(); it != _values->end(); ++it) {
for (it = values.begin(); it != values.end(); ++it) {
if (!it->isIntValue()) if (!it->isIntValue())
continue; continue;
if ((!ret || it->intvalue > ret->intvalue) && if ((!ret || it->intvalue > ret->intvalue) &&
@ -777,8 +781,9 @@ public:
} }
const ValueFlow::Value * getMovedValue() const { const ValueFlow::Value * getMovedValue() const {
std::list<ValueFlow::Value>::const_iterator it; if (!_values)
for (it = values.begin(); it != values.end(); ++it) { return nullptr;
for (std::list<ValueFlow::Value>::const_iterator it = _values->begin(); it != _values->end(); ++it) {
if (it->isMovedValue() && it->moveKind != ValueFlow::Value::NonMovedVariable) if (it->isMovedValue() && it->moveKind != ValueFlow::Value::NonMovedVariable)
return &(*it); return &(*it);
} }
@ -793,6 +798,9 @@ public:
const Token *getValueTokenDeadPointer() const; const Token *getValueTokenDeadPointer() const;
/** Add token value. Return true if value is added. */
bool addValue(const ValueFlow::Value &value);
private: private:
void next(Token *nextToken) { void next(Token *nextToken) {
@ -903,6 +911,9 @@ private:
// ValueType // ValueType
ValueType *valuetype; ValueType *valuetype;
// ValueFlow
std::list<ValueFlow::Value>* _values;
public: public:
void astOperand1(Token *tok); void astOperand1(Token *tok);
void astOperand2(Token *tok); void astOperand2(Token *tok);
@ -936,6 +947,11 @@ public:
_astOperand1 = _astOperand2 = _astParent = nullptr; _astOperand1 = _astOperand2 = _astParent = nullptr;
} }
void clearValueFlow() {
delete _values;
_values = nullptr;
}
std::string astString(const char *sep = "") const { std::string astString(const char *sep = "") const {
std::string ret; std::string ret;
if (_astOperand1) if (_astOperand1)

View File

@ -3666,7 +3666,7 @@ bool Tokenizer::simplifyTokenList2()
// Clear AST,ValueFlow. These will be created again at the end of this function. // Clear AST,ValueFlow. These will be created again at the end of this function.
for (Token *tok = list.front(); tok; tok = tok->next()) { for (Token *tok = list.front(); tok; tok = tok->next()) {
tok->clearAst(); tok->clearAst();
tok->values.clear(); tok->clearValueFlow();
} }
// f(x=g()) => x=g(); f(x) // f(x=g()) => x=g(); f(x)
@ -3904,8 +3904,8 @@ void Tokenizer::dump(std::ostream &out) const
out << " variable=\"" << tok->variable() << '\"'; out << " variable=\"" << tok->variable() << '\"';
if (tok->function()) if (tok->function())
out << " function=\"" << tok->function() << '\"'; out << " function=\"" << tok->function() << '\"';
if (!tok->values.empty()) if (!tok->values().empty())
out << " values=\"" << &tok->values << '\"'; out << " values=\"" << &tok->values() << '\"';
if (tok->type()) if (tok->type())
out << " type-scope=\"" << tok->type()->classScope << '\"'; out << " type-scope=\"" << tok->type()->classScope << '\"';
if (tok->astParent()) if (tok->astParent())

View File

@ -235,55 +235,6 @@ static bool bailoutSelfAssignment(const Token * const tok)
return false; return false;
} }
/** Add token value. Return true if value is added. */
static bool addValue(Token *tok, const ValueFlow::Value &value)
{
if (value.isKnown()) {
// Clear all other values since value is known
tok->values.clear();
}
// Don't handle more than 10 values for performance reasons
// TODO: add setting?
if (tok->values.size() >= 10U)
return false;
// if value already exists, don't add it again
std::list<ValueFlow::Value>::iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) {
// different intvalue => continue
if (it->intvalue != value.intvalue)
continue;
// different types => continue
if (it->valueType != value.valueType)
continue;
if (value.isTokValue() && (it->tokvalue != value.tokvalue) && (it->tokvalue->str() != value.tokvalue->str()))
continue;
// same value, but old value is inconclusive so replace it
if (it->inconclusive && !value.inconclusive) {
*it = value;
if (it->varId == 0)
it->varId = tok->varId();
break;
}
// Same value already exists, don't add new value
return false;
}
// Add value
if (it == tok->values.end()) {
ValueFlow::Value v(value);
if (v.varId == 0)
v.varId = tok->varId();
tok->values.push_back(v);
}
return true;
}
static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign sign, unsigned int bit) static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign sign, unsigned int bit)
{ {
if (value.isFloatValue()) { if (value.isFloatValue()) {
@ -302,7 +253,7 @@ static ValueFlow::Value castValue(ValueFlow::Value value, const ValueType::Sign
/** set ValueFlow value and perform calculations if possible */ /** set ValueFlow value and perform calculations if possible */
static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Settings *settings) static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Settings *settings)
{ {
if (!addValue(tok,value)) if (!tok->addValue(value))
return; return;
Token *parent = const_cast<Token*>(tok->astParent()); Token *parent = const_cast<Token*>(tok->astParent());
@ -334,8 +285,8 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
else if (parent->str() == "?" && tok->str() == ":" && tok == parent->astOperand2() && parent->astOperand1()) { else if (parent->str() == "?" && tok->str() == ":" && tok == parent->astOperand2() && parent->astOperand1()) {
// is condition always true/false? // is condition always true/false?
if (parent->astOperand1()->values.size() == 1U && parent->astOperand1()->values.front().isKnown()) { if (parent->astOperand1()->values().size() == 1U && parent->astOperand1()->values().front().isKnown()) {
const ValueFlow::Value &condvalue = parent->astOperand1()->values.front(); const ValueFlow::Value &condvalue = parent->astOperand1()->values().front();
const bool cond(condvalue.isTokValue() || (condvalue.isIntValue() && condvalue.intvalue != 0)); const bool cond(condvalue.isTokValue() || (condvalue.isIntValue() && condvalue.intvalue != 0));
if (cond && !tok->astOperand1()) { // true condition, no second operator if (cond && !tok->astOperand1()) { // true condition, no second operator
setTokenValue(parent, condvalue, settings); setTokenValue(parent, condvalue, settings);
@ -343,7 +294,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
const Token *op = cond ? tok->astOperand1() : tok->astOperand2(); const Token *op = cond ? tok->astOperand1() : tok->astOperand2();
if (!op) // #7769 segmentation fault at setTokenValue() if (!op) // #7769 segmentation fault at setTokenValue()
return; return;
const std::list<ValueFlow::Value> &values = op->values; const std::list<ValueFlow::Value> &values = op->values();
if (std::find(values.begin(), values.end(), value) != values.end()) if (std::find(values.begin(), values.end(), value) != values.end())
setTokenValue(parent, value, settings); setTokenValue(parent, value, settings);
} }
@ -382,10 +333,10 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
else if ((parent->isArithmeticalOp() || parent->isComparisonOp() || (parent->tokType() == Token::eBitOp) || (parent->tokType() == Token::eLogicalOp)) && else if ((parent->isArithmeticalOp() || parent->isComparisonOp() || (parent->tokType() == Token::eBitOp) || (parent->tokType() == Token::eLogicalOp)) &&
parent->astOperand1() && parent->astOperand1() &&
parent->astOperand2()) { parent->astOperand2()) {
const bool known = ((parent->astOperand1()->values.size() == 1U && const bool known = ((parent->astOperand1()->values().size() == 1U &&
parent->astOperand1()->values.front().isKnown()) || parent->astOperand1()->values().front().isKnown()) ||
(parent->astOperand2()->values.size() == 1U && (parent->astOperand2()->values().size() == 1U &&
parent->astOperand2()->values.front().isKnown())); parent->astOperand2()->values().front().isKnown()));
// known result when a operand is 0. // known result when a operand is 0.
if (Token::Match(parent, "[&*]") && value.isKnown() && value.isIntValue() && value.intvalue==0) { if (Token::Match(parent, "[&*]") && value.isKnown() && value.isIntValue() && value.intvalue==0) {
@ -393,13 +344,12 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
return; return;
} }
std::list<ValueFlow::Value>::const_iterator value1, value2; for (std::list<ValueFlow::Value>::const_iterator value1 = parent->astOperand1()->values().begin(); value1 != parent->astOperand1()->values().end(); ++value1) {
for (value1 = parent->astOperand1()->values.begin(); value1 != parent->astOperand1()->values.end(); ++value1) {
if (!value1->isIntValue() && !value1->isFloatValue() && !value1->isTokValue()) if (!value1->isIntValue() && !value1->isFloatValue() && !value1->isTokValue())
continue; continue;
if (value1->isTokValue() && (!parent->isComparisonOp() || value1->tokvalue->tokType() != Token::eString)) if (value1->isTokValue() && (!parent->isComparisonOp() || value1->tokvalue->tokType() != Token::eString))
continue; continue;
for (value2 = parent->astOperand2()->values.begin(); value2 != parent->astOperand2()->values.end(); ++value2) { for (std::list<ValueFlow::Value>::const_iterator value2 = parent->astOperand2()->values().begin(); value2 != parent->astOperand2()->values().end(); ++value2) {
if (!value2->isIntValue() && !value2->isFloatValue() && !value2->isTokValue()) if (!value2->isIntValue() && !value2->isFloatValue() && !value2->isTokValue())
continue; continue;
if (value2->isTokValue() && (!parent->isComparisonOp() || value2->tokvalue->tokType() != Token::eString || value1->isTokValue())) if (value2->isTokValue() && (!parent->isComparisonOp() || value2->tokvalue->tokType() != Token::eString || value1->isTokValue()))
@ -558,7 +508,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
// ! // !
else if (parent->str() == "!") { else if (parent->str() == "!") {
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) { for (it = tok->values().begin(); it != tok->values().end(); ++it) {
if (!it->isIntValue()) if (!it->isIntValue())
continue; continue;
ValueFlow::Value v(*it); ValueFlow::Value v(*it);
@ -570,7 +520,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
// ~ // ~
else if (parent->str() == "~") { else if (parent->str() == "~") {
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) { for (it = tok->values().begin(); it != tok->values().end(); ++it) {
if (!it->isIntValue()) if (!it->isIntValue())
continue; continue;
ValueFlow::Value v(*it); ValueFlow::Value v(*it);
@ -594,7 +544,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
// unary minus // unary minus
else if (parent->str() == "-" && !parent->astOperand2()) { else if (parent->str() == "-" && !parent->astOperand2()) {
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) { for (it = tok->values().begin(); it != tok->values().end(); ++it) {
if (!it->isIntValue() && !it->isFloatValue()) if (!it->isIntValue() && !it->isFloatValue())
continue; continue;
ValueFlow::Value v(*it); ValueFlow::Value v(*it);
@ -608,11 +558,10 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
// Array element // Array element
else if (parent->str() == "[" && parent->astOperand1() && parent->astOperand2()) { else if (parent->str() == "[" && parent->astOperand1() && parent->astOperand2()) {
std::list<ValueFlow::Value>::const_iterator value1, value2; for (std::list<ValueFlow::Value>::const_iterator value1 = parent->astOperand1()->values().begin(); value1 != parent->astOperand1()->values().end(); ++value1) {
for (value1 = parent->astOperand1()->values.begin(); value1 != parent->astOperand1()->values.end(); ++value1) {
if (!value1->isTokValue()) if (!value1->isTokValue())
continue; continue;
for (value2 = parent->astOperand2()->values.begin(); value2 != parent->astOperand2()->values.end(); ++value2) { for (std::list<ValueFlow::Value>::const_iterator value2 = parent->astOperand2()->values().begin(); value2 != parent->astOperand2()->values().end(); ++value2) {
if (!value2->isIntValue()) if (!value2->isIntValue())
continue; continue;
if (value1->varId == 0U || value2->varId == 0U || if (value1->varId == 0U || value2->varId == 0U ||
@ -890,7 +839,7 @@ static void valueFlowBitAnd(TokenList *tokenlist)
if (tok->str() != "&") if (tok->str() != "&")
continue; continue;
if (tok->values.size() == 1U && tok->values.front().isKnown()) if (tok->values().size() == 1U && tok->values().front().isKnown())
continue; continue;
if (!tok->astOperand1() || !tok->astOperand2()) if (!tok->astOperand1() || !tok->astOperand2())
@ -1104,10 +1053,10 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, SymbolDatabase *symbo
if (tok->isComparisonOp() && tok->astOperand1() && tok->astOperand2()) { if (tok->isComparisonOp() && tok->astOperand1() && tok->astOperand2()) {
if (tok->astOperand1()->isName() && tok->astOperand2()->hasKnownIntValue()) { if (tok->astOperand1()->isName() && tok->astOperand2()->hasKnownIntValue()) {
vartok = tok->astOperand1(); vartok = tok->astOperand1();
num = tok->astOperand2()->values.front().intvalue; num = tok->astOperand2()->values().front().intvalue;
} else if (tok->astOperand1()->hasKnownIntValue() && tok->astOperand2()->isName()) { } else if (tok->astOperand1()->hasKnownIntValue() && tok->astOperand2()->isName()) {
vartok = tok->astOperand2(); vartok = tok->astOperand2();
num = tok->astOperand1()->values.front().intvalue; num = tok->astOperand1()->values().front().intvalue;
} else { } else {
continue; continue;
} }
@ -1230,7 +1179,7 @@ static void valueFlowAST(Token *tok, unsigned int varid, const ValueFlow::Value
return; return;
} else if (tok->str() == "||" && tok->astOperand1()) { } else if (tok->str() == "||" && tok->astOperand1()) {
bool nonzero = false; bool nonzero = false;
for (std::list<ValueFlow::Value>::const_iterator it = tok->astOperand1()->values.begin(); it != tok->astOperand1()->values.end(); ++it) { for (std::list<ValueFlow::Value>::const_iterator it = tok->astOperand1()->values().begin(); it != tok->astOperand1()->values().end(); ++it) {
nonzero |= (it->intvalue != 0); nonzero |= (it->intvalue != 0);
} }
if (!nonzero) if (!nonzero)
@ -1391,7 +1340,7 @@ static bool valueFlowForward(Token * const startToken,
} }
const Token * const condTok = tok2->next()->astOperand2(); const Token * const condTok = tok2->next()->astOperand2();
const bool condAlwaysTrue = (condTok && condTok->values.size() == 1U && condTok->values.front().isKnown() && condTok->values.front().intvalue != 0); const bool condAlwaysTrue = (condTok && condTok->values().size() == 1U && condTok->values().front().isKnown() && condTok->values().front().intvalue != 0);
// Should scope be skipped because variable value is checked? // Should scope be skipped because variable value is checked?
std::list<ValueFlow::Value> truevalues; std::list<ValueFlow::Value> truevalues;
@ -1627,7 +1576,7 @@ static bool valueFlowForward(Token * const startToken,
continue; continue;
if (condition->hasKnownIntValue()) { if (condition->hasKnownIntValue()) {
const ValueFlow::Value &condValue = condition->values.front(); const ValueFlow::Value &condValue = condition->values().front();
const Token *expr = (condValue.intvalue != 0) ? op2->astOperand1() : op2->astOperand2(); const Token *expr = (condValue.intvalue != 0) ? op2->astOperand1() : op2->astOperand2();
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = values.begin(); it != values.end(); ++it) for (it = values.begin(); it != values.end(); ++it)
@ -1975,10 +1924,10 @@ static void valueFlowAfterAssign(TokenList *tokenlist, SymbolDatabase* symboldat
const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd; const Token * const endOfVarScope = var->typeStartToken()->scope()->classEnd;
// Rhs values.. // Rhs values..
if (!tok->astOperand2() || tok->astOperand2()->values.empty()) if (!tok->astOperand2() || tok->astOperand2()->values().empty())
continue; continue;
std::list<ValueFlow::Value> values = tok->astOperand2()->values; std::list<ValueFlow::Value> values = tok->astOperand2()->values();
const bool constValue = tok->astOperand2()->isNumber(); const bool constValue = tok->astOperand2()->isNumber();
if (tokenlist->isCPP() && Token::Match(var->typeStartToken(), "bool|_Bool")) { if (tokenlist->isCPP() && Token::Match(var->typeStartToken(), "bool|_Bool")) {
@ -2052,7 +2001,7 @@ static void valueFlowAfterCondition(TokenList *tokenlist, SymbolDatabase* symbol
if (!var || !(var->isLocal() || var->isGlobal() || var->isArgument())) if (!var || !(var->isLocal() || var->isGlobal() || var->isArgument()))
continue; continue;
std::list<ValueFlow::Value> values; std::list<ValueFlow::Value> values;
values.push_back(ValueFlow::Value(tok, numtok ? numtok->values.front().intvalue : 0LL)); values.push_back(ValueFlow::Value(tok, numtok ? numtok->values().front().intvalue : 0LL));
if (Token::Match(tok->astParent(), "%oror%|&&")) { if (Token::Match(tok->astParent(), "%oror%|&&")) {
Token *parent = const_cast<Token*>(tok->astParent()); Token *parent = const_cast<Token*>(tok->astParent());
@ -2186,7 +2135,7 @@ static void execute(const Token *expr,
*error = true; *error = true;
else if (expr->hasKnownIntValue()) { else if (expr->hasKnownIntValue()) {
*result = expr->values.front().intvalue; *result = expr->values().front().intvalue;
} }
else if (expr->isNumber()) { else if (expr->isNumber()) {
@ -2315,11 +2264,11 @@ static void execute(const Token *expr,
else if (expr->str() == "[" && expr->astOperand1() && expr->astOperand2()) { else if (expr->str() == "[" && expr->astOperand1() && expr->astOperand2()) {
const Token *tokvalue; const Token *tokvalue;
if (!programMemory->getTokValue(expr->astOperand1()->varId(), &tokvalue)) { if (!programMemory->getTokValue(expr->astOperand1()->varId(), &tokvalue)) {
if (expr->astOperand1()->values.size() != 1U || !expr->astOperand1()->values.front().isTokValue()) { if (expr->astOperand1()->values().size() != 1U || !expr->astOperand1()->values().front().isTokValue()) {
*error = true; *error = true;
return; return;
} }
tokvalue = expr->astOperand1()->values.front().tokvalue; tokvalue = expr->astOperand1()->values().front().tokvalue;
} }
if (!tokvalue || !tokvalue->isLiteral()) { if (!tokvalue || !tokvalue->isLiteral()) {
*error = true; *error = true;
@ -2688,7 +2637,7 @@ static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue,
return; return;
if (Token::simpleMatch(tokenList.front(), "strlen ( arg1 )") && arg1) { if (Token::simpleMatch(tokenList.front(), "strlen ( arg1 )") && arg1) {
for (std::list<ValueFlow::Value>::const_iterator it = arg1->values.begin(); it != arg1->values.end(); ++it) { for (std::list<ValueFlow::Value>::const_iterator it = arg1->values().begin(); it != arg1->values().end(); ++it) {
const ValueFlow::Value &value = *it; const ValueFlow::Value &value = *it;
if (value.isTokValue() && value.tokvalue->tokType() == Token::eString) { if (value.isTokValue() && value.tokvalue->tokType() == Token::eString) {
ValueFlow::Value retval(value); // copy all "inconclusive", "condition", etc attributes ValueFlow::Value retval(value); // copy all "inconclusive", "condition", etc attributes
@ -2715,14 +2664,14 @@ static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue,
valueFlowNumber(&tokenList); valueFlowNumber(&tokenList);
for (Token *tok2 = tokenList.front(); tok2; tok2 = tok2->next()) { for (Token *tok2 = tokenList.front(); tok2; tok2 = tok2->next()) {
if (tok2->str() == "arg1" && arg1) { if (tok2->str() == "arg1" && arg1) {
setTokenValues(tok2, arg1->values, settings); setTokenValues(tok2, arg1->values(), settings);
} }
} }
// Find result.. // Find result..
for (const Token *tok2 = tokenList.front(); tok2; tok2 = tok2->next()) { for (const Token *tok2 = tokenList.front(); tok2; tok2 = tok2->next()) {
if (!tok2->astParent() && !tok2->values.empty()) { if (!tok2->astParent() && !tok2->values().empty()) {
setTokenValues(tok, tok2->values, settings); setTokenValues(tok, tok2->values(), settings);
return; return;
} }
} }
@ -2758,8 +2707,8 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
std::list<ValueFlow::Value> argvalues; std::list<ValueFlow::Value> argvalues;
// passing value(s) to function // passing value(s) to function
if (!argtok->values.empty() && Token::Match(argtok, "%name%|%num%|%str% [,)]")) if (!argtok->values().empty() && Token::Match(argtok, "%name%|%num%|%str% [,)]"))
argvalues = argtok->values; argvalues = argtok->values();
else { else {
// bool operator => values 1/0 are passed to function.. // bool operator => values 1/0 are passed to function..
const Token *op = argtok; const Token *op = argtok;
@ -2769,8 +2718,8 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
argvalues.clear(); argvalues.clear();
argvalues.push_back(ValueFlow::Value(0)); argvalues.push_back(ValueFlow::Value(0));
argvalues.push_back(ValueFlow::Value(1)); argvalues.push_back(ValueFlow::Value(1));
} else if (Token::Match(op, "%cop%") && !op->values.empty()) { } else if (Token::Match(op, "%cop%") && !op->values().empty()) {
argvalues = op->values; argvalues = op->values();
} else { } else {
// possible values are unknown.. // possible values are unknown..
continue; continue;
@ -2801,7 +2750,7 @@ static void valueFlowFunctionDefaultParameter(TokenList *tokenlist, SymbolDataba
for (std::size_t arg = function->minArgCount(); arg < function->argCount(); arg++) { for (std::size_t arg = function->minArgCount(); arg < function->argCount(); arg++) {
const Variable* var = function->getArgumentVar(arg); const Variable* var = function->getArgumentVar(arg);
if (var && var->hasDefault() && Token::Match(var->nameToken(), "%var% = %num%|%str% [,)]")) { if (var && var->hasDefault() && Token::Match(var->nameToken(), "%var% = %num%|%str% [,)]")) {
const std::list<ValueFlow::Value> &values = var->nameToken()->tokAt(2)->values; const std::list<ValueFlow::Value> &values = var->nameToken()->tokAt(2)->values();
std::list<ValueFlow::Value> argvalues; std::list<ValueFlow::Value> argvalues;
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) { for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
ValueFlow::Value v(*it); ValueFlow::Value v(*it);
@ -2836,10 +2785,10 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg
partok = partok->astOperand1(); partok = partok->astOperand1();
if (!isKnown(partok)) if (!isKnown(partok))
continue; continue;
parvalues.push_back(partok->values.front().intvalue); parvalues.push_back(partok->values().front().intvalue);
partok = partok->astParent(); partok = partok->astParent();
while (partok && partok->str() == ",") { while (partok && partok->str() == ",") {
parvalues.push_back(partok->astOperand2()->values.front().intvalue); parvalues.push_back(partok->astOperand2()->values().front().intvalue);
partok = partok->astParent(); partok = partok->astParent();
} }
if (partok != tok) if (partok != tok)
@ -2889,19 +2838,19 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg
const ValueFlow::Value *ValueFlow::valueFlowConstantFoldAST(const Token *expr, const Settings *settings) const ValueFlow::Value *ValueFlow::valueFlowConstantFoldAST(const Token *expr, const Settings *settings)
{ {
if (expr && expr->values.empty()) { if (expr && expr->values().empty()) {
valueFlowConstantFoldAST(expr->astOperand1(), settings); valueFlowConstantFoldAST(expr->astOperand1(), settings);
valueFlowConstantFoldAST(expr->astOperand2(), settings); valueFlowConstantFoldAST(expr->astOperand2(), settings);
valueFlowSetConstantValue(expr, settings, true /* TODO: this is a guess */); valueFlowSetConstantValue(expr, settings, true /* TODO: this is a guess */);
} }
return expr && expr->values.size() == 1U && expr->values.front().isKnown() ? &expr->values.front() : nullptr; return expr && expr->values().size() == 1U && expr->values().front().isKnown() ? &expr->values().front() : nullptr;
} }
void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings) void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
{ {
for (Token *tok = tokenlist->front(); tok; tok = tok->next()) for (Token *tok = tokenlist->front(); tok; tok = tok->next())
tok->values.clear(); tok->clearValueFlow();
valueFlowNumber(tokenlist); valueFlowNumber(tokenlist);
valueFlowString(tokenlist); valueFlowString(tokenlist);

View File

@ -95,7 +95,7 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) { if (tok->str() == "x" && tok->linenr() == linenr) {
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) { for (it = tok->values().begin(); it != tok->values().end(); ++it) {
if (it->isIntValue() && it->intvalue == value) if (it->isIntValue() && it->intvalue == value)
return true; return true;
} }
@ -115,7 +115,7 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) { if (tok->str() == "x" && tok->linenr() == linenr) {
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) { for (it = tok->values().begin(); it != tok->values().end(); ++it) {
if (it->isTokValue() && Token::simpleMatch(it->tokvalue, value)) if (it->isTokValue() && Token::simpleMatch(it->tokvalue, value))
return true; return true;
} }
@ -134,7 +134,7 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) { if (tok->str() == "x" && tok->linenr() == linenr) {
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) { for (it = tok->values().begin(); it != tok->values().end(); ++it) {
if (it->isMovedValue() && it->moveKind == moveKind) if (it->isMovedValue() && it->moveKind == moveKind)
return true; return true;
} }
@ -153,7 +153,7 @@ private:
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) { for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
if (tok->str() == "x" && tok->linenr() == linenr) { if (tok->str() == "x" && tok->linenr() == linenr) {
std::list<ValueFlow::Value>::const_iterator it; std::list<ValueFlow::Value>::const_iterator it;
for (it = tok->values.begin(); it != tok->values.end(); ++it) { for (it = tok->values().begin(); it != tok->values().end(); ++it) {
if (it->isIntValue() && it->intvalue == value && it->condition) if (it->isIntValue() && it->intvalue == value && it->condition)
return true; return true;
} }
@ -181,7 +181,7 @@ private:
errout.str(""); errout.str("");
tokenizer.tokenize(istr, "test.cpp"); tokenizer.tokenize(istr, "test.cpp");
const Token *tok = Token::findmatch(tokenizer.tokens(), tokstr); const Token *tok = Token::findmatch(tokenizer.tokens(), tokstr);
return tok ? tok->values : std::list<ValueFlow::Value>(); return tok ? tok->values() : std::list<ValueFlow::Value>();
} }
ValueFlow::Value valueOfTok(const char code[], const char tokstr[]) { ValueFlow::Value valueOfTok(const char code[], const char tokstr[]) {