diff options
author | Dmitry K <winsvega@mail.ru> | 2016-08-02 16:11:09 +0800 |
---|---|---|
committer | Dmitry K <winsvega@mail.ru> | 2016-08-02 16:11:09 +0800 |
commit | a10b6f92f97bf2eacc80534f6640e08f0b26e95d (patch) | |
tree | ffb7d72d52ae7a8d30194186bc15886c10118c5a /test | |
parent | d1c744450965644df17fcc73006dd7495e75c477 (diff) | |
parent | 85a61fe886c2d99d397bf30cc01d971558130287 (diff) | |
download | dexon-solidity-a10b6f92f97bf2eacc80534f6640e08f0b26e95d.tar.gz dexon-solidity-a10b6f92f97bf2eacc80534f6640e08f0b26e95d.tar.zst dexon-solidity-a10b6f92f97bf2eacc80534f6640e08f0b26e95d.zip |
Merge branch 'develop' of https://github.com/ethereum/solidity into develop
Diffstat (limited to 'test')
-rw-r--r-- | test/CMakeLists.txt | 2 | ||||
-rw-r--r-- | test/RPCSession.cpp | 16 | ||||
-rw-r--r-- | test/contracts/AuctionRegistrar.cpp | 12 | ||||
-rw-r--r-- | test/contracts/FixedFeeRegistrar.cpp | 6 | ||||
-rw-r--r-- | test/contracts/Wallet.cpp | 30 | ||||
-rw-r--r-- | test/libsolidity/GasMeter.cpp | 1 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 22 | ||||
-rw-r--r-- | test/libsolidity/SolidityExecutionFramework.cpp | 11 | ||||
-rw-r--r-- | test/libsolidity/SolidityExecutionFramework.h | 31 | ||||
-rw-r--r-- | test/libsolidity/SolidityOptimizer.cpp | 72 |
10 files changed, 153 insertions, 50 deletions
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index efcbb82e..2f001b21 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -26,7 +26,7 @@ file(GLOB HEADERS "*.h" "*/*.h") set(EXECUTABLE soltest) eth_simple_add_executable(${EXECUTABLE} ${SRC_LIST} ${HEADERS}) -eth_use(${EXECUTABLE} REQUIRED Solidity::solidity Eth::ethcore) +eth_use(${EXECUTABLE} REQUIRED Solidity::solidity) include_directories(BEFORE ..) target_link_libraries(${EXECUTABLE} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARIES}) diff --git a/test/RPCSession.cpp b/test/RPCSession.cpp index 68369567..124ee789 100644 --- a/test/RPCSession.cpp +++ b/test/RPCSession.cpp @@ -38,15 +38,25 @@ IPCSocket::IPCSocket(string const& _path): m_path(_path) BOOST_FAIL("Error opening IPC: socket path is too long!"); struct sockaddr_un saun; + memset(&saun, 0, sizeof(sockaddr_un)); saun.sun_family = AF_UNIX; strcpy(saun.sun_path, _path.c_str()); +// http://idletechnology.blogspot.ca/2011/12/unix-domain-sockets-on-osx.html +// +// SUN_LEN() might be optimal, but it seemingly affects the portability, +// with at least Android missing this macro. Just using the sizeof() for +// structure seemingly works, and would only have the side-effect of +// sending larger-than-required packets over the socket. Given that this +// code is only used for unit-tests, that approach seems simpler. +#if defined(__APPLE__) + saun.sun_len = sizeof(struct sockaddr_un); +#endif // defined(__APPLE__) + if ((m_socket = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) BOOST_FAIL("Error creating IPC socket object"); - int len = sizeof(saun.sun_family) + strlen(saun.sun_path); - - if (connect(m_socket, reinterpret_cast<struct sockaddr const*>(&saun), len) < 0) + if (connect(m_socket, reinterpret_cast<struct sockaddr const*>(&saun), sizeof(struct sockaddr_un)) < 0) BOOST_FAIL("Error connecting to IPC socket: " << _path); m_fp = fdopen(m_socket, "r"); diff --git a/test/contracts/AuctionRegistrar.cpp b/test/contracts/AuctionRegistrar.cpp index 9aa47189..8860727d 100644 --- a/test/contracts/AuctionRegistrar.cpp +++ b/test/contracts/AuctionRegistrar.cpp @@ -23,8 +23,8 @@ #include <string> #include <tuple> #include <boost/test/unit_test.hpp> +#include <libdevcore/ABI.h> #include <libdevcore/Hash.h> -#include <libethcore/ABI.h> #include <test/libsolidity/SolidityExecutionFramework.h> using namespace std; @@ -333,7 +333,7 @@ BOOST_AUTO_TEST_CASE(double_reserve_long) registrar.reserve(name); BOOST_CHECK_EQUAL(registrar.owner(name), m_sender); - sendEther(account(1), u256(10) * eth::ether); + sendEther(account(1), u256(10) * ether); m_sender = account(1); registrar.reserve(name); BOOST_CHECK_EQUAL(registrar.owner(name), account(0)); @@ -350,7 +350,7 @@ BOOST_AUTO_TEST_CASE(properties) for (string const& name: names) { m_sender = account(0); - sendEther(account(count), u256(20) * eth::ether); + sendEther(account(count), u256(20) * ether); m_sender = account(count); auto sender = m_sender; addr += count; @@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(disown) BOOST_CHECK_EQUAL(registrar.name(u160(124)), name); // someone else tries disowning - sendEther(account(1), u256(10) * eth::ether); + sendEther(account(1), u256(10) * ether); m_sender = account(1); registrar.disown(name); BOOST_CHECK_EQUAL(registrar.owner(name), account(0)); @@ -451,7 +451,7 @@ BOOST_AUTO_TEST_CASE(auction_bidding) registrar.setNextValue(12); registrar.reserve(name); // another bid by someone else - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); m_rpc.test_modifyTimestamp(startTime + 2 * m_biddingTime - 50); registrar.setNextValue(13); @@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE(auction_renewal) BOOST_CHECK_EQUAL(registrar.owner(name), m_sender); // try to re-register before interval end - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); m_rpc.test_modifyTimestamp(currentTimestamp() + m_renewalInterval - 1); registrar.setNextValue(80); diff --git a/test/contracts/FixedFeeRegistrar.cpp b/test/contracts/FixedFeeRegistrar.cpp index 8cb8257a..63db0531 100644 --- a/test/contracts/FixedFeeRegistrar.cpp +++ b/test/contracts/FixedFeeRegistrar.cpp @@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(double_reserve) BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs()); BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(account(0), h256::AlignRight))); - sendEther(account(1), 100 * eth::ether); + sendEther(account(1), 100 * ether); m_sender = account(1); BOOST_REQUIRE(callContractFunctionWithValue("reserve(string)", m_fee, encodeDyn(name)) == encodeArgs()); BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(account(0), h256::AlignRight))); @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(properties) { addr++; m_sender = account(0); - sendEther(account(count), 100 * eth::ether); + sendEther(account(count), 100 * ether); m_sender = account(count); Address owner = m_sender; // setting by sender works @@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(properties) count++; // but not by someone else m_sender = account(0); - sendEther(account(count), 100 * eth::ether); + sendEther(account(count), 100 * ether); m_sender = account(count); BOOST_CHECK(callContractFunction("owner(string)", encodeDyn(name)) == encodeArgs(h256(owner, h256::AlignRight))); BOOST_CHECK(callContractFunction("setAddr(string,address)", u256(0x40), addr + 1, u256(name.length()), name) == encodeArgs()); diff --git a/test/contracts/Wallet.cpp b/test/contracts/Wallet.cpp index fbab2404..27bdb396 100644 --- a/test/contracts/Wallet.cpp +++ b/test/contracts/Wallet.cpp @@ -474,13 +474,13 @@ BOOST_AUTO_TEST_CASE(add_owners) BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(account(1), h256::AlignRight)) == encodeArgs()); BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(account(1), h256::AlignRight)) == encodeArgs(true)); // now let the new owner add someone - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x13)) == encodeArgs()); BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x13)) == encodeArgs(true)); // and check that a non-owner cannot add a new owner m_sender = account(0); - sendEther(account(2), 10 * eth::ether); + sendEther(account(2), 10 * ether); m_sender = account(2); BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x20)) == encodeArgs()); BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x20)) == encodeArgs(false)); @@ -559,17 +559,17 @@ BOOST_AUTO_TEST_CASE(multisig_value_transfer) // check that balance is and stays zero at destination address BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); m_sender = account(0); - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); auto ophash = callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00); BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); m_sender = account(0); - sendEther(account(2), 10 * eth::ether); + sendEther(account(2), 10 * ether); m_sender = account(2); callContractFunction("confirm(bytes32)", ophash); BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); m_sender = account(0); - sendEther(account(3), 10 * eth::ether); + sendEther(account(3), 10 * ether); m_sender = account(3); callContractFunction("confirm(bytes32)", ophash); // now it should go through @@ -590,7 +590,7 @@ BOOST_AUTO_TEST_CASE(revoke_addOwner) BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs()); BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false)); m_sender = account(0); - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs()); BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false)); @@ -598,12 +598,12 @@ BOOST_AUTO_TEST_CASE(revoke_addOwner) m_sender = deployer; BOOST_REQUIRE(callContractFunction("revoke(bytes32)", opHash) == encodeArgs()); m_sender = account(0); - sendEther(account(2), 10 * eth::ether); + sendEther(account(2), 10 * ether); m_sender = account(2); BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs()); BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(false)); m_sender = account(0); - sendEther(account(3), 10 * eth::ether); + sendEther(account(3), 10 * ether); m_sender = account(3); BOOST_REQUIRE(callContractFunction("addOwner(address)", h256(0x33)) == encodeArgs()); BOOST_REQUIRE(callContractFunction("isOwner(address)", h256(0x33)) == encodeArgs(true)); @@ -621,24 +621,24 @@ BOOST_AUTO_TEST_CASE(revoke_transaction) Address deployer = m_sender; BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); m_sender = account(0); - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); auto opHash = callContractFunction("execute(address,uint256,bytes)", h256(0x05), 100, 0x60, 0x00); BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); m_sender = account(0); - sendEther(account(2), 10 * eth::ether); + sendEther(account(2), 10 * ether); m_sender = account(2); callContractFunction("confirm(bytes32)", opHash); BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); m_sender = account(0); - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); BOOST_REQUIRE(callContractFunction("revoke(bytes32)", opHash) == encodeArgs()); m_sender = deployer; callContractFunction("confirm(bytes32)", opHash); BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); m_sender = account(0); - sendEther(account(3), 10 * eth::ether); + sendEther(account(3), 10 * ether); m_sender = account(3); callContractFunction("confirm(bytes32)", opHash); // now it should go through @@ -659,7 +659,7 @@ BOOST_AUTO_TEST_CASE(daylimit) // try to send tx over daylimit BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); m_sender = account(1); BOOST_REQUIRE( callContractFunction("execute(address,uint256,bytes)", h256(0x05), 150, 0x60, 0x00) != @@ -668,7 +668,7 @@ BOOST_AUTO_TEST_CASE(daylimit) BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); // try to send tx under daylimit by stranger m_sender = account(0); - sendEther(account(4), 10 * eth::ether); + sendEther(account(4), 10 * ether); m_sender = account(4); BOOST_REQUIRE( callContractFunction("execute(address,uint256,bytes)", h256(0x05), 90, 0x60, 0x00) == @@ -677,7 +677,7 @@ BOOST_AUTO_TEST_CASE(daylimit) BOOST_CHECK_EQUAL(balanceAt(Address(0x05)), 0); // now send below limit by owner m_sender = account(0); - sendEther(account(1), 10 * eth::ether); + sendEther(account(1), 10 * ether); BOOST_REQUIRE( callContractFunction("execute(address,uint256,bytes)", h256(0x05), 90, 0x60, 0x00) == encodeArgs(u256(0)) diff --git a/test/libsolidity/GasMeter.cpp b/test/libsolidity/GasMeter.cpp index fc7a033f..41204a0a 100644 --- a/test/libsolidity/GasMeter.cpp +++ b/test/libsolidity/GasMeter.cpp @@ -21,6 +21,7 @@ */ #include <test/libsolidity/SolidityExecutionFramework.h> +#include <libevmasm/EVMSchedule.h> #include <libevmasm/GasMeter.h> #include <libevmasm/KnownState.h> #include <libevmasm/PathGasMeter.h> diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 8dcc878e..1b7c5ea4 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -21,6 +21,7 @@ * Unit tests for the solidity expression compiler, testing the behaviour of the code. */ +#include <functional> #include <string> #include <tuple> #include <boost/test/unit_test.hpp> @@ -29,6 +30,7 @@ #include <test/libsolidity/SolidityExecutionFramework.h> using namespace std; +using namespace std::placeholders; namespace dev { @@ -2462,7 +2464,7 @@ BOOST_AUTO_TEST_CASE(use_std_lib) contract Icarus is mortal { } )"; m_addStandardSources = true; - u256 amount(130 * eth::ether); + u256 amount(130 * ether); compileAndRun(sourceCode, amount, "Icarus"); u256 balanceBefore = balanceAt(m_sender); BOOST_CHECK(callContractFunction("kill()") == bytes()); @@ -5921,9 +5923,9 @@ BOOST_AUTO_TEST_CASE(version_stamp_for_libraries) m_optimize = true; bytes runtimeCode = compileAndRun(sourceCode, 0, "lib"); BOOST_CHECK(runtimeCode.size() >= 8); - BOOST_CHECK_EQUAL(runtimeCode[0], int(eth::Instruction::PUSH6)); // might change once we switch to 1.x.x + BOOST_CHECK_EQUAL(runtimeCode[0], int(Instruction::PUSH6)); // might change once we switch to 1.x.x BOOST_CHECK_EQUAL(runtimeCode[1], 3); // might change once we switch away from x.3.x - BOOST_CHECK_EQUAL(runtimeCode[7], int(eth::Instruction::POP)); + BOOST_CHECK_EQUAL(runtimeCode[7], int(Instruction::POP)); } BOOST_AUTO_TEST_CASE(contract_binary_dependencies) @@ -6837,6 +6839,20 @@ BOOST_AUTO_TEST_CASE(skip_dynamic_types_for_structs) BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(2), u256(6))); } +BOOST_AUTO_TEST_CASE(create_dynamic_array_with_zero_length) +{ + char const* sourceCode = R"( + contract C { + function f() returns (uint) { + var a = new uint[][](0); + return 7; + } + } + )"; + compileAndRun(sourceCode, 0, "C"); + BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(7))); +} + BOOST_AUTO_TEST_SUITE_END() } diff --git a/test/libsolidity/SolidityExecutionFramework.cpp b/test/libsolidity/SolidityExecutionFramework.cpp index da9cf5f1..a33f4caf 100644 --- a/test/libsolidity/SolidityExecutionFramework.cpp +++ b/test/libsolidity/SolidityExecutionFramework.cpp @@ -22,13 +22,21 @@ #include <cstdlib> #include <boost/test/framework.hpp> +#include <libdevcore/CommonIO.h> #include <test/libsolidity/SolidityExecutionFramework.h> + + using namespace std; using namespace dev; using namespace dev::solidity; using namespace dev::solidity::test; +namespace // anonymous +{ + h256 const EmptyTrie("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"); +} + string getIPCSocketPath() { string ipcPath; @@ -56,9 +64,6 @@ ExecutionFramework::ExecutionFramework() : m_rpc(RPCSession::instance(getIPCSocketPath())), m_sender(m_rpc.account(0)) { - if (g_logVerbosity != -1) - g_logVerbosity = 0; - m_rpc.test_rewindToBlock(0); } diff --git a/test/libsolidity/SolidityExecutionFramework.h b/test/libsolidity/SolidityExecutionFramework.h index 2b589498..5764784a 100644 --- a/test/libsolidity/SolidityExecutionFramework.h +++ b/test/libsolidity/SolidityExecutionFramework.h @@ -22,25 +22,33 @@ #pragma once -#include <string> -#include <tuple> -#include <fstream> +#include <functional> + #include "../TestHelper.h" #include "../RPCSession.h" -#include <libethcore/ABI.h> -#include <libethcore/SealEngine.h> -#include <libethereum/State.h> -#include <libethereum/Executive.h> -#include <libethereum/ChainParams.h> + +#include <libdevcore/ABI.h> +#include <libdevcore/FixedHash.h> +#include <libevmasm/Instruction.h> + #include <libsolidity/interface/CompilerStack.h> #include <libsolidity/interface/Exceptions.h> -#include <libethcore/BasicAuthority.h> -#include <libethcore/SealEngine.h> namespace dev { namespace solidity { + /// An Ethereum address: 20 bytes. + /// @NOTE This is not endian-specific; it's just a bunch of bytes. + using Address = h160; + + // The various denominations; here for ease of use where needed within code. + static const u256 ether = exp10<18>(); + static const u256 finney = exp10<15>(); + static const u256 szabo = exp10<12>(); + static const u256 shannon = exp10<9>(); + static const u256 wei = exp10<0>(); + namespace test { @@ -275,8 +283,7 @@ protected: dev::solidity::CompilerStack m_compiler; Address m_sender; Address m_contractAddress; - eth::EnvInfo m_envInfo; - u256 const m_gasPrice = 100 * eth::szabo; + u256 const m_gasPrice = 100 * szabo; u256 const m_gas = 100000000; bytes m_output; std::vector<LogEntry> m_logs; diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp index ad573823..206f23fb 100644 --- a/test/libsolidity/SolidityOptimizer.cpp +++ b/test/libsolidity/SolidityOptimizer.cpp @@ -79,6 +79,8 @@ public: bytes nonOptimizedOutput = callContractFunction(_sig, _arguments...); m_contractAddress = m_optimizedContract; bytes optimizedOutput = callContractFunction(_sig, _arguments...); + BOOST_CHECK_MESSAGE(!optimizedOutput.empty(), "No optimized output for " + _sig); + BOOST_CHECK_MESSAGE(!nonOptimizedOutput.empty(), "No un-optimized output for " + _sig); BOOST_CHECK_MESSAGE(nonOptimizedOutput == optimizedOutput, "Computed values do not match." "\nNon-Optimized: " + toHex(nonOptimizedOutput) + "\nOptimized: " + toHex(optimizedOutput)); @@ -176,7 +178,7 @@ BOOST_AUTO_TEST_CASE(identities) } })"; compileBothVersions(sourceCode); - compareVersions("f(uint256)", u256(0x12334664)); + compareVersions("f(int256)", u256(0x12334664)); } BOOST_AUTO_TEST_CASE(unused_expressions) @@ -230,6 +232,7 @@ BOOST_AUTO_TEST_CASE(array_copy) bytes2[] data1; bytes5[] data2; function f(uint x) returns (uint l, uint y) { + data1.length = msg.data.length; for (uint i = 0; i < msg.data.length; ++i) data1[i] = msg.data[i]; data2 = data1; @@ -241,7 +244,7 @@ BOOST_AUTO_TEST_CASE(array_copy) compileBothVersions(sourceCode); compareVersions("f(uint256)", 0); compareVersions("f(uint256)", 10); - compareVersions("f(uint256)", 36); + compareVersions("f(uint256)", 35); } BOOST_AUTO_TEST_CASE(function_calls) @@ -279,6 +282,8 @@ BOOST_AUTO_TEST_CASE(storage_write_in_loops) compareVersions("f(uint256)", 36); } +// Test disabled with https://github.com/ethereum/solidity/pull/762 +// Information in joining branches is not retained anymore. BOOST_AUTO_TEST_CASE(retain_information_in_branches) { // This tests that the optimizer knows that we already have "z == sha3(y)" inside both branches. @@ -312,7 +317,8 @@ BOOST_AUTO_TEST_CASE(retain_information_in_branches) if (_instr == Instruction::SHA3) numSHA3s++; }); - BOOST_CHECK_EQUAL(1, numSHA3s); +// TEST DISABLED - OPTIMIZER IS NOT EFFECTIVE ON THIS ONE ANYMORE +// BOOST_CHECK_EQUAL(1, numSHA3s); } BOOST_AUTO_TEST_CASE(store_tags_as_unions) @@ -346,7 +352,7 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions) } )"; compileBothVersions(sourceCode); - compareVersions("f()", 7, "abc"); + compareVersions("f(uint256,bytes32)", 7, "abc"); m_optimize = true; bytes optimizedBytecode = compileAndRun(sourceCode, 0, "test"); @@ -1174,6 +1180,64 @@ BOOST_AUTO_TEST_CASE(computing_constants) ) == optimizedBytecode.cend()); } +BOOST_AUTO_TEST_CASE(inconsistency) +{ + // This is a test of a bug in the optimizer. + char const* sourceCode = R"( + contract Inconsistency { + struct Value { + uint badnum; + uint number; + } + + struct Container { + uint[] valueIndices; + Value[] values; + } + + Container[] containers; + uint[] valueIndices; + uint INDEX_ZERO = 0; + uint debug; + + // Called with params: containerIndex=0, valueIndex=0 + function levelIII(uint containerIndex, uint valueIndex) private { + Container container = containers[containerIndex]; + Value value = container.values[valueIndex]; + debug = container.valueIndices[value.number]; + } + function levelII() private { + for (uint i = 0; i < valueIndices.length; i++) { + levelIII(INDEX_ZERO, valueIndices[i]); + } + } + + function trigger() public returns (uint) { + containers.length++; + Container container = containers[0]; + + container.values.push(Value({ + badnum: 9000, + number: 0 + })); + + container.valueIndices.length++; + valueIndices.length++; + + levelII(); + return debug; + } + + function DoNotCallButDoNotDelete() public { + levelII(); + levelIII(1, 2); + } + } + )"; + compileBothVersions(sourceCode); + compareVersions("trigger()"); +} + BOOST_AUTO_TEST_SUITE_END() } |