mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' of https://github.com/ethereum/solidity into develop
This commit is contained in:
+1
-1
@@ -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})
|
||||
|
||||
+13
-3
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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());
|
||||
|
||||
+15
-15
@@ -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))
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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()
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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()
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user