diff --git a/AST.cpp b/AST.cpp index 248abfdb9..a209235dc 100644 --- a/AST.cpp +++ b/AST.cpp @@ -686,9 +686,15 @@ 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() diff --git a/Types.cpp b/Types.cpp index 0e9ea9876..c4238f773 100644 --- a/Types.cpp +++ b/Types.cpp @@ -361,17 +361,28 @@ IntegerConstantType::IntegerConstantType(Literal const& _literal) bool IntegerConstantType::isImplicitlyConvertibleTo(Type const& _convertTo) const { - shared_ptr integerType = getIntegerType(); - if (!integerType) - return false; - - if (_convertTo.getCategory() == Category::FixedBytes) + if (IntegerType const* integerType = dynamic_cast(&_convertTo)) { - FixedBytesType const& convertTo = dynamic_cast(_convertTo); - return convertTo.getNumBytes() * 8 >= integerType->getNumBits(); + if (m_value == 0) + return true; + int forSignBit = (integerType->isSigned() ? 1 : 0); + if (m_value > 0) + { + if (m_value <= (u256(-1) >> (256 - integerType->getNumBits() + forSignBit))) + return true; + } + else if (-m_value <= (u256(1) << (integerType->getNumBits() - forSignBit))) + return true; + return false; } - - return integerType->isImplicitlyConvertibleTo(_convertTo); + else + if (_convertTo.getCategory() == Category::FixedBytes) + { + FixedBytesType const& fixedBytes = dynamic_cast(_convertTo); + return fixedBytes.getNumBytes() * 8 >= getIntegerType()->getNumBits(); + } + else + return false; } bool IntegerConstantType::isExplicitlyConvertibleTo(Type const& _convertTo) const @@ -514,9 +525,10 @@ shared_ptr IntegerConstantType::getIntegerType() const if (value > u256(-1)) return shared_ptr(); else - return make_shared(max(bytesRequired(value), 1u) * 8, - negative ? IntegerType::Modifier::Signed - : IntegerType::Modifier::Unsigned); + return make_shared( + max(bytesRequired(value), 1u) * 8, + negative ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned + ); } shared_ptr FixedBytesType::smallestTypeForLiteral(string const& _literal)