Skip to content

Commit ac0bd6d

Browse files
authored
Fix 12760: FN knownConditionTrueFalse for pointer + offset (#6491)
1 parent 270518c commit ac0bd6d

File tree

3 files changed

+23
-4
lines changed

3 files changed

+23
-4
lines changed

lib/valueflow.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,11 @@ static void valueFlowImpossibleValues(TokenList& tokenList, const Settings& sett
10911091
ValueFlow::Value value{0};
10921092
value.setImpossible();
10931093
setTokenValue(tok, std::move(value), settings);
1094+
} else if (tok->variable() && tok->variable()->isArray() && !tok->variable()->isArgument() &&
1095+
!tok->variable()->isStlType()) {
1096+
ValueFlow::Value value{0};
1097+
value.setImpossible();
1098+
setTokenValue(tok, std::move(value), settings);
10941099
} else if (tok->isIncompleteVar() && tok->astParent() && tok->astParent()->isUnaryOp("-") &&
10951100
isConvertedToIntegral(tok->astParent(), settings)) {
10961101
ValueFlow::Value value{0};

lib/vf_settokenvalue.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -441,10 +441,16 @@ namespace ValueFlow
441441
setTokenValue(parent, v, settings);
442442
}
443443

444+
// Offset of non null pointer is not null also
445+
else if (astIsPointer(tok) && Token::Match(parent, "+|-") && value.isIntValue() && value.isImpossible() &&
446+
value.intvalue == 0) {
447+
setTokenValue(parent, value, settings);
448+
}
449+
444450
// Calculations..
445-
else if ((parent->isArithmeticalOp() || parent->isComparisonOp() || (parent->tokType() == Token::eBitOp) || (parent->tokType() == Token::eLogicalOp)) &&
446-
parent->astOperand1() &&
447-
parent->astOperand2()) {
451+
else if ((parent->isArithmeticalOp() || parent->isComparisonOp() || (parent->tokType() == Token::eBitOp) ||
452+
(parent->tokType() == Token::eLogicalOp)) &&
453+
parent->astOperand1() && parent->astOperand2()) {
448454

449455
const bool noninvertible = isNonInvertibleOperation(parent);
450456

@@ -659,7 +665,8 @@ namespace ValueFlow
659665
}
660666

661667
// C++ init
662-
else if (parent->str() == "{" && Token::simpleMatch(parent->previous(), "= {") && Token::simpleMatch(parent->link(), "} ;")) {
668+
else if (parent->str() == "{" && Token::simpleMatch(parent->previous(), "= {") &&
669+
Token::simpleMatch(parent->link(), "} ;")) {
663670
const Token* lhs = parent->previous()->astOperand1();
664671
if (lhs && lhs->valueType()) {
665672
if (lhs->valueType()->isIntegral() || lhs->valueType()->isFloat() || (lhs->valueType()->pointer > 0 && value.isIntValue())) {

test/testcondition.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4600,6 +4600,13 @@ class TestCondition : public TestFixture {
46004600
" if ((i = g(), 1) != 0) {}\n"
46014601
"}\n");
46024602
ASSERT_EQUALS("[test.cpp:3]: (style) Condition '(i=g(),1)!=0' is always true\n", errout_str());
4603+
4604+
check("void f(unsigned i) {\n"
4605+
" const int a[2] = {};\n"
4606+
" const int* q = a + i;\n"
4607+
" if (q) {}\n"
4608+
"}\n");
4609+
ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'q' is always true\n", errout_str());
46034610
}
46044611

46054612
void alwaysTrueSymbolic()

0 commit comments

Comments
 (0)