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
|
BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||||
{
|
{
|
||||||
if (_convertTo.category() == category())
|
if ((_convertTo.category() == category()) || isImplicitlyConvertibleTo(_convertTo))
|
||||||
return true;
|
return true;
|
||||||
else if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))
|
else if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo))
|
||||||
return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();
|
return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable();
|
||||||
return isImplicitlyConvertibleTo(_convertTo) ||
|
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
||||||
_convertTo.category() == Category::Integer ||
|
return (!integerType->isSigned() && integerType->numBits() == 160);
|
||||||
(_convertTo.category() == Category::FixedBytes && 160 == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8);
|
else if (
|
||||||
|
(_convertTo.category() == Category::FixedBytes) &&
|
||||||
|
(160 == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8)
|
||||||
|
)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AddressType::toString(bool) const
|
string AddressType::toString(bool) const
|
||||||
@ -566,12 +572,20 @@ BoolResult IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
|
|||||||
|
|
||||||
BoolResult IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
BoolResult IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||||
{
|
{
|
||||||
return _convertTo.category() == category() ||
|
if (isImplicitlyConvertibleTo(_convertTo))
|
||||||
_convertTo.category() == Category::Address ||
|
return true;
|
||||||
_convertTo.category() == Category::Contract ||
|
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
||||||
_convertTo.category() == Category::Enum ||
|
return (numBits() == integerType->numBits()) || (isSigned() == integerType->isSigned());
|
||||||
(_convertTo.category() == Category::FixedBytes && numBits() == dynamic_cast<FixedBytesType const&>(_convertTo).numBytes() * 8) ||
|
else if (_convertTo.category() == Category::Address)
|
||||||
_convertTo.category() == Category::FixedPoint;
|
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
|
TypeResult IntegerType::unaryOperatorResult(Token _operator) const
|
||||||
@ -972,10 +986,7 @@ BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo)
|
|||||||
if (category == Category::FixedBytes)
|
if (category == Category::FixedBytes)
|
||||||
return false;
|
return false;
|
||||||
else if (category == Category::Address)
|
else if (category == Category::Address)
|
||||||
{
|
return !(isNegative() || isFractional() || integerType()->numBits() > 160);
|
||||||
if (isNegative() || isFractional() || integerType()->numBits() > 160)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (category == Category::Integer)
|
else if (category == Category::Integer)
|
||||||
return false;
|
return false;
|
||||||
else if (auto enumType = dynamic_cast<EnumType const*>(&_convertTo))
|
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
|
BoolResult FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const
|
||||||
{
|
{
|
||||||
return (_convertTo.category() == Category::Integer && numBytes() * 8 == dynamic_cast<IntegerType const&>(_convertTo).numBits()) ||
|
if (_convertTo.category() == category())
|
||||||
(_convertTo.category() == Category::Address && numBytes() == 20) ||
|
return true;
|
||||||
_convertTo.category() == Category::FixedPoint ||
|
else if (auto integerType = dynamic_cast<IntegerType const*>(&_convertTo))
|
||||||
_convertTo.category() == category();
|
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
|
TypeResult FixedBytesType::unaryOperatorResult(Token _operator) const
|
||||||
@ -2674,7 +2691,11 @@ size_t EnumType::numberOfMembers() const
|
|||||||
|
|
||||||
BoolResult EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) 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
|
unsigned EnumType::memberValue(ASTString const& _member) const
|
||||||
|
Loading…
Reference in New Issue
Block a user