aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-05-15 22:59:48 +0800
committerGitHub <noreply@github.com>2018-05-15 22:59:48 +0800
commit2ba0002998d12ea412f17d55b643ec85c02e6a30 (patch)
treec67243148b1b06eb6b8617fc344d0bc422874fa9
parent007ecc849c917cdb5b2feaa20bbab84e0fe79104 (diff)
parentdac0029d16ffe31fba2e6241f99893ea9a26926e (diff)
downloaddexon-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.md1
-rw-r--r--libsolidity/analysis/TypeChecker.cpp3
-rw-r--r--libsolidity/ast/Types.cpp6
-rw-r--r--libsolidity/ast/Types.h4
-rw-r--r--test/libsolidity/syntaxTests/constants/abi_encoding_constant.sol7
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));
+}
+// ----