Stricter explicit conversion between types.

A type can be converted to another if the conversion requires at most one of the following: sign,
width, kind (int, address, bytesXX, etc.) For example, the conversion `uint16(int8)` is now disallowed.
This commit is contained in:
hrkrshnn 2020-11-09 10:10:30 +01:00 committed by chriseth
parent d50676ecb0
commit 92ab32e532

View File

@ -443,13 +443,19 @@ BoolResult AddressType::isImplicitlyConvertibleTo(Type const& _other) const
BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
if (_convertTo.category() == category())
if ((_convertTo.category() == category()) || isImplicitlyConvertibleTo(_convertTo))
return true;
else if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))
return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();
return isImplicitlyConvertibleTo(_convertTo) ||
_convertTo.category() == Category::Integer ||
(_convertTo.category() == Category::FixedBytes && 160 == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8);
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
return (!integerType->isSigned() && integerType->numBits() == 160);
else if (
(_convertTo.category() == Category::FixedBytes) &&
(160 == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8)
)
return true;
return false;
}
string AddressType::toString(bool) const
@ -566,12 +572,20 @@ BoolResult IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
BoolResult IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
return _convertTo.category() == category() ||
_convertTo.category() == Category::Address ||
_convertTo.category() == Category::Contract ||
_convertTo.category() == Category::Enum ||
(_convertTo.category() == Category::FixedBytes && numBits() == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8) ||
_convertTo.category() == Category::FixedPoint;
if (isImplicitlyConvertibleTo(_convertTo))
return true;
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
return (numBits() == integerType->numBits()) || (isSigned() == integerType->isSigned());
else if (_convertTo.category() == Category::Address)
return (!isSigned() && numBits() == 160);
else if (auto fixedBytesType = dynamic_cast<FixedBytesType const*>(&_convertTo))
return (!isSigned() && (numBits() == fixedBytesType->numBytes() * 8));
else if (dynamic_cast<EnumType const*>(&_convertTo))
return true;
else if (auto fixedPointType = dynamic_cast<FixedPointType const*>(&_convertTo))
return (isSigned() == fixedPointType->isSigned()) && (numBits() == fixedPointType->numBits());
return false;
}
TypeResult IntegerType::unaryOperatorResult(Token _operator) const
@ -972,10 +986,7 @@ BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo)
if (category == Category::FixedBytes)
return false;
else if (category == Category::Address)
{
if (isNegative() || isFractional() || integerType()->numBits() > 160)
return false;
}
return !(isNegative() || isFractional() || integerType()->numBits() > 160);
else if (category == Category::Integer)
return false;
else if (auto enumType = dynamic_cast<EnumType const*>(&_convertTo))
@ -1446,10 +1457,16 @@ BoolResult FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) con
BoolResult FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
return (_convertTo.category() == Category::Integer && numBytes() * 8 == dynamic_cast<IntegerType const&>(_convertTo).numBits()) ||
(_convertTo.category() == Category::Address && numBytes() == 20) ||
_convertTo.category() == Category::FixedPoint ||
_convertTo.category() == category();
if (_convertTo.category() == category())
return true;
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
return (!integerType->isSigned() && integerType->numBits() == numBytes() * 8);
else if (_convertTo.category() == Category::Address && numBytes() == 20)
return true;
else if (auto fixedPointType = dynamic_cast<FixedPointType const*>(&_convertTo))
return fixedPointType->numBits() == numBytes() * 8;
return false;
}
TypeResult FixedBytesType::unaryOperatorResult(Token _operator) const
@ -2674,7 +2691,11 @@ size_t EnumType::numberOfMembers() const
BoolResult EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
return _convertTo == *this || _convertTo.category() == Category::Integer;
if (_convertTo == *this)
return true;
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
return !integerType->isSigned();
return false;
}
unsigned EnumType::memberValue(ASTString const& _member) const