Merge remote-tracking branch 'origin/develop' into breaking

This commit is contained in:
chriseth
2020-11-03 14:05:14 +01:00
206 changed files with 1420 additions and 862 deletions
-129
View File
@@ -73,28 +73,6 @@ BOOST_AUTO_TEST_CASE(value_types)
)
}
BOOST_AUTO_TEST_CASE(enums)
{
string sourceCode = R"(
contract C {
enum E { A, B }
function f(E e) public pure returns (uint x) {
assembly { x := e }
}
}
)";
bool newDecoder = solidity::test::CommonOptions::get().useABIEncoderV2;
BOTH_ENCODERS(
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("f(uint8)", 0), encodeArgs(u256(0)));
ABI_CHECK(callContractFunction("f(uint8)", 1), encodeArgs(u256(1)));
// The old decoder was not as strict about enums
ABI_CHECK(callContractFunction("f(uint8)", 2), (newDecoder ? encodeArgs() : encodeArgs(2)));
ABI_CHECK(callContractFunction("f(uint8)", u256(-1)), (newDecoder? encodeArgs() : encodeArgs(u256(0xff))));
newDecoder = true;
)
}
BOOST_AUTO_TEST_CASE(cleanup)
{
string sourceCode = R"(
@@ -184,113 +162,6 @@ BOOST_AUTO_TEST_CASE(fixed_arrays)
)
}
BOOST_AUTO_TEST_CASE(dynamic_arrays)
{
string sourceCode = R"(
contract C {
function f(uint a, uint16[] memory b, uint c)
public pure returns (uint, uint, uint) {
return (b.length, b[a], c);
}
}
)";
BOTH_ENCODERS(
compileAndRun(sourceCode);
bytes args = encodeArgs(
6, 0x60, 9,
7,
11, 12, 13, 14, 15, 16, 17
);
ABI_CHECK(
callContractFunction("f(uint256,uint16[],uint256)", args),
encodeArgs(u256(7), u256(17), u256(9))
);
)
}
BOOST_AUTO_TEST_CASE(dynamic_nested_arrays)
{
string sourceCode = R"(
contract C {
function f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)
public pure returns (uint, uint, uint, uint, uint, uint, uint) {
return (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);
}
function test() public view returns (uint, uint, uint, uint, uint, uint, uint) {
uint16[][] memory b = new uint16[][](3);
b[0] = new uint16[](2);
b[0][0] = 0x55;
b[0][1] = 0x56;
b[1] = new uint16[](4);
b[1][0] = 0x65;
b[1][1] = 0x66;
b[1][2] = 0x67;
b[1][3] = 0x68;
uint[2][][3] memory c;
c[0] = new uint[2][](1);
c[0][0][1] = 0x75;
c[1] = new uint[2][](5);
c[1][1][1] = 0x85;
return this.f(0x12, b, c, 0x13);
}
}
)";
NEW_ENCODER(
compileAndRun(sourceCode);
bytes args = encodeArgs(
0x12, 4 * 0x20, 17 * 0x20, 0x13,
// b
3, 3 * 0x20, 6 * 0x20, 11 * 0x20,
2, 85, 86,
4, 101, 102, 103, 104,
0,
// c
3 * 0x20, 6 * 0x20, 17 * 0x20,
1, 0, 117,
5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0,
0
);
bytes expectation = encodeArgs(0x12, 3, 4, 0x66, 5, 0x85, 0x13);
ABI_CHECK(callContractFunction("test()"), expectation);
ABI_CHECK(callContractFunction("f(uint256,uint16[][],uint256[2][][3],uint256)", args), expectation);
)
}
BOOST_AUTO_TEST_CASE(byte_arrays)
{
string sourceCode = R"(
contract C {
function f(uint a, bytes memory b, uint c)
public pure returns (uint, uint, byte, uint) {
return (a, b.length, b[3], c);
}
function f_external(uint a, bytes calldata b, uint c)
external pure returns (uint, uint, byte, uint) {
return (a, b.length, b[3], c);
}
}
)";
BOTH_ENCODERS(
compileAndRun(sourceCode);
bytes args = encodeArgs(
6, 0x60, 9,
7, "abcdefg"
);
ABI_CHECK(
callContractFunction("f(uint256,bytes,uint256)", args),
encodeArgs(u256(6), u256(7), "d", 9)
);
ABI_CHECK(
callContractFunction("f_external(uint256,bytes,uint256)", args),
encodeArgs(u256(6), u256(7), "d", 9)
);
)
}
BOOST_AUTO_TEST_CASE(calldata_arrays_too_large)
{
string sourceCode = R"(
+2
View File
@@ -34,6 +34,7 @@
#include <libsolidity/codegen/Compiler.h>
#include <libsolidity/ast/AST.h>
#include <libsolidity/analysis/TypeChecker.h>
#include <libsolidity/analysis/SyntaxChecker.h>
#include <liblangutil/ErrorReporter.h>
#include <boost/test/unit_test.hpp>
@@ -61,6 +62,7 @@ evmasm::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
BOOST_CHECK(!!sourceUnit);
Scoper::assignScopes(*sourceUnit);
BOOST_REQUIRE(SyntaxChecker(errorReporter, false).checkSyntax(*sourceUnit));
GlobalContext globalContext;
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter);
DeclarationTypeChecker declarationTypeChecker(errorReporter, solidity::test::CommonOptions::get().evmVersion());
+98 -316
View File
@@ -537,39 +537,6 @@ BOOST_AUTO_TEST_CASE(for_loop)
)
}
BOOST_AUTO_TEST_CASE(for_loop_empty)
{
char const* sourceCode = R"(
contract test {
function f() public returns(uint ret) {
ret = 1;
for (;;) {
ret += 1;
if (ret >= 10) break;
}
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
auto for_loop_empty_cpp = []() -> u256
{
u256 ret = 1;
for (;;)
{
ret += 1;
if (ret >= 10) break;
}
return ret;
};
testContractAgainstCpp("f()", for_loop_empty_cpp);
)
}
BOOST_AUTO_TEST_CASE(for_loop_simple_init_expr)
{
char const* sourceCode = R"(
@@ -649,85 +616,6 @@ BOOST_AUTO_TEST_CASE(for_loop_break_continue)
);
}
BOOST_AUTO_TEST_CASE(calling_other_functions)
{
char const* sourceCode = R"(
contract collatz {
function run(uint x) public returns(uint y) {
while ((y = x) > 1) {
if (x % 2 == 0) x = evenStep(x);
else x = oddStep(x);
}
}
function evenStep(uint x) public returns(uint y) {
return x / 2;
}
function oddStep(uint x) public returns(uint y) {
return 3 * x + 1;
}
}
)";
auto evenStep_cpp = [](u256 const& n) -> u256
{
return n / 2;
};
auto oddStep_cpp = [](u256 const& n) -> u256
{
return 3 * n + 1;
};
auto collatz_cpp = [&evenStep_cpp, &oddStep_cpp](u256 n) -> u256
{
u256 y;
while ((y = n) > 1)
{
if (n % 2 == 0)
n = evenStep_cpp(n);
else
n = oddStep_cpp(n);
}
return y;
};
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(0));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(1));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(2));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(8));
testContractAgainstCpp("run(uint256)", collatz_cpp, u256(127));
)
}
BOOST_AUTO_TEST_CASE(many_local_variables)
{
char const* sourceCode = R"(
contract test {
function run(uint x1, uint x2, uint x3) public returns(uint y) {
uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100;
y = a + b + c + x1 + x2 + x3;
y += b + x2;
}
}
)";
auto f = [](u256 const& x1, u256 const& x2, u256 const& x3) -> u256
{
u256 a = 0x1;
u256 b = 0x10;
u256 c = 0x100;
u256 y = a + b + c + x1 + x2 + x3;
return y + b + x2;
};
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
testContractAgainstCpp("run(uint256,uint256,uint256)", f, u256(0x1000), u256(0x10000), u256(0x100000));
)
}
BOOST_AUTO_TEST_CASE(short_circuiting)
{
char const* sourceCode = R"(
@@ -826,149 +714,6 @@ BOOST_AUTO_TEST_CASE(small_unsigned_types)
testContractAgainstCpp("run()", small_unsigned_types_cpp);
}
BOOST_AUTO_TEST_CASE(small_signed_types)
{
char const* sourceCode = R"(
contract test {
function run() public returns(int256 y) {
return -int32(10) * -int64(20);
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
auto small_signed_types_cpp = []() -> u256
{
return -int32_t(10) * -int64_t(20);
};
testContractAgainstCpp("run()", small_signed_types_cpp);
);
}
BOOST_AUTO_TEST_CASE(compound_assign)
{
char const* sourceCode = R"(
contract test {
uint value1;
uint value2;
function f(uint x, uint y) public returns (uint w) {
uint value3 = y;
value1 += x;
value3 *= x;
value2 *= value3 + value1;
return value2 += 7;
}
}
)";
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
u256 value1;
u256 value2;
auto f = [&](u256 const& _x, u256 const& _y) -> u256
{
u256 value3 = _y;
value1 += _x;
value3 *= _x;
value2 *= value3 + value1;
return value2 += 7;
};
testContractAgainstCpp("f(uint256,uint256)", f, u256(0), u256(6));
testContractAgainstCpp("f(uint256,uint256)", f, u256(1), u256(3));
testContractAgainstCpp("f(uint256,uint256)", f, u256(2), u256(25));
testContractAgainstCpp("f(uint256,uint256)", f, u256(3), u256(69));
testContractAgainstCpp("f(uint256,uint256)", f, u256(4), u256(84));
testContractAgainstCpp("f(uint256,uint256)", f, u256(5), u256(2));
testContractAgainstCpp("f(uint256,uint256)", f, u256(6), u256(51));
testContractAgainstCpp("f(uint256,uint256)", f, u256(7), u256(48));
)
}
BOOST_AUTO_TEST_CASE(mapping_state)
{
char const* sourceCode = R"(
contract Ballot {
mapping(address => bool) canVote;
mapping(address => uint) voteCount;
mapping(address => bool) voted;
function getVoteCount(address addr) public returns (uint retVoteCount) {
return voteCount[addr];
}
function grantVoteRight(address addr) public {
canVote[addr] = true;
}
function vote(address voter, address vote) public returns (bool success) {
if (!canVote[voter] || voted[voter]) return false;
voted[voter] = true;
voteCount[vote] = voteCount[vote] + 1;
return true;
}
}
)";
class Ballot
{
public:
u256 getVoteCount(u160 _address) { return m_voteCount[_address]; }
void grantVoteRight(u160 _address) { m_canVote[_address] = true; }
bool vote(u160 _voter, u160 _vote)
{
if (!m_canVote[_voter] || m_voted[_voter]) return false;
m_voted[_voter] = true;
m_voteCount[_vote]++;
return true;
}
private:
map<u160, bool> m_canVote;
map<u160, u256> m_voteCount;
map<u160, bool> m_voted;
};
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
Ballot ballot;
auto getVoteCount = bind(&Ballot::getVoteCount, &ballot, _1);
auto grantVoteRight = bind(&Ballot::grantVoteRight, &ballot, _1);
auto vote = bind(&Ballot::vote, &ballot, _1, _2);
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// voting without vote right should be rejected
testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// grant vote rights
testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(0));
testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(1));
// vote, should increase 2's vote count
testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(2));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// vote again, should be rejected
testContractAgainstCpp("vote(address,address)", vote, u160(0), u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// vote without right to vote
testContractAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
// grant vote right and now vote again
testContractAgainstCpp("grantVoteRight(address)", grantVoteRight, u160(2));
testContractAgainstCpp("vote(address,address)", vote, u160(2), u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(0));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(1));
testContractAgainstCpp("getVoteCount(address)", getVoteCount, u160(2));
)
}
BOOST_AUTO_TEST_CASE(mapping_state_inc_dec)
{
char const* sourceCode = R"(
@@ -2764,11 +2509,14 @@ BOOST_AUTO_TEST_CASE(delete_removes_bytes_data)
bytes data;
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("---", 7), bytes());
BOOST_CHECK(!storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("del()", 7), encodeArgs(true));
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("---", 7), bytes());
BOOST_CHECK(!storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("del()", 7), encodeArgs(true));
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data)
@@ -2780,13 +2528,16 @@ BOOST_AUTO_TEST_CASE(copy_from_calldata_removes_bytes_data)
bytes data;
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5), encodeArgs(true));
BOOST_CHECK(!storageEmpty(m_contractAddress));
sendMessage(bytes(), false);
BOOST_CHECK(m_transactionSuccessful);
BOOST_CHECK(m_output.empty());
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("set()", 1, 2, 3, 4, 5), encodeArgs(true));
BOOST_CHECK(!storageEmpty(m_contractAddress));
sendMessage(bytes(), false);
BOOST_CHECK(m_transactionSuccessful);
BOOST_CHECK(m_output.empty());
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(copy_removes_bytes_data)
@@ -3032,17 +2783,21 @@ BOOST_AUTO_TEST_CASE(bytes_in_arguments)
}
}
)";
compileAndRun(sourceCode);
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
string innercalldata1 = asString(FixedHash<4>(util::keccak256("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9));
string innercalldata2 = asString(FixedHash<4>(util::keccak256("g(uint256)")).asBytes() + encodeArgs(3));
bytes calldata = encodeArgs(
12, 32 * 4, u256(32 * 4 + 32 + (innercalldata1.length() + 31) / 32 * 32), 13,
u256(innercalldata1.length()), innercalldata1,
u256(innercalldata2.length()), innercalldata2);
ABI_CHECK(
callContractFunction("test(uint256,bytes,bytes,uint256)", calldata),
encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length()))
compileAndRun(sourceCode);
string innercalldata1 = asString(FixedHash<4>(util::keccak256("f(uint256,uint256)")).asBytes() + encodeArgs(8, 9));
string innercalldata2 = asString(FixedHash<4>(util::keccak256("g(uint256)")).asBytes() + encodeArgs(3));
bytes calldata = encodeArgs(
12, 32 * 4, u256(32 * 4 + 32 + (innercalldata1.length() + 31) / 32 * 32), 13,
u256(innercalldata1.length()), innercalldata1,
u256(innercalldata2.length()), innercalldata2);
ABI_CHECK(
callContractFunction("test(uint256,bytes,bytes,uint256)", calldata),
encodeArgs(12, (8 + 9) * 3, 13, u256(innercalldata1.length()))
);
);
}
@@ -3146,12 +2901,16 @@ BOOST_AUTO_TEST_CASE(dynamic_multi_array_cleanup)
function clear() public { delete data; }
}
)";
compileAndRun(sourceCode);
BOOST_CHECK(storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("fill()"), encodeArgs(8));
BOOST_CHECK(!storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("clear()"), bytes());
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
BOOST_CHECK(storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("fill()"), encodeArgs(8));
BOOST_CHECK(!storageEmpty(m_contractAddress));
ABI_CHECK(callContractFunction("clear()"), bytes());
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(array_copy_storage_storage_dyn_dyn)
@@ -3268,20 +3027,24 @@ BOOST_AUTO_TEST_CASE(array_copy_storage_abi)
}
}
)";
compileAndRun(sourceCode);
bytes valueSequence;
for (size_t i = 0; i < 101; ++i)
valueSequence += toBigEndian(u256(i));
ABI_CHECK(callContractFunction("test1()"), encodeArgs(0x20, 101) + valueSequence);
ABI_CHECK(callContractFunction("test2()"), encodeArgs(0x20, 101) + valueSequence);
ABI_CHECK(callContractFunction("test3()"), encodeArgs(0x20, 101) + valueSequence);
ABI_CHECK(callContractFunction("test4()"),
encodeArgs(0x20, 5, 0xa0, 0xa0 + 102 * 32 * 1, 0xa0 + 102 * 32 * 2, 0xa0 + 102 * 32 * 3, 0xa0 + 102 * 32 * 4) +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
bytes valueSequence;
for (size_t i = 0; i < 101; ++i)
valueSequence += toBigEndian(u256(i));
ABI_CHECK(callContractFunction("test1()"), encodeArgs(0x20, 101) + valueSequence);
ABI_CHECK(callContractFunction("test2()"), encodeArgs(0x20, 101) + valueSequence);
ABI_CHECK(callContractFunction("test3()"), encodeArgs(0x20, 101) + valueSequence);
ABI_CHECK(callContractFunction("test4()"),
encodeArgs(0x20, 5, 0xa0, 0xa0 + 102 * 32 * 1, 0xa0 + 102 * 32 * 2, 0xa0 + 102 * 32 * 3, 0xa0 + 102 * 32 * 4) +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence +
encodeArgs(101) + valueSequence
);
);
}
@@ -3307,9 +3070,12 @@ BOOST_AUTO_TEST_CASE(array_pop_uint16_transition)
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs(38, 28, 18));
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs(38, 28, 18));
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(array_pop_uint24_transition)
@@ -3334,9 +3100,12 @@ BOOST_AUTO_TEST_CASE(array_pop_uint24_transition)
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs(20, 10));
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs(20, 10));
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(array_pop_array_transition)
@@ -3382,9 +3151,12 @@ BOOST_AUTO_TEST_CASE(array_pop_storage_empty)
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs());
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs());
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(byte_array_pop_storage_empty)
@@ -3402,9 +3174,12 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_storage_empty)
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs());
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs());
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(byte_array_pop_long_storage_empty)
@@ -3427,9 +3202,12 @@ BOOST_AUTO_TEST_CASE(byte_array_pop_long_storage_empty)
}
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs(true));
BOOST_CHECK(storageEmpty(m_contractAddress));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("test()"), encodeArgs(true));
BOOST_CHECK(storageEmpty(m_contractAddress));
);
}
BOOST_AUTO_TEST_CASE(byte_array_pop_long_storage_empty_garbage_ref)
@@ -3505,15 +3283,19 @@ BOOST_AUTO_TEST_CASE(bytes_index_access)
}
}
)";
compileAndRun(sourceCode);
string array{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
30, 31, 32, 33};
ABI_CHECK(callContractFunction("direct(bytes,uint256)", 64, 33, u256(array.length()), array), encodeArgs(33));
ABI_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", 64, 33, u256(array.length()), array), encodeArgs(33));
ABI_CHECK(callContractFunction("storageWrite()"), encodeArgs(0x193));
ALSO_VIA_YUL(
DISABLE_EWASM_TESTRUN()
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("direct(bytes,uint256)", 64, 33, u256(array.length()), array), encodeArgs(33));
ABI_CHECK(callContractFunction("storageCopyRead(bytes,uint256)", 64, 33, u256(array.length()), array), encodeArgs(33));
ABI_CHECK(callContractFunction("storageWrite()"), encodeArgs(0x193));
);
}
BOOST_AUTO_TEST_CASE(array_copy_calldata_storage)
+19 -15
View File
@@ -27,6 +27,7 @@
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/analysis/NameAndTypeResolver.h>
#include <libsolidity/analysis/Scoper.h>
#include <libsolidity/analysis/SyntaxChecker.h>
#include <libsolidity/analysis/DeclarationTypeChecker.h>
#include <libsolidity/codegen/CompilerContext.h>
#include <libsolidity/codegen/ExpressionCompiler.h>
@@ -93,18 +94,20 @@ Declaration const& resolveDeclaration(
}
bytes compileFirstExpression(
const string& _sourceCode,
string const& _sourceCode,
vector<vector<string>> _functions = {},
vector<vector<string>> _localVariables = {}
)
{
string sourceCode = "pragma solidity >=0.0; // SPDX-License-Identifier: GPL-3\n" + _sourceCode;
ASTPointer<SourceUnit> sourceUnit;
try
{
ErrorList errors;
ErrorReporter errorReporter(errors);
sourceUnit = Parser(errorReporter, solidity::test::CommonOptions::get().evmVersion()).parse(
make_shared<Scanner>(CharStream(_sourceCode, ""))
make_shared<Scanner>(CharStream(sourceCode, ""))
);
if (!sourceUnit)
return bytes();
@@ -119,6 +122,7 @@ bytes compileFirstExpression(
ErrorReporter errorReporter(errors);
GlobalContext globalContext;
Scoper::assignScopes(*sourceUnit);
BOOST_REQUIRE(SyntaxChecker(errorReporter, false).checkSyntax(*sourceUnit));
NameAndTypeResolver resolver(globalContext, solidity::test::CommonOptions::get().evmVersion(), errorReporter);
resolver.registerDeclarations(*sourceUnit);
BOOST_REQUIRE_MESSAGE(resolver.resolveNamesAndTypes(*sourceUnit), "Resolving names failed");
@@ -187,7 +191,7 @@ BOOST_AUTO_TEST_CASE(literal_false)
{
char const* sourceCode = R"(
contract test {
function f() { bool x = false; }
function f() public { bool x = false; }
}
)";
bytes code = compileFirstExpression(sourceCode);
@@ -200,7 +204,7 @@ BOOST_AUTO_TEST_CASE(int_literal)
{
char const* sourceCode = R"(
contract test {
function f() { uint x = 0x12345678901234567890; }
function f() public { uint x = 0x12345678901234567890; }
}
)";
bytes code = compileFirstExpression(sourceCode);
@@ -229,7 +233,7 @@ BOOST_AUTO_TEST_CASE(int_with_gwei_ether_subdenomination)
{
char const* sourceCode = R"(
contract test {
function test () {
function f() public {
uint x = 1 gwei;
}
}
@@ -259,7 +263,7 @@ BOOST_AUTO_TEST_CASE(comparison)
{
char const* sourceCode = R"(
contract test {
function f() { bool x = (0x10aa < 0x11aa) != true; }
function f() public { bool x = (0x10aa < 0x11aa) != true; }
}
)";
bytes code = compileFirstExpression(sourceCode);
@@ -291,7 +295,7 @@ BOOST_AUTO_TEST_CASE(short_circuiting)
{
char const* sourceCode = R"(
contract test {
function f() { bool x = true != (4 <= 8 + 10 || 9 != 2); }
function f() public { bool x = true != (4 <= 8 + 10 || 9 != 2); }
}
)";
bytes code = compileFirstExpression(sourceCode);
@@ -322,7 +326,7 @@ BOOST_AUTO_TEST_CASE(arithmetic)
{
char const* sourceCode = R"(
contract test {
function f(uint y) { unchecked { ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); } }
function f(uint y) public { unchecked { ((((((((y ^ 8) & 7) | 6) - 5) + 4) % 3) / 2) * 1); } }
}
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
@@ -418,7 +422,7 @@ BOOST_AUTO_TEST_CASE(unary_operators)
{
char const* sourceCode = R"(
contract test {
function f(int y) { unchecked { !(~- y == 2); } }
function f(int y) public { unchecked { !(~- y == 2); } }
}
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "y"}});
@@ -508,7 +512,7 @@ BOOST_AUTO_TEST_CASE(assignment)
{
char const* sourceCode = R"(
contract test {
function f(uint a, uint b) { unchecked { (a += b) * 2; } }
function f(uint a, uint b) public { unchecked { (a += b) * 2; } }
}
)";
bytes code = compileFirstExpression(sourceCode, {}, {{"test", "f", "a"}, {"test", "f", "b"}});
@@ -546,7 +550,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_8bits)
{
char const* sourceCode = R"(
contract test {
function f() { int8 x = -0x80; }
function f() public { int8 x = -0x80; }
}
)";
bytes code = compileFirstExpression(sourceCode);
@@ -559,7 +563,7 @@ BOOST_AUTO_TEST_CASE(negative_literals_16bits)
{
char const* sourceCode = R"(
contract test {
function f() { int64 x = ~0xabc; }
function f() public { int64 x = ~0xabc; }
}
)";
bytes code = compileFirstExpression(sourceCode);
@@ -574,7 +578,7 @@ BOOST_AUTO_TEST_CASE(intermediately_overflowing_literals)
// have been applied
char const* sourceCode = R"(
contract test {
function f() { uint8 x = (0x00ffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }
function f() public { uint8 x = (0x00ffffffffffffffffffffffffffffffffffffffff * 0xffffffffffffffffffffffffff01) & 0xbf; }
}
)";
bytes code = compileFirstExpression(sourceCode);
@@ -587,7 +591,7 @@ BOOST_AUTO_TEST_CASE(blockhash)
{
char const* sourceCode = R"(
contract test {
function f() {
function f() public {
blockhash(3);
}
}
@@ -619,7 +623,7 @@ BOOST_AUTO_TEST_CASE(selfbalance)
{
char const* sourceCode = R"(
contract test {
function f() returns (uint) {
function f() public returns (uint) {
return address(this).balance;
}
}
@@ -20,5 +20,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x20, 0x8, 0x40, 0x3, 0x9, 0xa, 0xb
@@ -0,0 +1,16 @@
contract C {
function f(uint a, bytes memory b, uint c)
public pure returns (uint, uint, byte, uint) {
return (a, b.length, b[3], c);
}
function f_external(uint a, bytes calldata b, uint c)
external pure returns (uint, uint, byte, uint) {
return (a, b.length, b[3], c);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9
// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9
@@ -0,0 +1,10 @@
contract C {
function f(uint a, uint16[] memory b, uint c)
public pure returns (uint, uint, uint) {
return (b.length, b[a], c);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9
@@ -0,0 +1,13 @@
contract C {
enum E { A, B }
function f(E e) public pure returns (uint x) {
assembly { x := e }
}
}
// ====
// ABIEncoderV1Only: true
// ----
// f(uint8): 0 -> 0
// f(uint8): 1 -> 1
// f(uint8): 2 -> 2
// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> 0xff
@@ -0,0 +1,18 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint a, bytes memory b, uint c)
public pure returns (uint, uint, byte, uint) {
return (a, b.length, b[3], c);
}
function f_external(uint a, bytes calldata b, uint c)
external pure returns (uint, uint, byte, uint) {
return (a, b.length, b[3], c);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9
// f_external(uint256,bytes,uint256): 6, 0x60, 9, 7, "abcdefg" -> 6, 7, "d", 9
@@ -41,6 +41,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >homestead
// ----
// g() -> 32, 132, hex"15cfcc01", 32, 32, 1, 42, hex"00000000000000000000000000000000000000000000000000000000"
@@ -0,0 +1,12 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint a, uint16[] memory b, uint c)
public pure returns (uint, uint, uint) {
return (b.length, b[a], c);
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,uint16[],uint256): 6, 0x60, 9, 7, 11, 12, 13, 14, 15, 16, 17 -> 7, 17, 9
@@ -0,0 +1,32 @@
pragma experimental ABIEncoderV2;
contract C {
function f(uint a, uint16[][] memory b, uint[2][][3] memory c, uint d)
public pure returns (uint, uint, uint, uint, uint, uint, uint) {
return (a, b.length, b[1].length, b[1][1], c[1].length, c[1][1][1], d);
}
function test() public view returns (uint, uint, uint, uint, uint, uint, uint) {
uint16[][] memory b = new uint16[][](3);
b[0] = new uint16[](2);
b[0][0] = 0x55;
b[0][1] = 0x56;
b[1] = new uint16[](4);
b[1][0] = 0x65;
b[1][1] = 0x66;
b[1][2] = 0x67;
b[1][3] = 0x68;
uint[2][][3] memory c;
c[0] = new uint[2][](1);
c[0][0][1] = 0x75;
c[1] = new uint[2][](5);
c[1][1][1] = 0x85;
return this.f(12, b, c, 13);
}
}
// ====
// compileViaYul: also
// ----
// test() -> 12, 3, 4, 0x66, 5, 0x85, 13
// f(uint256,uint16[][],uint256[2][][3],uint256): 12, 0x80, 0x220, 13, 3, 0x60, 0xC0, 0x160, 2, 85, 86, 4, 101, 102, 103, 104, 0, 0x60, 0xC0, 0x220, 1, 0, 117, 5, 0, 0, 0, 133, 0, 0, 0, 0, 0, 0, 0 -> 12, 3, 4, 0x66, 5, 0x85, 13
@@ -0,0 +1,15 @@
pragma experimental ABIEncoderV2;
contract C {
enum E { A, B }
function f(E e) public pure returns (uint x) {
assembly { x := e }
}
}
// ====
// compileViaYul: also
// ----
// f(uint8): 0 -> 0
// f(uint8): 1 -> 1
// f(uint8): 2 -> FAILURE
// f(uint8): 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff -> FAILURE
@@ -7,5 +7,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 0x80, 0x21, 0x40, 0x7, "abcdefg" -> 0x21, 0x40, 0x7, "abcdefg"
@@ -14,5 +14,7 @@ contract c {
uint8(data[97]) == 97;
}
}
// ====
// compileViaYul: also
// ----
// test1() -> true
@@ -10,6 +10,8 @@ contract c {
bytes data;
}
// ====
// compileViaYul: also
// ----
// getLength() -> 0
// set(): 1, 2 -> true
@@ -6,5 +6,7 @@ contract C {
return s[0];
}
}
// ====
// compileViaYul: also
// ----
// f() -> "a"
@@ -5,5 +5,7 @@ contract C {
return s[0];
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 0x08, "abcdefgh" -> "a"
@@ -0,0 +1,42 @@
pragma experimental ABIEncoderV2;
struct S {
uint16 x;
bytes a;
uint16 y;
bytes b;
}
contract C {
uint padding;
S data;
function f() public returns (bytes memory, bytes memory) {
S memory x;
x.x = 7;
x.b = "1234567890123456789012345678901 1234567890123456789012345678901 123456789";
x.a = "abcdef";
x.y = 9;
data = x;
return (data.a, data.b);
}
function g() public returns (bytes memory, bytes memory) {
S memory x;
x.x = 7;
x.b = "12345678923456789";
x.a = "1234567890123456789012345678901 1234567890123456789012345678901 123456789";
x.y = 9;
data = x;
return (data.a, data.b);
}
function h() public returns (bytes memory, bytes memory) {
S memory x;
data = x;
return (data.a, data.b);
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0x40, 0x80, 6, 0x6162636465660000000000000000000000000000000000000000000000000000, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000
// g() -> 0x40, 0xc0, 0x49, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738393031323334353637383930313233343536373839303120, 0x3132333435363738390000000000000000000000000000000000000000000000, 0x11, 0x3132333435363738393233343536373839000000000000000000000000000000
// h() -> 0x40, 0x60, 0x00, 0x00
// storage: empty
@@ -0,0 +1,50 @@
function dataslot() pure returns (bytes32) {
return keccak256(abi.encode(1));
}
function readDataSlot(uint offset) view returns (bytes32 r) {
bytes32 s = dataslot();
assembly { r := sload(add(s, offset)) }
}
function readDataSlot() view returns (bytes32) {
return readDataSlot(0);
}
function readHead() view returns (bytes32 r) {
assembly { r := sload(1) }
}
contract C {
uint padding;
bytes data;
function f() public returns (uint) {
bytes32 zero;
if (!(readDataSlot() == zero)) return 1;
data = "abc";
if (!(readDataSlot() == zero)) return 2;
data = "1234567890123456789012345678901234567890123456789012345678901234567890";
if (!(readDataSlot() != zero)) return 3;
if (!(readDataSlot(1) != zero)) return 4;
if (!(readDataSlot(2) != zero)) return 5;
if (!(readDataSlot(3) == zero)) return 6;
if (!(readDataSlot(4) == zero)) return 7;
data = "abc";
if (!(readDataSlot() == zero)) return 8;
if (!(readDataSlot(1) == zero)) return 9;
if (!(readDataSlot(2) == zero)) return 10;
if (!(readDataSlot(3) == zero)) return 11;
data = "1234567890123456789012345678901234567890123456789012345678901234567890";
data = "123456789012345678901234567890123456";
if (!(readDataSlot() != zero)) return 12;
if (!(readDataSlot(1) != zero)) return 13;
if (!(readDataSlot(2) == zero)) return 14;
if (!(readDataSlot(3) == zero)) return 15;
return 0xff;
}
}
// ====
// compileViaYul: also
// ----
// f() -> 0xff
@@ -17,6 +17,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// one() -> 3
// two() -> FAILURE, hex"4e487b71", 0x51
@@ -5,6 +5,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f(uint256): 0 -> 0x20, 0x4, "This"
// f(uint256): 1 -> 0x20, 0x2, "is"
@@ -13,5 +13,7 @@ contract C {
return this.h(a);
}
}
// ====
// compileViaYul: also
// ----
// g() -> 0x0700000000000000000000000000000000000000000000000000000000000000
@@ -16,6 +16,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// use(uint256): 3 -> 6
// result_in_constructor() -> 4
@@ -0,0 +1,25 @@
contract C {
uint16 public result_in_constructor;
function(uint16) returns (uint16) internal x;
uint16 public other = 0x1fff;
constructor() {
x = doubleInv;
result_in_constructor = use(2);
}
function doubleInv(uint16 _arg) public returns (uint16 _ret) {
_ret = ~(_arg * 2);
}
function use(uint16 _arg) public returns (uint16) {
return x(_arg);
}
}
// ====
// compileViaYul: also
// ----
// use(uint16): 3 -> 0xfff9
// result_in_constructor() -> 0xfffb
// other() -> 0x1fff
@@ -14,5 +14,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// t() -> 7
@@ -17,5 +17,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// t() -> 7
@@ -0,0 +1,13 @@
contract test {
function f() public returns(uint ret) {
ret = 1;
for (;;) {
ret += 1;
if (ret >= 10) break;
}
}
}
// ====
// compileViaYul: also
// ----
// f() -> 10
@@ -0,0 +1,22 @@
contract collatz {
function run(uint x) public returns(uint y) {
while ((y = x) > 1) {
if (x % 2 == 0) x = evenStep(x);
else x = oddStep(x);
}
}
function evenStep(uint x) public returns(uint y) {
return x / 2;
}
function oddStep(uint x) public returns(uint y) {
return 3 * x + 1;
}
}
// ====
// compileViaYul: also
// ----
// run(uint256): 0 -> 0
// run(uint256): 1 -> 1
// run(uint256): 2 -> 1
// run(uint256): 8 -> 1
// run(uint256): 127 -> 1
@@ -16,5 +16,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// t() -> FAILURE, hex"4e487b71", 0x51
@@ -20,6 +20,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// set() -> 7
// ca() -> 7
@@ -6,5 +6,7 @@ contract C {
return [this.f, this.g][0]{value: 1}();
}
}
// ====
// compileViaYul: also
// ----
// h(), 1 ether -> 1
@@ -25,6 +25,8 @@ contract Flow {
}
}
// ====
// compileViaYul: also
// ----
// success() -> false
// f() -> 7
@@ -11,5 +11,7 @@ contract C {
return x + 1;
}
}
// ====
// compileViaYul: also
// ----
// f(uint256): 7 -> 8
@@ -14,5 +14,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// test() -> true
@@ -0,0 +1,34 @@
struct S {
uint16 a;
function() returns (uint) x;
uint16 b;
}
contract Flow {
S[2] t;
function X() internal pure returns (uint) {
return 1;
}
function Y() internal pure returns (uint) {
return 2;
}
constructor() {
t[0].a = 0xff07;
t[0].b = 0xff07;
t[1].x = Y;
t[1].a = 0xff07;
t[1].b = 0xff07;
t[0].x = X;
}
function f() public returns (uint, uint) {
return (t[0].x(), t[1].x());
}
}
// ====
// compileViaYul: also
// ----
// f() -> 1, 2
@@ -7,5 +7,7 @@ contract Test {
}
}
// ====
// compileViaYul: also
// ----
// f() -> FAILURE, hex"4e487b71", 0x51
@@ -0,0 +1,11 @@
contract test {
function run(uint x1, uint x2, uint x3) public returns(uint y) {
uint8 a = 0x1; uint8 b = 0x10; uint16 c = 0x100;
y = a + b + c + x1 + x2 + x3;
y += b + x2;
}
}
// ====
// compileViaYul: also
// ----
// run(uint256,uint256,uint256): 0x1000, 0x10000, 0x100000 -> 0x121121
@@ -0,0 +1,9 @@
contract test {
function run() public returns(int256 y) {
return -int32(10) * -int64(20);
}
}
// ====
// compileViaYul: also
// ----
// run() -> 200
@@ -29,6 +29,8 @@ contract Homer is ERC165, Simpson {
}
}
// ====
// compileViaYul: also
// ----
// supportsInterface(bytes4): left(0x01ffc9a0) -> false
// supportsInterface(bytes4): left(0x01ffc9a7) -> true
@@ -40,6 +40,8 @@ contract Lisa is ERC165MappingImplementation, Simpson {
}
}
// ====
// compileViaYul: also
// ----
// supportsInterface(bytes4): left(0x01ffc9a0) -> false
// supportsInterface(bytes4): left(0x01ffc9a7) -> true
@@ -14,6 +14,8 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// g() -> 2
// h() -> FAILURE, hex"4e487b71", 0x51
@@ -0,0 +1,22 @@
contract test {
uint value1;
uint value2;
function f(uint x, uint y) public returns (uint w) {
uint value3 = y;
value1 += x;
value3 *= x;
value2 *= value3 + value1;
return value2 += 7;
}
}
// ====
// compileViaYul: also
// ----
// f(uint256,uint256): 0, 6 -> 7
// f(uint256,uint256): 1, 3 -> 0x23
// f(uint256,uint256): 2, 25 -> 0x0746
// f(uint256,uint256): 3, 69 -> 396613
// f(uint256,uint256): 4, 84 -> 137228105
// f(uint256,uint256): 5, 2 -> 0xcc7c5e28
// f(uint256,uint256): 6, 51 -> 1121839760671
// f(uint256,uint256): 7, 48 -> 408349672884251
@@ -17,6 +17,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// EVMVersion: >=byzantium
// ----
// test_store_ok() -> 1
@@ -18,6 +18,8 @@ contract D {
return (stateBool, stateDecimal, stateBytes);
}
}
// ====
// compileViaYul: also
// ----
// stateBool() -> true
// stateBool() -> right(true)
@@ -32,6 +32,8 @@ contract C {
return (["any", "any"], ["any", "any", "any"]);
}
}
// ====
// compileViaYul: also
// ----
// r() -> true, false, true
// s() -> 123, 456, 789
@@ -41,4 +43,3 @@ contract C {
// w2() -> 0x20, 0x40, 0x80, 3, "any", 3, "any"
// w3() -> 0x20, 0x60, 0xa0, 0xe0, 3, "any", 3, "any", 3, "any"
// x() -> 0x40, 0x0100, 0x40, 0x80, 3, "any", 3, "any", 0x60, 0xa0, 0xe0, 3, "any", 3, "any", 3, "any"
@@ -2,6 +2,8 @@ contract Test {
bytes x;
function set(bytes memory _a) public { x = _a; }
}
// ====
// compileViaYul: also
// ----
// set(bytes): 0x20, 3, "abc"
// storage: nonempty
@@ -0,0 +1,46 @@
contract Ballot {
mapping(address => bool) canVote;
mapping(address => uint) voteCount;
mapping(address => bool) voted;
function getVoteCount(address addr) public returns (uint retVoteCount) {
return voteCount[addr];
}
function grantVoteRight(address addr) public {
canVote[addr] = true;
}
function vote(address voter, address vote) public returns (bool success) {
if (!canVote[voter] || voted[voter]) return false;
voted[voter] = true;
voteCount[vote] = voteCount[vote] + 1;
return true;
}
}
// ====
// compileViaYul: also
// ----
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 0
// vote(address,address): 0, 2 -> false
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 0
// grantVoteRight(address): 0 ->
// grantVoteRight(address): 1 ->
// vote(address,address): 0, 2 -> true
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 1
// vote(address,address): 0, 1 -> false
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 1
// vote(address,address): 2, 1 -> false
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 0
// getVoteCount(address): 2 -> 1
// grantVoteRight(address): 2 ->
// vote(address,address): 2, 1 -> true
// getVoteCount(address): 0 -> 0
// getVoteCount(address): 1 -> 1
// getVoteCount(address): 2 -> 1
@@ -8,5 +8,7 @@ contract Test {
assert(val[0].vals.length == 42);
}
}
// -----
// ====
// compileViaYul: also
// ----
// func() ->
@@ -35,5 +35,7 @@ contract InvalidTest {
x++;
}
}
// ====
// compileViaYul: also
// ----
// run() -> FAILURE, hex"4e487b71", 0x51
@@ -14,6 +14,8 @@ contract InvalidTest {
storedFn();
}
}
// ====
// compileViaYul: also
// ----
// f() -> FAILURE, hex"4e487b71", 0x51
// f() -> FAILURE, hex"4e487b71", 0x51
@@ -32,5 +32,7 @@ contract C {
}
}
// ====
// compileViaYul: also
// ----
// f(bytes): 0x20, 0x5, "abcde" -> 0
@@ -19,5 +19,7 @@ contract C {
return (a, b);
}
}
// ====
// compileViaYul: also
// ----
// g() -> 5, 6
@@ -8,6 +8,8 @@ contract C {
bytes savedData;
}
// ====
// compileViaYul: also
// ----
// save() -> 24 # empty copy loop #
// save(): "abcdefg" -> 24
@@ -8,4 +8,4 @@ contract C {
}
}
// ----
// Warning 2529: (82-89): CHC: Empty array "pop" detected here.
// Warning 2529: (82-89): CHC: Empty array "pop" happens here.
@@ -8,4 +8,4 @@ contract C {
}
}
// ----
// Warning 2529: (82-89): CHC: Empty array "pop" detected here.
// Warning 2529: (82-89): CHC: Empty array "pop" happens here.
@@ -8,5 +8,5 @@ contract C {
}
}
// ----
// Warning 2529: (82-89): CHC: Empty array "pop" detected here.
// Warning 2529: (93-100): CHC: Empty array "pop" detected here.
// Warning 2529: (82-89): CHC: Empty array "pop" happens here.
// Warning 2529: (93-100): CHC: Empty array "pop" happens here.
@@ -8,4 +8,4 @@ contract C {
}
}
// ----
// Warning 2529: (94-101): CHC: Empty array "pop" detected here.
// Warning 2529: (94-101): CHC: Empty array "pop" happens here.
@@ -11,4 +11,4 @@ contract C {
}
}
// ----
// Warning 2529: (122-129): CHC: Empty array "pop" detected here.
// Warning 2529: (122-129): CHC: Empty array "pop" happens here.
@@ -11,4 +11,4 @@ contract C {
}
}
// ----
// Warning 2529: (127-134): CHC: Empty array "pop" detected here.
// Warning 2529: (127-134): CHC: Empty array "pop" happens here.

Some files were not shown because too many files have changed in this diff Show More