mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
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:
parent
d50676ecb0
commit
92ab32e532
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user