aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaweł Bylica <chfast@gmail.com>2015-05-19 20:11:06 +0800
committerPaweł Bylica <chfast@gmail.com>2015-05-19 20:11:06 +0800
commit711933ab79e4c2951ff3ce04b93769051fd33aed (patch)
treed23dc645f7a9b402da7dc2e292bd9105873e0780
parent047e72c6792fb4b83e48b6230ae6bfea605cd273 (diff)
parent8512e30f0ac9193c21d1ce70409426a469ff395a (diff)
downloaddexon-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.cpp3
-rw-r--r--TestHelper.h1
-rw-r--r--libsolidity/SolidityEndToEndTest.cpp31
-rw-r--r--libsolidity/SolidityOptimizer.cpp45
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;