mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #10223 from ethereum/strict-conversion
[BREAKING] Strict conversion
This commit is contained in:
commit
9bb83ef82d
@ -16,6 +16,7 @@ Breaking Changes:
|
|||||||
* Code Generator: Use ``revert`` with error signature ``Panic(uint256)`` and error codes instead of invalid opcode on failing assertions.
|
* Code Generator: Use ``revert`` with error signature ``Panic(uint256)`` and error codes instead of invalid opcode on failing assertions.
|
||||||
* Type System: Explicit conversions from literals to integer type is as strict as implicit conversions.
|
* Type System: Explicit conversions from literals to integer type is as strict as implicit conversions.
|
||||||
* Type System: Explicit conversions from literals to enums are only allowed if the value fits in the enum.
|
* Type System: Explicit conversions from literals to enums are only allowed if the value fits in the enum.
|
||||||
|
* Type System: Explicit conversions between two types are disallowed if it changes more than one of sign, width or kind at the same time.
|
||||||
* Type System: Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of public functions and events.
|
* Type System: Declarations with the name ``this``, ``super`` and ``_`` are disallowed, with the exception of public functions and events.
|
||||||
* Type System: Disallow ``type(super)``.
|
* Type System: Disallow ``type(super)``.
|
||||||
* Command Line Interface: JSON fields `abi`, `devdoc`, `userdoc` and `storage-layout` are now sub-objects rather than strings.
|
* Command Line Interface: JSON fields `abi`, `devdoc`, `userdoc` and `storage-layout` are now sub-objects rather than strings.
|
||||||
|
@ -49,6 +49,28 @@ New Restrictions
|
|||||||
3. Explicit conversions between literals and enums are only allowed if the literal can
|
3. Explicit conversions between literals and enums are only allowed if the literal can
|
||||||
represent a value in the enum.
|
represent a value in the enum.
|
||||||
|
|
||||||
|
* There are new restrictions on explicit type conversions. The conversion is only allowed when there
|
||||||
|
is at most one change in sign, width or type-category (``int``, ``address``, ``bytesNN``, etc.)
|
||||||
|
|
||||||
|
Let us use the notation ``T(S)`` to denote the explicit conversion ``T(x)``, where, ``T`` and
|
||||||
|
``S`` are types, and ``x`` is any arbitrary variable of type ``S``. An example of such a
|
||||||
|
disallowed conversion would be ``uint16(int8)`` since it changes both width (8 bits to 16 bits)
|
||||||
|
and sign (signed integer to unsigned integer). In order to do the conversion, one has to go
|
||||||
|
through an intermediate type. In the previous example, this would be ``uint16(uint8(int8))`` or
|
||||||
|
``uint16(int16(int8))``. Note that the two ways to convert will produce different results e.g.,
|
||||||
|
for ``-1``. The following are some examples of conversions that are disallowed by this rule.
|
||||||
|
|
||||||
|
- ``address(uint)`` and ``uint(address)``: converting both type-category and width. Replace this by
|
||||||
|
``address(uint160(uint))`` and ``uint(uint160(address))`` respectively.
|
||||||
|
- ``int80(bytes10)`` and ``bytes10(int80)``: converting both type-category and sign. Replace this by
|
||||||
|
``int80(uint80(bytes10))`` and ``bytes10(uint80(int80)`` respectively.
|
||||||
|
- ``Contract(uint)``: converting both type-category and width. Replace this by
|
||||||
|
``Contract(address(uint160(uint)))``.
|
||||||
|
|
||||||
|
These conversions were disallowed to avoid ambiguity. For example, in the expression ``uint16 x =
|
||||||
|
uint16(int8(-1))``, the value of ``x`` would depend on whether the sign or the width conversion
|
||||||
|
was applied first.
|
||||||
|
|
||||||
* Function call options can only be given once, i.e. ``c.f{gas: 10000}{value: 1}()`` is invalid and has to be changed to ``c.f{gas: 10000, value: 1}()``.
|
* Function call options can only be given once, i.e. ``c.f{gas: 10000}{value: 1}()`` is invalid and has to be changed to ``c.f{gas: 10000, value: 1}()``.
|
||||||
|
|
||||||
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
* The global functions ``log0``, ``log1``, ``log2``, ``log3`` and ``log4`` have been removed.
|
||||||
|
@ -202,7 +202,7 @@ restrictions highly readable.
|
|||||||
{
|
{
|
||||||
owner = _newOwner;
|
owner = _newOwner;
|
||||||
// just some example condition
|
// just some example condition
|
||||||
if (uint(owner) & 0 == 1)
|
if (uint160(owner) & 0 == 1)
|
||||||
// This did not refund for Solidity
|
// This did not refund for Solidity
|
||||||
// before version 0.4.0.
|
// before version 0.4.0.
|
||||||
return;
|
return;
|
||||||
|
@ -260,7 +260,7 @@ which only need to be created if there is a dispute.
|
|||||||
// This complicated expression just tells you how the address
|
// This complicated expression just tells you how the address
|
||||||
// can be pre-computed. It is just there for illustration.
|
// can be pre-computed. It is just there for illustration.
|
||||||
// You actually only need ``new D{salt: salt}(arg)``.
|
// You actually only need ``new D{salt: salt}(arg)``.
|
||||||
address predictedAddress = address(uint(keccak256(abi.encodePacked(
|
address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
|
||||||
byte(0xff),
|
byte(0xff),
|
||||||
address(this),
|
address(this),
|
||||||
salt,
|
salt,
|
||||||
@ -268,7 +268,7 @@ which only need to be created if there is a dispute.
|
|||||||
type(D).creationCode,
|
type(D).creationCode,
|
||||||
arg
|
arg
|
||||||
))
|
))
|
||||||
))));
|
)))));
|
||||||
|
|
||||||
D d = new D{salt: salt}(arg);
|
D d = new D{salt: salt}(arg);
|
||||||
require(address(d) == predictedAddress);
|
require(address(d) == predictedAddress);
|
||||||
|
@ -784,7 +784,7 @@ Another example that uses external function types::
|
|||||||
|
|
||||||
|
|
||||||
contract OracleUser {
|
contract OracleUser {
|
||||||
Oracle constant private ORACLE_CONST = Oracle(0x1234567); // known contract
|
Oracle constant private ORACLE_CONST = Oracle(address(0x00000000219ab540356cBB839Cbe05303d7705Fa)); // known contract
|
||||||
uint private exchangeRate;
|
uint private exchangeRate;
|
||||||
|
|
||||||
function buySomething() public {
|
function buySomething() public {
|
||||||
|
@ -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
|
||||||
|
@ -61,7 +61,7 @@ contract ScalarEvent is Event {
|
|||||||
convertedWinningOutcome = OUTCOME_RANGE;
|
convertedWinningOutcome = OUTCOME_RANGE;
|
||||||
// Map outcome to outcome range
|
// Map outcome to outcome range
|
||||||
else
|
else
|
||||||
convertedWinningOutcome = uint24(OUTCOME_RANGE * (outcome - lowerBound) / (upperBound - lowerBound));
|
convertedWinningOutcome = uint24(uint(OUTCOME_RANGE * (outcome - lowerBound) / (upperBound - lowerBound)));
|
||||||
uint factorShort = OUTCOME_RANGE - convertedWinningOutcome;
|
uint factorShort = OUTCOME_RANGE - convertedWinningOutcome;
|
||||||
uint factorLong = OUTCOME_RANGE - factorShort;
|
uint factorLong = OUTCOME_RANGE - factorShort;
|
||||||
uint shortOutcomeTokenCount = outcomeTokens[SHORT].balanceOf(msg.sender);
|
uint shortOutcomeTokenCount = outcomeTokens[SHORT].balanceOf(msg.sender);
|
||||||
|
@ -103,19 +103,19 @@ contract multiowned {
|
|||||||
// as well as the selection of addresses capable of confirming them.
|
// as well as the selection of addresses capable of confirming them.
|
||||||
constructor(address[] memory _owners, uint _required) {
|
constructor(address[] memory _owners, uint _required) {
|
||||||
m_numOwners = _owners.length + 1;
|
m_numOwners = _owners.length + 1;
|
||||||
m_owners[1] = uint(msg.sender);
|
m_owners[1] = uint160(msg.sender);
|
||||||
m_ownerIndex[uint(msg.sender)] = 1;
|
m_ownerIndex[uint160(msg.sender)] = 1;
|
||||||
for (uint i = 0; i < _owners.length; ++i)
|
for (uint i = 0; i < _owners.length; ++i)
|
||||||
{
|
{
|
||||||
m_owners[2 + i] = uint(_owners[i]);
|
m_owners[2 + i] = uint160(_owners[i]);
|
||||||
m_ownerIndex[uint(_owners[i])] = 2 + i;
|
m_ownerIndex[uint160(_owners[i])] = 2 + i;
|
||||||
}
|
}
|
||||||
m_required = _required;
|
m_required = _required;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Revokes a prior confirmation of the given operation
|
// Revokes a prior confirmation of the given operation
|
||||||
function revoke(bytes32 _operation) external {
|
function revoke(bytes32 _operation) external {
|
||||||
uint ownerIndex = m_ownerIndex[uint(msg.sender)];
|
uint ownerIndex = m_ownerIndex[uint160(msg.sender)];
|
||||||
// make sure they're an owner
|
// make sure they're an owner
|
||||||
if (ownerIndex == 0) return;
|
if (ownerIndex == 0) return;
|
||||||
uint ownerIndexBit = 2**ownerIndex;
|
uint ownerIndexBit = 2**ownerIndex;
|
||||||
@ -130,13 +130,13 @@ contract multiowned {
|
|||||||
// Replaces an owner `_from` with another `_to`.
|
// Replaces an owner `_from` with another `_to`.
|
||||||
function changeOwner(address _from, address _to) onlymanyowners(keccak256(msg.data)) public virtual {
|
function changeOwner(address _from, address _to) onlymanyowners(keccak256(msg.data)) public virtual {
|
||||||
if (isOwner(_to)) return;
|
if (isOwner(_to)) return;
|
||||||
uint ownerIndex = m_ownerIndex[uint(_from)];
|
uint ownerIndex = m_ownerIndex[uint160(_from)];
|
||||||
if (ownerIndex == 0) return;
|
if (ownerIndex == 0) return;
|
||||||
|
|
||||||
clearPending();
|
clearPending();
|
||||||
m_owners[ownerIndex] = uint(_to);
|
m_owners[ownerIndex] = uint160(_to);
|
||||||
m_ownerIndex[uint(_from)] = 0;
|
m_ownerIndex[uint160(_from)] = 0;
|
||||||
m_ownerIndex[uint(_to)] = ownerIndex;
|
m_ownerIndex[uint160(_to)] = ownerIndex;
|
||||||
emit OwnerChanged(_from, _to);
|
emit OwnerChanged(_from, _to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,18 +149,18 @@ contract multiowned {
|
|||||||
if (m_numOwners >= c_maxOwners)
|
if (m_numOwners >= c_maxOwners)
|
||||||
return;
|
return;
|
||||||
m_numOwners++;
|
m_numOwners++;
|
||||||
m_owners[m_numOwners] = uint(_owner);
|
m_owners[m_numOwners] = uint160(_owner);
|
||||||
m_ownerIndex[uint(_owner)] = m_numOwners;
|
m_ownerIndex[uint160(_owner)] = m_numOwners;
|
||||||
emit OwnerAdded(_owner);
|
emit OwnerAdded(_owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeOwner(address _owner) onlymanyowners(keccak256(msg.data)) external {
|
function removeOwner(address _owner) onlymanyowners(keccak256(msg.data)) external {
|
||||||
uint ownerIndex = m_ownerIndex[uint(_owner)];
|
uint ownerIndex = m_ownerIndex[uint160(_owner)];
|
||||||
if (ownerIndex == 0) return;
|
if (ownerIndex == 0) return;
|
||||||
if (m_required > m_numOwners - 1) return;
|
if (m_required > m_numOwners - 1) return;
|
||||||
|
|
||||||
m_owners[ownerIndex] = 0;
|
m_owners[ownerIndex] = 0;
|
||||||
m_ownerIndex[uint(_owner)] = 0;
|
m_ownerIndex[uint160(_owner)] = 0;
|
||||||
clearPending();
|
clearPending();
|
||||||
reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot
|
reorganizeOwners(); //make sure m_numOwner is equal to the number of owners and always points to the optimal free slot
|
||||||
emit OwnerRemoved(_owner);
|
emit OwnerRemoved(_owner);
|
||||||
@ -174,12 +174,12 @@ contract multiowned {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isOwner(address _addr) public returns (bool) {
|
function isOwner(address _addr) public returns (bool) {
|
||||||
return m_ownerIndex[uint(_addr)] > 0;
|
return m_ownerIndex[uint160(_addr)] > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasConfirmed(bytes32 _operation, address _owner) public view returns (bool) {
|
function hasConfirmed(bytes32 _operation, address _owner) public view returns (bool) {
|
||||||
PendingState storage pending = m_pending[_operation];
|
PendingState storage pending = m_pending[_operation];
|
||||||
uint ownerIndex = m_ownerIndex[uint(_owner)];
|
uint ownerIndex = m_ownerIndex[uint160(_owner)];
|
||||||
|
|
||||||
// make sure they're an owner
|
// make sure they're an owner
|
||||||
if (ownerIndex == 0) return false;
|
if (ownerIndex == 0) return false;
|
||||||
@ -197,7 +197,7 @@ contract multiowned {
|
|||||||
|
|
||||||
function confirmAndCheck(bytes32 _operation) internal returns (bool) {
|
function confirmAndCheck(bytes32 _operation) internal returns (bool) {
|
||||||
// determine what index the present sender is:
|
// determine what index the present sender is:
|
||||||
uint ownerIndex = m_ownerIndex[uint(msg.sender)];
|
uint ownerIndex = m_ownerIndex[uint160(msg.sender)];
|
||||||
// make sure they're an owner
|
// make sure they're an owner
|
||||||
if (ownerIndex == 0) return false;
|
if (ownerIndex == 0) return false;
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ function colony_test
|
|||||||
FORCE_ABIv2=false
|
FORCE_ABIv2=false
|
||||||
CONFIG="truffle.js"
|
CONFIG="truffle.js"
|
||||||
|
|
||||||
truffle_setup https://github.com/solidity-external-tests/colonyNetwork.git develop_070
|
truffle_setup https://github.com/solidity-external-tests/colonyNetwork.git develop_080
|
||||||
run_install install_fn
|
run_install install_fn
|
||||||
|
|
||||||
cd lib
|
cd lib
|
||||||
|
@ -33,10 +33,10 @@ function gnosis_safe_test
|
|||||||
OPTIMIZER_LEVEL=1
|
OPTIMIZER_LEVEL=1
|
||||||
CONFIG="truffle.js"
|
CONFIG="truffle.js"
|
||||||
|
|
||||||
truffle_setup https://github.com/solidity-external-tests/safe-contracts.git development_070
|
truffle_setup https://github.com/solidity-external-tests/safe-contracts.git development_080
|
||||||
|
|
||||||
force_truffle_version ^5.0.42
|
force_truffle_version ^5.0.42
|
||||||
sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_070|g' package.json
|
sed -i 's|github:gnosis/mock-contract#sol_0_5_0|github:solidity-external-tests/mock-contract#master_080|g' package.json
|
||||||
rm -f package-lock.json
|
rm -f package-lock.json
|
||||||
rm -rf node_modules/
|
rm -rf node_modules/
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ function zeppelin_test
|
|||||||
OPTIMIZER_LEVEL=1
|
OPTIMIZER_LEVEL=1
|
||||||
CONFIG="truffle-config.js"
|
CONFIG="truffle-config.js"
|
||||||
|
|
||||||
truffle_setup https://github.com/solidity-external-tests/openzeppelin-contracts.git upgrade-0.7.0
|
truffle_setup https://github.com/solidity-external-tests/openzeppelin-contracts.git upgrade-0.8.0
|
||||||
run_install install_fn
|
run_install install_fn
|
||||||
|
|
||||||
truffle_run_test compile_fn test_fn
|
truffle_run_test compile_fn test_fn
|
||||||
|
@ -471,7 +471,7 @@ BOOST_AUTO_TEST_CASE(structs2)
|
|||||||
s1[0].t[0].e = E.B;
|
s1[0].t[0].e = E.B;
|
||||||
s1[0].t[0].y = 0x12;
|
s1[0].t[0].y = 0x12;
|
||||||
s2 = new S[](2);
|
s2 = new S[](2);
|
||||||
s2[1].c = C(0x1234);
|
s2[1].c = C(address(0x1234));
|
||||||
s2[1].t = new T[](3);
|
s2[1].t = new T[](3);
|
||||||
s2[1].t[1].x = 0x21;
|
s2[1].t[1].x = 0x21;
|
||||||
s2[1].t[1].e = E.C;
|
s2[1].t[1].e = E.C;
|
||||||
|
@ -162,10 +162,10 @@ BOOST_AUTO_TEST_CASE(single_callvaluecheck)
|
|||||||
a = b;
|
a = b;
|
||||||
}
|
}
|
||||||
function f1(address b) public pure returns (uint c) {
|
function f1(address b) public pure returns (uint c) {
|
||||||
return uint(b) + 2;
|
return uint160(b) + 2;
|
||||||
}
|
}
|
||||||
function f2(address b) public pure returns (uint) {
|
function f2(address b) public pure returns (uint) {
|
||||||
return uint(b) + 8;
|
return uint160(b) + 8;
|
||||||
}
|
}
|
||||||
function f3(address, uint c) pure public returns (uint) {
|
function f3(address, uint c) pure public returns (uint) {
|
||||||
return c - 5;
|
return c - 5;
|
||||||
@ -178,10 +178,10 @@ BOOST_AUTO_TEST_CASE(single_callvaluecheck)
|
|||||||
a = b;
|
a = b;
|
||||||
}
|
}
|
||||||
function f1(address b) public pure returns (uint c) {
|
function f1(address b) public pure returns (uint c) {
|
||||||
return uint(b) + 2;
|
return uint160(b) + 2;
|
||||||
}
|
}
|
||||||
function f2(address b) public pure returns (uint) {
|
function f2(address b) public pure returns (uint) {
|
||||||
return uint(b) + 8;
|
return uint160(b) + 8;
|
||||||
}
|
}
|
||||||
function f3(address, uint c) payable public returns (uint) {
|
function f3(address, uint c) payable public returns (uint) {
|
||||||
return c - 5;
|
return c - 5;
|
||||||
|
@ -673,9 +673,9 @@ BOOST_AUTO_TEST_CASE(sign_extension)
|
|||||||
contract test {
|
contract test {
|
||||||
function run() public returns(uint256 y) {
|
function run() public returns(uint256 y) {
|
||||||
unchecked {
|
unchecked {
|
||||||
int64 x = -int32(0xff);
|
int64 x = -int32(int64(0xff));
|
||||||
if (x >= 0xff) return 0;
|
if (x >= 0xff) return 0;
|
||||||
return 0 - uint256(x);
|
return 0 - uint256(int256(x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5683,7 +5683,7 @@ BOOST_AUTO_TEST_CASE(dirty_scratch_space_prior_to_constant_optimiser)
|
|||||||
return 0x0000000000001234123412431234123412412342112341234124312341234124;
|
return 0x0000000000001234123412431234123412412342112341234124312341234124;
|
||||||
}
|
}
|
||||||
function g(address a) internal pure returns (uint) {
|
function g(address a) internal pure returns (uint) {
|
||||||
unchecked { return uint(a) * 0x0000000000001234123412431234123412412342112341234124312341234124; }
|
unchecked { return uint(uint160(a)) * 0x0000000000001234123412431234123412412342112341234124312341234124; }
|
||||||
}
|
}
|
||||||
function h(uint a) internal pure returns (uint) {
|
function h(uint a) internal pure returns (uint) {
|
||||||
unchecked { return a * 0x0000000000001234123412431234123412412342112341234124312341234124; }
|
unchecked { return a * 0x0000000000001234123412431234123412412342112341234124312341234124; }
|
||||||
|
@ -437,7 +437,7 @@ BOOST_AUTO_TEST_CASE(constant_optimization_early_exit)
|
|||||||
char const* sourceCode = R"(
|
char const* sourceCode = R"(
|
||||||
contract HexEncoding {
|
contract HexEncoding {
|
||||||
function hexEncodeTest(address addr) public returns (bytes32 ret) {
|
function hexEncodeTest(address addr) public returns (bytes32 ret) {
|
||||||
uint x = uint(addr) / 2**32;
|
uint x = uint(uint160(addr)) / 2**32;
|
||||||
|
|
||||||
// Nibble interleave
|
// Nibble interleave
|
||||||
x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;
|
x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;
|
||||||
@ -457,7 +457,7 @@ BOOST_AUTO_TEST_CASE(constant_optimization_early_exit)
|
|||||||
assembly {
|
assembly {
|
||||||
mstore(0, x)
|
mstore(0, x)
|
||||||
}
|
}
|
||||||
x = uint(addr) * 2**96;
|
x = uint160(addr) * 2**96;
|
||||||
|
|
||||||
// Nibble interleave
|
// Nibble interleave
|
||||||
x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;
|
x = x & 0x00000000000000000000000000000000ffffffffffffffffffffffffffffffff;
|
||||||
|
@ -7,7 +7,7 @@ contract c {
|
|||||||
for (uint8 i = 0; i <= 40; i++)
|
for (uint8 i = 0; i <= 40; i++)
|
||||||
data.push(byte(i+1));
|
data.push(byte(i+1));
|
||||||
for (int8 j = 40; j >= 0; j--) {
|
for (int8 j = 40; j >= 0; j--) {
|
||||||
require(data[uint8(j)] == byte(j+1));
|
require(data[uint8(j)] == byte(uint8(j+1)));
|
||||||
require(data.length == uint8(j+1));
|
require(data.length == uint8(j+1));
|
||||||
data.pop();
|
data.pop();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
contract C {
|
contract C {
|
||||||
function f(int16[] calldata a) external returns (bool correct) {
|
function f(int16[] calldata a) external returns (bool correct) {
|
||||||
uint32 x = uint32(a[1]);
|
uint32 x = uint32(uint16(a[1]));
|
||||||
uint r;
|
uint r;
|
||||||
assembly {
|
assembly {
|
||||||
r := x
|
r := x
|
||||||
|
@ -4,7 +4,7 @@ abstract contract D {
|
|||||||
|
|
||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
D d = D(0x1212);
|
D d = D(address(0x1212));
|
||||||
|
|
||||||
function f() public returns (uint256) {
|
function f() public returns (uint256) {
|
||||||
d.g();
|
d.g();
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
contract C {
|
contract C {
|
||||||
function f() external {}
|
function f() external {}
|
||||||
function g() external {
|
function g() external {
|
||||||
C c = C(0x0000000000000000000000000000000000000000000000000000000000000000);
|
C c = C(address(0x0000000000000000000000000000000000000000000000000000000000000000));
|
||||||
c.f();
|
c.f();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,9 @@ contract C {
|
|||||||
b = (0 - uint8(a)) * 2;
|
b = (0 - uint8(a)) * 2;
|
||||||
c = a * int8(120) * int8(121);
|
c = a * int8(120) * int8(121);
|
||||||
}
|
}
|
||||||
x1 = uint256(a);
|
x1 = uint256(int256(a));
|
||||||
x2 = b;
|
x2 = b;
|
||||||
x3 = uint256(c);
|
x3 = uint256(int256(c));
|
||||||
x4 = d;
|
x4 = d;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
contract Test {
|
contract Test {
|
||||||
function test() public returns (uint ret) { return uint(address(uint128(type(uint200).max))); }
|
function test() public returns (uint ret) { return uint(uint160(address(uint160(uint128(type(uint200).max))))); }
|
||||||
}
|
}
|
||||||
// ====
|
// ====
|
||||||
// compileViaYul: also
|
// compileViaYul: also
|
||||||
|
@ -9,9 +9,9 @@ contract C1 {
|
|||||||
|
|
||||||
contract C {
|
contract C {
|
||||||
function test() public returns (C1 x, C1 y) {
|
function test() public returns (C1 x, C1 y) {
|
||||||
C1 c = new C1(C1(9));
|
C1 c = new C1(C1(address(9)));
|
||||||
x = c.bla();
|
x = c.bla();
|
||||||
y = this.t1(C1(7));
|
y = this.t1(C1(address(7)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function t1(C1 a) public returns (C1) {
|
function t1(C1 a) public returns (C1) {
|
||||||
@ -19,7 +19,7 @@ contract C {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function t2() public returns (C1) {
|
function t2() public returns (C1) {
|
||||||
return C1(9);
|
return C1(address(9));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ contract C {
|
|||||||
uint16[] m;
|
uint16[] m;
|
||||||
}
|
}
|
||||||
function f(S calldata s) public pure returns (bool correct) {
|
function f(S calldata s) public pure returns (bool correct) {
|
||||||
int8 x = int8(s.m[0]);
|
int8 x = int8(int16(s.m[0]));
|
||||||
uint r;
|
uint r;
|
||||||
assembly {
|
assembly {
|
||||||
r := x
|
r := x
|
||||||
|
@ -4,7 +4,7 @@ contract C {
|
|||||||
assembly {
|
assembly {
|
||||||
mstore(m, 0xdeadbeef15dead)
|
mstore(m, 0xdeadbeef15dead)
|
||||||
}
|
}
|
||||||
int32 x = int32(m[0]);
|
int32 x = int32(uint32(m[0]));
|
||||||
uint r;
|
uint r;
|
||||||
assembly {
|
assembly {
|
||||||
r := x
|
r := x
|
||||||
|
@ -21,19 +21,19 @@ contract C {
|
|||||||
assert(x == 255);
|
assert(x == 255);
|
||||||
|
|
||||||
// signed <- unsigned
|
// signed <- unsigned
|
||||||
int8 y = int8(type(uint16).max);
|
int8 y = int8(uint8(type(uint16).max));
|
||||||
assert(y == -1);
|
assert(y == -1);
|
||||||
y = int8(uint16(100));
|
y = int8(uint8(uint16(100)));
|
||||||
assert(y == 100);
|
assert(y == 100);
|
||||||
y = int8(uint16(200));
|
y = int8(uint8(uint16(200)));
|
||||||
assert(y == -56);
|
assert(y == -56);
|
||||||
|
|
||||||
// unsigned <- signed
|
// unsigned <- signed
|
||||||
uint8 v = uint8(type(uint16).max);
|
uint8 v = uint8(type(uint16).max);
|
||||||
assert(v == 255);
|
assert(v == 255);
|
||||||
v = uint8(int16(300));
|
v = uint8(int8(int16(300)));
|
||||||
assert(v == 44);
|
assert(v == 44);
|
||||||
v = uint8(int16(200));
|
v = uint8(int8(int16(200)));
|
||||||
assert(v == 200);
|
assert(v == 200);
|
||||||
|
|
||||||
// fixed bytes
|
// fixed bytes
|
||||||
|
@ -13,16 +13,16 @@ contract C {
|
|||||||
assert(y == -(2**255) + 10);
|
assert(y == -(2**255) + 10);
|
||||||
int256 z = int256(uint(2**255 + 10));
|
int256 z = int256(uint(2**255 + 10));
|
||||||
assert(z == -(2**255) + 10);
|
assert(z == -(2**255) + 10);
|
||||||
int256 t = int256(bytes32(uint256(200)));
|
int256 t = int256(uint256(bytes32(uint256(200))));
|
||||||
assert(t == 200);
|
assert(t == 200);
|
||||||
int256 v = int256(bytes32(uint256(2**255 + 10)));
|
int256 v = int256(uint256(bytes32(uint256(2**255 + 10))));
|
||||||
assert(v == -(2**255) + 10);
|
assert(v == -(2**255) + 10);
|
||||||
int160 a = int160(address(type(uint160).max));
|
int160 a = int160(uint160(address(type(uint160).max)));
|
||||||
assert(a == -1);
|
assert(a == -1);
|
||||||
int160 b = int160(address(uint(2**159 + 10)));
|
int160 b = int160(uint160(address(uint160(uint(2**159 + 10)))));
|
||||||
assert(b == -(2**159) + 10);
|
assert(b == -(2**159) + 10);
|
||||||
D d;
|
D d;
|
||||||
int160 e = int160(address(d));
|
int160 e = int160(uint160(address(d)));
|
||||||
assert(e == 0);
|
assert(e == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,28 +9,28 @@ contract C {
|
|||||||
assert(x == 65535);
|
assert(x == 65535);
|
||||||
int8 i = int8(-1);
|
int8 i = int8(-1);
|
||||||
assert(i == -1);
|
assert(i == -1);
|
||||||
x = uint16(int8(-1));
|
x = uint16(uint8(int8(-1)));
|
||||||
assert(x == 65535);
|
assert(x == 255);
|
||||||
x = uint16(int16(i));
|
x = uint16(int16(i));
|
||||||
assert(x == 65535);
|
assert(x == 65535);
|
||||||
uint z = uint(i);
|
uint z = uint(uint8(i));
|
||||||
assert(z == 2**256 - 1);
|
assert(z == 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f2() public pure {
|
function f2() public pure {
|
||||||
// signed <- unsigned
|
// signed <- unsigned
|
||||||
int16 y = int16(uint8(uint(65535)));
|
int16 y = int16(uint16(uint8(uint(65535))));
|
||||||
assert(y == 255);
|
assert(y == 255);
|
||||||
int z = int(uint8(type(uint).max));
|
int z = int(uint(uint8(type(uint).max)));
|
||||||
assert(z == 255);
|
assert(z == 255);
|
||||||
z = int(uint8(255));
|
z = int(uint(uint8(255)));
|
||||||
assert(z == 255);
|
assert(z == 255);
|
||||||
}
|
}
|
||||||
|
|
||||||
function f3() public pure {
|
function f3() public pure {
|
||||||
// signed <- signed
|
// signed <- signed
|
||||||
int16 y = int16(int8(uint(65535)));
|
int16 y = int16(uint16(uint8(int8(int(uint(65535))))));
|
||||||
assert(y == -1);
|
assert(y == 255);
|
||||||
int z = int(int8(-1));
|
int z = int(int8(-1));
|
||||||
assert(z == -1);
|
assert(z == -1);
|
||||||
z = int(int8(int(255)));
|
z = int(int8(int(255)));
|
||||||
@ -51,9 +51,9 @@ contract C {
|
|||||||
assert(y == 65535);
|
assert(y == 65535);
|
||||||
y = uint16(uint8(type(uint16).max));
|
y = uint16(uint8(type(uint16).max));
|
||||||
assert(y == 255);
|
assert(y == 255);
|
||||||
address a = address(uint8(0));
|
address a = address(uint160(uint8(0)));
|
||||||
assert(a == address(0));
|
assert(a == address(0));
|
||||||
D d = D(uint8(0));
|
D d = D(address(uint160(uint8(0))));
|
||||||
assert(a == address(d));
|
assert(a == address(d));
|
||||||
bytes2 b1 = 0xcafe;
|
bytes2 b1 = 0xcafe;
|
||||||
bytes4 b2 = bytes4(b1);
|
bytes4 b2 = bytes4(b1);
|
||||||
|
@ -13,8 +13,8 @@ import "A";
|
|||||||
|
|
||||||
contract Test {
|
contract Test {
|
||||||
function foo() public view {
|
function foo() public view {
|
||||||
C(0x00).set({_item: C.Item(50), _z: false, _y: "abc", _x: 30});
|
C(address(0x00)).set({_item: C.Item(50), _z: false, _y: "abc", _x: 30});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 2443: (B:90-100): The type of this parameter, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
// TypeError 2443: (B:99-109): The type of this parameter, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
||||||
|
@ -9,8 +9,8 @@ import "A";
|
|||||||
|
|
||||||
contract D {
|
contract D {
|
||||||
function g() public view {
|
function g() public view {
|
||||||
C(0x00).f();
|
C(address(0x00)).f();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 2428: (B:65-76): The type of return parameter 1, string[], is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
// TypeError 2428: (B:65-85): The type of return parameter 1, string[], is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
||||||
|
@ -13,8 +13,8 @@ import "A";
|
|||||||
|
|
||||||
contract Test {
|
contract Test {
|
||||||
function foo() public view {
|
function foo() public view {
|
||||||
C(0x00).get();
|
C(address(0x00)).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 2428: (B:70-83): The type of return parameter 1, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
// TypeError 2428: (B:70-92): The type of return parameter 1, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
||||||
|
@ -13,8 +13,8 @@ import "A";
|
|||||||
|
|
||||||
contract Test {
|
contract Test {
|
||||||
function foo() public view {
|
function foo() public view {
|
||||||
C(0x00).get();
|
C(address(0x00)).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 2428: (B:70-83): The type of return parameter 1, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
// TypeError 2428: (B:70-92): The type of return parameter 1, struct C.Item, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
||||||
|
@ -11,7 +11,7 @@ contract A {
|
|||||||
|
|
||||||
contract B {
|
contract B {
|
||||||
modifier validate() {
|
modifier validate() {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ contract A {
|
|||||||
|
|
||||||
contract B {
|
contract B {
|
||||||
constructor() validate {
|
constructor() validate {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
modifier validate() {
|
modifier validate() {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,11 +11,11 @@ contract A {
|
|||||||
|
|
||||||
contract B {
|
contract B {
|
||||||
constructor() {
|
constructor() {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
function foo() public view {
|
function foo() public view {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
==== Source: B ====
|
==== Source: B ====
|
||||||
|
@ -11,7 +11,7 @@ contract A {
|
|||||||
|
|
||||||
contract B {
|
contract B {
|
||||||
modifier validate() virtual {
|
modifier validate() virtual {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ import "X";
|
|||||||
|
|
||||||
contract V2A {
|
contract V2A {
|
||||||
modifier modV2A() {
|
modifier modV2A() {
|
||||||
X(0x00).get();
|
X(address(0x00)).get();
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import "A";
|
|||||||
|
|
||||||
contract D {
|
contract D {
|
||||||
function g() public view {
|
function g() public view {
|
||||||
C(0x00).f();
|
C(address(0x00)).f();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
|
@ -15,7 +15,7 @@ import "A";
|
|||||||
|
|
||||||
contract Test {
|
contract Test {
|
||||||
function foo() public view {
|
function foo() public view {
|
||||||
C(0x00).get();
|
C(address(0x00)).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
|
@ -15,7 +15,7 @@ import "A";
|
|||||||
|
|
||||||
contract Test {
|
contract Test {
|
||||||
function foo() public view {
|
function foo() public view {
|
||||||
C(0x00).get();
|
C(address(0x00)).get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
|
@ -13,7 +13,7 @@ import "A";
|
|||||||
|
|
||||||
contract B {
|
contract B {
|
||||||
modifier validate() {
|
modifier validate() {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,4 +27,4 @@ contract C is B {
|
|||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 2428: (B:60-73): The type of return parameter 1, struct Data, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
// TypeError 2428: (B:60-82): The type of return parameter 1, struct Data, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
||||||
|
@ -13,7 +13,7 @@ import "A";
|
|||||||
|
|
||||||
contract B {
|
contract B {
|
||||||
modifier validate() {
|
modifier validate() {
|
||||||
A(0x00).get();
|
A(address(0x00)).get();
|
||||||
_;
|
_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -29,4 +29,4 @@ contract C is B {
|
|||||||
{}
|
{}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 2428: (B:60-73): The type of return parameter 1, struct Data, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
// TypeError 2428: (B:60-82): The type of return parameter 1, struct Data, is only supported in ABI coder v2. Use "pragma abicoder v2;" to enable the feature.
|
||||||
|
@ -2,12 +2,12 @@
|
|||||||
contract A { constructor(string memory) { } }
|
contract A { constructor(string memory) { } }
|
||||||
contract B is A {
|
contract B is A {
|
||||||
function f() pure public {
|
function f() pure public {
|
||||||
A x = A(0); // convert from address
|
A x = A(address(0)); // convert from address
|
||||||
string memory y = "ab";
|
string memory y = "ab";
|
||||||
A(y); // call as a function is invalid
|
A(y); // call as a function is invalid
|
||||||
x;
|
x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 3656: (124-294): Contract "B" should be marked as abstract.
|
// TypeError 3656: (124-303): Contract "B" should be marked as abstract.
|
||||||
// TypeError 9640: (243-247): Explicit type conversion not allowed from "string memory" to "contract A".
|
// TypeError 9640: (252-256): Explicit type conversion not allowed from "string memory" to "contract A".
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
==== Source: a ====
|
==== Source: a ====
|
||||||
contract A {}
|
contract A {}
|
||||||
==== Source: dir/a/b/c ====
|
==== Source: dir/a/b/c ====
|
||||||
import "../../.././a" as x; contract B is x.A { fallback() external { x.A r = x.A(20); r; } }
|
import "../../.././a" as x; contract B is x.A { fallback() external { x.A r = x.A(address(20)); r; } }
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
contract First {
|
contract First {
|
||||||
function fun() public returns (bool) {
|
function fun() public returns (bool) {
|
||||||
return Second(1).fun(1, true, 3) > 0;
|
return Second(address(1)).fun(1, true, 3) > 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
contract Second {
|
contract Second {
|
||||||
function fun(uint, bool, uint) public returns (uint) {
|
function fun(uint, bool, uint) public returns (uint) {
|
||||||
if (First(2).fun() == true) return 1;
|
if (First(address(2)).fun() == true) return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Warning 6321: (183-187): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.
|
// Warning 6321: (192-196): Unnamed return variable can remain unassigned. Add an explicit return with value to all non-reverting code paths or name the variable.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
contract A { function f() public virtual { uint8 x = C(0).g(); } }
|
contract A { function f() public virtual { uint8 x = C(address(0)).g(); } }
|
||||||
contract B { function f() public virtual {} function g() public returns (uint8) {} }
|
contract B { function f() public virtual {} function g() public returns (uint8) {} }
|
||||||
contract C is A, B { function f() public override (A, B) { A.f(); } }
|
contract C is A, B { function f() public override (A, B) { A.f(); } }
|
||||||
// ----
|
// ----
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
contract A { }
|
contract A { }
|
||||||
contract B is A {
|
contract B is A {
|
||||||
function f() public { A a = B(1); }
|
function f() public { A a = B(address(1)); }
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Warning 2072: (59-62): Unused local variable.
|
// Warning 2072: (59-62): Unused local variable.
|
||||||
// Warning 2018: (37-72): Function state mutability can be restricted to pure
|
// Warning 2018: (37-81): Function state mutability can be restricted to pure
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
contract A { }
|
contract A { }
|
||||||
contract B is A {
|
contract B is A {
|
||||||
function f() public { B b = A(1); }
|
function f() public { B b = A(address(1)); }
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9574: (59-69): Type contract A is not implicitly convertible to expected type contract B.
|
// TypeError 9574: (59-78): Type contract A is not implicitly convertible to expected type contract B.
|
||||||
|
@ -2,6 +2,6 @@ contract c {
|
|||||||
function f() public {}
|
function f() public {}
|
||||||
}
|
}
|
||||||
contract d {
|
contract d {
|
||||||
function g() public { c(0).f(); }
|
function g() public { c(address(0)).f(); }
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
|
@ -2,7 +2,7 @@ contract c {
|
|||||||
function f() internal {}
|
function f() internal {}
|
||||||
}
|
}
|
||||||
contract d {
|
contract d {
|
||||||
function g() public { c(0).f(); }
|
function g() public { c(address(0)).f(); }
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9582: (83-89): Member "f" not found or not visible after argument-dependent lookup in contract c.
|
// TypeError 9582: (83-98): Member "f" not found or not visible after argument-dependent lookup in contract c.
|
||||||
|
@ -2,7 +2,7 @@ contract c {
|
|||||||
uint a;
|
uint a;
|
||||||
}
|
}
|
||||||
contract d {
|
contract d {
|
||||||
function g() public { c(0).a(); }
|
function g() public { c(address(0)).a(); }
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// TypeError 9582: (66-72): Member "a" not found or not visible after argument-dependent lookup in contract c.
|
// TypeError 9582: (66-81): Member "a" not found or not visible after argument-dependent lookup in contract c.
|
||||||
|
@ -2,7 +2,7 @@ contract c {
|
|||||||
uint public a;
|
uint public a;
|
||||||
}
|
}
|
||||||
contract d {
|
contract d {
|
||||||
function g() public { c(0).a(); }
|
function g() public { c(address(0)).a(); }
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// Warning 2018: (51-84): Function state mutability can be restricted to view
|
// Warning 2018: (51-93): Function state mutability can be restricted to view
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
contract C {
|
contract C {
|
||||||
C constant x = C(0x123);
|
C constant x = C(address(0x123));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
contract c {
|
contract c {
|
||||||
modifier mod1(uint a) { if (msg.sender == address(a)) _; }
|
modifier mod1(uint a) { if (msg.sender == address(uint160(a))) _; }
|
||||||
modifier mod2 { if (msg.sender == address(2)) _; }
|
modifier mod2 { if (msg.sender == address(2)) _; }
|
||||||
function f() public mod1(7) mod2 { }
|
function f() public mod1(7) mod2 { }
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
contract C {
|
contract C {
|
||||||
function f(uint x) public pure returns (address payable) {
|
function f(uint x) public pure returns (address payable) {
|
||||||
return address(x);
|
return address(uint160(x));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@ contract Main {
|
|||||||
A constant JU = JV;
|
A constant JU = JV;
|
||||||
A constant JV = JW;
|
A constant JV = JW;
|
||||||
A constant JW = JX;
|
A constant JW = JX;
|
||||||
A constant JX = A(0x00);
|
A constant JX = A(address(0x00));
|
||||||
}
|
}
|
||||||
// ----
|
// ----
|
||||||
// DeclarationError 7380: (6105-6123): Variable definition exhausting cyclic dependency validator.
|
// DeclarationError 7380: (6105-6123): Variable definition exhausting cyclic dependency validator.
|
||||||
|
@ -131,5 +131,5 @@ contract Main {
|
|||||||
A constant EZ = FA;
|
A constant EZ = FA;
|
||||||
A constant FA = FB;
|
A constant FA = FB;
|
||||||
A constant FB = FC;
|
A constant FB = FC;
|
||||||
A constant FC = A(0x00);
|
A constant FC = A(address(0x00));
|
||||||
}
|
}
|
||||||
|
42
test/libsolidity/syntaxTests/types/strict_explicit.sol
Normal file
42
test/libsolidity/syntaxTests/types/strict_explicit.sol
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
contract B{}
|
||||||
|
contract C
|
||||||
|
{
|
||||||
|
function f() public pure {
|
||||||
|
|
||||||
|
uint16 a = uint16(uint8(int8(-1)));
|
||||||
|
a;
|
||||||
|
|
||||||
|
int8 b = -1;
|
||||||
|
b;
|
||||||
|
uint16 c = uint16(uint8(b));
|
||||||
|
c;
|
||||||
|
|
||||||
|
int8 d = int8(int16(uint16(type(uint16).max)));
|
||||||
|
d;
|
||||||
|
|
||||||
|
uint16 e = type(uint16).max;
|
||||||
|
e;
|
||||||
|
int8 g = int8(uint8(e));
|
||||||
|
g;
|
||||||
|
|
||||||
|
address h = address(uint160(uint(type(uint).max)));
|
||||||
|
h;
|
||||||
|
|
||||||
|
uint i = uint(uint160(address(0)));
|
||||||
|
i;
|
||||||
|
|
||||||
|
uint j = type(uint).max;
|
||||||
|
j;
|
||||||
|
address k = address(uint160(j));
|
||||||
|
k;
|
||||||
|
|
||||||
|
int80 l = int80(uint80(bytes10("h")));
|
||||||
|
l;
|
||||||
|
bytes10 m = bytes10(uint80(int80(-1)));
|
||||||
|
m;
|
||||||
|
|
||||||
|
B n = B(address(uint160(uint(int(100)))));
|
||||||
|
n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
52
test/libsolidity/syntaxTests/types/strict_explicit_err.sol
Normal file
52
test/libsolidity/syntaxTests/types/strict_explicit_err.sol
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
contract B{}
|
||||||
|
|
||||||
|
enum E { Zero }
|
||||||
|
|
||||||
|
contract C
|
||||||
|
{
|
||||||
|
function f() public pure {
|
||||||
|
|
||||||
|
uint16 a = uint16(int8(-1));
|
||||||
|
|
||||||
|
int8 b = -1;
|
||||||
|
uint16 c = uint16(b);
|
||||||
|
|
||||||
|
int8 d = int8(uint16(type(uint16).max));
|
||||||
|
|
||||||
|
uint16 e = type(uint16).max;
|
||||||
|
int8 g = int8(e);
|
||||||
|
|
||||||
|
address h = address(uint(type(uint).max));
|
||||||
|
|
||||||
|
uint i = uint(address(0));
|
||||||
|
|
||||||
|
uint j = type(uint).max;
|
||||||
|
address k = address(j);
|
||||||
|
|
||||||
|
int80 l = int80(bytes10("h"));
|
||||||
|
bytes10 m = bytes10(int80(-1));
|
||||||
|
|
||||||
|
B n = B(int(100));
|
||||||
|
int o = int(new B());
|
||||||
|
|
||||||
|
B p = B(0x00);
|
||||||
|
|
||||||
|
int q = int(E(0));
|
||||||
|
int r = int(E.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ----
|
||||||
|
// TypeError 9640: (95-111): Explicit type conversion not allowed from "int8" to "uint16".
|
||||||
|
// TypeError 9640: (154-163): Explicit type conversion not allowed from "int8" to "uint16".
|
||||||
|
// TypeError 9640: (183-213): Explicit type conversion not allowed from "uint16" to "int8".
|
||||||
|
// TypeError 9640: (270-277): Explicit type conversion not allowed from "uint16" to "int8".
|
||||||
|
// TypeError 9640: (300-329): Explicit type conversion not allowed from "uint256" to "address".
|
||||||
|
// TypeError 9640: (349-365): Explicit type conversion not allowed from "address payable" to "uint256".
|
||||||
|
// TypeError 9640: (421-431): Explicit type conversion not allowed from "uint256" to "address".
|
||||||
|
// TypeError 9640: (452-471): Explicit type conversion not allowed from "bytes10" to "int80".
|
||||||
|
// TypeError 9640: (493-511): Explicit type conversion not allowed from "int80" to "bytes10".
|
||||||
|
// TypeError 9640: (528-539): Explicit type conversion not allowed from "int256" to "contract B".
|
||||||
|
// TypeError 9640: (557-569): Explicit type conversion not allowed from "contract B" to "int256".
|
||||||
|
// TypeError 9640: (586-593): Explicit type conversion not allowed from "int_const 0" to "contract B".
|
||||||
|
// TypeError 9640: (612-621): Explicit type conversion not allowed from "enum E" to "int256".
|
||||||
|
// TypeError 9640: (639-650): Explicit type conversion not allowed from "enum E" to "int256".
|
@ -3,7 +3,7 @@ contract C {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
function g() pure public returns (bytes4) {
|
function g() pure public returns (bytes4) {
|
||||||
C x = C(0x123);
|
C x = C(address(0x123));
|
||||||
return x.f.selector;
|
return x.f.selector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user