| 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)) |
nothing calls this directly
no test coverage detected