Fix 10226: FN: knownConditionTrueFalse (#3537)

This commit is contained in:
Paul Fultz II 2021-10-31 08:51:07 -05:00 committed by GitHub
parent 3e6540c4b3
commit df59b07ba1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 4 deletions

View File

@ -5493,6 +5493,32 @@ ValueFlow::Value inferCondition(std::string op, MathLib::bigint val, const Token
return ValueFlow::Value{};
}
struct IteratorInferModel : InferModel {
virtual ValueFlow::Value::ValueType getType() const = 0;
virtual bool match(const ValueFlow::Value& value) const OVERRIDE {
return value.valueType == getType();
}
virtual ValueFlow::Value yield(MathLib::bigint value) const OVERRIDE
{
ValueFlow::Value result(value);
result.valueType = getType();
result.setKnown();
return result;
}
};
struct EndIteratorInferModel : IteratorInferModel {
virtual ValueFlow::Value::ValueType getType() const OVERRIDE {
return ValueFlow::Value::ValueType::ITERATOR_END;
}
};
struct StartIteratorInferModel : IteratorInferModel {
virtual ValueFlow::Value::ValueType getType() const OVERRIDE {
return ValueFlow::Value::ValueType::ITERATOR_END;
}
};
static void valueFlowInferCondition(TokenList* tokenlist,
const Settings* settings)
{
@ -5511,10 +5537,22 @@ static void valueFlowInferCondition(TokenList* tokenlist,
value.bound = ValueFlow::Value::Bound::Point;
setTokenValue(tok, value, settings);
} else if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) {
std::vector<ValueFlow::Value> result =
infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
for (const ValueFlow::Value& value : result) {
setTokenValue(tok, value, settings);
if (astIsIterator(tok->astOperand1()) || astIsIterator(tok->astOperand2())) {
for (ValuePtr<InferModel> model :
std::vector<ValuePtr<InferModel>>{EndIteratorInferModel{}, StartIteratorInferModel{}}) {
std::vector<ValueFlow::Value> result =
infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
for (ValueFlow::Value value : result) {
value.valueType = ValueFlow::Value::ValueType::INT;
setTokenValue(tok, value, settings);
}
}
} else {
std::vector<ValueFlow::Value> result =
infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
for (const ValueFlow::Value& value : result) {
setTokenValue(tok, value, settings);
}
}
}
}

View File

@ -4115,6 +4115,16 @@ private:
" if( s.size() < 3 ) return;\n"
"}\n");
ASSERT_EQUALS("", errout.str());
// #10226
check("int f(std::vector<int>::iterator it, const std::vector<int>& vector) {\n"
" if (!(it != vector.end() && it != vector.begin()))\n"
" throw 0;\n"
" if (it != vector.end() && *it == 0)\n"
" return -1;\n"
" return *it;\n"
"}\n");
ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'it!=vector.end()' is always true\n", errout.str());
}
void alwaysTrueLoop()