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

Method executeMultiCondition

lib/programmemory.cpp:1364–1447  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1362 }
1363
1364 ValueFlow::Value executeMultiCondition(bool b, const Token* expr)
1365 {
1366 if (pm->hasValue(expr->exprId())) {
1367 const ValueFlow::Value& v = utils::as_const(*pm).at(expr->exprId());
1368 if (v.isIntValue())
1369 return v;
1370 }
1371
1372 // Evaluate recursively if there are no exprids
1373 if ((expr->astOperand1() && expr->astOperand1()->exprId() == 0) ||
1374 (expr->astOperand2() && expr->astOperand2()->exprId() == 0)) {
1375 ValueFlow::Value lhs = execute(expr->astOperand1());
1376 if (isTrueOrFalse(lhs, b))
1377 return lhs;
1378 ValueFlow::Value rhs = execute(expr->astOperand2());
1379 if (isTrueOrFalse(rhs, b))
1380 return rhs;
1381 if (isTrueOrFalse(lhs, !b) && isTrueOrFalse(rhs, !b))
1382 return lhs;
1383 return unknown();
1384 }
1385
1386 nonneg int n = astCount(expr, expr->str().c_str());
1387 if (n > 50)
1388 return unknown();
1389 std::vector<const Token*> conditions1 = flattenConditions(expr);
1390 if (conditions1.empty())
1391 return unknown();
1392 std::unordered_map<nonneg int, ValueFlow::Value> condValues = executeAll(conditions1, &b);
1393 bool allNegated = true;
1394 ValueFlow::Value negatedValue = unknown();
1395 for (const auto& p : condValues) {
1396 const ValueFlow::Value& v = p.second;
1397 if (isTrueOrFalse(v, b))
1398 return v;
1399 allNegated &= isTrueOrFalse(v, !b);
1400 if (allNegated && negatedValue.isUninitValue())
1401 negatedValue = v;
1402 }
1403 if (condValues.size() == conditions1.size() && allNegated)
1404 return negatedValue;
1405 if (n > 4)
1406 return unknown();
1407 if (!sortConditions(conditions1))
1408 return unknown();
1409
1410 for (const auto& p : *pm) {
1411 const Token* tok = p.first.tok;
1412 if (!tok)
1413 continue;
1414 const ValueFlow::Value& value = p.second;
1415
1416 if (tok->str() == expr->str() && !astHasExpr(tok, expr->exprId())) {
1417 // TODO: Handle when it is greater
1418 if (n != astCount(tok, expr->str().c_str()))
1419 continue;
1420 std::vector<const Token*> conditions2 = flattenConditions(tok);
1421 if (!sortConditions(conditions2))

Callers

nothing calls this directly

Calls 15

executeFunction · 0.85
isTrueOrFalseFunction · 0.85
unknownFunction · 0.85
astCountFunction · 0.85
astHasExprFunction · 0.85
setDifferenceFunction · 0.85
pruneConditionsFunction · 0.85
evalSameConditionFunction · 0.85
atMethod · 0.80
astOperand1Method · 0.80
astOperand2Method · 0.80
hasValueMethod · 0.45

Tested by

no test coverage detected