mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Add more tests and assertions
This commit is contained in:
parent
9d895e002d
commit
b750ca9741
@ -127,6 +127,8 @@ void CompilerContext::addVariable(VariableDeclaration const& _declaration,
|
||||
unsigned _offsetToCurrent)
|
||||
{
|
||||
solAssert(m_asm->deposit() >= 0 && unsigned(m_asm->deposit()) >= _offsetToCurrent, "");
|
||||
unsigned sizeOnStack = _declaration.annotation().type->sizeOnStack();
|
||||
solAssert(sizeOnStack == 1 || sizeOnStack == 2, "");
|
||||
m_localVariables[&_declaration].push_back(unsigned(m_asm->deposit()) - _offsetToCurrent);
|
||||
}
|
||||
|
||||
|
@ -1172,6 +1172,7 @@ void CompilerUtils::popStackSlots(size_t _amount)
|
||||
|
||||
void CompilerUtils::popAndJump(unsigned _toHeight, eth::AssemblyItem const& _jumpTo)
|
||||
{
|
||||
solAssert(m_context.stackHeight() >= _toHeight, "");
|
||||
unsigned amount = m_context.stackHeight() - _toHeight;
|
||||
popStackSlots(amount);
|
||||
m_context.appendJumpTo(_jumpTo);
|
||||
|
@ -999,6 +999,7 @@ eth::AssemblyPointer ContractCompiler::cloneRuntime() const
|
||||
void ContractCompiler::popScopedVariables(ASTNode const* _node)
|
||||
{
|
||||
unsigned blockHeight = m_scopeStackHeight.at(m_modifierDepth).at(_node);
|
||||
solAssert(m_context.stackHeight() >= blockHeight, "");
|
||||
unsigned stackDiff = m_context.stackHeight() - blockHeight;
|
||||
CompilerUtils(m_context).popStackSlots(stackDiff);
|
||||
m_context.removeVariablesAboveStackHeight(blockHeight);
|
||||
|
@ -523,6 +523,45 @@ BOOST_AUTO_TEST_CASE(do_while_loop_continue)
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs(42));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(array_multiple_local_vars)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function f(uint256[] seq) public pure returns (uint256) {
|
||||
uint i = 0;
|
||||
uint sum = 0;
|
||||
while (i < seq.length)
|
||||
{
|
||||
uint idx = i;
|
||||
if (idx >= 10) break;
|
||||
uint x = seq[idx];
|
||||
if (x >= 1000) {
|
||||
uint n = i + 1;
|
||||
i = n;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
uint y = sum + x;
|
||||
sum = y;
|
||||
}
|
||||
if (sum >= 500) return sum;
|
||||
i++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
ABI_CHECK(callContractFunction("f(uint256[])", 32, 3, u256(1000), u256(1), u256(2)), encodeArgs(3));
|
||||
ABI_CHECK(callContractFunction("f(uint256[])", 32, 3, u256(100), u256(500), u256(300)), encodeArgs(600));
|
||||
ABI_CHECK(callContractFunction(
|
||||
"f(uint256[])", 32, 11,
|
||||
u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8), u256(9), u256(10), u256(111)
|
||||
), encodeArgs(55));
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE(do_while_loop_multiple_local_vars)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
@ -628,21 +667,30 @@ BOOST_AUTO_TEST_CASE(nested_loops)
|
||||
BOOST_AUTO_TEST_CASE(nested_loops_multiple_local_vars)
|
||||
{
|
||||
// tests that break and continue statements in nested loops jump to the correct place
|
||||
// and free local variables properly
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function f(uint x) returns(uint y) {
|
||||
while (x > 0) {
|
||||
uint z = x + 10;
|
||||
uint k = z + 1;
|
||||
if (k > 20) break;
|
||||
if (k > 20) {
|
||||
break;
|
||||
uint p = 100;
|
||||
k += p;
|
||||
}
|
||||
if (k > 15) {
|
||||
x--;
|
||||
continue;
|
||||
uint t = 1000;
|
||||
x += t;
|
||||
}
|
||||
while (k > 10) {
|
||||
uint m = k - 1;
|
||||
if (m == 10) return x;
|
||||
return k;
|
||||
uint h = 10000;
|
||||
z += h;
|
||||
}
|
||||
x--;
|
||||
break;
|
||||
@ -727,6 +775,66 @@ BOOST_AUTO_TEST_CASE(for_loop_multiple_local_vars)
|
||||
testContractAgainstCppOnRange("f(uint256)", for_loop, 0, 12);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(nested_for_loop_multiple_local_vars)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract test {
|
||||
function f(uint x) public pure returns(uint r) {
|
||||
for (uint i = 0; i < 5; i++)
|
||||
{
|
||||
uint z = x + 1;
|
||||
if (z < 3) {
|
||||
break;
|
||||
uint p = z + 2;
|
||||
}
|
||||
for (uint j = 0; j < 5; j++)
|
||||
{
|
||||
uint k = z * 2;
|
||||
if (j + k < 8) {
|
||||
x++;
|
||||
continue;
|
||||
uint t = z * 3;
|
||||
}
|
||||
x++;
|
||||
if (x > 20) {
|
||||
return 84;
|
||||
uint h = x + 42;
|
||||
}
|
||||
}
|
||||
if (x > 30) {
|
||||
return 42;
|
||||
uint b = 0xcafe;
|
||||
}
|
||||
}
|
||||
return 42;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
|
||||
auto for_loop = [](u256 n) -> u256
|
||||
{
|
||||
for (u256 i = 0; i < 5; i++)
|
||||
{
|
||||
u256 z = n + 1;
|
||||
if (z < 3) break;
|
||||
for (u256 j = 0; j < 5; j++)
|
||||
{
|
||||
u256 k = z * 2;
|
||||
if (j + k < 8) {
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
n++;
|
||||
if (n > 20) return 84;
|
||||
}
|
||||
if (n > 30) return 42;
|
||||
}
|
||||
return 42;
|
||||
};
|
||||
|
||||
testContractAgainstCppOnRange("f(uint256)", for_loop, 0, 12);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(for_loop)
|
||||
{
|
||||
@ -9396,6 +9504,50 @@ BOOST_AUTO_TEST_CASE(break_in_modifier)
|
||||
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(continue_in_modifier)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
uint public x;
|
||||
modifier run() {
|
||||
for (uint i = 0; i < 10; i++) {
|
||||
if (i % 2 == 1) continue;
|
||||
_;
|
||||
}
|
||||
}
|
||||
function f() run {
|
||||
x++;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(0)));
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs());
|
||||
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(5)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(return_in_modifier)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
contract C {
|
||||
uint public x;
|
||||
modifier run() {
|
||||
for (uint i = 1; i < 10; i++) {
|
||||
if (i == 5) return;
|
||||
_;
|
||||
}
|
||||
}
|
||||
function f() run {
|
||||
x++;
|
||||
}
|
||||
}
|
||||
)";
|
||||
compileAndRun(sourceCode, 0, "C");
|
||||
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(0)));
|
||||
ABI_CHECK(callContractFunction("f()"), encodeArgs());
|
||||
ABI_CHECK(callContractFunction("x()"), encodeArgs(u256(4)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(stacked_return_with_modifiers)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
|
Loading…
Reference in New Issue
Block a user