Refactorization: Allocate Token::_values (ValueFlow information) dynamically, reducing size of each token by around 10%
This commit is contained in:
parent
2938278f00
commit
3c8f5b85ae
|
@ -87,7 +87,7 @@ static bool match(const Token *tok, const std::string &rhs)
|
|||
{
|
||||
if (tok->str() == rhs)
|
||||
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 false;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ bool CheckAutoVariables::isAutoVarArray(const Token *tok)
|
|||
|
||||
// ValueFlow
|
||||
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;
|
||||
if (val.isTokValue() && isAutoVarArray(val.tokvalue))
|
||||
return true;
|
||||
|
|
|
@ -1132,7 +1132,7 @@ void CheckBufferOverrun::checkGlobalAndLocalVariable()
|
|||
if (!value)
|
||||
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)
|
||||
continue;
|
||||
const Variable *var = it->tokvalue->variable();
|
||||
|
|
|
@ -261,8 +261,8 @@ void CheckCondition::checkBadBitmaskCheck()
|
|||
(parent->str() == "(" && Token::Match(parent->astOperand1(), "if|while")) ||
|
||||
(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()) ||
|
||||
(tok->astOperand2()->values.size() == 1 && tok->astOperand2()->values.front().intvalue != 0 && tok->astOperand2()->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());
|
||||
|
||||
if (isBoolean && isTrue)
|
||||
badBitmaskCheckError(tok);
|
||||
|
@ -1049,7 +1049,7 @@ void CheckCondition::alwaysTrueFalse()
|
|||
if (isExpandedMacro)
|
||||
continue;
|
||||
|
||||
alwaysTrueFalseError(tok, tok->values.front().intvalue != 0);
|
||||
alwaysTrueFalseError(tok, tok->values().front().intvalue != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -474,8 +474,8 @@ static bool findFormat(unsigned int arg, const Token *firstArg,
|
|||
argTok->variable()->dimensionKnown(0) &&
|
||||
argTok->variable()->dimension(0) != 0))) {
|
||||
*formatArgTok = argTok->nextArgument();
|
||||
if (!argTok->values.empty() && argTok->values.front().isTokValue() && argTok->values.front().tokvalue && argTok->values.front().tokvalue->tokType() == Token::eString)
|
||||
*formatStringTok = argTok->values.front().tokvalue;
|
||||
if (!argTok->values().empty() && argTok->values().front().isTokValue() && argTok->values().front().tokvalue && argTok->values().front().tokvalue->tokType() == Token::eString)
|
||||
*formatStringTok = argTok->values().front().tokvalue;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -547,7 +547,7 @@ void CheckLeakAutoVar::functionCall(const Token *tok, VarInfo *varInfo, const Va
|
|||
if (arg->str() == "&")
|
||||
arg = arg->next();
|
||||
|
||||
bool isnull = arg->hasKnownIntValue() && arg->values.front().intvalue == 0;
|
||||
bool isnull = arg->hasKnownIntValue() && arg->values().front().intvalue == 0;
|
||||
|
||||
// Is variable allocated?
|
||||
if (!isnull && (!af || af->arg == argNr))
|
||||
|
|
|
@ -481,18 +481,18 @@ static bool alwaysTrue(const Token *tok)
|
|||
{
|
||||
if (!tok)
|
||||
return false;
|
||||
if (tok->values.size() == 1U &&
|
||||
tok->values.front().intvalue != 0 &&
|
||||
tok->values.front().isKnown())
|
||||
if (tok->values().size() == 1U &&
|
||||
tok->values().front().intvalue != 0 &&
|
||||
tok->values().front().isKnown())
|
||||
return true;
|
||||
if (tok->str() == "||")
|
||||
return alwaysTrue(tok->astOperand1()) || alwaysTrue(tok->astOperand2());
|
||||
if (tok->str() == "true")
|
||||
return true;
|
||||
return (tok->isComparisonOp() &&
|
||||
tok->values.size() == 1U &&
|
||||
tok->values.front().isKnown() &&
|
||||
tok->values.front().intvalue != 0);
|
||||
tok->values().size() == 1U &&
|
||||
tok->values().front().isKnown() &&
|
||||
tok->values().front().intvalue != 0);
|
||||
}
|
||||
|
||||
bool CheckMemoryLeakInFunction::test_white_list(const std::string &funcname, const Settings *settings, bool cpp)
|
||||
|
|
|
@ -284,7 +284,7 @@ void CheckOther::warningOldStylePointerCast()
|
|||
tok = tok->next();
|
||||
|
||||
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;
|
||||
|
||||
// Is "type" a class?
|
||||
|
|
|
@ -337,7 +337,7 @@ void CheckType::checkFloatToIntegerOverflow()
|
|||
continue;
|
||||
|
||||
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)
|
||||
continue;
|
||||
if (it->inconclusive && !_settings->inconclusive)
|
||||
|
|
|
@ -219,8 +219,8 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<unsigned
|
|||
}
|
||||
|
||||
else if (tok->isComparisonOp()) {
|
||||
if (tok->values.size() == 1U && tok->values.front().isKnown()) {
|
||||
if (tok->values.front().intvalue)
|
||||
if (tok->values().size() == 1U && tok->values().front().isKnown()) {
|
||||
if (tok->values().front().intvalue)
|
||||
*alwaysTrue = true;
|
||||
else
|
||||
*alwaysFalse = true;
|
||||
|
|
|
@ -1016,7 +1016,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
Token::Match(tok, "%name% ;") &&
|
||||
tok->varId() == 0 &&
|
||||
tok->hasKnownIntValue() &&
|
||||
tok->values.front().intvalue == 0) {
|
||||
tok->values().front().intvalue == 0) {
|
||||
variables.use(varid1, tok);
|
||||
} else {
|
||||
variables.write(varid1, tok);
|
||||
|
|
|
@ -1321,8 +1321,8 @@ void SymbolDatabase::createSymbolDatabaseEnums()
|
|||
ValueFlow::valueFlowConstantFoldAST(rhs, _settings);
|
||||
|
||||
// get constant folded value:
|
||||
if (rhs && rhs->values.size() == 1U && rhs->values.front().isKnown()) {
|
||||
enumerator.value = rhs->values.front().intvalue;
|
||||
if (rhs && rhs->values().size() == 1U && rhs->values().front().isKnown()) {
|
||||
enumerator.value = rhs->values().front().intvalue;
|
||||
enumerator.value_known = true;
|
||||
value = enumerator.value + 1;
|
||||
}
|
||||
|
@ -1425,8 +1425,8 @@ void SymbolDatabase::createSymbolDatabaseUnknownArrayDimensions()
|
|||
ValueFlow::valueFlowConstantFoldAST(rhs, _settings);
|
||||
|
||||
// get constant folded value:
|
||||
if (rhs && rhs->values.size() == 1U && rhs->values.front().isKnown()) {
|
||||
dimension.num = rhs->values.front().intvalue;
|
||||
if (rhs && rhs->values().size() == 1U && rhs->values().front().isKnown()) {
|
||||
dimension.num = rhs->values().front().intvalue;
|
||||
dimension.known = true;
|
||||
}
|
||||
}
|
||||
|
|
109
lib/token.cpp
109
lib/token.cpp
|
@ -50,7 +50,8 @@ Token::Token(Token **t) :
|
|||
_astOperand2(nullptr),
|
||||
_astParent(nullptr),
|
||||
_originalName(nullptr),
|
||||
valuetype(nullptr)
|
||||
valuetype(nullptr),
|
||||
_values(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -58,6 +59,7 @@ Token::~Token()
|
|||
{
|
||||
delete _originalName;
|
||||
delete valuetype;
|
||||
delete _values;
|
||||
}
|
||||
|
||||
void Token::update_property_info()
|
||||
|
@ -213,7 +215,7 @@ void Token::swapWithNext()
|
|||
std::swap(_scope, _next->_scope);
|
||||
std::swap(_function, _next->_function);
|
||||
std::swap(_originalName, _next->_originalName);
|
||||
std::swap(values, _next->values);
|
||||
std::swap(_values, _next->_values);
|
||||
std::swap(valuetype, _next->valuetype);
|
||||
std::swap(_progressValue, _next->_progressValue);
|
||||
}
|
||||
|
@ -236,7 +238,11 @@ void Token::deleteThis()
|
|||
_originalName = _next->_originalName;
|
||||
_next->_originalName = nullptr;
|
||||
}
|
||||
values = _next->values;
|
||||
if (_next->_values) {
|
||||
delete _values;
|
||||
_values = _next->_values;
|
||||
_next->_values = nullptr;
|
||||
}
|
||||
if (_next->valuetype) {
|
||||
delete valuetype;
|
||||
valuetype = _next->valuetype;
|
||||
|
@ -261,7 +267,11 @@ void Token::deleteThis()
|
|||
_originalName = _previous->_originalName;
|
||||
_previous->_originalName = nullptr;
|
||||
}
|
||||
values = _previous->values;
|
||||
if (_previous->_values) {
|
||||
delete _values;
|
||||
_values = _previous->_values;
|
||||
_previous->_values = nullptr;
|
||||
}
|
||||
if (_previous->valuetype) {
|
||||
delete 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() << '\"';
|
||||
if (tok->function())
|
||||
out << " function=\"" << tok->function() << '\"';
|
||||
if (!tok->values.empty())
|
||||
out << " values=\"" << &tok->values << '\"';
|
||||
if (!tok->values().empty())
|
||||
out << " values=\"" << &tok->values() << '\"';
|
||||
|
||||
if (!tok->astOperand1() && !tok->astOperand2()) {
|
||||
out << "/>" << std::endl;
|
||||
|
@ -1318,19 +1328,19 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
|
|||
else
|
||||
out << "\n\n##Value flow" << std::endl;
|
||||
for (const Token *tok = this; tok; tok = tok->next()) {
|
||||
if (tok->values.empty())
|
||||
if (!tok->_values)
|
||||
continue;
|
||||
if (xml)
|
||||
out << " <values id=\"" << &tok->values << "\">" << std::endl;
|
||||
out << " <values id=\"" << tok->_values << "\">" << std::endl;
|
||||
else if (line != tok->linenr())
|
||||
out << "Line " << tok->linenr() << std::endl;
|
||||
line = tok->linenr();
|
||||
if (!xml) {
|
||||
out << " " << tok->str() << (tok->values.front().isKnown() ? " always " : " possible ");
|
||||
if (tok->values.size() > 1U)
|
||||
out << " " << tok->str() << (tok->_values->front().isKnown() ? " always " : " possible ");
|
||||
if (tok->_values->size() > 1U)
|
||||
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) {
|
||||
out << " <value ";
|
||||
switch (it->valueType) {
|
||||
|
@ -1357,7 +1367,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
|
|||
}
|
||||
|
||||
else {
|
||||
if (it != tok->values.begin())
|
||||
if (it != tok->_values->begin())
|
||||
out << ",";
|
||||
switch (it->valueType) {
|
||||
case ValueFlow::Value::INT:
|
||||
|
@ -1377,7 +1387,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
|
|||
}
|
||||
if (xml)
|
||||
out << " </values>" << std::endl;
|
||||
else if (tok->values.size() > 1U)
|
||||
else if (tok->_values->size() > 1U)
|
||||
out << '}' << std::endl;
|
||||
else
|
||||
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
|
||||
{
|
||||
if (!_values)
|
||||
return nullptr;
|
||||
const ValueFlow::Value *ret = nullptr;
|
||||
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 (!ret || ret->inconclusive || (ret->condition && !it->inconclusive))
|
||||
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
|
||||
{
|
||||
if (!_values)
|
||||
return nullptr;
|
||||
const ValueFlow::Value *ret = nullptr;
|
||||
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 (!ret || ret->inconclusive || (ret->condition && !it->inconclusive))
|
||||
ret = &(*it);
|
||||
|
@ -1430,10 +1444,12 @@ const ValueFlow::Value * Token::getValueGE(const MathLib::bigint val, const Sett
|
|||
|
||||
const Token *Token::getValueTokenMinStrSize() const
|
||||
{
|
||||
if (!_values)
|
||||
return nullptr;
|
||||
const Token *ret = nullptr;
|
||||
std::size_t minsize = ~0U;
|
||||
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) {
|
||||
std::size_t size = getStrSize(it->tokvalue);
|
||||
if (!ret || size < minsize) {
|
||||
|
@ -1447,10 +1463,12 @@ const Token *Token::getValueTokenMinStrSize() const
|
|||
|
||||
const Token *Token::getValueTokenMaxStrLength() const
|
||||
{
|
||||
if (!_values)
|
||||
return nullptr;
|
||||
const Token *ret = nullptr;
|
||||
std::size_t maxlength = 0U;
|
||||
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) {
|
||||
std::size_t length = getStrLength(it->tokvalue);
|
||||
if (!ret || length > maxlength) {
|
||||
|
@ -1474,7 +1492,7 @@ const Token *Token::getValueTokenDeadPointer() const
|
|||
const Scope * const functionscope = getfunctionscope(this->scope());
|
||||
|
||||
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?
|
||||
if (!it->isTokValue() || (it->tokvalue && it->tokvalue->str() != "&"))
|
||||
continue;
|
||||
|
@ -1502,6 +1520,61 @@ const Token *Token::getValueTokenDeadPointer() const
|
|||
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)
|
||||
{
|
||||
unsigned int total_count = 0;
|
||||
|
|
36
lib/token.h
36
lib/token.h
|
@ -736,6 +736,11 @@ public:
|
|||
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.
|
||||
*/
|
||||
|
@ -747,16 +752,14 @@ public:
|
|||
*_originalName = name;
|
||||
}
|
||||
|
||||
/** Values of token */
|
||||
std::list<ValueFlow::Value> values;
|
||||
|
||||
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 {
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
if (!_values)
|
||||
return nullptr;
|
||||
for (std::list<ValueFlow::Value>::const_iterator it = _values->begin(); it != _values->end(); ++it) {
|
||||
if (it->isIntValue() && it->intvalue == val)
|
||||
return &(*it);
|
||||
}
|
||||
|
@ -764,9 +767,10 @@ public:
|
|||
}
|
||||
|
||||
const ValueFlow::Value * getMaxValue(bool condition) const {
|
||||
if (!_values)
|
||||
return nullptr;
|
||||
const ValueFlow::Value *ret = nullptr;
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
for (std::list<ValueFlow::Value>::const_iterator it = _values->begin(); it != _values->end(); ++it) {
|
||||
if (!it->isIntValue())
|
||||
continue;
|
||||
if ((!ret || it->intvalue > ret->intvalue) &&
|
||||
|
@ -777,8 +781,9 @@ public:
|
|||
}
|
||||
|
||||
const ValueFlow::Value * getMovedValue() const {
|
||||
std::list<ValueFlow::Value>::const_iterator it;
|
||||
for (it = values.begin(); it != values.end(); ++it) {
|
||||
if (!_values)
|
||||
return nullptr;
|
||||
for (std::list<ValueFlow::Value>::const_iterator it = _values->begin(); it != _values->end(); ++it) {
|
||||
if (it->isMovedValue() && it->moveKind != ValueFlow::Value::NonMovedVariable)
|
||||
return &(*it);
|
||||
}
|
||||
|
@ -793,6 +798,9 @@ public:
|
|||
|
||||
const Token *getValueTokenDeadPointer() const;
|
||||
|
||||
/** Add token value. Return true if value is added. */
|
||||
bool addValue(const ValueFlow::Value &value);
|
||||
|
||||
private:
|
||||
|
||||
void next(Token *nextToken) {
|
||||
|
@ -903,6 +911,9 @@ private:
|
|||
// ValueType
|
||||
ValueType *valuetype;
|
||||
|
||||
// ValueFlow
|
||||
std::list<ValueFlow::Value>* _values;
|
||||
|
||||
public:
|
||||
void astOperand1(Token *tok);
|
||||
void astOperand2(Token *tok);
|
||||
|
@ -936,6 +947,11 @@ public:
|
|||
_astOperand1 = _astOperand2 = _astParent = nullptr;
|
||||
}
|
||||
|
||||
void clearValueFlow() {
|
||||
delete _values;
|
||||
_values = nullptr;
|
||||
}
|
||||
|
||||
std::string astString(const char *sep = "") const {
|
||||
std::string ret;
|
||||
if (_astOperand1)
|
||||
|
|
|
@ -3666,7 +3666,7 @@ bool Tokenizer::simplifyTokenList2()
|
|||
// Clear AST,ValueFlow. These will be created again at the end of this function.
|
||||
for (Token *tok = list.front(); tok; tok = tok->next()) {
|
||||
tok->clearAst();
|
||||
tok->values.clear();
|
||||
tok->clearValueFlow();
|
||||
}
|
||||
|
||||
// f(x=g()) => x=g(); f(x)
|
||||
|
@ -3904,8 +3904,8 @@ void Tokenizer::dump(std::ostream &out) const
|
|||
out << " variable=\"" << tok->variable() << '\"';
|
||||
if (tok->function())
|
||||
out << " function=\"" << tok->function() << '\"';
|
||||
if (!tok->values.empty())
|
||||
out << " values=\"" << &tok->values << '\"';
|
||||
if (!tok->values().empty())
|
||||
out << " values=\"" << &tok->values() << '\"';
|
||||
if (tok->type())
|
||||
out << " type-scope=\"" << tok->type()->classScope << '\"';
|
||||
if (tok->astParent())
|
||||
|
|
|
@ -235,55 +235,6 @@ static bool bailoutSelfAssignment(const Token * const tok)
|
|||
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)
|
||||
{
|
||||
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 */
|
||||
static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Settings *settings)
|
||||
{
|
||||
if (!addValue(tok,value))
|
||||
if (!tok->addValue(value))
|
||||
return;
|
||||
|
||||
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()) {
|
||||
// is condition always true/false?
|
||||
if (parent->astOperand1()->values.size() == 1U && parent->astOperand1()->values.front().isKnown()) {
|
||||
const ValueFlow::Value &condvalue = parent->astOperand1()->values.front();
|
||||
if (parent->astOperand1()->values().size() == 1U && parent->astOperand1()->values().front().isKnown()) {
|
||||
const ValueFlow::Value &condvalue = parent->astOperand1()->values().front();
|
||||
const bool cond(condvalue.isTokValue() || (condvalue.isIntValue() && condvalue.intvalue != 0));
|
||||
if (cond && !tok->astOperand1()) { // true condition, no second operator
|
||||
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();
|
||||
if (!op) // #7769 segmentation fault at setTokenValue()
|
||||
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())
|
||||
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)) &&
|
||||
parent->astOperand1() &&
|
||||
parent->astOperand2()) {
|
||||
const bool known = ((parent->astOperand1()->values.size() == 1U &&
|
||||
parent->astOperand1()->values.front().isKnown()) ||
|
||||
(parent->astOperand2()->values.size() == 1U &&
|
||||
parent->astOperand2()->values.front().isKnown()));
|
||||
const bool known = ((parent->astOperand1()->values().size() == 1U &&
|
||||
parent->astOperand1()->values().front().isKnown()) ||
|
||||
(parent->astOperand2()->values().size() == 1U &&
|
||||
parent->astOperand2()->values().front().isKnown()));
|
||||
|
||||
// known result when a operand is 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;
|
||||
}
|
||||
|
||||
std::list<ValueFlow::Value>::const_iterator value1, value2;
|
||||
for (value1 = parent->astOperand1()->values.begin(); value1 != parent->astOperand1()->values.end(); ++value1) {
|
||||
for (std::list<ValueFlow::Value>::const_iterator value1 = parent->astOperand1()->values().begin(); value1 != parent->astOperand1()->values().end(); ++value1) {
|
||||
if (!value1->isIntValue() && !value1->isFloatValue() && !value1->isTokValue())
|
||||
continue;
|
||||
if (value1->isTokValue() && (!parent->isComparisonOp() || value1->tokvalue->tokType() != Token::eString))
|
||||
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())
|
||||
continue;
|
||||
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() == "!") {
|
||||
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())
|
||||
continue;
|
||||
ValueFlow::Value v(*it);
|
||||
|
@ -570,7 +520,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
|||
// ~
|
||||
else if (parent->str() == "~") {
|
||||
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())
|
||||
continue;
|
||||
ValueFlow::Value v(*it);
|
||||
|
@ -594,7 +544,7 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
|||
// unary minus
|
||||
else if (parent->str() == "-" && !parent->astOperand2()) {
|
||||
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())
|
||||
continue;
|
||||
ValueFlow::Value v(*it);
|
||||
|
@ -608,11 +558,10 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
|
|||
|
||||
// Array element
|
||||
else if (parent->str() == "[" && parent->astOperand1() && parent->astOperand2()) {
|
||||
std::list<ValueFlow::Value>::const_iterator value1, value2;
|
||||
for (value1 = parent->astOperand1()->values.begin(); value1 != parent->astOperand1()->values.end(); ++value1) {
|
||||
for (std::list<ValueFlow::Value>::const_iterator value1 = parent->astOperand1()->values().begin(); value1 != parent->astOperand1()->values().end(); ++value1) {
|
||||
if (!value1->isTokValue())
|
||||
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())
|
||||
continue;
|
||||
if (value1->varId == 0U || value2->varId == 0U ||
|
||||
|
@ -890,7 +839,7 @@ static void valueFlowBitAnd(TokenList *tokenlist)
|
|||
if (tok->str() != "&")
|
||||
continue;
|
||||
|
||||
if (tok->values.size() == 1U && tok->values.front().isKnown())
|
||||
if (tok->values().size() == 1U && tok->values().front().isKnown())
|
||||
continue;
|
||||
|
||||
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->astOperand1()->isName() && tok->astOperand2()->hasKnownIntValue()) {
|
||||
vartok = tok->astOperand1();
|
||||
num = tok->astOperand2()->values.front().intvalue;
|
||||
num = tok->astOperand2()->values().front().intvalue;
|
||||
} else if (tok->astOperand1()->hasKnownIntValue() && tok->astOperand2()->isName()) {
|
||||
vartok = tok->astOperand2();
|
||||
num = tok->astOperand1()->values.front().intvalue;
|
||||
num = tok->astOperand1()->values().front().intvalue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
@ -1230,7 +1179,7 @@ static void valueFlowAST(Token *tok, unsigned int varid, const ValueFlow::Value
|
|||
return;
|
||||
} else if (tok->str() == "||" && tok->astOperand1()) {
|
||||
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);
|
||||
}
|
||||
if (!nonzero)
|
||||
|
@ -1391,7 +1340,7 @@ static bool valueFlowForward(Token * const startToken,
|
|||
}
|
||||
|
||||
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?
|
||||
std::list<ValueFlow::Value> truevalues;
|
||||
|
@ -1627,7 +1576,7 @@ static bool valueFlowForward(Token * const startToken,
|
|||
continue;
|
||||
|
||||
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();
|
||||
std::list<ValueFlow::Value>::const_iterator 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;
|
||||
|
||||
// Rhs values..
|
||||
if (!tok->astOperand2() || tok->astOperand2()->values.empty())
|
||||
if (!tok->astOperand2() || tok->astOperand2()->values().empty())
|
||||
continue;
|
||||
|
||||
std::list<ValueFlow::Value> values = tok->astOperand2()->values;
|
||||
std::list<ValueFlow::Value> values = tok->astOperand2()->values();
|
||||
const bool constValue = tok->astOperand2()->isNumber();
|
||||
|
||||
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()))
|
||||
continue;
|
||||
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%|&&")) {
|
||||
Token *parent = const_cast<Token*>(tok->astParent());
|
||||
|
@ -2186,7 +2135,7 @@ static void execute(const Token *expr,
|
|||
*error = true;
|
||||
|
||||
else if (expr->hasKnownIntValue()) {
|
||||
*result = expr->values.front().intvalue;
|
||||
*result = expr->values().front().intvalue;
|
||||
}
|
||||
|
||||
else if (expr->isNumber()) {
|
||||
|
@ -2315,11 +2264,11 @@ static void execute(const Token *expr,
|
|||
else if (expr->str() == "[" && expr->astOperand1() && expr->astOperand2()) {
|
||||
const Token *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;
|
||||
return;
|
||||
}
|
||||
tokvalue = expr->astOperand1()->values.front().tokvalue;
|
||||
tokvalue = expr->astOperand1()->values().front().tokvalue;
|
||||
}
|
||||
if (!tokvalue || !tokvalue->isLiteral()) {
|
||||
*error = true;
|
||||
|
@ -2688,7 +2637,7 @@ static void valueFlowLibraryFunction(Token *tok, const std::string &returnValue,
|
|||
return;
|
||||
|
||||
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;
|
||||
if (value.isTokValue() && value.tokvalue->tokType() == Token::eString) {
|
||||
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);
|
||||
for (Token *tok2 = tokenList.front(); tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == "arg1" && arg1) {
|
||||
setTokenValues(tok2, arg1->values, settings);
|
||||
setTokenValues(tok2, arg1->values(), settings);
|
||||
}
|
||||
}
|
||||
|
||||
// Find result..
|
||||
for (const Token *tok2 = tokenList.front(); tok2; tok2 = tok2->next()) {
|
||||
if (!tok2->astParent() && !tok2->values.empty()) {
|
||||
setTokenValues(tok, tok2->values, settings);
|
||||
if (!tok2->astParent() && !tok2->values().empty()) {
|
||||
setTokenValues(tok, tok2->values(), settings);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2758,8 +2707,8 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
|
|||
std::list<ValueFlow::Value> argvalues;
|
||||
|
||||
// passing value(s) to function
|
||||
if (!argtok->values.empty() && Token::Match(argtok, "%name%|%num%|%str% [,)]"))
|
||||
argvalues = argtok->values;
|
||||
if (!argtok->values().empty() && Token::Match(argtok, "%name%|%num%|%str% [,)]"))
|
||||
argvalues = argtok->values();
|
||||
else {
|
||||
// bool operator => values 1/0 are passed to function..
|
||||
const Token *op = argtok;
|
||||
|
@ -2769,8 +2718,8 @@ static void valueFlowSubFunction(TokenList *tokenlist, ErrorLogger *errorLogger,
|
|||
argvalues.clear();
|
||||
argvalues.push_back(ValueFlow::Value(0));
|
||||
argvalues.push_back(ValueFlow::Value(1));
|
||||
} else if (Token::Match(op, "%cop%") && !op->values.empty()) {
|
||||
argvalues = op->values;
|
||||
} else if (Token::Match(op, "%cop%") && !op->values().empty()) {
|
||||
argvalues = op->values();
|
||||
} else {
|
||||
// possible values are unknown..
|
||||
continue;
|
||||
|
@ -2801,7 +2750,7 @@ static void valueFlowFunctionDefaultParameter(TokenList *tokenlist, SymbolDataba
|
|||
for (std::size_t arg = function->minArgCount(); arg < function->argCount(); arg++) {
|
||||
const Variable* var = function->getArgumentVar(arg);
|
||||
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;
|
||||
for (std::list<ValueFlow::Value>::const_iterator it = values.begin(); it != values.end(); ++it) {
|
||||
ValueFlow::Value v(*it);
|
||||
|
@ -2836,10 +2785,10 @@ static void valueFlowFunctionReturn(TokenList *tokenlist, ErrorLogger *errorLogg
|
|||
partok = partok->astOperand1();
|
||||
if (!isKnown(partok))
|
||||
continue;
|
||||
parvalues.push_back(partok->values.front().intvalue);
|
||||
parvalues.push_back(partok->values().front().intvalue);
|
||||
partok = partok->astParent();
|
||||
while (partok && partok->str() == ",") {
|
||||
parvalues.push_back(partok->astOperand2()->values.front().intvalue);
|
||||
parvalues.push_back(partok->astOperand2()->values().front().intvalue);
|
||||
partok = partok->astParent();
|
||||
}
|
||||
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)
|
||||
{
|
||||
if (expr && expr->values.empty()) {
|
||||
if (expr && expr->values().empty()) {
|
||||
valueFlowConstantFoldAST(expr->astOperand1(), settings);
|
||||
valueFlowConstantFoldAST(expr->astOperand2(), settings);
|
||||
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)
|
||||
{
|
||||
for (Token *tok = tokenlist->front(); tok; tok = tok->next())
|
||||
tok->values.clear();
|
||||
tok->clearValueFlow();
|
||||
|
||||
valueFlowNumber(tokenlist);
|
||||
valueFlowString(tokenlist);
|
||||
|
|
|
@ -95,7 +95,7 @@ private:
|
|||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
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)
|
||||
return true;
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ private:
|
|||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
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))
|
||||
return true;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ private:
|
|||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
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)
|
||||
return true;
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ private:
|
|||
for (const Token *tok = tokenizer.tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "x" && tok->linenr() == linenr) {
|
||||
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)
|
||||
return true;
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ private:
|
|||
errout.str("");
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
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[]) {
|
||||
|
|
Loading…
Reference in New Issue