Skip to content

Commit 2d37a77

Browse files
authored
Fix 11296: FN: knownConditionTrueFalse ( a !=0 && b != 0 && a == 0) (#4444)
1 parent 016793f commit 2d37a77

3 files changed

Lines changed: 19 additions & 6 deletions

File tree

lib/valueflow.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1984,9 +1984,12 @@ static bool isConditionKnown(const Token* tok, bool then)
19841984
if (then)
19851985
op = "&&";
19861986
const Token* parent = tok->astParent();
1987-
while (parent && (parent->str() == op || parent->str() == "!"))
1987+
while (parent && (parent->str() == op || parent->str() == "!" || parent->isCast()))
19881988
parent = parent->astParent();
1989-
return Token::Match(parent, "(|;");
1989+
const Token* top = tok->astTop();
1990+
if (top && Token::Match(top->previous(), "if|while|for ("))
1991+
return parent == top || Token::simpleMatch(parent, ";");
1992+
return parent && parent->str() != op;
19901993
}
19911994

19921995
static const std::string& invertAssign(const std::string& assign)
@@ -6353,12 +6356,16 @@ static bool isIntegralOnlyOperator(const Token* tok) {
63536356
return Token::Match(tok, "%|<<|>>|&|^|~|%or%");
63546357
}
63556358

6356-
static bool isIntegral(const Token* tok)
6359+
static bool isIntegralOrPointer(const Token* tok)
63576360
{
63586361
if (!tok)
63596362
return false;
63606363
if (astIsIntegral(tok, false))
63616364
return true;
6365+
if (astIsPointer(tok))
6366+
return true;
6367+
if (Token::Match(tok, "NULL|nullptr"))
6368+
return true;
63626369
if (tok->valueType())
63636370
return false;
63646371
// These operators only work on integers
@@ -6367,7 +6374,7 @@ static bool isIntegral(const Token* tok)
63676374
if (isIntegralOnlyOperator(tok->astParent()))
63686375
return true;
63696376
if (Token::Match(tok, "+|-|*|/") && tok->isBinaryOp())
6370-
return isIntegral(tok->astOperand1()) && isIntegral(tok->astOperand2());
6377+
return isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2());
63716378
return false;
63726379
}
63736380

@@ -6400,7 +6407,7 @@ static void valueFlowInferCondition(TokenList* tokenlist,
64006407
setTokenValue(tok, value, settings);
64016408
}
64026409
}
6403-
} else if (isIntegral(tok->astOperand1()) && isIntegral(tok->astOperand2())) {
6410+
} else if (isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2())) {
64046411
std::vector<ValueFlow::Value> result =
64056412
infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
64066413
for (const ValueFlow::Value& value : result) {

test/testcondition.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1309,7 +1309,7 @@ class TestCondition : public TestFixture {
13091309
check("int f(char c) {\n"
13101310
" return (c <= 'a' && c >= 'z');\n"
13111311
"}", "test.cpp", false);
1312-
ASSERT_EQUALS("", errout.str());
1312+
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 'c>='z'' is always false\n", errout.str());
13131313
}
13141314

13151315
void incorrectLogicOperator7() { // opposite expressions
@@ -4714,6 +4714,11 @@ class TestCondition : public TestFixture {
47144714
// #11098
47154715
check("void f(unsigned int x) { if (x == -1u) {} }\n");
47164716
ASSERT_EQUALS("", errout.str());
4717+
4718+
check("bool f(const int *p, const int *q) {\n"
4719+
" return p != NULL && q != NULL && p == NULL;\n"
4720+
"}\n");
4721+
ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'p==NULL' is always false\n", errout.str());
47174722
}
47184723

47194724
void alwaysTrueContainer() {

test/testvalueflow.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5089,6 +5089,7 @@ class TestValueFlow : public TestFixture {
50895089
" return((n=42) && *n == 'A');\n"
50905090
"}";
50915091
values = tokenValues(code, "n ==");
5092+
values.remove_if(&isNotUninitValue);
50925093
ASSERT_EQUALS(true, values.empty());
50935094

50945095
// #8233

0 commit comments

Comments
 (0)