Fix 11296: FN: knownConditionTrueFalse ( a !=0 && b != 0 && a == 0) (#4444)

This commit is contained in:
Paul Fultz II 2022-09-06 00:31:48 -05:00 committed by GitHub
parent 016793f258
commit 2d37a77281
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 6 deletions

View File

@ -1984,9 +1984,12 @@ static bool isConditionKnown(const Token* tok, bool then)
if (then)
op = "&&";
const Token* parent = tok->astParent();
while (parent && (parent->str() == op || parent->str() == "!"))
while (parent && (parent->str() == op || parent->str() == "!" || parent->isCast()))
parent = parent->astParent();
return Token::Match(parent, "(|;");
const Token* top = tok->astTop();
if (top && Token::Match(top->previous(), "if|while|for ("))
return parent == top || Token::simpleMatch(parent, ";");
return parent && parent->str() != op;
}
static const std::string& invertAssign(const std::string& assign)
@ -6353,12 +6356,16 @@ static bool isIntegralOnlyOperator(const Token* tok) {
return Token::Match(tok, "%|<<|>>|&|^|~|%or%");
}
static bool isIntegral(const Token* tok)
static bool isIntegralOrPointer(const Token* tok)
{
if (!tok)
return false;
if (astIsIntegral(tok, false))
return true;
if (astIsPointer(tok))
return true;
if (Token::Match(tok, "NULL|nullptr"))
return true;
if (tok->valueType())
return false;
// These operators only work on integers
@ -6367,7 +6374,7 @@ static bool isIntegral(const Token* tok)
if (isIntegralOnlyOperator(tok->astParent()))
return true;
if (Token::Match(tok, "+|-|*|/") && tok->isBinaryOp())
return isIntegral(tok->astOperand1()) && isIntegral(tok->astOperand2());
return isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2());
return false;
}
@ -6400,7 +6407,7 @@ static void valueFlowInferCondition(TokenList* tokenlist,
setTokenValue(tok, value, settings);
}
}
} else if (isIntegral(tok->astOperand1()) && isIntegral(tok->astOperand2())) {
} else if (isIntegralOrPointer(tok->astOperand1()) && isIntegralOrPointer(tok->astOperand2())) {
std::vector<ValueFlow::Value> result =
infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
for (const ValueFlow::Value& value : result) {

View File

@ -1309,7 +1309,7 @@ private:
check("int f(char c) {\n"
" return (c <= 'a' && c >= 'z');\n"
"}", "test.cpp", false);
ASSERT_EQUALS("", errout.str());
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:2]: (style) Condition 'c>='z'' is always false\n", errout.str());
}
void incorrectLogicOperator7() { // opposite expressions
@ -4714,6 +4714,11 @@ private:
// #11098
check("void f(unsigned int x) { if (x == -1u) {} }\n");
ASSERT_EQUALS("", errout.str());
check("bool f(const int *p, const int *q) {\n"
" return p != NULL && q != NULL && p == NULL;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:2]: (style) Condition 'p==NULL' is always false\n", errout.str());
}
void alwaysTrueContainer() {

View File

@ -5089,6 +5089,7 @@ private:
" return((n=42) && *n == 'A');\n"
"}";
values = tokenValues(code, "n ==");
values.remove_if(&isNotUninitValue);
ASSERT_EQUALS(true, values.empty());
// #8233