diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 8d8c497f2..4668374fb 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -544,10 +544,15 @@ static void setTokenValue(Token* tok, const ValueFlow::Value &value, const Setti // cast.. 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")) return; 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); } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 61b397a71..c75a23bca 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -140,6 +140,7 @@ private: TEST_CASE(valueFlowUnknownMixedOperators); TEST_CASE(valueFlowIdempotent); + TEST_CASE(valueFlowUnsigned); } static bool isNotTokValue(const ValueFlow::Value &val) { @@ -5607,6 +5608,28 @@ private: "}\n"; 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)