| 1723 | } |
| 1724 | |
| 1725 | BoolResult ArrayType::validForLocation(DataLocation _loc) const |
| 1726 | { |
| 1727 | if (auto arrayBaseType = dynamic_cast<ArrayType const*>(baseType())) |
| 1728 | { |
| 1729 | BoolResult result = arrayBaseType->validForLocation(_loc); |
| 1730 | if (!result) |
| 1731 | return result; |
| 1732 | } |
| 1733 | if (isDynamicallySized()) |
| 1734 | return true; |
| 1735 | switch (_loc) |
| 1736 | { |
| 1737 | case DataLocation::Memory: |
| 1738 | { |
| 1739 | bigint size = bigint(length()); |
| 1740 | auto type = m_baseType; |
| 1741 | while (auto arrayType = dynamic_cast<ArrayType const*>(type)) |
| 1742 | { |
| 1743 | if (arrayType->isDynamicallySized()) |
| 1744 | break; |
| 1745 | else |
| 1746 | { |
| 1747 | size *= arrayType->length(); |
| 1748 | type = arrayType->baseType(); |
| 1749 | } |
| 1750 | } |
| 1751 | if (type->isDynamicallySized()) |
| 1752 | size *= type->memoryHeadSize(); |
| 1753 | else |
| 1754 | size *= type->memoryDataSize(); |
| 1755 | if (size >= std::numeric_limits<unsigned>::max()) |
| 1756 | return BoolResult::err("Type too large for memory."); |
| 1757 | break; |
| 1758 | } |
| 1759 | case DataLocation::CallData: |
| 1760 | { |
| 1761 | if (unlimitedStaticCalldataSize(true) >= std::numeric_limits<unsigned>::max()) |
| 1762 | return BoolResult::err("Type too large for calldata."); |
| 1763 | break; |
| 1764 | } |
| 1765 | case DataLocation::Storage: |
| 1766 | if (storageSizeUpperBound() >= bigint(1) << 256) |
| 1767 | return BoolResult::err("Type too large for storage."); |
| 1768 | break; |
| 1769 | case DataLocation::Transient: |
| 1770 | solUnimplemented("Transient data location is only supported for value types."); |
| 1771 | break; |
| 1772 | } |
| 1773 | return true; |
| 1774 | } |
| 1775 | |
| 1776 | bigint ArrayType::unlimitedStaticCalldataSize(bool _padded) const |
| 1777 | { |
no test coverage detected