Fix 10226: FN: knownConditionTrueFalse (#3537)
This commit is contained in:
parent
3e6540c4b3
commit
df59b07ba1
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue