Fix 11296: FN: knownConditionTrueFalse ( a !=0 && b != 0 && a == 0) (#4444)
This commit is contained in:
parent
016793f258
commit
2d37a77281
|
@ -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) {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue