Skip to content

Commit 37f4de2

Browse files
authored
fixed #13513 - adjusted access of known int values (danmar#7181)
1 parent 6b1b18b commit 37f4de2

19 files changed

+110
-95
lines changed

lib/astutils.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ static bool match(const Token *tok, const std::string &rhs)
360360
{
361361
if (tok->str() == rhs)
362362
return true;
363-
if (!tok->varId() && tok->hasKnownIntValue() && MathLib::toString(tok->values().front().intvalue) == rhs)
363+
if (!tok->varId() && tok->hasKnownIntValue() && MathLib::toString(tok->getKnownIntValue()) == rhs)
364364
return true;
365365
return false;
366366
}
@@ -1524,7 +1524,7 @@ bool isUsedAsBool(const Token* const tok, const Settings& settings)
15241524
if (parent->isUnaryOp("*"))
15251525
return isUsedAsBool(parent, settings);
15261526
if (Token::Match(parent, "==|!=") && (tok->astSibling()->isNumber() || tok->astSibling()->isKeyword()) && tok->astSibling()->hasKnownIntValue() &&
1527-
tok->astSibling()->values().front().intvalue == 0)
1527+
tok->astSibling()->getKnownIntValue() == 0)
15281528
return true;
15291529
if (parent->str() == "(" && astIsRHS(tok) && Token::Match(parent->astOperand1(), "if|while"))
15301530
return true;
@@ -1656,11 +1656,11 @@ bool isSameExpression(bool macro, const Token *tok1, const Token *tok2, const Se
16561656
const Token* varTok1 = nullptr;
16571657
const Token* varTok2 = exprTok;
16581658
const ValueFlow::Value* value = nullptr;
1659-
if (condTok->astOperand1()->hasKnownIntValue()) {
1660-
value = &condTok->astOperand1()->values().front();
1659+
if (const ValueFlow::Value* vi1 = condTok->astOperand1()->getKnownValue(ValueFlow::Value::ValueType::INT)) {
1660+
value = vi1;
16611661
varTok1 = condTok->astOperand2();
1662-
} else if (condTok->astOperand2()->hasKnownIntValue()) {
1663-
value = &condTok->astOperand2()->values().front();
1662+
} else if (const ValueFlow::Value* vi2 = condTok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) {
1663+
value = vi2;
16641664
varTok1 = condTok->astOperand1();
16651665
}
16661666
const bool exprIsNot = Token::simpleMatch(exprTok, "!");
@@ -3715,8 +3715,8 @@ static std::set<MathLib::bigint> getSwitchValues(const Token *startbrace, bool &
37153715
}
37163716
if (Token::simpleMatch(tok, "case")) {
37173717
const Token *valueTok = tok->astOperand1();
3718-
if (valueTok->hasKnownIntValue())
3719-
values.insert(valueTok->getKnownIntValue());
3718+
if (const ValueFlow::Value* v = valueTok->getKnownValue(ValueFlow::Value::ValueType::INT))
3719+
values.insert(v->intvalue);
37203720
continue;
37213721
}
37223722
}

lib/checkbufferoverrun.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,8 @@ static std::vector<ValueFlow::Value> getOverrunIndexValues(const Token* tok,
267267
? ValueFlow::isOutOfBounds(makeSizeValue(size, path), indexTokens[i])
268268
: std::vector<ValueFlow::Value>{};
269269
if (values.empty()) {
270-
if (indexTokens[i]->hasKnownIntValue())
271-
indexValues.push_back(indexTokens[i]->values().front());
270+
if (const ValueFlow::Value* v = indexTokens[i]->getKnownValue(ValueFlow::Value::ValueType::INT))
271+
indexValues.push_back(*v);
272272
else
273273
indexValues.push_back(ValueFlow::Value::unknown());
274274
continue;
@@ -1065,12 +1065,10 @@ void CheckBufferOverrun::objectIndex()
10651065
const Token *idx = tok->astOperand2();
10661066
if (!idx || !obj)
10671067
continue;
1068-
if (idx->hasKnownIntValue()) {
1069-
if (idx->getKnownIntValue() == 0)
1068+
if (const ValueFlow::Value* v = idx->getKnownValue(ValueFlow::Value::ValueType::INT)) {
1069+
if (v->intvalue == 0)
10701070
continue;
10711071
}
1072-
if (idx->hasKnownIntValue() && idx->getKnownIntValue() == 0)
1073-
continue;
10741072

10751073
std::vector<ValueFlow::Value> values = ValueFlow::getLifetimeObjValues(obj, false, -1);
10761074
for (const ValueFlow::Value& v:values) {

lib/checkcondition.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,8 @@ void CheckCondition::checkBadBitmaskCheck()
322322
(parent->str() == "(" && Token::Match(parent->astOperand1(), "if|while")) ||
323323
(parent->str() == "return" && parent->astOperand1() == tok && inBooleanFunction(tok));
324324

325-
const bool isTrue = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->values().front().intvalue != 0) ||
326-
(tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->values().front().intvalue != 0);
325+
const bool isTrue = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->getKnownIntValue() != 0) ||
326+
(tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->getKnownIntValue() != 0);
327327

328328
if (isBoolean && isTrue)
329329
badBitmaskCheckError(tok);
@@ -333,8 +333,8 @@ void CheckCondition::checkBadBitmaskCheck()
333333
if (mTokenizer->hasIfdef(startStop.first, startStop.second))
334334
continue;
335335

336-
const bool isZero1 = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->values().front().intvalue == 0);
337-
const bool isZero2 = (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->values().front().intvalue == 0);
336+
const bool isZero1 = (tok->astOperand1()->hasKnownIntValue() && tok->astOperand1()->getKnownIntValue() == 0);
337+
const bool isZero2 = (tok->astOperand2()->hasKnownIntValue() && tok->astOperand2()->getKnownIntValue() == 0);
338338
if (!isZero1 && !isZero2)
339339
continue;
340340

@@ -1700,7 +1700,7 @@ void CheckCondition::checkInvalidTestForOverflow()
17001700
const Token * const other = expr->astSibling();
17011701

17021702
// x [+-] c cmp x
1703-
if ((other->isNumber() && other->getKnownIntValue() > 0) ||
1703+
if ((other->isNumber() && other->hasKnownIntValue() && other->getKnownIntValue() > 0) ||
17041704
(!other->isNumber() && other->valueType() && other->valueType()->isIntegral() && other->valueType()->sign == ValueType::Sign::UNSIGNED)) {
17051705
bool result;
17061706
if (lhs->str() == "+")

lib/checkleakautovar.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ bool CheckLeakAutoVar::checkScope(const Token * const startToken,
718718
tok = tok->next();
719719
while (Token::Match(tok, "%name% ::|.") || (startparen && Token::Match(tok, "%name% ,")))
720720
tok = tok->tokAt(2);
721-
const bool isnull = tok->hasKnownIntValue() && tok->values().front().intvalue == 0;
721+
const bool isnull = tok->hasKnownIntValue() && tok->getKnownIntValue() == 0;
722722
if (!isnull && tok->varId() && tok->strAt(1) != "[") {
723723
const VarInfo::AllocInfo allocation(arrayDelete ? NEW_ARRAY : NEW, VarInfo::DEALLOC, delTok);
724724
changeAllocStatus(varInfo, allocation, tok, tok);
@@ -1035,7 +1035,7 @@ void CheckLeakAutoVar::functionCall(const Token *tokName, const Token *tokOpenin
10351035
if (isAddressOf)
10361036
arg = arg->next();
10371037

1038-
const bool isnull = !isAddressOf && (arg->hasKnownIntValue() && arg->values().front().intvalue == 0);
1038+
const bool isnull = !isAddressOf && (arg->hasKnownIntValue() && arg->getKnownIntValue() == 0);
10391039

10401040
// Is variable allocated?
10411041
if (!isnull && (!af || af->arg == argNr)) {

lib/checknullpointer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ void CheckNullPointer::nullConstantDereference()
392392
const Token *argtok = args[argnr];
393393
if (!argtok->hasKnownIntValue())
394394
continue;
395-
if (argtok->values().front().intvalue != 0)
395+
if (argtok->getKnownIntValue() != 0)
396396
continue;
397397
if (mSettings->library.isnullargbad(tok, argnr+1))
398398
nullPointerError(argtok);

lib/checkother.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ void CheckOther::warningOldStylePointerCast()
347347
tok = tok->next();
348348

349349
const Token *p = tok->tokAt(4);
350-
if (p->hasKnownIntValue() && p->values().front().intvalue==0) // Casting nullpointers is safe
350+
if (p->hasKnownIntValue() && p->getKnownIntValue()==0) // Casting nullpointers is safe
351351
continue;
352352

353353
if (typeTok->tokType() == Token::eType || typeTok->tokType() == Token::eName)
@@ -1399,8 +1399,8 @@ static bool isLargeContainer(const Variable* var, const Settings* settings)
13991399
const std::size_t maxByValueSize = 2 * settings->platform.sizeof_pointer;
14001400
if (var->dimensions().empty()) {
14011401
if (vt->container->startPattern == "std :: bitset <") {
1402-
if (vt->containerTypeToken->hasKnownIntValue())
1403-
return vt->containerTypeToken->getKnownIntValue() / 8 > maxByValueSize;
1402+
if (const ValueFlow::Value* v = vt->containerTypeToken->getKnownValue(ValueFlow::Value::ValueType::INT))
1403+
return v->intvalue / 8 > maxByValueSize;
14041404
}
14051405
return false;
14061406
}

lib/checkstl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ bool CheckStl::isContainerSizeGE(const Token * containerToken, const Token *expr
304304
mul = expr->astOperand1();
305305
else
306306
return false;
307-
return mul && (!mul->hasKnownIntValue() || mul->values().front().intvalue != 0);
307+
return mul && (!mul->hasKnownIntValue() || mul->getKnownIntValue() != 0);
308308
}
309309
if (expr->str() == "+") {
310310
const Token *op;
@@ -2492,7 +2492,7 @@ void CheckStl::checkDereferenceInvalidIterator2()
24922492
if (cValue && cValue->intvalue == 0) {
24932493
if (Token::Match(tok->astParent(), "+|-") && astIsIntegral(tok->astSibling(), false)) {
24942494
if (tok->astSibling() && tok->astSibling()->hasKnownIntValue()) {
2495-
if (tok->astSibling()->values().front().intvalue == 0)
2495+
if (tok->astSibling()->getKnownIntValue() == 0)
24962496
continue;
24972497
} else {
24982498
advanceIndex = tok->astSibling();
@@ -2906,8 +2906,8 @@ namespace {
29062906
alwaysFalse = false;
29072907
return;
29082908
}
2909-
(returnTok->values().front().intvalue ? alwaysTrue : alwaysFalse) &= true;
2910-
(returnTok->values().front().intvalue ? alwaysFalse : alwaysTrue) &= false;
2909+
(returnTok->getKnownIntValue() ? alwaysTrue : alwaysFalse) &= true;
2910+
(returnTok->getKnownIntValue() ? alwaysFalse : alwaysTrue) &= false;
29112911
});
29122912
if (alwaysTrue == alwaysFalse)
29132913
return "";

lib/checktype.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,8 @@ void CheckType::checkLongCast()
344344
if (tok->str() != "=" || !Token::Match(tok->astOperand2(), "*|<<") || tok->astOperand2()->isUnaryOp("*"))
345345
continue;
346346

347-
if (tok->astOperand2()->hasKnownIntValue()) {
348-
const ValueFlow::Value &v = tok->astOperand2()->values().front();
349-
if (mSettings->platform.isIntValue(v.intvalue))
347+
if (const ValueFlow::Value* v = tok->astOperand2()->getKnownValue(ValueFlow::Value::ValueType::INT)) {
348+
if (mSettings->platform.isIntValue(v->intvalue))
350349
continue;
351350
}
352351

lib/checkuninitvar.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,8 @@ static void conditionAlwaysTrueOrFalse(const Token *tok, const std::map<nonneg i
292292
if (!tok)
293293
return;
294294

295-
if (tok->hasKnownIntValue()) {
296-
if (tok->getKnownIntValue() == 0)
295+
if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) {
296+
if (v->intvalue == 0)
297297
*alwaysFalse = true;
298298
else
299299
*alwaysTrue = true;

lib/forwardanalyzer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ namespace {
617617
if (!condTok->hasKnownIntValue() || inLoop) {
618618
if (!analyzer->lowerToPossible())
619619
return Break(Analyzer::Terminate::Bail);
620-
} else if (condTok->values().front().intvalue == inElse) {
620+
} else if (condTok->getKnownIntValue() == inElse) {
621621
return Break();
622622
}
623623
// Handle loop

lib/fwdanalysis.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token *
223223
const Token *bodyStart = tok->linkAt(1)->next();
224224
const Token *conditionStart = tok->next();
225225
const Token *condTok = conditionStart->astOperand2();
226-
if (condTok->hasKnownIntValue()) {
227-
const bool cond = !!condTok->values().front().intvalue;
226+
if (const ValueFlow::Value* v = condTok->getKnownValue(ValueFlow::Value::ValueType::INT)) {
227+
const bool cond = !!v->intvalue;
228228
if (cond) {
229229
FwdAnalysis::Result result = checkRecursive(expr, bodyStart, bodyStart->link(), exprVarIds, local, true, depth);
230230
if (result.type != Result::Type::NONE)

lib/pathanalysis.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ static const Token* assignExpr(const Token* tok)
4848

4949
std::pair<bool, bool> PathAnalysis::checkCond(const Token * tok, bool& known)
5050
{
51-
if (tok->hasKnownIntValue()) {
51+
if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT)) {
5252
known = true;
53-
return std::make_pair(!!tok->values().front().intvalue, !tok->values().front().intvalue);
53+
return std::make_pair(!!v->intvalue, !v->intvalue);
5454
}
5555
auto it = std::find_if(tok->values().cbegin(), tok->values().cend(), [](const ValueFlow::Value& v) {
5656
return v.isIntValue();

lib/programmemory.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ void ProgramMemory::setValue(const Token* expr, const ValueFlow::Value& value) {
6464
const Token* subexpr = solveExprValue(
6565
expr,
6666
[&](const Token* tok) -> std::vector<MathLib::bigint> {
67-
if (tok->hasKnownIntValue())
68-
return {tok->values().front().intvalue};
67+
if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT))
68+
return {v->intvalue};
6969
MathLib::bigint result = 0;
7070
if (getIntValue(tok->exprId(), result))
7171
return {result};
@@ -305,8 +305,8 @@ static void programMemoryParseCondition(ProgramMemory& pm, const Token* tok, con
305305
auto eval = [&](const Token* t) -> std::vector<MathLib::bigint> {
306306
if (!t)
307307
return std::vector<MathLib::bigint>{};
308-
if (t->hasKnownIntValue())
309-
return {t->values().front().intvalue};
308+
if (const ValueFlow::Value* v = t->getKnownValue(ValueFlow::Value::ValueType::INT))
309+
return {v->intvalue};
310310
MathLib::bigint result = 0;
311311
bool error = false;
312312
execute(t, pm, &result, &error, settings);
@@ -1372,7 +1372,7 @@ namespace {
13721372
if (!expr)
13731373
return unknown();
13741374
if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",")
1375-
return expr->values().front();
1375+
return *expr->getKnownValue(ValueFlow::Value::ValueType::INT);
13761376
if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) ||
13771377
(value = expr->getKnownValue(ValueFlow::Value::ValueType::TOK)) ||
13781378
(value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) ||

lib/symboldatabase.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1815,8 +1815,8 @@ void SymbolDatabase::setArrayDimensionsUsingValueFlow()
18151815
if (!tok->isName())
18161816
tokenList.addtoken(tok->str(), 0, 0, 0, false);
18171817

1818-
else if (tok->hasKnownIntValue())
1819-
tokenList.addtoken(MathLib::toString(tok->getKnownIntValue()), 0, 0, 0, false);
1818+
else if (const ValueFlow::Value* v = tok->getKnownValue(ValueFlow::Value::ValueType::INT))
1819+
tokenList.addtoken(MathLib::toString(v->intvalue), 0, 0, 0, false);
18201820

18211821
else {
18221822
fail = true;
@@ -1848,9 +1848,9 @@ void SymbolDatabase::setArrayDimensionsUsingValueFlow()
18481848
dimension.known = false;
18491849

18501850
// check for a single token dimension
1851-
if (dimension.tok->hasKnownIntValue()) {
1851+
if (const ValueFlow::Value* v = dimension.tok->getKnownValue(ValueFlow::Value::ValueType::INT)) {
18521852
dimension.known = true;
1853-
dimension.num = dimension.tok->getKnownIntValue();
1853+
dimension.num = v->intvalue;
18541854
continue;
18551855
}
18561856

@@ -3746,9 +3746,13 @@ bool Variable::arrayDimensions(const Settings& settings, bool& isContainer)
37463746
// TODO: only perform when ValueFlow is enabled
37473747
// TODO: collect timing information for this call?
37483748
ValueFlow::valueFlowConstantFoldAST(const_cast<Token *>(dimension_.tok), settings);
3749-
if (dimension_.tok && (dimension_.tok->hasKnownIntValue() ||
3750-
(dimension_.tok->isTemplateArg() && !dimension_.tok->values().empty()))) {
3751-
dimension_.num = dimension_.tok->getKnownIntValue();
3749+
if (dimension_.tok) {
3750+
if (const ValueFlow::Value* v = dimension_.tok->getKnownValue(ValueFlow::Value::ValueType::INT))
3751+
dimension_.num = v->intvalue;
3752+
else if (dimension_.tok->isTemplateArg() && !dimension_.tok->values().empty()) {
3753+
assert(dimension_.tok->values().size() == 1);
3754+
dimension_.num = dimension_.tok->values().front().intvalue;
3755+
}
37523756
dimension_.known = true;
37533757
}
37543758
}

lib/token.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,13 +2503,15 @@ std::shared_ptr<ScopeInfo2> Token::scopeInfo() const
25032503
return mImpl->mScopeInfo;
25042504
}
25052505

2506+
// if there is a known INT value it will always be the first entry
25062507
bool Token::hasKnownIntValue() const
25072508
{
25082509
if (!mImpl->mValues)
25092510
return false;
2510-
return std::any_of(mImpl->mValues->begin(), mImpl->mValues->end(), [](const ValueFlow::Value& value) {
2511-
return value.isKnown() && value.isIntValue();
2512-
});
2511+
if (mImpl->mValues->empty())
2512+
return false;
2513+
const ValueFlow::Value& value = mImpl->mValues->front();
2514+
return value.isIntValue() && value.isKnown();
25132515
}
25142516

25152517
bool Token::hasKnownValue() const
@@ -2540,6 +2542,15 @@ const ValueFlow::Value* Token::getKnownValue(ValueFlow::Value::ValueType t) cons
25402542
{
25412543
if (!mImpl->mValues)
25422544
return nullptr;
2545+
if (mImpl->mValues->empty())
2546+
return nullptr;
2547+
// known INT values are always the first entry
2548+
if (t == ValueFlow::Value::ValueType::INT) {
2549+
const auto& v = mImpl->mValues->front();
2550+
if (!v.isKnown() || !v.isIntValue())
2551+
return nullptr;
2552+
return &v;
2553+
}
25432554
auto it = std::find_if(mImpl->mValues->begin(), mImpl->mValues->end(), [&](const ValueFlow::Value& value) {
25442555
return value.isKnown() && value.valueType == t;
25452556
});

lib/token.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,6 +1309,9 @@ class CPPCHECKLIB Token {
13091309

13101310
const ValueFlow::Value* getKnownValue(ValueFlow::Value::ValueType t) const;
13111311
MathLib::bigint getKnownIntValue() const {
1312+
assert(!mImpl->mValues->empty());
1313+
assert(mImpl->mValues->front().isKnown());
1314+
assert(mImpl->mValues->front().valueType == ValueFlow::Value::ValueType::INT);
13121315
return mImpl->mValues->front().intvalue;
13131316
}
13141317

0 commit comments

Comments
 (0)