| 1447 | } |
| 1448 | |
| 1449 | ValueFlow::Value executeImpl(const Token* expr) |
| 1450 | { |
| 1451 | const ValueFlow::Value* value = nullptr; |
| 1452 | if (!expr) |
| 1453 | return unknown(); |
| 1454 | if (expr->hasKnownIntValue() && !expr->isAssignmentOp() && expr->str() != ",") |
| 1455 | return *expr->getKnownValue(ValueFlow::Value::ValueType::INT); |
| 1456 | if ((value = expr->getKnownValue(ValueFlow::Value::ValueType::FLOAT)) || |
| 1457 | (value = expr->getKnownValue(ValueFlow::Value::ValueType::TOK)) || |
| 1458 | (value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_START)) || |
| 1459 | (value = expr->getKnownValue(ValueFlow::Value::ValueType::ITERATOR_END)) || |
| 1460 | (value = expr->getKnownValue(ValueFlow::Value::ValueType::CONTAINER_SIZE))) { |
| 1461 | return *value; |
| 1462 | } |
| 1463 | if (expr->isNumber()) { |
| 1464 | if (MathLib::isFloat(expr->str())) |
| 1465 | return unknown(); |
| 1466 | MathLib::bigint i = MathLib::toBigNumber(expr); |
| 1467 | if (i < 0 && astIsUnsigned(expr)) |
| 1468 | return unknown(); |
| 1469 | return ValueFlow::Value{i}; |
| 1470 | } |
| 1471 | if (expr->isBoolean()) |
| 1472 | return ValueFlow::Value{expr->str() == "true"}; |
| 1473 | if (Token::Match(expr->tokAt(-2), ". %name% (") && astIsContainer(expr->tokAt(-2)->astOperand1())) { |
| 1474 | const Token* containerTok = expr->tokAt(-2)->astOperand1(); |
| 1475 | const Library::Container::Yield yield = containerTok->valueType()->container->getYield(expr->strAt(-1)); |
| 1476 | if (yield == Library::Container::Yield::SIZE) { |
| 1477 | ValueFlow::Value v = execute(containerTok); |
| 1478 | if (!v.isContainerSizeValue()) |
| 1479 | return unknown(); |
| 1480 | v.valueType = ValueFlow::Value::ValueType::INT; |
| 1481 | return v; |
| 1482 | } |
| 1483 | if (yield == Library::Container::Yield::EMPTY) { |
| 1484 | ValueFlow::Value v = execute(containerTok); |
| 1485 | if (!v.isContainerSizeValue()) |
| 1486 | return unknown(); |
| 1487 | if (v.isImpossible() && v.intvalue == 0) |
| 1488 | return ValueFlow::Value{0}; |
| 1489 | if (!v.isImpossible()) |
| 1490 | return ValueFlow::Value{v.intvalue == 0}; |
| 1491 | } |
| 1492 | } else if (expr->isAssignmentOp() && expr->astOperand1() && expr->astOperand2() && |
| 1493 | expr->astOperand1()->exprId() > 0) { |
| 1494 | ValueFlow::Value rhs = execute(expr->astOperand2()); |
| 1495 | if (rhs.isUninitValue()) |
| 1496 | return unknown(); |
| 1497 | if (expr->str() != "=") { |
| 1498 | if (!pm->hasValue(expr->astOperand1()->exprId())) |
| 1499 | return unknown(); |
| 1500 | ValueFlow::Value& lhs = pm->at(expr->astOperand1()->exprId()); |
| 1501 | rhs = evaluate(expr, lhs, rhs, /*removeAssign*/ true); |
| 1502 | if (lhs.isIntValue()) |
| 1503 | ValueFlow::Value::visitValue(rhs, std::bind(assign{}, std::ref(lhs.intvalue), std::placeholders::_1)); |
| 1504 | else if (lhs.isFloatValue()) |
| 1505 | ValueFlow::Value::visitValue(rhs, |
| 1506 | std::bind(assign{}, std::ref(lhs.floatValue), std::placeholders::_1)); |
nothing calls this directly
no test coverage detected