| 1635 | } |
| 1636 | |
| 1637 | void SMTEncoder::indexOrMemberAssignment(Expression const& _expr, smtutil::Expression const& _rightHandSide) |
| 1638 | { |
| 1639 | auto toStore = _rightHandSide; |
| 1640 | auto const* lastExpr = &_expr; |
| 1641 | while (true) |
| 1642 | { |
| 1643 | if (auto const* indexAccess = dynamic_cast<IndexAccess const*>(lastExpr)) |
| 1644 | { |
| 1645 | auto const& base = indexAccess->baseExpression(); |
| 1646 | if (dynamic_cast<Identifier const*>(&base)) |
| 1647 | base.accept(*this); |
| 1648 | |
| 1649 | Type const* baseType = base.annotation().type; |
| 1650 | auto indexExpr = expr(*indexAccess->indexExpression(), keyType(baseType)); |
| 1651 | auto symbArray = std::dynamic_pointer_cast<smt::SymbolicArrayVariable>(m_context.expression(base)); |
| 1652 | solAssert(symbArray, ""); |
| 1653 | toStore = smtutil::Expression::tuple_constructor( |
| 1654 | smtutil::Expression(std::make_shared<smtutil::SortSort>(smt::smtSort(*baseType)), baseType->toString(true)), |
| 1655 | {smtutil::Expression::store(symbArray->elements(), indexExpr, toStore), symbArray->length()} |
| 1656 | ); |
| 1657 | defineExpr(*indexAccess, smtutil::Expression::select( |
| 1658 | symbArray->elements(), |
| 1659 | indexExpr |
| 1660 | )); |
| 1661 | lastExpr = &indexAccess->baseExpression(); |
| 1662 | } |
| 1663 | else if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(lastExpr)) |
| 1664 | { |
| 1665 | auto const& base = memberAccess->expression(); |
| 1666 | if (dynamic_cast<Identifier const*>(&base)) |
| 1667 | base.accept(*this); |
| 1668 | |
| 1669 | if ( |
| 1670 | auto const* structType = dynamic_cast<StructType const*>(base.annotation().type); |
| 1671 | structType && structType->recursive() |
| 1672 | ) |
| 1673 | { |
| 1674 | m_unsupportedErrors.warning( |
| 1675 | 4375_error, |
| 1676 | memberAccess->location(), |
| 1677 | "Assertion checker does not support recursive structs." |
| 1678 | ); |
| 1679 | return; |
| 1680 | } |
| 1681 | if (auto varDecl = identifierToVariable(*memberAccess)) |
| 1682 | { |
| 1683 | if (varDecl->hasReferenceOrMappingType()) |
| 1684 | resetReferences(*varDecl); |
| 1685 | |
| 1686 | assignment(*varDecl, toStore); |
| 1687 | break; |
| 1688 | } |
| 1689 | |
| 1690 | auto symbStruct = std::dynamic_pointer_cast<smt::SymbolicStructVariable>(m_context.expression(base)); |
| 1691 | solAssert(symbStruct, ""); |
| 1692 | symbStruct->assignMember(memberAccess->memberName(), toStore); |
| 1693 | toStore = symbStruct->currentValue(); |
| 1694 | defineExpr(*memberAccess, symbStruct->member(memberAccess->memberName())); |
nothing calls this directly
no test coverage detected