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

View File

@ -1309,7 +1309,7 @@ private:
check("int f(char c) {\n" check("int f(char c) {\n"
" return (c <= 'a' && c >= 'z');\n" " return (c <= 'a' && c >= 'z');\n"
"}", "test.cpp", false); "}", "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 void incorrectLogicOperator7() { // opposite expressions
@ -4714,6 +4714,11 @@ private:
// #11098 // #11098
check("void f(unsigned int x) { if (x == -1u) {} }\n"); check("void f(unsigned int x) { if (x == -1u) {} }\n");
ASSERT_EQUALS("", errout.str()); 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() { void alwaysTrueContainer() {

View File

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