Skip to content

Commit df59b07

Browse files
authored
Fix 10226: FN: knownConditionTrueFalse (#3537)
1 parent 3e6540c commit df59b07

2 files changed

Lines changed: 52 additions & 4 deletions

File tree

lib/valueflow.cpp

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5493,6 +5493,32 @@ ValueFlow::Value inferCondition(std::string op, MathLib::bigint val, const Token
54935493
return ValueFlow::Value{};
54945494
}
54955495

5496+
struct IteratorInferModel : InferModel {
5497+
virtual ValueFlow::Value::ValueType getType() const = 0;
5498+
virtual bool match(const ValueFlow::Value& value) const OVERRIDE {
5499+
return value.valueType == getType();
5500+
}
5501+
virtual ValueFlow::Value yield(MathLib::bigint value) const OVERRIDE
5502+
{
5503+
ValueFlow::Value result(value);
5504+
result.valueType = getType();
5505+
result.setKnown();
5506+
return result;
5507+
}
5508+
};
5509+
5510+
struct EndIteratorInferModel : IteratorInferModel {
5511+
virtual ValueFlow::Value::ValueType getType() const OVERRIDE {
5512+
return ValueFlow::Value::ValueType::ITERATOR_END;
5513+
}
5514+
};
5515+
5516+
struct StartIteratorInferModel : IteratorInferModel {
5517+
virtual ValueFlow::Value::ValueType getType() const OVERRIDE {
5518+
return ValueFlow::Value::ValueType::ITERATOR_END;
5519+
}
5520+
};
5521+
54965522
static void valueFlowInferCondition(TokenList* tokenlist,
54975523
const Settings* settings)
54985524
{
@@ -5511,10 +5537,22 @@ static void valueFlowInferCondition(TokenList* tokenlist,
55115537
value.bound = ValueFlow::Value::Bound::Point;
55125538
setTokenValue(tok, value, settings);
55135539
} else if (Token::Match(tok, "%comp%|-") && tok->astOperand1() && tok->astOperand2()) {
5514-
std::vector<ValueFlow::Value> result =
5515-
infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
5516-
for (const ValueFlow::Value& value : result) {
5517-
setTokenValue(tok, value, settings);
5540+
if (astIsIterator(tok->astOperand1()) || astIsIterator(tok->astOperand2())) {
5541+
for (ValuePtr<InferModel> model :
5542+
std::vector<ValuePtr<InferModel>>{EndIteratorInferModel{}, StartIteratorInferModel{}}) {
5543+
std::vector<ValueFlow::Value> result =
5544+
infer(model, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
5545+
for (ValueFlow::Value value : result) {
5546+
value.valueType = ValueFlow::Value::ValueType::INT;
5547+
setTokenValue(tok, value, settings);
5548+
}
5549+
}
5550+
} else {
5551+
std::vector<ValueFlow::Value> result =
5552+
infer(IntegralInferModel{}, tok->str(), tok->astOperand1()->values(), tok->astOperand2()->values());
5553+
for (const ValueFlow::Value& value : result) {
5554+
setTokenValue(tok, value, settings);
5555+
}
55185556
}
55195557
}
55205558
}

test/testcondition.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4115,6 +4115,16 @@ class TestCondition : public TestFixture {
41154115
" if( s.size() < 3 ) return;\n"
41164116
"}\n");
41174117
ASSERT_EQUALS("", errout.str());
4118+
4119+
// #10226
4120+
check("int f(std::vector<int>::iterator it, const std::vector<int>& vector) {\n"
4121+
" if (!(it != vector.end() && it != vector.begin()))\n"
4122+
" throw 0;\n"
4123+
" if (it != vector.end() && *it == 0)\n"
4124+
" return -1;\n"
4125+
" return *it;\n"
4126+
"}\n");
4127+
ASSERT_EQUALS("[test.cpp:4]: (style) Condition 'it!=vector.end()' is always true\n", errout.str());
41184128
}
41194129

41204130
void alwaysTrueLoop()

0 commit comments

Comments
 (0)