Fix 10288: ValueFlow; False positives because of wrong known value when there is sign cast (#3268)

This commit is contained in:
Paul Fultz II 2021-05-23 03:20:29 -05:00 committed by GitHub
parent e2d9aaf23b
commit 47a4144b47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 1 deletions

View File

@ -544,10 +544,15 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti
// cast.. // cast..
if (const Token *castType = getCastTypeStartToken(parent)) { if (const Token *castType = getCastTypeStartToken(parent)) {
if (((tok->valueType() == nullptr && value.isImpossible()) || astIsPointer(tok)) && value.valueType == ValueFlow::Value::ValueType::INT && if (((tok->valueType() == nullptr && value.isImpossible()) || astIsPointer(tok)) &&
value.valueType == ValueFlow::Value::ValueType::INT &&
Token::simpleMatch(parent->astOperand1(), "dynamic_cast")) Token::simpleMatch(parent->astOperand1(), "dynamic_cast"))
return; return;
const ValueType &valueType = ValueType::parseDecl(castType, settings); const ValueType &valueType = ValueType::parseDecl(castType, settings);
if (value.isImpossible() && value.isIntValue() && value.intvalue < 0 && astIsUnsigned(tok) &&
valueType.sign == ValueType::SIGNED && tok->valueType() &&
ValueFlow::getSizeOf(*tok->valueType(), settings) >= ValueFlow::getSizeOf(valueType, settings))
return;
setTokenValueCast(parent, valueType, value, settings); setTokenValueCast(parent, valueType, value, settings);
} }

View File

@ -140,6 +140,7 @@ private:
TEST_CASE(valueFlowUnknownMixedOperators); TEST_CASE(valueFlowUnknownMixedOperators);
TEST_CASE(valueFlowIdempotent); TEST_CASE(valueFlowIdempotent);
TEST_CASE(valueFlowUnsigned);
} }
static bool isNotTokValue(const ValueFlow::Value &val) { static bool isNotTokValue(const ValueFlow::Value &val) {
@ -5607,6 +5608,28 @@ private:
"}\n"; "}\n";
ASSERT_EQUALS(false, testValueOfXKnown(code, 5U, 0)); ASSERT_EQUALS(false, testValueOfXKnown(code, 5U, 0));
} }
void valueFlowUnsigned() {
const char *code;
code = "auto f(uint32_t i) {\n"
" auto x = i;\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, -1));
code = "auto f(uint32_t i) {\n"
" auto x = (int32_t)i;\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(false, testValueOfXImpossible(code, 3U, -1));
code = "auto f(uint32_t i) {\n"
" auto x = (int64_t)i;\n"
" return x;\n"
"}\n";
ASSERT_EQUALS(true, testValueOfXImpossible(code, 3U, -1));
}
}; };
REGISTER_TEST(TestValueFlow) REGISTER_TEST(TestValueFlow)