diff options
author | chriseth <chris@ethereum.org> | 2018-05-15 22:59:48 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-15 22:59:48 +0800 |
commit | 2ba0002998d12ea412f17d55b643ec85c02e6a30 (patch) | |
tree | c67243148b1b06eb6b8617fc344d0bc422874fa9 | |
parent | 007ecc849c917cdb5b2feaa20bbab84e0fe79104 (diff) | |
parent | dac0029d16ffe31fba2e6241f99893ea9a26926e (diff) | |
download | dexon-solidity-2ba0002998d12ea412f17d55b643ec85c02e6a30.tar dexon-solidity-2ba0002998d12ea412f17d55b643ec85c02e6a30.tar.gz dexon-solidity-2ba0002998d12ea412f17d55b643ec85c02e6a30.tar.bz2 dexon-solidity-2ba0002998d12ea412f17d55b643ec85c02e6a30.tar.lz dexon-solidity-2ba0002998d12ea412f17d55b643ec85c02e6a30.tar.xz dexon-solidity-2ba0002998d12ea412f17d55b643ec85c02e6a30.tar.zst dexon-solidity-2ba0002998d12ea412f17d55b643ec85c02e6a30.zip |
Merge pull request #4139 from ethereum/abiEncodeIsPure
ABI encoding functions are pure and should be usable in constants.
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 3 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 6 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 4 | ||||
-rw-r--r-- | test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol | 7 |
5 files changed, 18 insertions, 3 deletions
diff --git a/Changelog.md b/Changelog.md index ddd33df7..d6f54070 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ Bugfixes: * Code Generator: Fix ``revert`` with reason coming from a state or local string variable. * Type Checker: Show proper error when trying to ``emit`` a non-event. * Type Checker: Warn about empty tuple components (this will turn into an error with version 0.5.0). + * Type Checker: The ABI encoding functions are pure and thus can be used for constants. ### 0.4.23 (2018-04-19) diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index a222bdf0..e8694e88 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -2093,6 +2093,9 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) if (auto tt = dynamic_cast<TypeType const*>(exprType.get())) if (tt->actualType()->category() == Type::Category::Enum) annotation.isPure = true; + if (auto magicType = dynamic_cast<MagicType const*>(exprType.get())) + if (magicType->kind() == MagicType::Kind::ABI) + annotation.isPure = true; return false; } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index dc548538..60e3183c 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -2865,7 +2865,11 @@ bool FunctionType::isPure() const m_kind == Kind::RIPEMD160 || m_kind == Kind::AddMod || m_kind == Kind::MulMod || - m_kind == Kind::ObjectCreation; + m_kind == Kind::ObjectCreation || + m_kind == Kind::ABIEncode || + m_kind == Kind::ABIEncodePacked || + m_kind == Kind::ABIEncodeWithSelector || + m_kind == Kind::ABIEncodeWithSignature; } TypePointers FunctionType::parseElementaryTypeVector(strings const& _types) diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 6defacfc..4884696d 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -1046,8 +1046,8 @@ public: return *m_declaration; } bool hasDeclaration() const { return !!m_declaration; } - /// @returns true if the result of this function only depends on its arguments - /// and it does not modify the state. + /// @returns true if the result of this function only depends on its arguments, + /// does not modify the state and is a compile-time constant. /// Currently, this will only return true for internal functions like keccak and ecrecover. bool isPure() const; bool isPayable() const { return m_stateMutability == StateMutability::Payable; } diff --git a/test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol b/test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol new file mode 100644 index 00000000..dd6968a0 --- /dev/null +++ b/test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol @@ -0,0 +1,7 @@ +contract C { + bytes32 constant a = keccak256(abi.encode(1, 2)); + bytes32 constant b = keccak256(abi.encodePacked(uint(1), a)); + bytes32 constant c = keccak256(abi.encodeWithSelector(0x12345678, b, 2)); + bytes32 constant d = keccak256(abi.encodeWithSignature("f()", 1, 2)); +} +// ---- |