diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 0c4ae7d4f1f..90526560b80 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -360,7 +360,7 @@ static bool match(const Token *tok, const std::string &rhs) { if (tok->str() == rhs) return true; - if (!tok->varId() && tok->hasKnownIntValue() && MathLib::toString(tok->values().front().intvalue) == rhs) + if (!tok->varId() && tok->hasKnownIntValue() && MathLib::toString(tok->getKnownIntValue()) == rhs) return true; return false; } @@ -1524,7 +1524,7 @@ bool isUsedAsBool(const Token* const tok, const Settings& settings) if (parent->isUnaryOp("*")) return isUsedAsBool(parent, settings); if (Token::Match(parent, "==|!=") && (tok->astSibling()->isNumber() || tok->astSibling()->isKeyword()) && tok->astSibling()->hasKnownIntValue() && - tok->astSibling()->values().front().intvalue == 0) + tok->astSibling()->getKnownIntValue() == 0) return true; if (parent->str() == "(" && astIsRHS(tok) && Token::Match(parent->astOperand1(), "if|while")) return true; @@ -1656,11 +1656,11 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se const Token* varTok1 = nullptr; const Token* varTok2 = exprTok; const ValueFlow::Value* value = nullptr; - if (condTok->astOperand1()->hasKnownIntValue()) { - value = &condTok->astOperand1()->values().front(); + if (const ValueFlow::Value* vi1 = condTok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + value = vi1; varTok1 = condTok->astOperand2(); - } else if (condTok->astOperand2()->hasKnownIntValue()) { - value = &condTok->astOperand2()->values().front(); + } else if (const ValueFlow::Value* vi2 = condTok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + value = vi2; varTok1 = condTok->astOperand1(); } const bool exprIsNot = Token::simpleMatch(exprTok, "!"); @@ -3715,8 +3715,8 @@ static std::set getSwitchValues(const Token *startbrace, bool & } if (Token::simpleMatch(tok, "case")) { const Token *valueTok = tok->astOperand1(); - if (valueTok->hasKnownIntValue()) - values.insert(valueTok->getKnownIntValue()); + if (const ValueFlow::Value* v = valueTok->getKnownValue(ValueFlow::Value::ValueType::INT)) + values.insert(v->intvalue); continue; } } diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 2c5e9ada26a..e79f8d05c6f 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -267,8 +267,8 @@ static std::vector getOverrunIndexValues(const Token* tok, ? ValueFlow::isOutOfBounds(makeSizeValue(size, path), indexTokens[i]) : std::vector{}; if (values.empty()) { - if (indexTokens[i]->hasKnownIntValue()) - indexValues.push_back(indexTokens[i]->values().front()); + if (const ValueFlow::Value* v = indexTokens[i]->getKnownValue(ValueFlow::Value::ValueType::INT)) + indexValues.push_back(*v); else indexValues.push_back(ValueFlow::Value::unknown()); continue; @@ -1065,12 +1065,10 @@ void CheckBufferOverrun::objectIndex() const Token *idx = tok->astOperand2(); if (!idx || !obj) continue; - if (idx->hasKnownIntValue()) { - if (idx->getKnownIntValue() == 0) + if (const ValueFlow::Value* v = idx->getKnownValue(ValueFlow::Value::ValueType::INT)) { + if (v->intvalue == 0) continue; } - if (idx->hasKnownIntValue() && idx->getKnownIntValue() == 0) - continue; std::vector values = ValueFlow::getLifetimeObjValues(obj, false, -1); for (const ValueFlow::Value& v:values) { diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index f0e30074105..056ae9fc41e 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -322,8 +322,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()->hasKnownIntValue() && tok->astOperand1()->values().front().intvalue != 0) || - (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->values().front().intvalue != 0); + const bool isTrue = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->getKnownIntValue() != 0) || + (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->getKnownIntValue() != 0); if (isBoolean && isTrue) badBitmaskCheckError(tok); @@ -333,8 +333,8 @@ void CheckCondition::checkBadBitmaskCheck() if (mTokenizer->hasIfdef(startStop.first, startStop.second)) continue; - const bool isZero1 = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->values().front().intvalue == 0); - const bool isZero2 = (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->values().front().intvalue == 0); + const bool isZero1 = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->getKnownIntValue() == 0); + const bool isZero2 = (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->getKnownIntValue() == 0); if (!isZero1 && !isZero2) continue; @@ -1700,7 +1700,7 @@ void CheckCondition::checkInvalidTestForOverflow() const Token * const other = expr->astSibling(); // x [+-] c cmp x - if ((other->isNumber() && other->getKnownIntValue() > 0) || + if ((other->isNumber() && other->hasKnownIntValue() && other->getKnownIntValue() > 0) || (!other->isNumber() && other->valueType() && other->valueType()->isIntegral() && other->valueType()->sign == ValueType::Sign::UNSIGNED)) { bool result; if (lhs->str() == "+") diff --git a/lib/checkleakautovar.cpp b/lib/checkleakautovar.cpp index e5adb16b350..2e10b433063 100644 --- a/lib/checkleakautovar.cpp +++ b/lib/checkleakautovar.cpp @@ -718,7 +718,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken, tok = tok->next(); while (Token::Match(tok, "%name% ::|.") || (startparen && Token::Match(tok, "%name% ,"))) tok = tok->tokAt(2); - const bool isnull = tok->hasKnownIntValue() && tok->values().front().intvalue == 0; + const bool isnull = tok->hasKnownIntValue() && tok->getKnownIntValue() == 0; if (!isnull && tok->varId() && tok->strAt(1) != "[") { const VarInfo::AllocInfo allocation(arrayDelete ? NEW_ARRAY : NEW, VarInfo::DEALLOC, delTok); changeAllocStatus(varInfo, allocation, tok, tok); @@ -1035,7 +1035,7 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin if (isAddressOf) arg = arg->next(); - const bool isnull = !isAddressOf && (arg->hasKnownIntValue() && arg->values().front().intvalue == 0); + const bool isnull = !isAddressOf && (arg->hasKnownIntValue() && arg->getKnownIntValue() == 0); // Is variable allocated? if (!isnull && (!af || af->arg == argNr)) { diff --git a/lib/checknullpointer.cpp b/lib/checknullpointer.cpp index 707392c1170..04b3232e06f 100644 --- a/lib/checknullpointer.cpp +++ b/lib/checknullpointer.cpp @@ -392,7 +392,7 @@ void CheckNullPointer::nullConstantDereference() const Token *argtok = args[argnr]; if (!argtok->hasKnownIntValue()) continue; - if (argtok->values().front().intvalue != 0) + if (argtok->getKnownIntValue() != 0) continue; if (mSettings->library.isnullargbad(tok, argnr+1)) nullPointerError(argtok); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 5d48dfc3faf..0677bd28730 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -347,7 +347,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->getKnownIntValue()==0) // Casting nullpointers is safe continue; if (typeTok->tokType() == Token::eType || typeTok->tokType() == Token::eName) @@ -1399,8 +1399,8 @@ static bool isLargeContainer(const Variable* var, const Settings* settings) const std::size_t maxByValueSize = 2 * settings->platform.sizeof_pointer; if (var->dimensions().empty()) { if (vt->container->startPattern == "std :: bitset <") { - if (vt->containerTypeToken->hasKnownIntValue()) - return vt->containerTypeToken->getKnownIntValue() / 8 > maxByValueSize; + if (const ValueFlow::Value* v = vt->containerTypeToken->getKnownValue(ValueFlow::Value::ValueType::INT)) + return v->intvalue / 8 > maxByValueSize; } return false; } diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index c5d82ab8ea4..d31e7e95ea2 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -304,7 +304,7 @@ bool CheckStl::isContainerSizeGE(const Token * containerToken, const Token *expr mul = expr->astOperand1(); else return false; - return mul && (!mul->hasKnownIntValue() || mul->values().front().intvalue != 0); + return mul && (!mul->hasKnownIntValue() || mul->getKnownIntValue() != 0); } if (expr->str() == "+") { const Token *op; @@ -2492,7 +2492,7 @@ void CheckStl::checkDereferenceInvalidIterator2() if (cValue && cValue->intvalue == 0) { if (Token::Match(tok->astParent(), "+|-") && astIsIntegral(tok->astSibling(), false)) { if (tok->astSibling() && tok->astSibling()->hasKnownIntValue()) { - if (tok->astSibling()->values().front().intvalue == 0) + if (tok->astSibling()->getKnownIntValue() == 0) continue; } else { advanceIndex = tok->astSibling(); @@ -2906,8 +2906,8 @@ namespace { alwaysFalse = false; return; } - (returnTok->values().front().intvalue ? alwaysTrue : alwaysFalse) &= true; - (returnTok->values().front().intvalue ? alwaysFalse : alwaysTrue) &= false; + (returnTok->getKnownIntValue() ? alwaysTrue : alwaysFalse) &= true; + (returnTok->getKnownIntValue() ? alwaysFalse : alwaysTrue) &= false; }); if (alwaysTrue == alwaysFalse) return ""; diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 551d2b2b578..646e15efcb4 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -344,9 +344,8 @@ void CheckType::checkLongCast() if (tok->str() != "=" || !Token::Match(tok->astOperand2(), "*|<<") || tok->astOperand2()->isUnaryOp("*")) continue; - if (tok->astOperand2()->hasKnownIntValue()) { - const ValueFlow::Value &v = tok->astOperand2()->values().front(); - if (mSettings->platform.isIntValue(v.intvalue)) + if (const ValueFlow::Value* v = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + if (mSettings->platform.isIntValue(v->intvalue)) continue; } diff --git a/lib/checkuninitvar.cpp b/lib/checkuninitvar.cpp index 7475ebcf6f9..62f10b883b5 100644 --- a/lib/checkuninitvar.cpp +++ b/lib/checkuninitvar.cpp @@ -292,8 +292,8 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::maphasKnownIntValue()) { - if (tok->getKnownIntValue() == 0) + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) { + if (v->intvalue == 0) *alwaysFalse = true; else *alwaysTrue = true; diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 30f7f6d9099..c390f586364 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -617,7 +617,7 @@ namespace { if (!condTok->hasKnownIntValue() || inLoop) { if (!analyzer->lowerToPossible()) return Break(Analyzer::Terminate::Bail); - } else if (condTok->values().front().intvalue == inElse) { + } else if (condTok->getKnownIntValue() == inElse) { return Break(); } // Handle loop diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index 70f8bc8c93e..a9da624e7c4 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -223,8 +223,8 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * const Token *bodyStart = tok->linkAt(1)->next(); const Token *conditionStart = tok->next(); const Token *condTok = conditionStart->astOperand2(); - if (condTok->hasKnownIntValue()) { - const bool cond = !!condTok->values().front().intvalue; + if (const ValueFlow::Value* v = condTok->getKnownValue(ValueFlow::Value::ValueType::INT)) { + const bool cond = !!v->intvalue; if (cond) { FwdAnalysis::Result result = checkRecursive(expr, bodyStart, bodyStart->link(), exprVarIds, local, true, depth); if (result.type != Result::Type::NONE) diff --git a/lib/pathanalysis.cpp b/lib/pathanalysis.cpp index 19783fb4cc2..99eefd51779 100644 --- a/lib/pathanalysis.cpp +++ b/lib/pathanalysis.cpp @@ -48,9 +48,9 @@ static const Token* assignExpr(const Token* tok) std::pair PathAnalysis::checkCond(const Token * tok, bool& known) { - if (tok->hasKnownIntValue()) { + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) { known = true; - return std::make_pair(!!tok->values().front().intvalue, !tok->values().front().intvalue); + return std::make_pair(!!v->intvalue, !v->intvalue); } auto it = std::find_if(tok->values().cbegin(), tok->values().cend(), [](const ValueFlow::Value& v) { return v.isIntValue(); diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 64c20b88807..de6c9733062 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -64,8 +64,8 @@ void ProgramMemory::setValue(const Token* expr, const ValueFlow::Value& value) { const Token* subexpr = solveExprValue( expr, [&](const Token* tok) -> std::vector { - if (tok->hasKnownIntValue()) - return {tok->values().front().intvalue}; + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {v->intvalue}; MathLib::bigint result = 0; if (getIntValue(tok->exprId(), result)) return {result}; @@ -305,8 +305,8 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con auto eval = [&](const Token* t) -> std::vector { if (!t) return std::vector{}; - if (t->hasKnownIntValue()) - return {t->values().front().intvalue}; + if (const ValueFlow::Value* v = t->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {v->intvalue}; MathLib::bigint result = 0; bool error = false; execute(t, pm, &result, &error, settings); @@ -1372,7 +1372,7 @@ namespace { if (!expr) return unknown(); if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",") - return expr->values().front(); + return *expr->getKnownValue(ValueFlow::Value::ValueType::INT); if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) || (value = expr->getKnownValue(ValueFlow::Value::ValueType::TOK)) || (value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) || diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c6038fd90c8..e5509c2fc6c 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1815,8 +1815,8 @@ void SymbolDatabase::setArrayDimensionsUsingValueFlow() if (!tok->isName()) tokenList.addtoken(tok->str(), 0, 0, 0, false); - else if (tok->hasKnownIntValue()) - tokenList.addtoken(MathLib::toString(tok->getKnownIntValue()), 0, 0, 0, false); + else if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + tokenList.addtoken(MathLib::toString(v->intvalue), 0, 0, 0, false); else { fail = true; @@ -1848,9 +1848,9 @@ void SymbolDatabase::setArrayDimensionsUsingValueFlow() dimension.known = false; // check for a single token dimension - if (dimension.tok->hasKnownIntValue()) { + if (const ValueFlow::Value* v = dimension.tok->getKnownValue(ValueFlow::Value::ValueType::INT)) { dimension.known = true; - dimension.num = dimension.tok->getKnownIntValue(); + dimension.num = v->intvalue; continue; } @@ -3746,9 +3746,13 @@ bool Variable::arrayDimensions(const Settings& settings, bool& isContainer) // TODO: only perform when ValueFlow is enabled // TODO: collect timing information for this call? ValueFlow::valueFlowConstantFoldAST(const_cast(dimension_.tok), settings); - if (dimension_.tok && (dimension_.tok->hasKnownIntValue() || - (dimension_.tok->isTemplateArg() && !dimension_.tok->values().empty()))) { - dimension_.num = dimension_.tok->getKnownIntValue(); + if (dimension_.tok) { + if (const ValueFlow::Value* v = dimension_.tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + dimension_.num = v->intvalue; + else if (dimension_.tok->isTemplateArg() && !dimension_.tok->values().empty()) { + assert(dimension_.tok->values().size() == 1); + dimension_.num = dimension_.tok->values().front().intvalue; + } dimension_.known = true; } } diff --git a/lib/token.cpp b/lib/token.cpp index 45985ae8198..0ed2ff1ab51 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2503,13 +2503,15 @@ std::shared_ptr Token::scopeInfo() const return mImpl->mScopeInfo; } +// if there is a known INT value it will always be the first entry bool Token::hasKnownIntValue() const { if (!mImpl->mValues) return false; - return std::any_of(mImpl->mValues->begin(), mImpl->mValues->end(), [](const ValueFlow::Value& value) { - return value.isKnown() && value.isIntValue(); - }); + if (mImpl->mValues->empty()) + return false; + const ValueFlow::Value& value = mImpl->mValues->front(); + return value.isIntValue() && value.isKnown(); } bool Token::hasKnownValue() const @@ -2540,6 +2542,15 @@ const ValueFlow::Value* Token::getKnownValue(ValueFlow::Value::ValueType t) cons { if (!mImpl->mValues) return nullptr; + if (mImpl->mValues->empty()) + return nullptr; + // known INT values are always the first entry + if (t == ValueFlow::Value::ValueType::INT) { + const auto& v = mImpl->mValues->front(); + if (!v.isKnown() || !v.isIntValue()) + return nullptr; + return &v; + } auto it = std::find_if(mImpl->mValues->begin(), mImpl->mValues->end(), [&](const ValueFlow::Value& value) { return value.isKnown() && value.valueType == t; }); diff --git a/lib/token.h b/lib/token.h index 56fef5f4687..826a66d2448 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1309,6 +1309,9 @@ class CPPCHECKLIB Token { const ValueFlow::Value* getKnownValue(ValueFlow::Value::ValueType t) const; MathLib::bigint getKnownIntValue() const { + assert(!mImpl->mValues->empty()); + assert(mImpl->mValues->front().isKnown()); + assert(mImpl->mValues->front().valueType == ValueFlow::Value::ValueType::INT); return mImpl->mValues->front().intvalue; } diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e4dc2bb3957..89baf503cac 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -317,8 +317,8 @@ static void parseCompareEachInt( const std::function& each) { parseCompareEachInt(tok, each, [](const Token* t) -> std::vector { - if (t->hasKnownIntValue()) - return {t->values().front()}; + if (const ValueFlow::Value* v = t->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {*v}; std::vector result; std::copy_if(t->values().cbegin(), t->values().cend(), std::back_inserter(result), [&](const ValueFlow::Value& v) { if (v.path < 1) @@ -361,8 +361,8 @@ const Token* ValueFlow::parseCompareInt(const Token* tok, const Token *ValueFlow::parseCompareInt(const Token *tok, ValueFlow::Value &true_value, ValueFlow::Value &false_value) { return parseCompareInt(tok, true_value, false_value, [](const Token* t) -> std::vector { - if (t->hasKnownIntValue()) - return {t->values().front().intvalue}; + if (const ValueFlow::Value* v = t->getKnownValue(Value::ValueType::INT)) + return {v->intvalue}; return std::vector{}; }); } @@ -649,7 +649,7 @@ static void valueFlowArray(TokenList& tokenlist, const Settings& settings) static bool isNonZero(const Token* tok) { - return tok && (!tok->hasKnownIntValue() || tok->values().front().intvalue != 0); + return tok && (!tok->hasKnownIntValue() || tok->getKnownIntValue() != 0); } static const Token* getOtherOperand(const Token* tok) @@ -767,12 +767,12 @@ static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings if (index < 0 || index >= args.size()) continue; const Token* arg = args[static_cast(index)]; - if (!arg->hasKnownIntValue()) - continue; - const ValueFlow::Value& v = arg->values().front(); - result.intvalue = v.intvalue; - result.errorPath.insert(result.errorPath.end(), v.errorPath.cbegin(), v.errorPath.cend()); - setTokenValue(tok, std::move(result), settings); + const ValueFlow::Value* v = arg->getKnownValue(ValueFlow::Value::ValueType::INT); + if (v) { + result.intvalue = v->intvalue; + result.errorPath.insert(result.errorPath.end(), v->errorPath.cbegin(), v->errorPath.cend()); + setTokenValue(tok, std::move(result), settings); + } } } } @@ -878,11 +878,11 @@ static void valueFlowSameExpressions(TokenList& tokenlist, const Settings& setti static bool getExpressionRange(const Token* expr, MathLib::bigint* minvalue, MathLib::bigint* maxvalue) { - if (expr->hasKnownIntValue()) { + if (const ValueFlow::Value* v = expr->getKnownValue(ValueFlow::Value::ValueType::INT)) { if (minvalue) - *minvalue = expr->values().front().intvalue; + *minvalue = v->intvalue; if (maxvalue) - *maxvalue = expr->values().front().intvalue; + *maxvalue = v->intvalue; return true; } @@ -935,16 +935,16 @@ static void valueFlowRightShift(TokenList& tokenList, const Settings& settings) if (tok->str() != ">>") continue; - if (tok->hasKnownValue()) + if (tok->hasKnownIntValue()) continue; if (!tok->astOperand1() || !tok->astOperand2()) continue; - if (!tok->astOperand2()->hasKnownValue()) + if (!tok->astOperand2()->hasKnownIntValue()) continue; - const MathLib::bigint rhsvalue = tok->astOperand2()->values().front().intvalue; + const MathLib::bigint rhsvalue = tok->astOperand2()->getKnownIntValue(); if (rhsvalue < 0) continue; @@ -988,8 +988,8 @@ static std::vector minUnsignedValue(const Token* tok, int depth return result; if (depth < 0) return result; - if (tok->hasKnownIntValue()) { - result = {tok->values().front().intvalue}; + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) { + result = {v->intvalue}; } else if (!Token::Match(tok, "-|%|&|^") && tok->isConstOp() && tok->astOperand1() && tok->astOperand2()) { std::vector op1 = minUnsignedValue(tok->astOperand1(), depth - 1); if (!op1.empty()) { @@ -1022,7 +1022,7 @@ static bool isSameToken(const Token* tok1, const Token* tok2) if (tok1->exprId() != 0 && tok1->exprId() == tok2->exprId()) return true; if (tok1->hasKnownIntValue() && tok2->hasKnownIntValue()) - return tok1->values().front().intvalue == tok2->values().front().intvalue; + return tok1->getKnownIntValue() == tok2->getKnownIntValue(); return false; } @@ -1065,8 +1065,8 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett continue; std::vector values; for (const Token* tok2 : tokens) { - if (tok2->hasKnownIntValue()) { - values.emplace_back(tok2->values().front()); + if (const ValueFlow::Value* v = tok2->getKnownValue(ValueFlow::Value::ValueType::INT)) { + values.emplace_back(*v); } else { ValueFlow::Value symValue{}; symValue.valueType = ValueFlow::Value::ValueType::SYMBOLIC; @@ -1096,7 +1096,7 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett } } else if (Token::simpleMatch(tok, "%") && tok->astOperand2() && tok->astOperand2()->hasKnownIntValue()) { - ValueFlow::Value value{tok->astOperand2()->values().front()}; + ValueFlow::Value value{tok->astOperand2()->getKnownIntValue()}; value.bound = ValueFlow::Value::Bound::Lower; value.setImpossible(); setTokenValue(tok, std::move(value), settings); @@ -1151,7 +1151,7 @@ static void valueFlowEnumValue(SymbolDatabase & symboldatabase, const Settings & auto* rhs = const_cast(enumerator.start->previous()->astOperand2()); ValueFlow::valueFlowConstantFoldAST(rhs, settings); if (rhs && rhs->hasKnownIntValue()) { - enumerator.value = rhs->values().front().intvalue; + enumerator.value = rhs->getKnownIntValue(); enumerator.value_known = true; value = enumerator.value + 1; prev_enum_is_known = true; @@ -1177,7 +1177,7 @@ static void valueFlowGlobalConstVar(TokenList& tokenList, const Settings& settin tok->variable()->isConst() && tok->valueType() && tok->valueType()->isIntegral() && tok->valueType()->pointer == 0 && tok->valueType()->constness == 1 && Token::Match(tok, "%name% =") && tok->next()->astOperand2() && tok->next()->astOperand2()->hasKnownIntValue()) { - vars[tok->variable()] = tok->next()->astOperand2()->values().front(); + vars[tok->variable()] = *tok->next()->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT); } } @@ -1204,7 +1204,7 @@ static void valueFlowGlobalStaticVar(TokenList& tokenList, const Settings& setti tok->valueType() && tok->valueType()->isIntegral() && tok->valueType()->pointer == 0 && tok->valueType()->constness == 0 && Token::Match(tok, "%name% =") && tok->next()->astOperand2() && tok->next()->astOperand2()->hasKnownIntValue()) { - vars[tok->variable()] = tok->next()->astOperand2()->values().front(); + vars[tok->variable()] = *tok->next()->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT); } else { // If variable is written anywhere in TU then remove it from vars if (!tok->astParent()) @@ -3606,12 +3606,12 @@ static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, con continue; const ValueFlow::Value* constant = nullptr; const Token* vartok = nullptr; - if (tok->astOperand1()->hasKnownIntValue()) { - constant = &tok->astOperand1()->values().front(); + if (const ValueFlow::Value* v = tok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + constant = v; vartok = tok->astOperand2(); } - if (tok->astOperand2()->hasKnownIntValue()) { - constant = &tok->astOperand2()->values().front(); + if (const ValueFlow::Value* v = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + constant = v; vartok = tok->astOperand1(); } if (!constant) @@ -4512,7 +4512,7 @@ struct ConditionHandler { if (Token::Match(tok->astParent(), "==|!=")) { const Token* sibling = tok->astSibling(); if (sibling->hasKnownIntValue() && (astIsBool(tok) || astIsBool(sibling))) { - const bool value = !!sibling->values().front().intvalue; + const bool value = !!sibling->getKnownIntValue(); if (inverted) *inverted ^= value == Token::simpleMatch(tok->astParent(), "!="); continue; @@ -6366,8 +6366,8 @@ static ValueFlow::Value makeContainerSizeValue(MathLib::bigint s, bool known = t static std::vector makeContainerSizeValue(const Token* tok, bool known = true) { - if (tok->hasKnownIntValue()) - return {makeContainerSizeValue(tok->values().front().intvalue, known)}; + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {makeContainerSizeValue(v->intvalue, known)}; return {}; } @@ -6531,7 +6531,7 @@ static void valueFlowContainerSize(const TokenList& tokenlist, if (dim.known) { size = dim.num; } else if (dim.tok && dim.tok->hasKnownIntValue() && dim.tok->strAt(1) == ">") { - size = dim.tok->values().front().intvalue; + size = dim.tok->getKnownIntValue(); } } if (size < 0) @@ -6649,7 +6649,7 @@ static void valueFlowContainerSize(const TokenList& tokenlist, valueFlowForward(tok->next(), containerTok, std::move(value), tokenlist, errorLogger, settings); } else if (action == Library::Container::Action::RESIZE && tok->tokAt(2)->astOperand2() && tok->tokAt(2)->astOperand2()->hasKnownIntValue()) { - ValueFlow::Value value(tok->tokAt(2)->astOperand2()->values().front()); + ValueFlow::Value value(*tok->tokAt(2)->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)); value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; value.setKnown(); valueFlowForward(tok->linkAt(2), containerTok, std::move(value), tokenlist, errorLogger, settings); diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index 769699e7575..8782dbd534b 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -657,8 +657,8 @@ struct ValueFlowAnalyzer : Analyzer { template std::vector evaluateInt(const Token* tok, F getProgramMemory) const { - if (tok->hasKnownIntValue()) - return {static_cast(tok->values().front().intvalue)}; + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {static_cast(v->intvalue)}; std::vector result; ProgramMemory pm = getProgramMemory(); if (Token::Match(tok, "&&|%oror%")) { @@ -1554,8 +1554,8 @@ static const Token* solveExprValue(const Token* expr, ValueFlow::Value& value) return ValueFlow::solveExprValue( expr, [](const Token* tok) -> std::vector { - if (tok->hasKnownIntValue()) - return {tok->values().front().intvalue}; + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {v->intvalue}; return {}; }, value); diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 5fa10a24924..a04a9750c6b 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -536,8 +536,8 @@ namespace ValueFlow args1.end(), args2.begin(), [&](const Token* atok, const Token* btok) { - return atok->values().front().intvalue == - btok->values().front().intvalue; + return atok->getKnownIntValue() == + btok->getKnownIntValue(); }); } else { equal = false;