From a309669f7555bfa9e63197cee652a6cc52785796 Mon Sep 17 00:00:00 2001 From: Harikrishnan Mulackal Date: Wed, 23 Sep 2020 12:29:00 +0200 Subject: [PATCH] Disallow explicit conversions from negative literals to ``address`` --- Changelog.md | 1 + docs/080-breaking-changes.rst | 17 +++++++++++++++++ docs/index.rst | 1 + docs/using-the-compiler.rst | 4 ++-- libsolidity/ast/Types.cpp | 16 ++++++++++------ .../types/type_conversion_cleanup.sol | 4 ++-- .../smtCheckerTests/typecast/same_size.sol | 8 ++++---- .../syntaxTests/types/address/conversion.sol | 9 +++++++++ .../types/address/conversion_error.sol | 15 +++++++++++++++ 9 files changed, 61 insertions(+), 14 deletions(-) create mode 100644 docs/080-breaking-changes.rst create mode 100644 test/libsolidity/syntaxTests/types/address/conversion.sol create mode 100644 test/libsolidity/syntaxTests/types/address/conversion_error.sol diff --git a/Changelog.md b/Changelog.md index 5a3558798..d589e6c8a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,6 +2,7 @@ Breaking Changes: * Type System: Unary negation can only be used on signed integers, not on unsigned integers. + * Type System: Disallow explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` type. Compiler Features: * SMTChecker: Support ``addmod`` and ``mulmod``. diff --git a/docs/080-breaking-changes.rst b/docs/080-breaking-changes.rst new file mode 100644 index 000000000..60bd365fa --- /dev/null +++ b/docs/080-breaking-changes.rst @@ -0,0 +1,17 @@ +******************************** +Solidity v0.8.0 Breaking Changes +******************************** + +This section highlights the main breaking changes introduced in Solidity +version 0.8.0, along with the reasoning behind the changes and how to update +affected code. +For the full list check +`the release changelog `_. + +Semantic and Syntactic Changes +============================== + +This section lists changes where you have to modify your code +and it does something else afterwards. + +* Explicit conversions from negative literals and literals larger than ``type(uint160).max`` to ``address`` are now disallowed. diff --git a/docs/index.rst b/docs/index.rst index 2468c4867..343a1da4c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -128,6 +128,7 @@ Contents 050-breaking-changes.rst 060-breaking-changes.rst 070-breaking-changes.rst + 080-breaking-changes.rst natspec-format.rst security-considerations.rst resources.rst diff --git a/docs/using-the-compiler.rst b/docs/using-the-compiler.rst index 4b192a36d..c251495b2 100644 --- a/docs/using-the-compiler.rst +++ b/docs/using-the-compiler.rst @@ -613,8 +613,8 @@ Available upgrade modules +----------------------------+---------+--------------------------------------------------+ Please read :doc:`0.5.0 release notes <050-breaking-changes>`, -:doc:`0.6.0 release notes <060-breaking-changes>` and -:doc:`0.7.0 release notes <070-breaking-changes>` for further details. +:doc:`0.6.0 release notes <060-breaking-changes>`, +:doc:`0.7.0 release notes <070-breaking-changes>` and :doc:`0.8.0 release notes <080-breaking-changes>` for further details. Synopsis ~~~~~~~~ diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 35325f26d..e9ddc7547 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -963,13 +963,17 @@ BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) { if (isImplicitlyConvertibleTo(_convertTo)) return true; - else if (_convertTo.category() != Category::FixedBytes) - { - TypePointer mobType = mobileType(); - return (mobType && mobType->isExplicitlyConvertibleTo(_convertTo)); - } - else + + auto category = _convertTo.category(); + if (category == Category::FixedBytes) return false; + if (category == Category::Address) + if (isNegative() || isFractional() || integerType()->numBits() > 160) + return false; + + TypePointer mobType = mobileType(); + return (mobType && mobType->isExplicitlyConvertibleTo(_convertTo)); + } TypeResult RationalNumberType::unaryOperatorResult(Token _operator) const diff --git a/test/libsolidity/semanticTests/types/type_conversion_cleanup.sol b/test/libsolidity/semanticTests/types/type_conversion_cleanup.sol index 7a12c689c..703fd0cc4 100644 --- a/test/libsolidity/semanticTests/types/type_conversion_cleanup.sol +++ b/test/libsolidity/semanticTests/types/type_conversion_cleanup.sol @@ -1,7 +1,7 @@ contract Test { - function test() public returns (uint ret) { return uint(address(Test(address(0x11223344556677889900112233445566778899001122)))); } + function test() public returns (uint ret) { return uint(address(uint128(0x11223344556677889900112233445566778899001122))); } } // ==== // compileViaYul: also // ---- -// test() -> 0x0000000000000000000000003344556677889900112233445566778899001122 +// test() -> 158887387085137674884660775897412931874 diff --git a/test/libsolidity/smtCheckerTests/typecast/same_size.sol b/test/libsolidity/smtCheckerTests/typecast/same_size.sol index 4d5bed1a1..c74cf1804 100644 --- a/test/libsolidity/smtCheckerTests/typecast/same_size.sol +++ b/test/libsolidity/smtCheckerTests/typecast/same_size.sol @@ -17,9 +17,9 @@ contract C { assert(t == 200); int256 v = int256(bytes32(uint256(2**255 + 10))); assert(v == -(2**255) + 10); - int160 a = int160(address(-1)); + int160 a = int160(address(type(uint160).max)); assert(a == -1); - int160 b = int160(address(2**159 + 10)); + int160 b = int160(address(uint(2**159 + 10))); assert(b == -(2**159) + 10); D d; int160 e = int160(address(d)); @@ -42,7 +42,7 @@ contract C { assert(w == 2**256 - 2); bytes4 b = bytes4(uint32(-2)); assert(uint32(b) == uint32(2**32 - 2)); - address a = address(-1); + address a = address(type(uint160).max); assert(uint160(a) == uint160(2**160 - 1)); address c = address(0); assert(uint160(c) == 0); @@ -71,4 +71,4 @@ contract C { } } // ---- -// Warning 8364: (1304-1305): Assertion checker does not yet implement type type(enum E) +// Warning 8364: (1340-1341): Assertion checker does not yet implement type type(enum E) diff --git a/test/libsolidity/syntaxTests/types/address/conversion.sol b/test/libsolidity/syntaxTests/types/address/conversion.sol new file mode 100644 index 000000000..7fac4edfb --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address/conversion.sol @@ -0,0 +1,9 @@ +contract C { + function f() public pure returns (address) { + return address(2**160 -1); + } + function g() public pure returns (address) { + return address(uint(-1)); + } +} +// ---- diff --git a/test/libsolidity/syntaxTests/types/address/conversion_error.sol b/test/libsolidity/syntaxTests/types/address/conversion_error.sol new file mode 100644 index 000000000..99155ae47 --- /dev/null +++ b/test/libsolidity/syntaxTests/types/address/conversion_error.sol @@ -0,0 +1,15 @@ +contract C { + function f() public pure returns (address) { + return address(-1); + } + function g() public pure returns (address) { + return -1; + } + function h() public pure returns (address) { + return address(2**160); + } +} +// ---- +// TypeError 9640: (77-88): Explicit type conversion not allowed from "int_const -1" to "address". +// TypeError 6359: (160-162): Return argument type int_const -1 is not implicitly convertible to expected type (type of first return variable) address. +// TypeError 9640: (225-240): Explicit type conversion not allowed from "int_const 1461...(41 digits omitted)...2976" to "address".