MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / infer

Function infer

lib/infer.cpp:286–361  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

284}
285
286std::vector<ValueFlow::Value> infer(const ValuePtr<InferModel>& model,
287 const std::string& op,
288 std::list<ValueFlow::Value> lhsValues,
289 std::list<ValueFlow::Value> rhsValues)
290{
291 std::vector<ValueFlow::Value> result;
292 auto notMatch = [&](const ValueFlow::Value& value) {
293 return !model->match(value);
294 };
295 lhsValues.remove_if(notMatch);
296 if (lhsValues.empty())
297 return result;
298 rhsValues.remove_if(notMatch);
299 if (rhsValues.empty())
300 return result;
301
302 Interval lhs = Interval::fromValues(lhsValues);
303 Interval rhs = Interval::fromValues(rhsValues);
304
305 if (op == "-") {
306 Interval diff = lhs - rhs;
307 if (diff.isScalar()) {
308 std::vector<const ValueFlow::Value*> refs = diff.getScalarRef();
309 ValueFlow::Value value(diff.getScalar());
310 addToErrorPath(value, refs);
311 setValueKind(value, refs);
312 result.push_back(std::move(value));
313 } else {
314 if (!diff.minvalue.empty()) {
315 ValueFlow::Value value(diff.minvalue.front() - 1);
316 value.setImpossible();
317 value.bound = ValueFlow::Value::Bound::Upper;
318 addToErrorPath(value, diff.minRef);
319 result.push_back(std::move(value));
320 }
321 if (!diff.maxvalue.empty()) {
322 ValueFlow::Value value(diff.maxvalue.front() + 1);
323 value.setImpossible();
324 value.bound = ValueFlow::Value::Bound::Lower;
325 addToErrorPath(value, diff.maxRef);
326 result.push_back(std::move(value));
327 }
328 }
329 } else if ((op == "!=" || op == "==") && lhs.isScalarOrEmpty() && rhs.isScalarOrEmpty()) {
330 if (lhs.isScalar() && rhs.isScalar()) {
331 std::vector<const ValueFlow::Value*> refs = Interval::merge(lhs.getScalarRef(), rhs.getScalarRef());
332 ValueFlow::Value value(calculate(op, lhs.getScalar(), rhs.getScalar()));
333 addToErrorPath(value, refs);
334 setValueKind(value, refs);
335 result.push_back(std::move(value));
336 } else {
337 std::vector<const ValueFlow::Value*> refs;
338 if (lhs.isScalar() && inferNotEqual(rhsValues, lhs.getScalar()))
339 refs = lhs.getScalarRef();
340 else if (rhs.isScalar() && inferNotEqual(lhsValues, rhs.getScalar()))
341 refs = rhs.getScalarRef();
342 if (!refs.empty()) {
343 ValueFlow::Value value(op == "!=");

Callers 4

inferConditionFunction · 0.85
valueFlowSymbolicInferFunction · 0.85
valueFlowInferConditionFunction · 0.85
executeImplMethod · 0.85

Calls 13

setValueKindFunction · 0.85
calculateFunction · 0.85
inferNotEqualFunction · 0.85
isScalarMethod · 0.80
getScalarRefMethod · 0.80
getScalarMethod · 0.80
frontMethod · 0.80
isScalarOrEmptyMethod · 0.80
addToErrorPathFunction · 0.70
matchMethod · 0.45
emptyMethod · 0.45
push_backMethod · 0.45

Tested by

no test coverage detected