aboutsummaryrefslogtreecommitdiffstats
path: root/test/libsolidity/InlineAssembly.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-02-14 12:00:41 +0800
committerGitHub <noreply@github.com>2018-02-14 12:00:41 +0800
commit3155dd8058672ce8f04bc2c0f2536cb549067d0a (patch)
tree7ddb56e276c74db30671eb17ffdde5eda027142d /test/libsolidity/InlineAssembly.cpp
parentc4cbbb054b5ed3b8ceaa21ee5b47b0704762ff40 (diff)
parentef8292c6bb337d3c4b27836da6732b85021d1c5d (diff)
downloaddexon-solidity-3155dd8058672ce8f04bc2c0f2536cb549067d0a.tar
dexon-solidity-3155dd8058672ce8f04bc2c0f2536cb549067d0a.tar.gz
dexon-solidity-3155dd8058672ce8f04bc2c0f2536cb549067d0a.tar.bz2
dexon-solidity-3155dd8058672ce8f04bc2c0f2536cb549067d0a.tar.lz
dexon-solidity-3155dd8058672ce8f04bc2c0f2536cb549067d0a.tar.xz
dexon-solidity-3155dd8058672ce8f04bc2c0f2536cb549067d0a.tar.zst
dexon-solidity-3155dd8058672ce8f04bc2c0f2536cb549067d0a.zip
Merge pull request #3503 from ethereum/develop
Merge develop into release for v0.4.20.
Diffstat (limited to 'test/libsolidity/InlineAssembly.cpp')
-rw-r--r--test/libsolidity/InlineAssembly.cpp91
1 files changed, 76 insertions, 15 deletions
diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp
index e9fb8431..b09eb261 100644
--- a/test/libsolidity/InlineAssembly.cpp
+++ b/test/libsolidity/InlineAssembly.cpp
@@ -51,10 +51,11 @@ boost::optional<Error> parseAndReturnFirstError(
string const& _source,
bool _assemble = false,
bool _allowWarnings = true,
+ AssemblyStack::Language _language = AssemblyStack::Language::Assembly,
AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
)
{
- AssemblyStack stack;
+ AssemblyStack stack(_language);
bool success = false;
try
{
@@ -87,22 +88,29 @@ bool successParse(
string const& _source,
bool _assemble = false,
bool _allowWarnings = true,
+ AssemblyStack::Language _language = AssemblyStack::Language::Assembly,
AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
)
{
- return !parseAndReturnFirstError(_source, _assemble, _allowWarnings, _machine);
+ return !parseAndReturnFirstError(_source, _assemble, _allowWarnings, _language, _machine);
}
-bool successAssemble(string const& _source, bool _allowWarnings = true)
+bool successAssemble(string const& _source, bool _allowWarnings = true, AssemblyStack::Language _language = AssemblyStack::Language::Assembly)
{
- return successParse(_source, true, _allowWarnings, AssemblyStack::Machine::EVM) &&
- successParse(_source, true, _allowWarnings, AssemblyStack::Machine::EVM15);
+ return
+ successParse(_source, true, _allowWarnings, _language, AssemblyStack::Machine::EVM) &&
+ successParse(_source, true, _allowWarnings, _language, AssemblyStack::Machine::EVM15);
}
-Error expectError(std::string const& _source, bool _assemble, bool _allowWarnings = false)
+Error expectError(
+ std::string const& _source,
+ bool _assemble,
+ bool _allowWarnings = false,
+ AssemblyStack::Language _language = AssemblyStack::Language::Assembly
+)
{
- auto error = parseAndReturnFirstError(_source, _assemble, _allowWarnings);
+ auto error = parseAndReturnFirstError(_source, _assemble, _allowWarnings, _language);
BOOST_REQUIRE(error);
return *error;
}
@@ -120,14 +128,17 @@ void parsePrintCompare(string const& _source, bool _canWarn = false)
}
-#define CHECK_ERROR(text, assemble, typ, substring, warnings) \
+#define CHECK_ERROR_LANG(text, assemble, typ, substring, warnings, language) \
do \
{ \
- Error err = expectError((text), (assemble), warnings); \
+ Error err = expectError((text), (assemble), warnings, (language)); \
BOOST_CHECK(err.type() == (Error::Type::typ)); \
BOOST_CHECK(searchErrorMessage(err, (substring))); \
} while(0)
+#define CHECK_ERROR(text, assemble, typ, substring, warnings) \
+CHECK_ERROR_LANG(text, assemble, typ, substring, warnings, AssemblyStack::Language::Assembly)
+
#define CHECK_PARSE_ERROR(text, type, substring) \
CHECK_ERROR(text, false, type, substring, false)
@@ -137,6 +148,14 @@ CHECK_ERROR(text, false, type, substring, false)
#define CHECK_ASSEMBLE_ERROR(text, type, substring) \
CHECK_ERROR(text, true, type, substring, false)
+#define CHECK_STRICT_ERROR(text, type, substring) \
+CHECK_ERROR_LANG(text, false, type, substring, false, AssemblyStack::Language::StrictAssembly)
+
+#define CHECK_STRICT_WARNING(text, type, substring) \
+CHECK_ERROR(text, false, type, substring, false, AssemblyStack::Language::StrictAssembly)
+
+#define SUCCESS_STRICT(text) \
+do { successParse((text), false, false, AssemblyStack::Language::StrictAssembly); } while (false)
BOOST_AUTO_TEST_SUITE(SolidityInlineAssembly)
@@ -266,7 +285,7 @@ BOOST_AUTO_TEST_CASE(if_statement_scope)
BOOST_AUTO_TEST_CASE(if_statement_invalid)
{
- CHECK_PARSE_ERROR("{ if calldatasize {}", ParserError, "Instructions are not supported as conditions for if");
+ CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected token \"(\"");
BOOST_CHECK("{ if calldatasize() {}");
CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", ParserError, "Instruction \"mstore\" not allowed in this context");
CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected token LBrace");
@@ -296,7 +315,7 @@ BOOST_AUTO_TEST_CASE(switch_duplicate_case)
BOOST_AUTO_TEST_CASE(switch_invalid_expression)
{
CHECK_PARSE_ERROR("{ switch {} default {} }", ParserError, "Literal, identifier or instruction expected.");
- CHECK_PARSE_ERROR("{ switch calldatasize default {} }", ParserError, "Instructions are not supported as expressions for switch");
+ CHECK_PARSE_ERROR("{ switch mload default {} }", ParserError, "Expected token \"(\"");
CHECK_PARSE_ERROR("{ switch mstore(1, 1) default {} }", ParserError, "Instruction \"mstore\" not allowed in this context");
}
@@ -332,7 +351,7 @@ BOOST_AUTO_TEST_CASE(for_invalid_expression)
CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected token LBrace got 'Number'");
CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected token LBrace got 'Number'");
CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected token LBrace got 'Number'");
- CHECK_PARSE_ERROR("{ for {} calldatasize {} {} }", ParserError, "Instructions are not supported as conditions for the for statement.");
+ CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected token \"(\"");
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", ParserError, "Instruction \"mstore\" not allowed in this context");
}
@@ -455,6 +474,47 @@ BOOST_AUTO_TEST_CASE(multiple_assignment)
BOOST_AUTO_TEST_SUITE_END()
+BOOST_AUTO_TEST_SUITE(LooseStrictMode)
+
+BOOST_AUTO_TEST_CASE(no_opcodes_in_strict)
+{
+ BOOST_CHECK(successParse("{ pop(callvalue) }"));
+ BOOST_CHECK(successParse("{ callvalue pop }"));
+ CHECK_STRICT_ERROR("{ pop(callvalue) }", ParserError, "Non-functional instructions are not allowed in this context.");
+ CHECK_STRICT_ERROR("{ callvalue pop }", ParserError, "Call or assignment expected");
+ SUCCESS_STRICT("{ pop(callvalue()) }");
+ BOOST_CHECK(successParse("{ switch callvalue case 0 {} }"));
+ CHECK_STRICT_ERROR("{ switch callvalue case 0 {} }", ParserError, "Non-functional instructions are not allowed in this context.");
+}
+
+BOOST_AUTO_TEST_CASE(no_labels_in_strict)
+{
+ BOOST_CHECK(successParse("{ a: }"));
+ CHECK_STRICT_ERROR("{ a: }", ParserError, "Labels are not supported");
+}
+
+BOOST_AUTO_TEST_CASE(no_stack_assign_in_strict)
+{
+ BOOST_CHECK(successParse("{ let x 4 =: x }"));
+ CHECK_STRICT_ERROR("{ let x 4 =: x }", ParserError, "Call or assignment expected.");
+}
+
+BOOST_AUTO_TEST_CASE(no_dup_swap_in_strict)
+{
+ BOOST_CHECK(successParse("{ swap1 }"));
+ CHECK_STRICT_ERROR("{ swap1 }", ParserError, "Call or assignment expected.");
+ BOOST_CHECK(successParse("{ dup1 pop }"));
+ CHECK_STRICT_ERROR("{ dup1 pop }", ParserError, "Call or assignment expected.");
+ BOOST_CHECK(successParse("{ swap2 }"));
+ CHECK_STRICT_ERROR("{ swap2 }", ParserError, "Call or assignment expected.");
+ BOOST_CHECK(successParse("{ dup2 pop }"));
+ CHECK_STRICT_ERROR("{ dup2 pop }", ParserError, "Call or assignment expected.");
+ CHECK_PARSE_ERROR("{ switch dup1 case 0 {} }", ParserError, "Instruction \"dup1\" not allowed in this context");
+ CHECK_STRICT_ERROR("{ switch dup1 case 0 {} }", ParserError, "Instruction \"dup1\" not allowed in this context");
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
BOOST_AUTO_TEST_SUITE(Printing)
BOOST_AUTO_TEST_CASE(print_smoke)
@@ -540,7 +600,7 @@ BOOST_AUTO_TEST_CASE(function_calls)
function g(a, b, c)
{
}
- g(1, mul(2, address), f(mul(2, caller)))
+ g(1, mul(2, address()), f(mul(2, caller())))
y()
})";
boost::replace_all(source, "\t", " ");
@@ -712,8 +772,9 @@ BOOST_AUTO_TEST_CASE(jump_warning)
{
CHECK_PARSE_WARNING("{ 1 jump }", Warning, "Jump instructions");
CHECK_PARSE_WARNING("{ 1 2 jumpi }", Warning, "Jump instructions");
- CHECK_PARSE_WARNING("{ a: jump(a) }", Warning, "Jump instructions");
- CHECK_PARSE_WARNING("{ a: jumpi(a, 2) }", Warning, "Jump instructions");
+ CHECK_PARSE_WARNING("{ jump(44) }", Warning, "Jump instructions");
+ CHECK_PARSE_WARNING("{ jumpi(44, 2) }", Warning, "Jump instructions");
+ CHECK_PARSE_WARNING("{ a: }", Warning, "Jump instructions");
}
BOOST_AUTO_TEST_SUITE_END()