From e82940d361e6dc708df6b2b516068cdd7c6eb41d Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 5 Jan 2025 02:13:06 +0100 Subject: [PATCH 01/11] fixed #13513 - adjusted access of known int values --- lib/astutils.cpp | 8 +++---- lib/checkbufferoverrun.cpp | 2 +- lib/checkcondition.cpp | 8 +++---- lib/checkleakautovar.cpp | 4 ++-- lib/checknullpointer.cpp | 2 +- lib/checkother.cpp | 2 +- lib/checkstl.cpp | 8 +++---- lib/checktype.cpp | 3 +-- lib/forwardanalyzer.cpp | 2 +- lib/fwdanalysis.cpp | 2 +- lib/pathanalysis.cpp | 2 +- lib/programmemory.cpp | 6 +++--- lib/token.cpp | 8 +++++++ lib/token.h | 5 +++++ lib/valueflow.cpp | 44 +++++++++++++++++++------------------- lib/vf_analyzers.cpp | 4 ++-- lib/vf_settokenvalue.cpp | 4 ++-- 17 files changed, 63 insertions(+), 51 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 0c4ae7d4f1f..68d8711a453 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; @@ -1657,10 +1657,10 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se const Token* varTok2 = exprTok; const ValueFlow::Value* value = nullptr; if (condTok->astOperand1()->hasKnownIntValue()) { - value = &condTok->astOperand1()->values().front(); + value = condTok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT); varTok1 = condTok->astOperand2(); } else if (condTok->astOperand2()->hasKnownIntValue()) { - value = &condTok->astOperand2()->values().front(); + value = condTok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT); varTok1 = condTok->astOperand1(); } const bool exprIsNot = Token::simpleMatch(exprTok, "!"); diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 2c5e9ada26a..394fc0c9191 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -268,7 +268,7 @@ static std::vector getOverrunIndexValues(const Token* tok, : std::vector{}; if (values.empty()) { if (indexTokens[i]->hasKnownIntValue()) - indexValues.push_back(indexTokens[i]->values().front()); + indexValues.push_back(*indexTokens[i]->getKnownValue(ValueFlow::Value::ValueType::INT)); else indexValues.push_back(ValueFlow::Value::unknown()); continue; diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index f0e30074105..8a67615f678 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; 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..f9bcd814bf9 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) 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..7edfc053ba0 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -345,8 +345,7 @@ void CheckType::checkLongCast() continue; if (tok->astOperand2()->hasKnownIntValue()) { - const ValueFlow::Value &v = tok->astOperand2()->values().front(); - if (mSettings->platform.isIntValue(v.intvalue)) + if (mSettings->platform.isIntValue(tok->astOperand2()->getKnownIntValue())) continue; } 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..cf584be318e 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -224,7 +224,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * const Token *conditionStart = tok->next(); const Token *condTok = conditionStart->astOperand2(); if (condTok->hasKnownIntValue()) { - const bool cond = !!condTok->values().front().intvalue; + const bool cond = !!condTok->getKnownIntValue(); 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..441450a40bd 100644 --- a/lib/pathanalysis.cpp +++ b/lib/pathanalysis.cpp @@ -50,7 +50,7 @@ std::pair PathAnalysis::checkCond(const Token * tok, bool& known) { if (tok->hasKnownIntValue()) { known = true; - return std::make_pair(!!tok->values().front().intvalue, !tok->values().front().intvalue); + return std::make_pair(!!tok->getKnownIntValue(), !tok->getKnownIntValue()); } 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..abe9f165ae6 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -65,7 +65,7 @@ void ProgramMemory::setValue(const Token* expr, const ValueFlow::Value& value) { expr, [&](const Token* tok) -> std::vector { if (tok->hasKnownIntValue()) - return {tok->values().front().intvalue}; + return {tok->getKnownIntValue()}; MathLib::bigint result = 0; if (getIntValue(tok->exprId(), result)) return {result}; @@ -306,7 +306,7 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con if (!t) return std::vector{}; if (t->hasKnownIntValue()) - return {t->values().front().intvalue}; + return {t->getKnownIntValue()}; 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/token.cpp b/lib/token.cpp index 45985ae8198..c036b6a3809 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2536,6 +2536,14 @@ bool Token::hasKnownSymbolicValue(const Token* tok) const }); } +const ValueFlow::Value* Token::getKnownValue() const +{ + if (!mImpl->mValues) + return nullptr; + auto it = std::find_if(mImpl->mValues->begin(), mImpl->mValues->end(), std::mem_fn(&ValueFlow::Value::isKnown)); + return it == mImpl->mValues->end() ? nullptr : &*it; +} + const ValueFlow::Value* Token::getKnownValue(ValueFlow::Value::ValueType t) const { if (!mImpl->mValues) diff --git a/lib/token.h b/lib/token.h index 56fef5f4687..cac654f34fd 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1307,8 +1307,13 @@ class CPPCHECKLIB Token { bool hasKnownValue(ValueFlow::Value::ValueType t) const; bool hasKnownSymbolicValue(const Token* tok) const; + const ValueFlow::Value* getKnownValue() const; const ValueFlow::Value* getKnownValue(ValueFlow::Value::ValueType t) const; MathLib::bigint getKnownIntValue() const { + // TODO: need to perform lookup + 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..d7d7ecb7171 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -318,7 +318,7 @@ static void parseCompareEachInt( { parseCompareEachInt(tok, each, [](const Token* t) -> std::vector { if (t->hasKnownIntValue()) - return {t->values().front()}; + return {*t->getKnownValue(ValueFlow::Value::ValueType::INT)}; std::vector result; std::copy_if(t->values().cbegin(), t->values().cend(), std::back_inserter(result), [&](const ValueFlow::Value& v) { if (v.path < 1) @@ -362,7 +362,7 @@ const Token *ValueFlow::parseCompareInt(const Token *tok, ValueFlow::Value &true { return parseCompareInt(tok, true_value, false_value, [](const Token* t) -> std::vector { if (t->hasKnownIntValue()) - return {t->values().front().intvalue}; + return {t->getKnownIntValue()}; 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) @@ -769,9 +769,9 @@ static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings 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()); + const ValueFlow::Value* v = arg->getKnownValue(ValueFlow::Value::ValueType::INT); + result.intvalue = v->intvalue; + result.errorPath.insert(result.errorPath.end(), v->errorPath.cbegin(), v->errorPath.cend()); setTokenValue(tok, std::move(result), settings); } } @@ -880,9 +880,9 @@ static bool getExpressionRange(const Token* expr, MathLib::bigint* minvalue, Mat { if (expr->hasKnownIntValue()) { if (minvalue) - *minvalue = expr->values().front().intvalue; + *minvalue = expr->getKnownIntValue(); if (maxvalue) - *maxvalue = expr->values().front().intvalue; + *maxvalue = expr->getKnownIntValue(); return true; } @@ -944,7 +944,7 @@ static void valueFlowRightShift(TokenList& tokenList, const Settings& settings) if (!tok->astOperand2()->hasKnownValue()) continue; - const MathLib::bigint rhsvalue = tok->astOperand2()->values().front().intvalue; + const MathLib::bigint rhsvalue = tok->astOperand2()->getKnownValue()->intvalue; if (rhsvalue < 0) continue; @@ -989,7 +989,7 @@ static std::vector minUnsignedValue(const Token* tok, int depth if (depth < 0) return result; if (tok->hasKnownIntValue()) { - result = {tok->values().front().intvalue}; + result = {tok->getKnownIntValue()}; } 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; } @@ -1066,7 +1066,7 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett std::vector values; for (const Token* tok2 : tokens) { if (tok2->hasKnownIntValue()) { - values.emplace_back(tok2->values().front()); + values.emplace_back(*tok2->getKnownValue(ValueFlow::Value::ValueType::INT)); } 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()) @@ -3607,11 +3607,11 @@ static void valueFlowSymbolicOperators(const SymbolDatabase& symboldatabase, con const ValueFlow::Value* constant = nullptr; const Token* vartok = nullptr; if (tok->astOperand1()->hasKnownIntValue()) { - constant = &tok->astOperand1()->values().front(); + constant = tok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT); vartok = tok->astOperand2(); } if (tok->astOperand2()->hasKnownIntValue()) { - constant = &tok->astOperand2()->values().front(); + constant = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT); 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; @@ -6367,7 +6367,7 @@ 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)}; + return {makeContainerSizeValue(tok->getKnownIntValue(), 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..d42550c010f 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -658,7 +658,7 @@ struct ValueFlowAnalyzer : Analyzer { std::vector evaluateInt(const Token* tok, F getProgramMemory) const { if (tok->hasKnownIntValue()) - return {static_cast(tok->values().front().intvalue)}; + return {static_cast(tok->getKnownIntValue())}; std::vector result; ProgramMemory pm = getProgramMemory(); if (Token::Match(tok, "&&|%oror%")) { @@ -1555,7 +1555,7 @@ static const Token* solveExprValue(const Token* expr, ValueFlow::Value& value) expr, [](const Token* tok) -> std::vector { if (tok->hasKnownIntValue()) - return {tok->values().front().intvalue}; + return {tok->getKnownIntValue()}; 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; From df236fae1167edc994af3518a5fa2cc4d3308e4d Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 18 Jan 2025 17:24:59 +0100 Subject: [PATCH 02/11] symboldatabase.cpp: split logic in `Variable::arrayDimensions()` --- lib/symboldatabase.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c6038fd90c8..612ce690ac8 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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 (dimension_.tok->hasKnownIntValue()) + dimension_.num = dimension_.tok->getKnownIntValue(); + 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; } } From 3a0f6f9600ae8bf05907ae796f99527f916e7fe1 Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 19 Jan 2025 15:55:30 +0100 Subject: [PATCH 03/11] Token: simplified `hasKnownIntValue()` --- lib/token.cpp | 8 +++++--- lib/token.h | 1 - 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index c036b6a3809..d4d63ac8e33 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 diff --git a/lib/token.h b/lib/token.h index cac654f34fd..eb23a4210c1 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1310,7 +1310,6 @@ class CPPCHECKLIB Token { const ValueFlow::Value* getKnownValue() const; const ValueFlow::Value* getKnownValue(ValueFlow::Value::ValueType t) const; MathLib::bigint getKnownIntValue() const { - // TODO: need to perform lookup assert(!mImpl->mValues->empty()); assert(mImpl->mValues->front().isKnown()); assert(mImpl->mValues->front().valueType == ValueFlow::Value::ValueType::INT); From ce4a6740ae0309615231635fd6ddbb62edcc097a Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 19 Jan 2025 17:38:19 +0100 Subject: [PATCH 04/11] checkcondition.cpp: added missing `hasKnownIntValue()` check --- lib/checkcondition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 8a67615f678..056ae9fc41e 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -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() == "+") From 909021ec0687ae9b2ecd09e090ebff3b826d03bc Mon Sep 17 00:00:00 2001 From: firewave Date: Sun, 19 Jan 2025 17:39:15 +0100 Subject: [PATCH 05/11] valueflow.cpp: adjusted checks in `valueFlowRightShift()` --- lib/valueflow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index d7d7ecb7171..48de71346b0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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()->getKnownValue()->intvalue; + const MathLib::bigint rhsvalue = tok->astOperand2()->getKnownIntValue(); if (rhsvalue < 0) continue; From 104cd582eebb7cbdab98985a441ee1e279b2dd8e Mon Sep 17 00:00:00 2001 From: firewave Date: Mon, 27 Jan 2025 13:10:53 +0100 Subject: [PATCH 06/11] Token: added special handling for `ValueFlow::Value::ValueType::INT` in `getKnownValue()` --- lib/token.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/token.cpp b/lib/token.cpp index d4d63ac8e33..563632a1ccc 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2550,6 +2550,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; }); From 7b26c1d22f8bccfea4aa86a551c595b43b766237 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 18 Mar 2025 11:59:28 +0100 Subject: [PATCH 07/11] avoid some unnecessary `Token::hasKnownIntValue()` calls --- lib/astutils.cpp | 8 ++++---- lib/checkbufferoverrun.cpp | 4 ++-- lib/valueflow.cpp | 26 +++++++++++++------------- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 68d8711a453..0082a22956c 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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()->getKnownValue(ValueFlow::Value::ValueType::INT); + if (const ValueFlow::Value* v_int = condTok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + value = v_int; varTok1 = condTok->astOperand2(); - } else if (condTok->astOperand2()->hasKnownIntValue()) { - value = condTok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT); + } else if (const ValueFlow::Value* v_int = condTok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + value = v_int; varTok1 = condTok->astOperand1(); } const bool exprIsNot = Token::simpleMatch(exprTok, "!"); diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 394fc0c9191..4860d0acd20 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]->getKnownValue(ValueFlow::Value::ValueType::INT)); + if (const ValueFlow::Value* v = indexTokens[i]->getKnownValue(ValueFlow::Value::ValueType::INT)) + indexValues.push_back(*v); else indexValues.push_back(ValueFlow::Value::unknown()); continue; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 48de71346b0..c124317a86c 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->getKnownValue(ValueFlow::Value::ValueType::INT)}; + 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) @@ -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->getKnownValue(ValueFlow::Value::ValueType::INT); - result.intvalue = v->intvalue; - result.errorPath.insert(result.errorPath.end(), v->errorPath.cbegin(), v->errorPath.cend()); - setTokenValue(tok, std::move(result), settings); + if (v) { + result.intvalue = v->intvalue; + result.errorPath.insert(result.errorPath.end(), v->errorPath.cbegin(), v->errorPath.cend()); + setTokenValue(tok, std::move(result), settings); + } } } } @@ -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->getKnownValue(ValueFlow::Value::ValueType::INT)); + 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; @@ -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()->getKnownValue(ValueFlow::Value::ValueType::INT); + if (const ValueFlow::Value* v = tok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + constant = v; vartok = tok->astOperand2(); } - if (tok->astOperand2()->hasKnownIntValue()) { - constant = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT); + if (const ValueFlow::Value* v = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + constant = v; vartok = tok->astOperand1(); } if (!constant) From 10198b3b107452c0a8bb76297cb1b33d939f2dd6 Mon Sep 17 00:00:00 2001 From: firewave Date: Tue, 18 Mar 2025 12:01:17 +0100 Subject: [PATCH 08/11] astutils.cpp: fixed warning about shadowed variable --- lib/astutils.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 0082a22956c..806aff90afd 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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 (const ValueFlow::Value* v_int = condTok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) { - value = v_int; + if (const ValueFlow::Value* vi1 = condTok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + value = vi1; varTok1 = condTok->astOperand2(); - } else if (const ValueFlow::Value* v_int = condTok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { - value = v_int; + } else if (const ValueFlow::Value* vi2 = condTok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) { + value = vi2; varTok1 = condTok->astOperand1(); } const bool exprIsNot = Token::simpleMatch(exprTok, "!"); From 5323ae88ff646b2505b07bd6226f05e566847cda Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 22 Mar 2025 11:34:59 +0100 Subject: [PATCH 09/11] Token: removed unused `getKnownValue()` --- lib/token.cpp | 8 -------- lib/token.h | 1 - 2 files changed, 9 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index 563632a1ccc..0ed2ff1ab51 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2538,14 +2538,6 @@ bool Token::hasKnownSymbolicValue(const Token* tok) const }); } -const ValueFlow::Value* Token::getKnownValue() const -{ - if (!mImpl->mValues) - return nullptr; - auto it = std::find_if(mImpl->mValues->begin(), mImpl->mValues->end(), std::mem_fn(&ValueFlow::Value::isKnown)); - return it == mImpl->mValues->end() ? nullptr : &*it; -} - const ValueFlow::Value* Token::getKnownValue(ValueFlow::Value::ValueType t) const { if (!mImpl->mValues) diff --git a/lib/token.h b/lib/token.h index eb23a4210c1..826a66d2448 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1307,7 +1307,6 @@ class CPPCHECKLIB Token { bool hasKnownValue(ValueFlow::Value::ValueType t) const; bool hasKnownSymbolicValue(const Token* tok) const; - const ValueFlow::Value* getKnownValue() const; const ValueFlow::Value* getKnownValue(ValueFlow::Value::ValueType t) const; MathLib::bigint getKnownIntValue() const { assert(!mImpl->mValues->empty()); From 312314257969f5fd3cf08ec302574a930aba9267 Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 22 Mar 2025 11:53:38 +0100 Subject: [PATCH 10/11] checkbufferoverrun.cpp: removed duplicated condition --- lib/checkbufferoverrun.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index 4860d0acd20..fc24b7ca086 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1069,8 +1069,6 @@ void CheckBufferOverrun::objectIndex() if (idx->getKnownIntValue() == 0) continue; } - if (idx->hasKnownIntValue() && idx->getKnownIntValue() == 0) - continue; std::vector values = ValueFlow::getLifetimeObjValues(obj, false, -1); for (const ValueFlow::Value& v:values) { From 92547ea8d77b0ae3e058a79dbd88cb9c3fce295a Mon Sep 17 00:00:00 2001 From: firewave Date: Sat, 22 Mar 2025 11:57:20 +0100 Subject: [PATCH 11/11] avoid more unnecessary `Token::hasKnownIntValue()` calls --- lib/astutils.cpp | 4 ++-- lib/checkbufferoverrun.cpp | 4 ++-- lib/checkother.cpp | 4 ++-- lib/checktype.cpp | 4 ++-- lib/checkuninitvar.cpp | 4 ++-- lib/fwdanalysis.cpp | 4 ++-- lib/pathanalysis.cpp | 4 ++-- lib/programmemory.cpp | 8 ++++---- lib/symboldatabase.cpp | 12 ++++++------ lib/valueflow.cpp | 18 +++++++++--------- lib/vf_analyzers.cpp | 8 ++++---- 11 files changed, 37 insertions(+), 37 deletions(-) diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 806aff90afd..90526560b80 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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 fc24b7ca086..e79f8d05c6f 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1065,8 +1065,8 @@ 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; } diff --git a/lib/checkother.cpp b/lib/checkother.cpp index f9bcd814bf9..0677bd28730 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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/checktype.cpp b/lib/checktype.cpp index 7edfc053ba0..646e15efcb4 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -344,8 +344,8 @@ void CheckType::checkLongCast() if (tok->str() != "=" || !Token::Match(tok->astOperand2(), "*|<<") || tok->astOperand2()->isUnaryOp("*")) continue; - if (tok->astOperand2()->hasKnownIntValue()) { - if (mSettings->platform.isIntValue(tok->astOperand2()->getKnownIntValue())) + 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/fwdanalysis.cpp b/lib/fwdanalysis.cpp index cf584be318e..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->getKnownIntValue(); + 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 441450a40bd..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->getKnownIntValue(), !tok->getKnownIntValue()); + 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 abe9f165ae6..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->getKnownIntValue()}; + 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->getKnownIntValue()}; + 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); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 612ce690ac8..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; } @@ -3747,8 +3747,8 @@ bool Variable::arrayDimensions(const Settings& settings, bool& isContainer) // TODO: collect timing information for this call? ValueFlow::valueFlowConstantFoldAST(const_cast(dimension_.tok), settings); if (dimension_.tok) { - if (dimension_.tok->hasKnownIntValue()) - dimension_.num = dimension_.tok->getKnownIntValue(); + 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; diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c124317a86c..89baf503cac 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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->getKnownIntValue()}; + if (const ValueFlow::Value* v = t->getKnownValue(Value::ValueType::INT)) + return {v->intvalue}; return std::vector{}; }); } @@ -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->getKnownIntValue(); + *minvalue = v->intvalue; if (maxvalue) - *maxvalue = expr->getKnownIntValue(); + *maxvalue = v->intvalue; return true; } @@ -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->getKnownIntValue()}; + 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()) { @@ -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->getKnownIntValue(), known)}; + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {makeContainerSizeValue(v->intvalue, known)}; return {}; } diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index d42550c010f..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->getKnownIntValue())}; + 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->getKnownIntValue()}; + if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) + return {v->intvalue}; return {}; }, value);