aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/SolidityOptimizer.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-05-13 03:27:04 +0800
committerchriseth <c@ethdev.com>2015-05-13 23:15:32 +0800
commitb50362042e3d9597bad0a8db5d725b8c023dc555 (patch)
treee9de6c93e0d3e4a9152adba1f62637ed7d3b7554 /libsolidity/SolidityOptimizer.cpp
parentb0b3223fedab7f040c9b4782793a66a48f4d7b63 (diff)
downloaddexon-solidity-b50362042e3d9597bad0a8db5d725b8c023dc555.tar
dexon-solidity-b50362042e3d9597bad0a8db5d725b8c023dc555.tar.gz
dexon-solidity-b50362042e3d9597bad0a8db5d725b8c023dc555.tar.bz2
dexon-solidity-b50362042e3d9597bad0a8db5d725b8c023dc555.tar.lz
dexon-solidity-b50362042e3d9597bad0a8db5d725b8c023dc555.tar.xz
dexon-solidity-b50362042e3d9597bad0a8db5d725b8c023dc555.tar.zst
dexon-solidity-b50362042e3d9597bad0a8db5d725b8c023dc555.zip
Known state: store tags on stack as unions.
Diffstat (limited to 'libsolidity/SolidityOptimizer.cpp')
-rw-r--r--libsolidity/SolidityOptimizer.cpp43
1 files changed, 43 insertions, 0 deletions
diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp
index efc9316b..ce43887e 100644
--- a/libsolidity/SolidityOptimizer.cpp
+++ b/libsolidity/SolidityOptimizer.cpp
@@ -315,6 +315,49 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches)
BOOST_CHECK_EQUAL(1, numSHA3s);
}
+BOOST_AUTO_TEST_CASE(store_tags_as_unions)
+{
+ // This calls the same function from two sources and both calls have a certain sha3 on
+ // the stack at the same position.
+ // Without storing tags as unions, the return from the shared function would not know where to
+ // jump and thus all jumpdests are forced to clear their state and we do not know about the
+ // sha3 anymore.
+ // Note that, for now, this only works if the functions have the same number of return
+ // parameters since otherwise, the return jump addresses are at different stack positions
+ // which triggers the "unknown jump target" situation.
+ char const* sourceCode = R"(
+ contract test {
+ bytes32 data;
+ function f(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
+ r_d = sha3(y);
+ shared(y);
+ r_d = sha3(y);
+ r_a = 5;
+ }
+ function g(uint x, bytes32 y) external returns (uint r_a, bytes32 r_d) {
+ r_d = sha3(y);
+ shared(y);
+ r_d = bytes32(uint(sha3(y)) + 2);
+ r_a = 7;
+ }
+ function shared(bytes32 y) internal {
+ data = sha3(y);
+ }
+ }
+ )";
+ compileBothVersions(sourceCode);
+ compareVersions("f()", 7, "abc");
+
+ m_optimize = true;
+ bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test");
+ size_t numSHA3s = 0;
+ eth::eachInstruction(optimizedBytecode, [&](Instruction _instr, u256 const&) {
+ if (_instr == eth::Instruction::SHA3)
+ numSHA3s++;
+ });
+ BOOST_CHECK_EQUAL(2, numSHA3s);
+}
+
BOOST_AUTO_TEST_CASE(cse_intermediate_swap)
{
eth::KnownState state;