Merge pull request #10085 from ethereum/yul-syntax-test-extractions

Extracting inline assembly syntax tests.
This commit is contained in:
chriseth 2020-11-04 17:06:20 +01:00 committed by GitHub
commit d1e1e961f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
86 changed files with 492 additions and 398 deletions

View File

@ -14,7 +14,7 @@ indent_size = 4
indent_style = space
indent_size = 4
[std/**.sol]
[*.sol]
indent_style = space
indent_size = 4

View File

@ -220,16 +220,17 @@ def examine_id_coverage(top_dir, source_id_to_file_names, new_ids_only=False):
return False
old_source_only_ids = {
"1123", "1133", "1218", "1220", "1584", "1823", "1950",
"1988", "2418", "2461", "2512", "2592", "2657", "2800", "2842", "2856",
"1123", "1218", "1220", "1584", "1823", "1950",
"1988", "2461", "2512", "2592", "2657", "2800", "2842", "2856",
"3046", "3263", "3356", "3441", "3682", "3876",
"3893", "3996", "4010", "4281", "4802", "4805", "4828",
"4904", "4990", "5052", "5073", "5170", "5188", "5272", "5347", "5473",
"5622", "6041", "6052", "6084", "6272", "6708", "6792", "6931", "7110", "7128", "7186",
"3893", "3996", "4010", "4281", "4802",
"5052", "5073", "5170", "5188", "5272", "5347", "5473",
"5622", "6041", "6084", "6272", "7110", "7128", "7186",
"7589", "7593", "7653", "7812", "7885", "8065", "8084", "8140",
"8261", "8312", "8592", "8758", "9011",
"9085", "9390", "9440", "9547", "9551", "9615", "9980"
"9085", "9390", "9440", "9547", "9551", "9615", "9980",
}
new_source_only_ids = source_only_ids - old_source_only_ids
if len(new_source_only_ids) != 0:
print("The following new error code(s), not covered by tests, found:")

View File

@ -170,343 +170,7 @@ do { successParse((text), false, false, AssemblyStack::Language::StrictAssembly)
BOOST_AUTO_TEST_SUITE(SolidityInlineAssembly)
BOOST_AUTO_TEST_SUITE(Parsing)
BOOST_AUTO_TEST_CASE(smoke_test)
{
BOOST_CHECK(successParse("{ }"));
}
BOOST_AUTO_TEST_CASE(surplus_input)
{
CHECK_PARSE_ERROR("{ } { }", ParserError, "Expected end of source but got '{'");
}
BOOST_AUTO_TEST_CASE(simple_instructions)
{
BOOST_CHECK(successParse("{ let y := mul(0x10, mul(0x20, mload(0x40)))}"));
}
BOOST_AUTO_TEST_CASE(selfdestruct)
{
BOOST_CHECK(successParse("{ selfdestruct(0x02) }"));
}
BOOST_AUTO_TEST_CASE(keywords)
{
BOOST_CHECK(successParse("{ return (byte(1, 2), 2) pop(address()) }"));
}
BOOST_AUTO_TEST_CASE(constants)
{
BOOST_CHECK(successParse("{ pop(mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(vardecl)
{
BOOST_CHECK(successParse("{ let x := 7 }"));
}
BOOST_AUTO_TEST_CASE(vardecl_name_clashes)
{
CHECK_PARSE_ERROR("{ let x := 1 let x := 2 }", DeclarationError, "Variable name x already taken in this scope.");
}
BOOST_AUTO_TEST_CASE(vardecl_multi)
{
BOOST_CHECK(successParse("{ function f() -> x, y {} let x, y := f() }"));
}
BOOST_AUTO_TEST_CASE(vardecl_multi_conflict)
{
CHECK_PARSE_ERROR("{ function f() -> x, y {} let x, x := f() }", DeclarationError, "Variable name x already taken in this scope.");
}
BOOST_AUTO_TEST_CASE(vardecl_bool)
{
successParse("{ let x := true }");
successParse("{ let x := false }");
}
BOOST_AUTO_TEST_CASE(vardecl_empty)
{
BOOST_CHECK(successParse("{ let x }"));
}
BOOST_AUTO_TEST_CASE(functional)
{
BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(functional_partial)
{
CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected '(' but got '}'");
}
BOOST_AUTO_TEST_CASE(functional_partial_success)
{
BOOST_CHECK(successParse("{ let x := byte(1, 2) }"));
}
BOOST_AUTO_TEST_CASE(functional_assignment)
{
BOOST_CHECK(successParse("{ let x := 2 x := 7 }"));
}
BOOST_AUTO_TEST_CASE(functional_assignment_complex)
{
BOOST_CHECK(successParse("{ let x := 2 x := add(add(7, mul(6, x)), mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(vardecl_complex)
{
BOOST_CHECK(successParse("{ let y := 2 let x := add(add(7, mul(6, y)), mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(variable_use_before_decl)
{
CHECK_PARSE_ERROR("{ x := 2 let x := 3 }", DeclarationError, "Variable x used before it was declared.");
CHECK_PARSE_ERROR("{ let x := mul(2, x) }", DeclarationError, "Variable x used before it was declared.");
}
BOOST_AUTO_TEST_CASE(if_statement)
{
BOOST_CHECK(successParse("{ if 42 {} }"));
BOOST_CHECK(successParse("{ if 42 { let x := 3 } }"));
BOOST_CHECK(successParse("{ function f() -> x {} if f() { pop(f()) } }"));
}
BOOST_AUTO_TEST_CASE(if_statement_scope)
{
BOOST_CHECK(successParse("{ let x := 2 if 42 { x := 3 } }"));
CHECK_PARSE_ERROR("{ if 32 { let x := 3 } x := 2 }", DeclarationError, "Variable not found or variable not lvalue.");
}
BOOST_AUTO_TEST_CASE(if_statement_invalid)
{
CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' but got '{'");
BOOST_CHECK("{ if calldatasize() {}");
CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected '{' but got reserved keyword 'let'");
}
BOOST_AUTO_TEST_CASE(switch_statement)
{
BOOST_CHECK(successParse("{ switch 42 default {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} case 2 {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} default {} }"));
BOOST_CHECK(successParse("{ switch 42 case 1 {} case 2 {} default {} }"));
BOOST_CHECK(successParse("{ switch mul(1, 2) case 1 {} case 2 {} default {} }"));
BOOST_CHECK(successParse("{ function f() -> x {} switch f() case 1 {} case 2 {} default {} }"));
}
BOOST_AUTO_TEST_CASE(switch_no_cases)
{
CHECK_PARSE_ERROR("{ switch 42 }", ParserError, "Switch statement without any cases.");
}
BOOST_AUTO_TEST_CASE(switch_duplicate_case)
{
CHECK_PARSE_ERROR("{ switch 42 case 1 {} case 1 {} default {} }", DeclarationError, "Duplicate case defined.");
}
BOOST_AUTO_TEST_CASE(switch_invalid_expression)
{
CHECK_PARSE_ERROR("{ switch {} case 1 {} default {} }", ParserError, "Literal or identifier expected.");
CHECK_PARSE_ERROR(
"{ switch mload case 1 {} default {} }",
ParserError,
"Expected '(' but got reserved keyword 'case'"
);
CHECK_PARSE_ERROR(
"{ switch mstore(1, 1) case 1 {} default {} }",
TypeError,
"Expected expression to evaluate to one value, but got 0 values instead."
);
}
BOOST_AUTO_TEST_CASE(switch_default_before_case)
{
CHECK_PARSE_ERROR("{ switch 42 default {} case 1 {} }", ParserError, "Case not allowed after default case.");
}
BOOST_AUTO_TEST_CASE(switch_duplicate_default_case)
{
CHECK_PARSE_ERROR("{ switch 42 default {} default {} }", ParserError, "Only one default case allowed.");
}
BOOST_AUTO_TEST_CASE(switch_invalid_case)
{
CHECK_PARSE_ERROR("{ switch 42 case mul(1, 2) {} case 2 {} default {} }", ParserError, "Literal expected.");
}
BOOST_AUTO_TEST_CASE(switch_invalid_body)
{
CHECK_PARSE_ERROR("{ switch 42 case 1 mul case 2 {} default {} }", ParserError, "Expected '{' but got identifier");
}
BOOST_AUTO_TEST_CASE(for_statement)
{
BOOST_CHECK(successParse("{ for {} 1 {} {} }"));
BOOST_CHECK(successParse("{ for { let i := 1 } lt(i, 5) { i := add(i, 1) } {} }"));
}
BOOST_AUTO_TEST_CASE(for_invalid_expression)
{
CHECK_PARSE_ERROR("{ for {} {} {} {} }", ParserError, "Literal or identifier expected.");
CHECK_PARSE_ERROR("{ for 1 1 {} {} }", ParserError, "Expected '{' but got 'Number'");
CHECK_PARSE_ERROR("{ for {} 1 1 {} }", ParserError, "Expected '{' but got 'Number'");
CHECK_PARSE_ERROR("{ for {} 1 {} 1 }", ParserError, "Expected '{' but got 'Number'");
CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' but got '{'");
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to evaluate to one value, but got 0 values instead.");
}
BOOST_AUTO_TEST_CASE(for_visibility)
{
BOOST_CHECK(successParse("{ for { let i := 1 } i { pop(i) } { pop(i) } }"));
CHECK_PARSE_ERROR("{ for {} i { let i := 1 } {} }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} 1 { let i := 1 } { pop(i) } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} 1 { pop(i) } { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for { pop(i) } 1 { let i := 1 } {} }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for { pop(i) } 1 { } { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} i {} { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for {} 1 { pop(i) } { let i := 1 } }", DeclarationError, "Identifier not found");
CHECK_PARSE_ERROR("{ for { let x := 1 } 1 { let x := 1 } {} }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ for { let x := 1 } 1 {} { let x := 1 } }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ let x := 1 for { let x := 1 } 1 {} {} }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ let x := 1 for {} 1 { let x := 1 } {} }", DeclarationError, "Variable name x already taken in this scope");
CHECK_PARSE_ERROR("{ let x := 1 for {} 1 {} { let x := 1 } }", DeclarationError, "Variable name x already taken in this scope");
// Check that body and post are not sub-scopes of each other.
BOOST_CHECK(successParse("{ for {} 1 { let x := 1 } { let x := 1 } }"));
}
BOOST_AUTO_TEST_CASE(blocks)
{
BOOST_CHECK(successParse("{ let x := 7 { let y := 3 } { let z := 2 } }"));
}
BOOST_AUTO_TEST_CASE(number_literals)
{
BOOST_CHECK(successParse("{ let x := 1 }"));
CHECK_PARSE_ERROR("{ let x := .1 }", ParserError, "Invalid number literal.");
CHECK_PARSE_ERROR("{ let x := 1e5 }", ParserError, "Invalid number literal.");
CHECK_PARSE_ERROR("{ let x := 67.235 }", ParserError, "Invalid number literal.");
CHECK_STRICT_ERROR("{ let x := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff }", TypeError, "Number literal too large (> 256 bits)");
}
BOOST_AUTO_TEST_CASE(function_definitions)
{
BOOST_CHECK(successParse("{ function f() { } function g(a) -> x { } }"));
}
BOOST_AUTO_TEST_CASE(function_definitions_multiple_args)
{
BOOST_CHECK(successParse("{ function f(a, d) { } function g(a, d) -> x, y { } }"));
}
BOOST_AUTO_TEST_CASE(function_calls)
{
BOOST_CHECK(successParse("{ function f(a) -> b {} function g(a, b, c) {} function x() { g(1, 2, f(mul(2, 3))) x() } }"));
}
BOOST_AUTO_TEST_CASE(opcode_for_functions)
{
CHECK_PARSE_ERROR("{ function gas() { } }", ParserError, "Cannot use builtin");
}
BOOST_AUTO_TEST_CASE(opcode_for_function_args)
{
CHECK_PARSE_ERROR("{ function f(gas) { } }", ParserError, "Cannot use builtin");
CHECK_PARSE_ERROR("{ function f() -> gas { } }", ParserError, "Cannot use builtin");
}
BOOST_AUTO_TEST_CASE(name_clashes)
{
CHECK_PARSE_ERROR("{ let g := 2 function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_subscope)
{
CHECK_PARSE_ERROR("{ function g() { function g() {} } }", DeclarationError, "Function name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_subscope_reverse)
{
CHECK_PARSE_ERROR("{ { function g() {} } function g() { } }", DeclarationError, "Function name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope)
{
CHECK_PARSE_ERROR("{ function g() { let g := 0 } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope_reverse)
{
CHECK_PARSE_ERROR("{ { let g := 0 } function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(functions_in_parallel_scopes)
{
BOOST_CHECK(successParse("{ { function g() {} } { function g() {} } }"));
}
BOOST_AUTO_TEST_CASE(variable_access_cross_functions)
{
CHECK_PARSE_ERROR("{ let x := 2 function g() { pop(x) } }", DeclarationError, "Identifier not found.");
}
BOOST_AUTO_TEST_CASE(invalid_tuple_assignment)
{
CHECK_PARSE_ERROR("{ let x, y := 1 }", DeclarationError, "Variable count mismatch: 2 variables and 1 values");
}
BOOST_AUTO_TEST_CASE(instruction_too_few_arguments)
{
CHECK_PARSE_ERROR("{ pop(mul()) }", TypeError, "Function expects 2 arguments but got 0.");
CHECK_PARSE_ERROR("{ pop(mul(1)) }", TypeError, "Function expects 2 arguments but got 1.");
}
BOOST_AUTO_TEST_CASE(instruction_too_many_arguments)
{
CHECK_PARSE_ERROR("{ pop(mul(1, 2, 3)) }", TypeError, "Function expects 2 arguments but got 3");
}
BOOST_AUTO_TEST_CASE(recursion_depth)
{
string input;
for (size_t i = 0; i < 20000; i++)
input += "{";
input += "let x := 0";
for (size_t i = 0; i < 20000; i++)
input += "}";
CHECK_PARSE_ERROR(input, ParserError, "recursion");
}
BOOST_AUTO_TEST_CASE(multiple_assignment)
{
CHECK_PARSE_ERROR("{ let x function f() -> a, b {} 123, x := f() }", ParserError, "Variable name must precede \",\" in multiple assignment.");
CHECK_PARSE_ERROR("{ let x function f() -> a, b {} x, 123 := f() }", ParserError, "Variable name must precede \":=\" in assignment.");
/// NOTE: Travis hiccups if not having a variable
char const* text = R"(
{
function f(a) -> r1, r2 {
r1 := a
r2 := 7
}
let x := 9
let y := 2
x, y := f(x)
}
)";
BOOST_CHECK(successParse(text));
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(Printing)
BOOST_AUTO_TEST_SUITE(Printing) // {{{
BOOST_AUTO_TEST_CASE(print_smoke)
{
@ -593,8 +257,9 @@ BOOST_AUTO_TEST_CASE(function_calls)
}
BOOST_AUTO_TEST_SUITE_END()
// }}}
BOOST_AUTO_TEST_SUITE(Analysis)
BOOST_AUTO_TEST_SUITE(Analysis) // {{{
BOOST_AUTO_TEST_CASE(string_literals)
{
@ -633,50 +298,6 @@ BOOST_AUTO_TEST_CASE(revert)
BOOST_CHECK(successAssemble("{ revert(0, 0) }"));
}
BOOST_AUTO_TEST_CASE(function_calls)
{
BOOST_CHECK(successAssemble("{ function f() {} }"));
BOOST_CHECK(successAssemble("{ function f() { let y := 2 } }"));
BOOST_CHECK(successAssemble("{ function f() -> z { let y := 2 } }"));
BOOST_CHECK(successAssemble("{ function f(a) { let y := 2 } }"));
BOOST_CHECK(successAssemble("{ function f(a) { let y := a } }"));
BOOST_CHECK(successAssemble("{ function f() -> x, y, z {} }"));
BOOST_CHECK(successAssemble("{ function f(x, y, z) {} }"));
BOOST_CHECK(successAssemble("{ function f(a, b) -> x, y, z { y := a } }"));
BOOST_CHECK(successAssemble("{ function f() {} f() }"));
BOOST_CHECK(successAssemble("{ function f() -> x, y { x := 1 y := 2} let a, b := f() }"));
BOOST_CHECK(successAssemble("{ function f(a, b) -> x, y { x := b y := a } let a, b := f(2, 3) }"));
BOOST_CHECK(successAssemble("{ function rec(a) { rec(sub(a, 1)) } rec(2) }"));
BOOST_CHECK(successAssemble("{ let r := 2 function f() -> x, y { x := 1 y := 2} let a, b := f() b := r }"));
BOOST_CHECK(successAssemble("{ function f() { g() } function g() { f() } }"));
}
BOOST_AUTO_TEST_CASE(embedded_functions)
{
BOOST_CHECK(successAssemble("{ function f(r, s) -> x { function g(a) -> b { } x := g(2) } let x := f(2, 3) }"));
}
BOOST_AUTO_TEST_CASE(switch_statement)
{
BOOST_CHECK(successAssemble("{ switch 1 default {} }"));
BOOST_CHECK(successAssemble("{ switch 1 case 1 {} default {} }"));
BOOST_CHECK(successAssemble("{ switch 1 case 1 {} }"));
BOOST_CHECK(successAssemble("{ let a := 3 switch a case 1 { a := 1 } case 2 { a := 5 } a := 9}"));
BOOST_CHECK(successAssemble("{ let a := 2 switch calldataload(0) case 1 { a := 1 } case 2 { a := 5 } }"));
}
BOOST_AUTO_TEST_CASE(for_statement)
{
BOOST_CHECK(successAssemble("{ for {} 1 {} {} }"));
BOOST_CHECK(successAssemble("{ let x := calldatasize() for { let i := 0} lt(i, x) { i := add(i, 1) } { mstore(i, 2) } }"));
}
BOOST_AUTO_TEST_CASE(if_statement)
{
BOOST_CHECK(successAssemble("{ if 1 {} }"));
BOOST_CHECK(successAssemble("{ let x := 0 if eq(calldatasize(), 0) { x := 1 } mstore(0, x) }"));
}
BOOST_AUTO_TEST_CASE(large_constant)
{
auto source = R"({
@ -706,13 +327,6 @@ BOOST_AUTO_TEST_CASE(returndatacopy)
BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
}
BOOST_AUTO_TEST_CASE(returndatacopy_functional)
{
if (!solidity::test::CommonOptions::get().evmVersion().supportsReturndata())
return;
BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
}
BOOST_AUTO_TEST_CASE(staticcall)
{
if (!solidity::test::CommonOptions::get().evmVersion().hasStaticCall())
@ -751,7 +365,7 @@ BOOST_AUTO_TEST_CASE(jump_error)
CHECK_PARSE_WARNING("{ jumpi(44, 2) }", DeclarationError, "Function not found.");
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END() // }}}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -0,0 +1,3 @@
{
pop(mul(7, 8))
}

View File

@ -0,0 +1,5 @@
{
for {} {} {} {}
}
// ----
// ParserError 1856: (10-11): Literal or identifier expected.

View File

@ -0,0 +1,5 @@
{
for 1 1 {} {}
}
// ----
// ParserError 2314: (7-8): Expected '{' but got 'Number'

View File

@ -0,0 +1,5 @@
{
for {} 1 1 {}
}
// ----
// ParserError 2314: (12-13): Expected '{' but got 'Number'

View File

@ -0,0 +1,5 @@
{
for {} 1 {} 1
}
// ----
// ParserError 2314: (15-16): Expected '{' but got 'Number'

View File

@ -0,0 +1,5 @@
{
for {} mload {} {}
}
// ----
// ParserError 2314: (16-17): Expected '(' but got '{'

View File

@ -0,0 +1,7 @@
{
for {} mstore(1, 1) {} {}
}
// ====
// dialect: evm
// ----
// TypeError 3950: (10-22): Expected expression to evaluate to one value, but got 0 values instead.

View File

@ -0,0 +1,10 @@
{
{ for {} 1 {} {} }
{ for { let i := 1 } lt(i, 5) { i := add(i, 1) } {} }
{ for {} 1 {} {} }
{ let x := calldatasize() for { let i := 0} lt(i, x) { i := add(i, 1) } { mstore(i, 2) } }
}
// ====
// dialect: evm
// ----

View File

@ -0,0 +1,5 @@
{
for { let i := 1 } i { pop(i) } { pop(i) }
}
// ====
// dialect: evm

View File

@ -0,0 +1,7 @@
{
for {} i { let i := 1 } {}
}
// ====
// dialect: evm
// ----
// DeclarationError 8198: (10-11): Identifier not found.

View File

@ -0,0 +1,7 @@
{
for {} 1 { let i := 1 } { pop(i) }
}
// ====
// dialect: evm
// ----
// DeclarationError 8198: (33-34): Identifier not found.

View File

@ -0,0 +1,7 @@
{
for {} 1 { pop(i) } { let i := 1 }
}
// ====
// dialect: evm
// ----
// DeclarationError 8198: (18-19): Identifier not found.

View File

@ -0,0 +1,7 @@
{
for { pop(i) } 1 { let i := 1 } {}
}
// ====
// dialect: evm
// ----
// DeclarationError 8198: (13-14): Identifier not found.

View File

@ -0,0 +1,7 @@
{
for { pop(i) } 1 { } { let i := 1 }
}
// ====
// dialect: evm
// ----
// DeclarationError 8198: (13-14): Identifier not found.

View File

@ -0,0 +1,7 @@
{
for {} i {} { let i := 1 }
}
// ====
// dialect: evm
// ----
// DeclarationError 8198: (10-11): Identifier not found.

View File

@ -0,0 +1,7 @@
{
for {} 1 { pop(i) } { let i := 1 }
}
// ====
// dialect: evm
// ----
// DeclarationError 8198: (18-19): Identifier not found.

View File

@ -0,0 +1,7 @@
{
for { let x := 1 } 1 { let x := 1 } {}
}
// ====
// dialect: yul
// ----
// DeclarationError 1395: (26-36): Variable name x already taken in this scope.

View File

@ -0,0 +1,7 @@
{
for { let x := 1 } 1 {} { let x := 1 }
}
// ====
// dialect: yul
// ----
// DeclarationError 1395: (29-39): Variable name x already taken in this scope.

View File

@ -0,0 +1,5 @@
{
let x := 1 for { let x := 1 } 1 {} {}
}
// ----
// DeclarationError 1395: (20-30): Variable name x already taken in this scope.

View File

@ -0,0 +1,5 @@
{
let x := 1 for {} 1 { let x := 1 } {}
}
// ----
// DeclarationError 1395: (25-35): Variable name x already taken in this scope.

View File

@ -0,0 +1,5 @@
{
let x := 1 for {} 1 {} { let x := 1 }
}
// ----
// DeclarationError 1395: (28-38): Variable name x already taken in this scope.

View File

@ -0,0 +1,6 @@
{
// Check that body and post are not sub-scopes of each other.
for {} 1 { let x := 1 } { let x := 1 }
}
// ====
// dialect: evm

View File

@ -0,0 +1,17 @@
{
{ function f() {} }
{ function f() { let y := 2 } }
{ function f() -> z { let y := 2 } }
{ function f(a) { let y := 2 } }
{ function f(a) { let y := a } }
{ function f() -> x, y, z {} }
{ function f(x, y, z) {} }
{ function f(a, b) -> x, y, z { y := a } }
{ function f() {} f() }
{ function f() -> x, y { x := 1 y := 2} let a, b := f() }
{ function f(a, b) -> x, y { x := b y := a } let a, b := f(2, 3) }
{ function rec(a) { rec(sub(a, 1)) } rec(2) }
{ let r := 2 function f() -> x, y { x := 1 y := 2} let a, b := f() b := r }
{ function f() { g() } function g() { f() } }
{ function f(a) -> b {} function g(a, b, c) {} function x() { g(1, 2, f(mul(2, 3))) x() } }
}

View File

@ -0,0 +1,4 @@
{
function f(a, d) { }
function g(a, d) -> x, y { }
}

View File

@ -1,4 +1,7 @@
{
function f (a, b , c ) -> y,x,z {
}
}
function g() { }
function h(a) -> x { }
}

View File

@ -0,0 +1,7 @@
{
function f(r, s) -> x {
function g(a) -> b { }
x := g(2)
}
let x := f(2, 3)
}

View File

@ -0,0 +1,3 @@
{
let x := 2 x := add(add(7, mul(6, x)), mul(7, 8))
}

View File

@ -0,0 +1,3 @@
{
let x := 2 x := add(add(7, mul(6, x)), mul(7, 8))
}

View File

@ -0,0 +1,5 @@
{
let x := 2
x := 7
}

View File

@ -0,0 +1,5 @@
{
let x := byte
}
// ----
// ParserError 2314: (20-21): Expected '(' but got '}'

View File

@ -0,0 +1,3 @@
{
let x := byte(1, 2)
}

View File

@ -0,0 +1,5 @@
{
returndatacopy(0, 32, 64)
}
// ====
// EVMVersion: >=byzantium

View File

@ -0,0 +1,4 @@
{
{ function g() {} }
{ function g() {} }
}

View File

@ -0,0 +1,8 @@
{
{ if 42 {} }
{ if 42 { let x := 3 } }
{ function f() -> x {} if f() { pop(f()) } }
{ let x := 0 if eq(calldatasize(), 0) { x := 1 } mstore(0, x) }
}
// ====
// dialect: evm

View File

@ -0,0 +1,5 @@
{
if mload {}
}
// ----
// ParserError 2314: (15-16): Expected '(' but got '{'

View File

@ -0,0 +1,7 @@
{
if mstore(1, 1) {}
}
// ====
// dialect: evm
// ----
// TypeError 3950: (6-18): Expected expression to evaluate to one value, but got 0 values instead.

View File

@ -0,0 +1,7 @@
{
if 32 let x := 3
}
// ====
// dialect: yul
// ----
// ParserError 2314: (12-15): Expected '{' but got reserved keyword 'let'

View File

@ -0,0 +1,5 @@
{
if calldatasize {}
}
// ----
// ParserError 2314: (22-23): Expected '(' but got '{'

View File

@ -0,0 +1,6 @@
{
let x := 2
if 42 { x := 3 }
}
// ====
// dialect: evm

View File

@ -0,0 +1,8 @@
{
if 32 { let x := 3 }
x := 2
}
// ====
// dialect: evm
// ----
// DeclarationError 4634: (25-26): Variable not found or variable not lvalue.

View File

@ -0,0 +1,5 @@
{
pop(mul())
}
// ----
// TypeError 7000: (7-10): Function expects 2 arguments but got 0.

View File

@ -0,0 +1,5 @@
{
pop(mul(1))
}
// ----
// TypeError 7000: (7-10): Function expects 2 arguments but got 1.

View File

@ -0,0 +1,5 @@
{
pop(mul(1, 2, 3))
}
// ----
// TypeError 7000: (7-10): Function expects 2 arguments but got 3.

View File

@ -0,0 +1,5 @@
{
let x, y := 1
}
// ----
// DeclarationError 3812: (3-16): Variable count mismatch: 2 variables and 1 values.

View File

@ -0,0 +1,4 @@
{
return (byte(1, 2), 2)
pop(address()) // this is valid (but unreachable) code
}

View File

@ -0,0 +1,7 @@
{
function g() {
let g := 0
}
}
// ----
// DeclarationError 1395: (20-30): Variable name g already taken in this scope.

View File

@ -0,0 +1,6 @@
{
{ let g := 0 }
function g() {}
}
// ----
// DeclarationError 1395: (5-15): Variable name g already taken in this scope.

View File

@ -0,0 +1,7 @@
{
function g() {
function g() {}
}
}
// ----
// DeclarationError 6052: (20-35): Function name g already taken in this scope.

View File

@ -0,0 +1,8 @@
{
{
function g() {}
}
function g() {}
}
// ----
// DeclarationError 6052: (7-22): Function name g already taken in this scope.

View File

@ -0,0 +1,6 @@
{
let g := 2
function g() { }
}
// ----
// DeclarationError 1395: (6-16): Variable name g already taken in this scope.

View File

@ -0,0 +1,3 @@
{
let x := 1
}

View File

@ -0,0 +1,5 @@
{
let x := .1
}
// ----
// ParserError 4828: (12-14): Invalid number literal.

View File

@ -0,0 +1,5 @@
{
let x := 1e5
}
// ----
// ParserError 4828: (12-15): Invalid number literal.

View File

@ -0,0 +1,5 @@
{
let x := 67.235
}
// ----
// ParserError 4828: (12-18): Invalid number literal.

View File

@ -0,0 +1,5 @@
{
let x := 0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
}
// ----
// TypeError 6708: (12-79): Number literal too large (> 256 bits)

View File

@ -0,0 +1,5 @@
{
function f(gas) {}
}
// ----
// ParserError 5568: (14-17): Cannot use builtin function name "gas" as identifier name.

View File

@ -0,0 +1,5 @@
{
function f() -> gas {}
}
// ----
// ParserError 5568: (19-22): Cannot use builtin function name "gas" as identifier name.

View File

@ -0,0 +1,5 @@
{
function gas() {}
}
// ----
// ParserError 5568: (12-15): Cannot use builtin function name "gas" as identifier name.

View File

@ -0,0 +1,3 @@
{
selfdestruct(0x02)
}

View File

@ -0,0 +1,3 @@
{
let y := mul(0x10, mul(0x20, mload(0x40)))
}

View File

@ -0,0 +1 @@
{ { } }

View File

@ -0,0 +1,4 @@
{}
{}
// ----
// ParserError 2314: (3-4): Expected end of source but got '{'

View File

@ -0,0 +1,7 @@
{
switch 42
default {}
case 1 {}
}
// ----
// ParserError 4904: (35-39): Case not allowed after default case.

View File

@ -0,0 +1,7 @@
{
switch 42
default {}
default {}
}
// ----
// ParserError 6931: (35-42): Only one default case allowed.

View File

@ -0,0 +1,8 @@
{
switch 42
case 1 mul
case 2 {}
default {}
}
// ----
// ParserError 2314: (27-30): Expected '{' but got identifier

View File

@ -0,0 +1,8 @@
{
switch 42
case mul(1, 2) {}
case 2 {}
default {}
}
// ----
// ParserError 4805: (28-29): Literal expected.

View File

@ -0,0 +1,7 @@
{
switch {}
case 1 {}
default {}
}
// ----
// ParserError 1856: (13-14): Literal or identifier expected.

View File

@ -0,0 +1,7 @@
{
switch mload
case 1 {}
default {}
}
// ----
// ParserError 2314: (23-27): Expected '(' but got reserved keyword 'case'

View File

@ -0,0 +1,9 @@
{
switch mstore(1, 1)
case 1 {}
default {}
}
// ====
// dialect: evm
// ----
// TypeError 3950: (10-22): Expected expression to evaluate to one value, but got 0 values instead.

View File

@ -0,0 +1,3 @@
{ switch 42 default {} }
// ----
// Warning 9592: (2-22): "switch" statement with only a default case.

View File

@ -0,0 +1,8 @@
{
{ switch 42 case 1 {} }
{ switch 42 case 1 {} case 2 {} }
{ switch 42 case 1 {} default {} }
{ switch 42 case 1 {} case 2 {} default {} }
{ switch mul(1, 2) case 1 {} case 2 {} default {} }
{ function f() -> x {} switch f() case 1 {} case 2 {} default {} }
}

View File

@ -0,0 +1,10 @@
{
switch 42
case 1 {}
case 1 {}
default {}
}
// ====
// dialect: evm
// ----
// DeclarationError 6792: (25-34): Duplicate case defined.

View File

@ -0,0 +1,5 @@
{
switch 42
}
// ----
// ParserError 2418: (16-17): Switch statement without any cases.

View File

@ -0,0 +1,5 @@
{
let x := 7
}
// ====
// dialect: yul

View File

@ -0,0 +1,6 @@
{
let x := true
let y := false
}
// ====
// dialect: evm

View File

@ -0,0 +1,4 @@
{
let y := 2
let x := add(add(7, mul(6, y)), mul(7, 8))
}

View File

@ -0,0 +1,3 @@
{
let x
}

View File

@ -0,0 +1,4 @@
{
function f() -> x, y {}
let x, y := f()
}

View File

@ -0,0 +1,6 @@
{
function f() -> x, y {}
let x, x := f()
}
// ----
// DeclarationError 1395: (28-43): Variable name x already taken in this scope.

View File

@ -0,0 +1,6 @@
{
let x := 1
let x := 2
}
// ----
// DeclarationError 1395: (15-25): Variable name x already taken in this scope.

View File

@ -0,0 +1,8 @@
{
let x := 2
function g() {
pop(x)
}
}
// ----
// DeclarationError 8198: (36-37): Identifier not found.

View File

@ -0,0 +1,6 @@
{
x := 2
let x := 3
}
// ----
// DeclarationError 1133: (3-4): Variable x used before it was declared.

View File

@ -0,0 +1,6 @@
{
let x := mul(2, x)
}
// ----
// DeclarationError 4990: (19-20): Variable x used before it was declared.