Fix issue 9320: False positive knownConditionTrueFalse related to truncation (#2144)
This commit is contained in:
parent
e7ea748805
commit
e657cf4073
|
@ -445,6 +445,36 @@ static void followVariableExpressionError(const Token *tok1, const Token *tok2,
|
|||
errors->push_back(item);
|
||||
}
|
||||
|
||||
template<class Predicate, class F>
|
||||
static void findTokenValue(const Token* const tok, Predicate pred, F f)
|
||||
{
|
||||
auto x = std::find_if(tok->values().begin(), tok->values().end(), pred);
|
||||
if (x != tok->values().end())
|
||||
f(*x);
|
||||
}
|
||||
|
||||
bool isEqualKnownValue(const Token * const tok1, const Token * const tok2)
|
||||
{
|
||||
bool result = false;
|
||||
findTokenValue(tok1, std::mem_fn(&ValueFlow::Value::isKnown), [&](const ValueFlow::Value& v1) {
|
||||
findTokenValue(tok2, std::mem_fn(&ValueFlow::Value::isKnown), [&](const ValueFlow::Value& v2) {
|
||||
result = v1.equalValue(v2);
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isDifferentKnownValues(const Token * const tok1, const Token * const tok2)
|
||||
{
|
||||
bool result = false;
|
||||
findTokenValue(tok1, std::mem_fn(&ValueFlow::Value::isKnown), [&](const ValueFlow::Value& v1) {
|
||||
findTokenValue(tok2, std::mem_fn(&ValueFlow::Value::isKnown), [&](const ValueFlow::Value& v2) {
|
||||
result = !v1.equalValue(v2);
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2, const Library& library, bool pure, bool followVar, ErrorPath* errors)
|
||||
{
|
||||
if (tok1 == nullptr && tok2 == nullptr)
|
||||
|
@ -464,6 +494,8 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
|
|||
if (Token::simpleMatch(tok2, "!") && Token::simpleMatch(tok2->astOperand1(), "!") && !Token::simpleMatch(tok2->astParent(), "=")) {
|
||||
return isSameExpression(cpp, macro, tok1, tok2->astOperand1()->astOperand1(), library, pure, followVar, errors);
|
||||
}
|
||||
if (tok1->str() != tok2->str() && isDifferentKnownValues(tok1, tok2))
|
||||
return false;
|
||||
// Follow variable
|
||||
if (followVar && tok1->str() != tok2->str() && (Token::Match(tok1, "%var%") || Token::Match(tok2, "%var%"))) {
|
||||
const Token * varTok1 = followVariableExpression(tok1, cpp, tok2);
|
||||
|
@ -596,16 +628,6 @@ bool isSameExpression(bool cpp, bool macro, const Token *tok1, const Token *tok2
|
|||
return commutativeEquals;
|
||||
}
|
||||
|
||||
bool isEqualKnownValue(const Token * const tok1, const Token * const tok2)
|
||||
{
|
||||
return tok1->hasKnownValue() && tok2->hasKnownValue() && tok1->values() == tok2->values();
|
||||
}
|
||||
|
||||
bool isDifferentKnownValues(const Token * const tok1, const Token * const tok2)
|
||||
{
|
||||
return tok1->hasKnownValue() && tok2->hasKnownValue() && tok1->values() != tok2->values();
|
||||
}
|
||||
|
||||
static bool isZeroBoundCond(const Token * const cond)
|
||||
{
|
||||
if (cond == nullptr)
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace ValueFlow {
|
|||
{}
|
||||
Value(const Token *c, long long val);
|
||||
|
||||
bool operator==(const Value &rhs) const {
|
||||
bool equalValue(const ValueFlow::Value& rhs) const {
|
||||
if (valueType != rhs.valueType)
|
||||
return false;
|
||||
switch (valueType) {
|
||||
|
@ -95,6 +95,12 @@ namespace ValueFlow {
|
|||
if (tokvalue != rhs.tokvalue)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator==(const Value &rhs) const {
|
||||
if (!equalValue(rhs))
|
||||
return false;
|
||||
|
||||
return varvalue == rhs.varvalue &&
|
||||
condition == rhs.condition &&
|
||||
|
@ -105,6 +111,10 @@ namespace ValueFlow {
|
|||
valueKind == rhs.valueKind;
|
||||
}
|
||||
|
||||
bool operator!=(const Value &rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
|
||||
std::string infoString() const;
|
||||
|
||||
enum ValueType { INT, TOK, FLOAT, MOVED, UNINIT, CONTAINER_SIZE, LIFETIME, BUFFER_SIZE } valueType;
|
||||
|
|
|
@ -137,6 +137,7 @@ private:
|
|||
TEST_CASE(duplicateExpression6); // ticket #4639
|
||||
TEST_CASE(duplicateExpression7);
|
||||
TEST_CASE(duplicateExpression8);
|
||||
TEST_CASE(duplicateExpression9); // #9320
|
||||
TEST_CASE(duplicateExpressionLoop);
|
||||
TEST_CASE(duplicateValueTernary);
|
||||
TEST_CASE(duplicateExpressionTernary); // #6391
|
||||
|
@ -4584,6 +4585,16 @@ private:
|
|||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void duplicateExpression9() {
|
||||
// #9320
|
||||
check("void f() {\n"
|
||||
" uint16_t x = 1000;\n"
|
||||
" uint8_t y = x;\n"
|
||||
" if (x != y) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void duplicateExpressionLoop() {
|
||||
check("void f() {\n"
|
||||
" int a = 1;\n"
|
||||
|
|
Loading…
Reference in New Issue