check whether break/continue is in the loop

This commit is contained in:
Lu Guanqun
2016-01-15 15:12:23 +08:00
parent 02c1aacd25
commit e130bc7e7c
8 changed files with 187 additions and 12 deletions
-12
View File
@@ -166,18 +166,6 @@ BOOST_AUTO_TEST_CASE(while_loop)
testSolidityAgainstCppOnRange("f(uint256)", while_loop_cpp, 0, 5);
}
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";
compileAndRun(sourceCode);
testSolidityAgainstCpp("f(uint256)", [](u256 const&) -> u256 { return 2; }, u256(0));
}
BOOST_AUTO_TEST_CASE(nested_loops)
{
// tests that break and continue statements in nested loops jump to the correct place
@@ -27,6 +27,7 @@
#include <libsolidity/parsing/Scanner.h>
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/analysis/NameAndTypeResolver.h>
#include <libsolidity/analysis/SyntaxChecker.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/analysis/GlobalContext.h>
#include <libsolidity/analysis/TypeChecker.h>
@@ -57,6 +58,10 @@ parseAnalyseAndReturnError(string const& _source, bool _reportWarnings = false)
if(!sourceUnit)
return make_pair(sourceUnit, nullptr);
SyntaxChecker syntaxChecker(errors);
if (!syntaxChecker.checkSyntax(*sourceUnit))
return make_pair(sourceUnit, std::make_shared<Error::Type const>(errors[0]->type()));
std::shared_ptr<GlobalContext> globalContext = make_shared<GlobalContext>();
NameAndTypeResolver resolver(globalContext->declarations(), errors);
solAssert(Error::containsOnlyWarnings(errors), "");
@@ -2903,6 +2908,32 @@ BOOST_AUTO_TEST_CASE(lvalues_as_inline_array)
BOOST_CHECK(expectError(text) == Error::Type::TypeError);
}
BOOST_AUTO_TEST_CASE(break_not_in_loop)
{
char const* text = R"(
contract C {
function f() {
if (true)
break;
}
}
)";
BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
}
BOOST_AUTO_TEST_CASE(continue_not_in_loop)
{
char const* text = R"(
contract C {
function f() {
if (true)
continue;
}
}
)";
BOOST_CHECK(expectError(text) == Error::Type::SyntaxError);
}
BOOST_AUTO_TEST_SUITE_END()
}