diff options
-rw-r--r-- | AST.cpp | 11 | ||||
-rw-r--r-- | Types.cpp | 33 |
2 files changed, 30 insertions, 14 deletions
@@ -686,9 +686,14 @@ void Expression::expectType(Type const& _expectedType) checkTypeRequirements(nullptr); Type const& type = *getType(); if (!type.isImplicitlyConvertibleTo(_expectedType)) - BOOST_THROW_EXCEPTION(createTypeError("Type " + type.toString() + - " not implicitly convertible to expected type " - + _expectedType.toString() + ".")); + BOOST_THROW_EXCEPTION(createTypeError( + "Type " + + type.toString() + + " is not implicitly convertible to expected type " + + _expectedType.toString() + + "." + ) + ); } void Expression::requireLValue() @@ -361,17 +361,27 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal) bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const { - shared_ptr<IntegerType const> integerType = getIntegerType(); - if (!integerType) + if (auto targetType = dynamic_cast<IntegerType const*>(&_convertTo)) + { + if (m_value == 0) + return true; + int forSignBit = (targetType->isSigned() ? 1 : 0); + if (m_value > 0) + { + if (m_value <= (u256(-1) >> (256 - targetType->getNumBits() + forSignBit))) + return true; + } + else if (targetType->isSigned() && -m_value <= (u256(1) << (targetType->getNumBits() - forSignBit))) + return true; return false; - - if (_convertTo.getCategory() == Category::FixedBytes) + } + else if (_convertTo.getCategory() == Category::FixedBytes) { - FixedBytesType const& convertTo = dynamic_cast<FixedBytesType const&>(_convertTo); - return convertTo.getNumBytes() * 8 >= integerType->getNumBits(); + FixedBytesType const& fixedBytes = dynamic_cast<FixedBytesType const&>(_convertTo); + return fixedBytes.getNumBytes() * 8 >= getIntegerType()->getNumBits(); } - - return integerType->isImplicitlyConvertibleTo(_convertTo); + else + return false; } bool IntegerConstantType::isExplicitlyConvertibleTo(Type const& _convertTo) const @@ -514,9 +524,10 @@ shared_ptr<IntegerType const> IntegerConstantType::getIntegerType() const if (value > u256(-1)) return shared_ptr<IntegerType const>(); else - return make_shared<IntegerType>(max(bytesRequired(value), 1u) * 8, - negative ? IntegerType::Modifier::Signed - : IntegerType::Modifier::Unsigned); + return make_shared<IntegerType>( + max(bytesRequired(value), 1u) * 8, + negative ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned + ); } shared_ptr<FixedBytesType> FixedBytesType::smallestTypeForLiteral(string const& _literal) |