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{};
|
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,
|
static void valueFlowInferCondition(TokenList* tokenlist,
|
||||||
const Settings* settings)
|
const Settings* settings)
|
||||||
{
|
{
|
||||||
|
@ -5511,10 +5537,22 @@ static void valueFlowInferCondition(TokenList* tokenlist,
|
||||||
value.bound = ValueFlow::Value::Bound::Point;
|
value.bound = ValueFlow::Value::Bound::Point;
|
||||||
setTokenValue(tok, value, settings);
|
setTokenValue(tok, value, settings);
|
||||||
} else if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) {
|
} else if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) {
|
||||||
std::vector<ValueFlow::Value> result =
|
if (astIsIterator(tok->astOperand1()) || astIsIterator(tok->astOperand2())) {
|
||||||
infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
|
for (ValuePtr<InferModel> model :
|
||||||
for (const ValueFlow::Value& value : result) {
|
std::vector<ValuePtr<InferModel>>{EndIteratorInferModel{}, StartIteratorInferModel{}}) {
|
||||||
setTokenValue(tok, value, settings);
|
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"
|
" if( s.size() < 3 ) return;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void alwaysTrueLoop()
|
||||||
|
|
Loading…
Reference in New Issue