From 8e02768b104b563fe28a1b70894f7f910b3124fb Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 5 Nov 2014 18:37:27 +0100 Subject: [PATCH 1/2] Tests for break and continue in nested loops. --- test/solidityEndToEndTest.cpp | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index b28b8499a..7b9e07384 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -151,6 +151,42 @@ BOOST_AUTO_TEST_CASE(while_loop) BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(24))); } +BOOST_AUTO_TEST_CASE(nested_loops) +{ + // tests that break and continue statements in nested loops jump to the correct place + char const* sourceCode = "contract test {\n" + " function f(uint x) returns(uint y) {\n" + " while (x > 1) {\n" + " if (x == 10) break;\n" + " while (x > 5) {\n" + " if (x == 8) break;\n" + " x--;\n" + " if (x == 6) continue;\n" + " return x;\n" + " }\n" + " x--;\n" + " if (x == 3) continue;\n" + " break;\n" + " }\n" + " return x;\n" + " }\n" + "}\n"; + ExecutionFramework framework; + framework.compileAndRun(sourceCode); + BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(0))); + BOOST_CHECK(framework.callFunction(0, u256(1)) == toBigEndian(u256(1))); + BOOST_CHECK(framework.callFunction(0, u256(2)) == toBigEndian(u256(1))); + BOOST_CHECK(framework.callFunction(0, u256(3)) == toBigEndian(u256(2))); + BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(2))); + BOOST_CHECK(framework.callFunction(0, u256(5)) == toBigEndian(u256(4))); + BOOST_CHECK(framework.callFunction(0, u256(6)) == toBigEndian(u256(5))); + BOOST_CHECK(framework.callFunction(0, u256(7)) == toBigEndian(u256(5))); + BOOST_CHECK(framework.callFunction(0, u256(8)) == toBigEndian(u256(7))); + BOOST_CHECK(framework.callFunction(0, u256(9)) == toBigEndian(u256(8))); + BOOST_CHECK(framework.callFunction(0, u256(10)) == toBigEndian(u256(10))); + BOOST_CHECK(framework.callFunction(0, u256(11)) == toBigEndian(u256(10))); +} + BOOST_AUTO_TEST_CASE(calling_other_functions) { // note that the index of a function is its index in the sorted sequence of functions From c87f1c76b4f36d816bc84eb5e0830a7855468b16 Mon Sep 17 00:00:00 2001 From: Christian Date: Wed, 5 Nov 2014 18:44:05 +0100 Subject: [PATCH 2/2] Ignore break and continue outside of loops. --- libsolidity/Compiler.cpp | 10 ++++------ test/solidityEndToEndTest.cpp | 13 +++++++++++++ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index 654eceadb..d05552b9e 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -252,17 +252,15 @@ bool Compiler::visit(WhileStatement& _whileStatement) bool Compiler::visit(Continue&) { - if (asserts(!m_continueTags.empty())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Jump tag not available for \"continue\".")); - m_context.appendJumpTo(m_continueTags.back()); + if (!m_continueTags.empty()) + m_context.appendJumpTo(m_continueTags.back()); return false; } bool Compiler::visit(Break&) { - if (asserts(!m_breakTags.empty())) - BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Jump tag not available for \"break\".")); - m_context.appendJumpTo(m_breakTags.back()); + if (!m_breakTags.empty()) + m_context.appendJumpTo(m_breakTags.back()); return false; } diff --git a/test/solidityEndToEndTest.cpp b/test/solidityEndToEndTest.cpp index 7b9e07384..116310aed 100644 --- a/test/solidityEndToEndTest.cpp +++ b/test/solidityEndToEndTest.cpp @@ -151,6 +151,19 @@ BOOST_AUTO_TEST_CASE(while_loop) BOOST_CHECK(framework.callFunction(0, u256(4)) == toBigEndian(u256(24))); } +BOOST_AUTO_TEST_CASE(break_outside_loop) +{ + // break and continue outside loops should be simply ignored + char const* sourceCode = "contract test {\n" + " function f(uint x) returns(uint y) {\n" + " break; continue; return 2;\n" + " }\n" + "}\n"; + ExecutionFramework framework; + framework.compileAndRun(sourceCode); + BOOST_CHECK(framework.callFunction(0, u256(0)) == toBigEndian(u256(2))); +} + BOOST_AUTO_TEST_CASE(nested_loops) { // tests that break and continue statements in nested loops jump to the correct place