mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'develop' of https://github.com/ethereum/cpp-ethereum into develop
This commit is contained in:
commit
2210af0c34
@ -262,7 +262,21 @@ void ImportTest::importTransaction(json_spirit::mObject& _o)
|
|||||||
{
|
{
|
||||||
RLPStream transactionRLPStream = createRLPStreamFromTransactionFields(_o);
|
RLPStream transactionRLPStream = createRLPStreamFromTransactionFields(_o);
|
||||||
RLP transactionRLP(transactionRLPStream.out());
|
RLP transactionRLP(transactionRLPStream.out());
|
||||||
m_transaction = Transaction(transactionRLP.data(), CheckTransaction::Everything);
|
try
|
||||||
|
{
|
||||||
|
m_transaction = Transaction(transactionRLP.data(), CheckTransaction::Everything);
|
||||||
|
}
|
||||||
|
catch (InvalidSignature)
|
||||||
|
{
|
||||||
|
// create unsigned transaction
|
||||||
|
m_transaction = _o["to"].get_str().empty() ?
|
||||||
|
Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), importData(_o), toInt(_o["nonce"])) :
|
||||||
|
Transaction(toInt(_o["value"]), toInt(_o["gasPrice"]), toInt(_o["gasLimit"]), Address(_o["to"].get_str()), importData(_o), toInt(_o["nonce"]));
|
||||||
|
}
|
||||||
|
catch (Exception& _e)
|
||||||
|
{
|
||||||
|
cnote << "invalid transaction" << boost::diagnostic_information(_e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4187,6 +4187,28 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_signed)
|
|||||||
BOOST_CHECK(callContractFunction("q()") == encodeArgs(250));
|
BOOST_CHECK(callContractFunction("q()") == encodeArgs(250));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(failing_send)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract Helper {
|
||||||
|
uint[] data;
|
||||||
|
function () {
|
||||||
|
data[9]; // trigger exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract Main {
|
||||||
|
function callHelper(address _a) returns (bool r, uint bal) {
|
||||||
|
r = !_a.send(5);
|
||||||
|
bal = this.balance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "Helper");
|
||||||
|
u160 const c_helperAddress = m_contractAddress;
|
||||||
|
compileAndRun(sourceCode, 20, "Main");
|
||||||
|
BOOST_REQUIRE(callContractFunction("callHelper(address)", c_helperAddress) == encodeArgs(true, 20));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1876,6 +1876,40 @@ BOOST_AUTO_TEST_CASE(positive_integers_to_unsigned_out_of_bound)
|
|||||||
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(overwrite_memory_location_external)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
function f(uint[] memory a) external {}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(overwrite_storage_location_external)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
function f(uint[] storage a) external {}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK_THROW(parseTextAndResolveNames(sourceCode), TypeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(storage_location_local_variables)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
function f() {
|
||||||
|
uint[] storage x;
|
||||||
|
uint[] memory y;
|
||||||
|
uint[] memory z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK_NO_THROW(parseTextAndResolveNames(sourceCode));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,8 @@ BOOST_AUTO_TEST_CASE(store_tags_as_unions)
|
|||||||
if (_instr == eth::Instruction::SHA3)
|
if (_instr == eth::Instruction::SHA3)
|
||||||
numSHA3s++;
|
numSHA3s++;
|
||||||
});
|
});
|
||||||
BOOST_CHECK_EQUAL(2, numSHA3s);
|
// TEST DISABLED UNTIL 93693404 IS IMPLEMENTED
|
||||||
|
// BOOST_CHECK_EQUAL(2, numSHA3s);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(cse_intermediate_swap)
|
BOOST_AUTO_TEST_CASE(cse_intermediate_swap)
|
||||||
@ -440,6 +441,16 @@ BOOST_AUTO_TEST_CASE(cse_double_negation)
|
|||||||
checkCSE({Instruction::DUP5, Instruction::NOT, Instruction::NOT}, {Instruction::DUP5});
|
checkCSE({Instruction::DUP5, Instruction::NOT, Instruction::NOT}, {Instruction::DUP5});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(cse_double_iszero)
|
||||||
|
{
|
||||||
|
checkCSE({Instruction::GT, Instruction::ISZERO, Instruction::ISZERO}, {Instruction::GT});
|
||||||
|
checkCSE({Instruction::GT, Instruction::ISZERO}, {Instruction::GT, Instruction::ISZERO});
|
||||||
|
checkCSE(
|
||||||
|
{Instruction::ISZERO, Instruction::ISZERO, Instruction::ISZERO},
|
||||||
|
{Instruction::ISZERO}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(cse_associativity)
|
BOOST_AUTO_TEST_CASE(cse_associativity)
|
||||||
{
|
{
|
||||||
AssemblyItems input{
|
AssemblyItems input{
|
||||||
@ -908,6 +919,31 @@ BOOST_AUTO_TEST_CASE(cse_equality_on_initially_known_stack)
|
|||||||
BOOST_CHECK(find(output.begin(), output.end(), AssemblyItem(u256(1))) != output.end());
|
BOOST_CHECK(find(output.begin(), output.end(), AssemblyItem(u256(1))) != output.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(cse_access_previous_sequence)
|
||||||
|
{
|
||||||
|
// Tests that the code generator detects whether it tries to access SLOAD instructions
|
||||||
|
// from a sequenced expression which is not in its scope.
|
||||||
|
eth::KnownState state = createInitialState(AssemblyItems{
|
||||||
|
u256(0),
|
||||||
|
Instruction::SLOAD,
|
||||||
|
u256(1),
|
||||||
|
Instruction::ADD,
|
||||||
|
u256(0),
|
||||||
|
Instruction::SSTORE
|
||||||
|
});
|
||||||
|
// now stored: val_1 + 1 (value at sequence 1)
|
||||||
|
// if in the following instructions, the SLOAD cresolves to "val_1 + 1",
|
||||||
|
// this cannot be generated because we cannot load from sequence 1 anymore.
|
||||||
|
AssemblyItems input{
|
||||||
|
u256(0),
|
||||||
|
Instruction::SLOAD,
|
||||||
|
};
|
||||||
|
BOOST_CHECK_THROW(getCSE(input, state), StackTooDeepException);
|
||||||
|
// @todo for now, this throws an exception, but it should recover to the following
|
||||||
|
// (or an even better version) at some point:
|
||||||
|
// 0, SLOAD, 1, ADD, SSTORE, 0 SLOAD
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused)
|
BOOST_AUTO_TEST_CASE(control_flow_graph_remove_unused)
|
||||||
{
|
{
|
||||||
// remove parts of the code that are unused
|
// remove parts of the code that are unused
|
||||||
@ -1036,6 +1072,51 @@ BOOST_AUTO_TEST_CASE(block_deduplicator_loops)
|
|||||||
BOOST_CHECK_EQUAL(pushTags.size(), 1);
|
BOOST_CHECK_EQUAL(pushTags.size(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(computing_constants)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract c {
|
||||||
|
uint a;
|
||||||
|
uint b;
|
||||||
|
uint c;
|
||||||
|
function set() returns (uint a, uint b, uint c) {
|
||||||
|
a = 0x77abc0000000000000000000000000000000000000000000000000000000001;
|
||||||
|
b = 0x817416927846239487123469187231298734162934871263941234127518276;
|
||||||
|
g();
|
||||||
|
}
|
||||||
|
function g() {
|
||||||
|
b = 0x817416927846239487123469187231298734162934871263941234127518276;
|
||||||
|
c = 0x817416927846239487123469187231298734162934871263941234127518276;
|
||||||
|
}
|
||||||
|
function get() returns (uint ra, uint rb, uint rc) {
|
||||||
|
ra = a;
|
||||||
|
rb = b;
|
||||||
|
rc = c ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileBothVersions(sourceCode);
|
||||||
|
compareVersions("set()");
|
||||||
|
compareVersions("get()");
|
||||||
|
|
||||||
|
m_optimize = true;
|
||||||
|
m_optimizeRuns = 1;
|
||||||
|
bytes optimizedBytecode = compileAndRun(sourceCode, 0, "c");
|
||||||
|
bytes complicatedConstant = toBigEndian(u256("0x817416927846239487123469187231298734162934871263941234127518276"));
|
||||||
|
unsigned occurrences = 0;
|
||||||
|
for (auto iter = optimizedBytecode.cbegin(); iter < optimizedBytecode.cend(); ++occurrences)
|
||||||
|
iter = search(iter, optimizedBytecode.cend(), complicatedConstant.cbegin(), complicatedConstant.cend()) + 1;
|
||||||
|
BOOST_CHECK_EQUAL(2, occurrences);
|
||||||
|
|
||||||
|
bytes constantWithZeros = toBigEndian(u256("0x77abc0000000000000000000000000000000000000000000000000000000001"));
|
||||||
|
BOOST_CHECK(search(
|
||||||
|
optimizedBytecode.cbegin(),
|
||||||
|
optimizedBytecode.cend(),
|
||||||
|
constantWithZeros.cbegin(),
|
||||||
|
constantWithZeros.cend()
|
||||||
|
) == optimizedBytecode.cend());
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -873,6 +873,47 @@ BOOST_AUTO_TEST_CASE(var_array)
|
|||||||
BOOST_CHECK_THROW(parseText(text), ParserError);
|
BOOST_CHECK_THROW(parseText(text), ParserError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(location_specifiers_for_params)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract Foo {
|
||||||
|
function f(uint[] storage constant x, uint[] memory y) { }
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK_NO_THROW(parseText(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(location_specifiers_for_locals)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract Foo {
|
||||||
|
function f() {
|
||||||
|
uint[] storage x;
|
||||||
|
uint[] memory y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK_NO_THROW(parseText(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(location_specifiers_for_state)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract Foo {
|
||||||
|
uint[] memory x;
|
||||||
|
})";
|
||||||
|
BOOST_CHECK_THROW(parseText(text), ParserError);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(location_specifiers_with_var)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract Foo {
|
||||||
|
function f() { var memory x; }
|
||||||
|
})";
|
||||||
|
BOOST_CHECK_THROW(parseText(text), ParserError);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -77,13 +77,13 @@ BOOST_AUTO_TEST_CASE(storage_layout_mapping)
|
|||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(storage_layout_arrays)
|
BOOST_AUTO_TEST_CASE(storage_layout_arrays)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(1), 32).getStorageSize() == 1);
|
BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared<FixedBytesType>(1), 32).getStorageSize() == 1);
|
||||||
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(1), 33).getStorageSize() == 2);
|
BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared<FixedBytesType>(1), 33).getStorageSize() == 2);
|
||||||
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(2), 31).getStorageSize() == 2);
|
BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared<FixedBytesType>(2), 31).getStorageSize() == 2);
|
||||||
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(7), 8).getStorageSize() == 2);
|
BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared<FixedBytesType>(7), 8).getStorageSize() == 2);
|
||||||
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(7), 9).getStorageSize() == 3);
|
BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared<FixedBytesType>(7), 9).getStorageSize() == 3);
|
||||||
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(31), 9).getStorageSize() == 9);
|
BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared<FixedBytesType>(31), 9).getStorageSize() == 9);
|
||||||
BOOST_CHECK(ArrayType(ArrayType::Location::Storage, make_shared<FixedBytesType>(32), 9).getStorageSize() == 9);
|
BOOST_CHECK(ArrayType(ReferenceType::Location::Storage, make_shared<FixedBytesType>(32), 9).getStorageSize() == 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
@ -46,7 +46,7 @@ public:
|
|||||||
{
|
{
|
||||||
m_compiler.reset(false, m_addStandardSources);
|
m_compiler.reset(false, m_addStandardSources);
|
||||||
m_compiler.addSource("", _sourceCode);
|
m_compiler.addSource("", _sourceCode);
|
||||||
ETH_TEST_REQUIRE_NO_THROW(m_compiler.compile(m_optimize), "Compiling contract failed");
|
ETH_TEST_REQUIRE_NO_THROW(m_compiler.compile(m_optimize, m_optimizeRuns), "Compiling contract failed");
|
||||||
bytes code = m_compiler.getBytecode(_contractName);
|
bytes code = m_compiler.getBytecode(_contractName);
|
||||||
sendMessage(code, true, _value);
|
sendMessage(code, true, _value);
|
||||||
return m_output;
|
return m_output;
|
||||||
@ -180,6 +180,7 @@ protected:
|
|||||||
m_logs = executive.logs();
|
m_logs = executive.logs();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t m_optimizeRuns = 200;
|
||||||
bool m_optimize = false;
|
bool m_optimize = false;
|
||||||
bool m_addStandardSources = false;
|
bool m_addStandardSources = false;
|
||||||
dev::solidity::CompilerStack m_compiler;
|
dev::solidity::CompilerStack m_compiler;
|
||||||
|
Loading…
Reference in New Issue
Block a user