diff options
author | Paweł Bylica <chfast@gmail.com> | 2015-05-19 20:11:06 +0800 |
---|---|---|
committer | Paweł Bylica <chfast@gmail.com> | 2015-05-19 20:11:06 +0800 |
commit | 711933ab79e4c2951ff3ce04b93769051fd33aed (patch) | |
tree | d23dc645f7a9b402da7dc2e292bd9105873e0780 | |
parent | 047e72c6792fb4b83e48b6230ae6bfea605cd273 (diff) | |
parent | 8512e30f0ac9193c21d1ce70409426a469ff395a (diff) | |
download | dexon-solidity-711933ab79e4c2951ff3ce04b93769051fd33aed.tar dexon-solidity-711933ab79e4c2951ff3ce04b93769051fd33aed.tar.gz dexon-solidity-711933ab79e4c2951ff3ce04b93769051fd33aed.tar.bz2 dexon-solidity-711933ab79e4c2951ff3ce04b93769051fd33aed.tar.lz dexon-solidity-711933ab79e4c2951ff3ce04b93769051fd33aed.tar.xz dexon-solidity-711933ab79e4c2951ff3ce04b93769051fd33aed.tar.zst dexon-solidity-711933ab79e4c2951ff3ce04b93769051fd33aed.zip |
Merge remote-tracking branch 'upstream/develop' into evmjit-develop
-rw-r--r-- | TestHelper.cpp | 3 | ||||
-rw-r--r-- | TestHelper.h | 1 | ||||
-rw-r--r-- | libsolidity/SolidityEndToEndTest.cpp | 31 | ||||
-rw-r--r-- | libsolidity/SolidityOptimizer.cpp | 45 |
4 files changed, 79 insertions, 1 deletions
diff --git a/TestHelper.cpp b/TestHelper.cpp index 14d845a3..aada8304 100644 --- a/TestHelper.cpp +++ b/TestHelper.cpp @@ -726,6 +726,8 @@ Options::Options() bigData = true; else if (arg == "--checkstate") checkState = true; + else if (arg == "--wallet") + wallet = true; else if (arg == "--all") { performance = true; @@ -733,6 +735,7 @@ Options::Options() memory = true; inputLimits = true; bigData = true; + wallet= true; } else if (arg == "--singletest" && i + 1 < argc) { diff --git a/TestHelper.h b/TestHelper.h index d1da7e24..fc6c77fa 100644 --- a/TestHelper.h +++ b/TestHelper.h @@ -195,6 +195,7 @@ public: bool memory = false; bool inputLimits = false; bool bigData = false; + bool wallet = false; /// @} /// Get reference to options diff --git a/libsolidity/SolidityEndToEndTest.cpp b/libsolidity/SolidityEndToEndTest.cpp index ed5f1acd..6713382f 100644 --- a/libsolidity/SolidityEndToEndTest.cpp +++ b/libsolidity/SolidityEndToEndTest.cpp @@ -2558,6 +2558,37 @@ BOOST_AUTO_TEST_CASE(generic_call) BOOST_CHECK_EQUAL(m_state.balance(m_contractAddress), 50 - 2); } +BOOST_AUTO_TEST_CASE(generic_callcode) +{ + char const* sourceCode = R"**( + contract receiver { + uint public received; + function receive(uint256 x) { received = x; } + } + contract sender { + uint public received; + function doSend(address rec) returns (uint d) + { + bytes4 signature = bytes4(bytes32(sha3("receive(uint256)"))); + rec.callcode.value(2)(signature, 23); + return receiver(rec).received(); + } + } + )**"; + compileAndRun(sourceCode, 0, "receiver"); + u160 const c_receiverAddress = m_contractAddress; + compileAndRun(sourceCode, 50, "sender"); + u160 const c_senderAddress = m_contractAddress; + BOOST_CHECK(callContractFunction("doSend(address)", c_receiverAddress) == encodeArgs(0)); + BOOST_CHECK(callContractFunction("received()") == encodeArgs(23)); + m_contractAddress = c_receiverAddress; + BOOST_CHECK(callContractFunction("received()") == encodeArgs(0)); + BOOST_CHECK(m_state.storage(c_receiverAddress).empty()); + BOOST_CHECK(!m_state.storage(c_senderAddress).empty()); + BOOST_CHECK_EQUAL(m_state.balance(c_receiverAddress), 0); + BOOST_CHECK_EQUAL(m_state.balance(c_senderAddress), 50); +} + BOOST_AUTO_TEST_CASE(store_bytes) { // this test just checks that the copy loop does not mess up the stack diff --git a/libsolidity/SolidityOptimizer.cpp b/libsolidity/SolidityOptimizer.cpp index efc9316b..744fc48a 100644 --- a/libsolidity/SolidityOptimizer.cpp +++ b/libsolidity/SolidityOptimizer.cpp @@ -97,7 +97,7 @@ public: { eth::KnownState state; for (auto const& item: addDummyLocations(_input)) - state.feedItem(item); + state.feedItem(item, true); return state; } @@ -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; |