Adapting the tests to strict inline assembly.

This commit is contained in:
Christian Parpart 2019-09-10 13:35:55 +02:00
parent 4e1b9d7f1b
commit e40c498260
20 changed files with 45 additions and 212 deletions

View File

@ -1,5 +1,5 @@
Warning: Yul and its optimizer are still experimental. Please use the output with care.
Error: Function not found.
Error: Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are disallowed in strict assembly. Use functions, "switch", "if" or "for" statements instead.
--> strict_asm_jump/input.sol:1:3:
|
1 | { jump(1) }

View File

@ -188,22 +188,22 @@ BOOST_AUTO_TEST_CASE(surplus_input)
BOOST_AUTO_TEST_CASE(simple_instructions)
{
BOOST_CHECK(successParse("{ dup1 dup1 mul dup1 sub pop }"));
BOOST_CHECK(successParse("{ let y := mul(0x10, mul(0x20, mload(0x40)))}"));
}
BOOST_AUTO_TEST_CASE(selfdestruct)
{
BOOST_CHECK(successParse("{ 0x02 selfdestruct }"));
BOOST_CHECK(successParse("{ selfdestruct(0x02) }"));
}
BOOST_AUTO_TEST_CASE(keywords)
{
BOOST_CHECK(successParse("{ 1 2 byte 2 return address pop }"));
BOOST_CHECK(successParse("{ return (byte(1, 2), 2) pop(address()) }"));
}
BOOST_AUTO_TEST_CASE(constants)
{
BOOST_CHECK(successParse("{ 7 8 mul pop }"));
BOOST_CHECK(successParse("{ pop(mul(7, 8)) }"));
}
BOOST_AUTO_TEST_CASE(vardecl)
@ -237,29 +237,14 @@ BOOST_AUTO_TEST_CASE(vardecl_empty)
BOOST_CHECK(successParse("{ let x }"));
}
BOOST_AUTO_TEST_CASE(assignment)
{
BOOST_CHECK(successParse("{ let x := 2 7 8 add =: x }"));
}
BOOST_AUTO_TEST_CASE(label)
{
BOOST_CHECK(successParse("{ 7 abc: 8 eq abc jump pop }"));
}
BOOST_AUTO_TEST_CASE(label_complex)
{
BOOST_CHECK(successParse("{ 7 abc: 8 eq jump(abc) jumpi(eq(7, 8), abc) pop }"));
}
BOOST_AUTO_TEST_CASE(functional)
{
BOOST_CHECK(successParse("{ let x := 2 add(7, mul(6, x)) mul(7, 8) add =: x }"));
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 '(' (instruction \"byte\" expects 2 arguments)");
CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected '(' but got '}'");
}
BOOST_AUTO_TEST_CASE(functional_partial_success)
@ -274,12 +259,12 @@ BOOST_AUTO_TEST_CASE(functional_assignment)
BOOST_AUTO_TEST_CASE(functional_assignment_complex)
{
BOOST_CHECK(successParse("{ let x := 2 x := add(7, mul(6, x)) mul(7, 8) add }"));
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(7, mul(6, y)) add mul(7, 8) }"));
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)
@ -303,7 +288,7 @@ BOOST_AUTO_TEST_CASE(if_statement_scope)
BOOST_AUTO_TEST_CASE(if_statement_invalid)
{
CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)");
CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' but got '{'");
BOOST_CHECK("{ if calldatasize() {}");
CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
CHECK_PARSE_ERROR("{ if 32 let x := 3 }", ParserError, "Expected '{' but got reserved keyword 'let'");
@ -333,7 +318,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 mload default {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)");
CHECK_PARSE_ERROR("{ switch mload default {} }", ParserError, "Expected '(' but got reserved keyword 'default'");
CHECK_PARSE_ERROR("{ switch mstore(1, 1) default {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
}
@ -369,7 +354,7 @@ BOOST_AUTO_TEST_CASE(for_invalid_expression)
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 '(' (instruction \"mload\" expects 1 arguments)");
CHECK_PARSE_ERROR("{ for {} mload {} {} }", ParserError, "Expected '(' but got '{'");
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
}
@ -463,7 +448,7 @@ BOOST_AUTO_TEST_CASE(functions_in_parallel_scopes)
BOOST_AUTO_TEST_CASE(variable_access_cross_functions)
{
CHECK_PARSE_ERROR("{ let x := 2 function g() { x pop } }", DeclarationError, "Identifier not found.");
CHECK_PARSE_ERROR("{ let x := 2 function g() { pop(x) } }", DeclarationError, "Identifier not found.");
}
BOOST_AUTO_TEST_CASE(invalid_tuple_assignment)
@ -516,46 +501,6 @@ 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, "Expected '(' but got ')'");
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, "Expected '(' but got reserved keyword 'case'");
}
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");
}
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(Printing)
BOOST_AUTO_TEST_CASE(print_smoke)
@ -565,12 +510,12 @@ BOOST_AUTO_TEST_CASE(print_smoke)
BOOST_AUTO_TEST_CASE(print_instructions)
{
parsePrintCompare("{\n 7\n 8\n mul\n dup10\n add\n pop\n}");
parsePrintCompare("{ pop(7) }");
}
BOOST_AUTO_TEST_CASE(print_subblock)
{
parsePrintCompare("{\n {\n dup4\n add\n }\n}");
parsePrintCompare("{ { pop(7) } }");
}
BOOST_AUTO_TEST_CASE(print_functional)
@ -578,14 +523,9 @@ BOOST_AUTO_TEST_CASE(print_functional)
parsePrintCompare("{ let x := mul(sload(0x12), 7) }");
}
BOOST_AUTO_TEST_CASE(print_label)
{
parsePrintCompare("{\n loop:\n jump(loop)\n}", true);
}
BOOST_AUTO_TEST_CASE(print_assignments)
{
parsePrintCompare("{\n let x := mul(2, 3)\n 7\n =: x\n x := add(1, 2)\n}");
parsePrintCompare("{\n let x := mul(2, 3)\n pop(7)\n x := add(1, 2)\n}");
}
BOOST_AUTO_TEST_CASE(print_multi_assignments)
@ -595,7 +535,7 @@ BOOST_AUTO_TEST_CASE(print_multi_assignments)
BOOST_AUTO_TEST_CASE(print_string_literals)
{
parsePrintCompare("{\n \"\\n'\\xab\\x95\\\"\"\n pop\n}");
parsePrintCompare("{ let x := \"\\n'\\xab\\x95\\\"\" }");
}
BOOST_AUTO_TEST_CASE(print_string_literal_unicode)
@ -661,39 +601,21 @@ BOOST_AUTO_TEST_CASE(oversize_string_literals)
CHECK_ASSEMBLE_ERROR("{ let x := \"123456789012345678901234567890123\" }", TypeError, "String literal too long");
}
BOOST_AUTO_TEST_CASE(assignment_after_tag)
{
BOOST_CHECK(successParse("{ let x := 1 { 7 tag: =: x } }"));
}
BOOST_AUTO_TEST_CASE(magic_variables)
{
CHECK_ASSEMBLE_ERROR("{ this pop }", DeclarationError, "Identifier not found");
CHECK_ASSEMBLE_ERROR("{ ecrecover pop }", DeclarationError, "Identifier not found");
BOOST_CHECK(successAssemble("{ let ecrecover := 1 ecrecover pop }"));
CHECK_ASSEMBLE_ERROR("{ pop(this) }", DeclarationError, "Identifier not found");
CHECK_ASSEMBLE_ERROR("{ pop(ecrecover) }", DeclarationError, "Identifier not found");
BOOST_CHECK(successAssemble("{ let ecrecover := 1 pop(ecrecover) }"));
}
BOOST_AUTO_TEST_CASE(stack_variables)
{
BOOST_CHECK(successAssemble("{ let y := 3 { 2 { let x := y } pop} }"));
}
BOOST_AUTO_TEST_CASE(imbalanced_stack)
{
BOOST_CHECK(successAssemble("{ 1 2 mul pop }", false));
CHECK_ASSEMBLE_ERROR("{ 1 }", DeclarationError, "Unbalanced stack at the end of a block: 1 surplus item(s).");
CHECK_ASSEMBLE_ERROR("{ pop }", DeclarationError, "Unbalanced stack at the end of a block: 1 missing item(s).");
BOOST_CHECK(successAssemble("{ let x := 4 7 add }", false));
}
BOOST_AUTO_TEST_CASE(error_tag)
{
CHECK_ERROR("{ jump(invalidJumpLabel) }", true, DeclarationError, "Identifier not found", true);
BOOST_CHECK(successAssemble("{ let y := 3 { let z := 2 { let x := y } } }"));
}
BOOST_AUTO_TEST_CASE(designated_invalid_instruction)
{
BOOST_CHECK(successAssemble("{ invalid }"));
BOOST_CHECK(successAssemble("{ invalid() }"));
}
BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration)
@ -701,16 +623,6 @@ BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration)
CHECK_ASSEMBLE_ERROR("{ let gas := 1 }", ParserError, "Cannot use builtin");
}
BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_assignment)
{
CHECK_ASSEMBLE_ERROR("{ 2 =: gas }", ParserError, "Identifier expected, got builtin symbol");
}
BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_functional_assignment)
{
CHECK_ASSEMBLE_ERROR("{ gas := 2 }", ParserError, "Variable name must precede \":=\"");
}
BOOST_AUTO_TEST_CASE(revert)
{
BOOST_CHECK(successAssemble("{ revert(0, 0) }"));
@ -772,18 +684,10 @@ BOOST_AUTO_TEST_CASE(large_constant)
BOOST_AUTO_TEST_CASE(keccak256)
{
BOOST_CHECK(successAssemble("{ 0 0 keccak256 pop }"));
BOOST_CHECK(successAssemble("{ pop(keccak256(0, 0)) }"));
}
BOOST_AUTO_TEST_CASE(returndatasize)
{
if (!dev::test::Options::get().evmVersion().supportsReturndata())
return;
BOOST_CHECK(successAssemble("{ let r := returndatasize }"));
}
BOOST_AUTO_TEST_CASE(returndatasize_functional)
{
if (!dev::test::Options::get().evmVersion().supportsReturndata())
return;
@ -794,7 +698,7 @@ BOOST_AUTO_TEST_CASE(returndatacopy)
{
if (!dev::test::Options::get().evmVersion().supportsReturndata())
return;
BOOST_CHECK(successAssemble("{ 64 32 0 returndatacopy }"));
BOOST_CHECK(successAssemble("{ returndatacopy(0, 32, 64) }"));
}
BOOST_AUTO_TEST_CASE(returndatacopy_functional)
@ -836,27 +740,10 @@ BOOST_AUTO_TEST_CASE(shift_constantinople_warning)
CHECK_PARSE_WARNING("{ pop(sar(10, 32)) }", TypeError, "The \"sar\" instruction is only available for Constantinople-compatible VMs");
}
BOOST_AUTO_TEST_CASE(chainid_instanbul_warning)
BOOST_AUTO_TEST_CASE(jump_error)
{
if (dev::test::Options::get().evmVersion().hasChainID())
return;
CHECK_PARSE_WARNING("{ pop(chainid()) }", TypeError, "The \"chainid\" instruction is only available for Istanbul-compatible VMs");
}
BOOST_AUTO_TEST_CASE(selfbalance_instanbul_warning)
{
if (dev::test::Options::get().evmVersion().hasSelfBalance())
return;
CHECK_PARSE_WARNING("{ pop(selfbalance()) }", TypeError, "The \"selfbalance\" instruction is only available for Istanbul-compatible VMs");
}
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("{ jump(44) }", Warning, "Jump instructions");
CHECK_PARSE_WARNING("{ jumpi(44, 2) }", Warning, "Jump instructions");
CHECK_PARSE_WARNING("{ a: }", Warning, "Jump instructions");
CHECK_PARSE_WARNING("{ jump(44) }", SyntaxError, "Jump instructions and labels are low-level EVM features");
CHECK_PARSE_WARNING("{ jumpi(44, 2) }", SyntaxError, "Jump instructions and labels are low-level EVM features");
}
BOOST_AUTO_TEST_SUITE_END()

View File

@ -10274,7 +10274,7 @@ BOOST_AUTO_TEST_CASE(correctly_initialize_memory_array_in_constructor)
// Make memory dirty.
assembly {
for { let i := 0 } lt(i, 64) { i := add(i, 1) } {
mstore(msize, not(0))
mstore(msize(), not(0))
}
}
uint16[3] memory c;
@ -12920,7 +12920,7 @@ BOOST_AUTO_TEST_CASE(snark)
input[3] = p2.Y;
bool success;
assembly {
success := call(sub(gas, 2000), 6, 0, input, 0xc0, r, 0x60)
success := call(sub(gas(), 2000), 6, 0, input, 0xc0, r, 0x60)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
@ -12936,7 +12936,7 @@ BOOST_AUTO_TEST_CASE(snark)
input[2] = s;
bool success;
assembly {
success := call(sub(gas, 2000), 7, 0, input, 0x80, r, 0x60)
success := call(sub(gas(), 2000), 7, 0, input, 0x80, r, 0x60)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}
@ -12964,7 +12964,7 @@ BOOST_AUTO_TEST_CASE(snark)
uint[1] memory out;
bool success;
assembly {
success := call(sub(gas, 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
success := call(sub(gas(), 2000), 8, 0, add(input, 0x20), mul(inputSize, 0x20), out, 0x20)
// Use "invalid" to make gas estimation work
switch success case 0 { invalid() }
}

View File

@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(assembly_staticcall)
string text = R"(
contract C {
function i() view public {
assembly { pop(staticcall(gas, 1, 2, 3, 4, 5)) }
assembly { pop(staticcall(gas(), 1, 2, 3, 4, 5)) }
}
}
)";

View File

@ -1,13 +0,0 @@
contract C {
function f() public pure {
assembly {
l:
l()
}
}
}
// ----
// SyntaxError: (63-64): The use of labels is disallowed. Please use "if", "switch", "for" or function calls instead.
// SyntaxError: (63-64): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead.
// TypeError: (73-74): Attempt to call label instead of function.

View File

@ -8,4 +8,4 @@ contract C {
}
}
// ----
// TypeError: (86-87): Function k used without being called.
// ParserError: (92-93): Call or assignment expected.

View File

@ -7,5 +7,4 @@ contract C {
}
}
// ----
// SyntaxError: (75-82): The use of non-functional instructions is disallowed. Please use functional notation instead.
// SyntaxError: (95-98): The use of non-functional instructions is disallowed. Please use functional notation instead.
// ParserError: (95-98): Expected '(' but got identifier

View File

@ -6,4 +6,4 @@ contract C {
}
}
// ----
// SyntaxError: (75-82): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead.
// SyntaxError: (75-79): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are disallowed in strict assembly. Use functions, "switch", "if" or "for" statements instead.

View File

@ -1,10 +0,0 @@
contract C {
function f() public pure {
assembly {
jump(xy)
}
}
}
// ----
// DeclarationError: (68-70): Identifier not found.
// SyntaxError: (63-71): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead.

View File

@ -6,5 +6,4 @@ contract C {
}
}
// ----
// SyntaxError: (75-80): The use of labels is disallowed. Please use "if", "switch", "for" or function calls instead.
// SyntaxError: (75-80): Jump instructions and labels are low-level EVM features that can lead to incorrect stack access. Because of that they are discouraged. Please consider using "switch", "if" or "for" statements instead.
// ParserError: (80-81): Call or assignment expected.

View File

@ -6,5 +6,4 @@ contract C {
}
}
// ----
// SyntaxError: (75-83): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them.
// DeclarationError: (61-93): Unbalanced stack at the end of a block: 1 surplus item(s).
// TypeError: (75-83): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them.

View File

@ -6,5 +6,4 @@ contract C {
}
}
// ----
// SyntaxError: (75-76): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them.
// DeclarationError: (61-86): Unbalanced stack at the end of a block: 1 surplus item(s).
// ParserError: (85-86): Call or assignment expected.

View File

@ -1,9 +0,0 @@
contract C {
function f() public pure {
assembly {
return := 1
}
}
}
// ----
// ParserError: (70-72): Variable name must precede ":=" in assignment.

View File

@ -1,9 +0,0 @@
contract C {
function f() public pure {
assembly {
return : 1
}
}
}
// ----
// ParserError: (70-71): Label name must precede ":".

View File

@ -6,5 +6,4 @@ contract test {
}
}
// ----
// SyntaxError: (73-76): The use of non-functional instructions is disallowed. Please use functional notation instead.
// DeclarationError: (59-86): Unbalanced stack at the end of a block: 1 missing item(s).
// ParserError: (85-86): Expected '(' but got '}'

View File

@ -6,5 +6,4 @@ contract test {
}
}
// ----
// SyntaxError: (73-74): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them.
// DeclarationError: (59-84): Unbalanced stack at the end of a block: 1 surplus item(s).
// ParserError: (83-84): Call or assignment expected.

View File

@ -1,9 +1,9 @@
contract C {
function f() public pure {
assembly {
_offset
let x := _offset
}
}
}
// ----
// DeclarationError: (75-82): In variable names _slot and _offset can only be used as a suffix.
// DeclarationError: (84-91): In variable names _slot and _offset can only be used as a suffix.

View File

@ -1,9 +1,9 @@
contract C {
function f() public pure {
assembly {
_slot
let x := _slot
}
}
}
// ----
// DeclarationError: (75-80): In variable names _slot and _offset can only be used as a suffix.
// DeclarationError: (84-89): In variable names _slot and _offset can only be used as a suffix.

View File

@ -9,7 +9,7 @@ contract C {
assembly { x := 7 }
}
function g() view public {
assembly { for {} 1 { pop(sload(0)) } { } pop(gas) }
assembly { for {} 1 { pop(sload(0)) } { } pop(gas()) }
}
function h() view public {
assembly { function g() { pop(blockhash(20)) } }
@ -18,6 +18,6 @@ contract C {
assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) }
}
function k() public {
assembly { pop(call(gas, 1, 2, 3, 4, 5, 6)) }
assembly { pop(call(gas(), 1, 2, 3, 4, 5, 6)) }
}
}

View File

@ -208,11 +208,6 @@ BOOST_AUTO_TEST_CASE(tuple_assignment)
BOOST_CHECK(successParse("{ function f() -> a:u256, b:u256, c:u256 {} let x:u256, y:u256, z:u256 := f() }"));
}
BOOST_AUTO_TEST_CASE(label)
{
CHECK_ERROR("{ label: }", ParserError, "Labels are not supported.");
}
BOOST_AUTO_TEST_CASE(instructions)
{
CHECK_ERROR("{ pop }", ParserError, "Call or assignment expected.");
@ -549,11 +544,9 @@ BOOST_AUTO_TEST_CASE(builtins_parser)
SimpleDialect dialect;
CHECK_ERROR_DIALECT("{ let builtin := 6 }", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect);
CHECK_ERROR_DIALECT("{ function builtin() {} }", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect);
CHECK_ERROR_DIALECT("{ builtin := 6 }", ParserError, "Variable name must precede \":=\" in assignment.", dialect);
CHECK_ERROR_DIALECT("{ function f(x) { f(builtin) } }", ParserError, "Expected '(' but got ')'", dialect);
CHECK_ERROR_DIALECT("{ function f(builtin) {}", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect);
CHECK_ERROR_DIALECT("{ function f() -> builtin {}", ParserError, "Cannot use builtin function name \"builtin\" as identifier name.", dialect);
CHECK_ERROR_DIALECT("{ function g() -> a,b {} builtin, builtin2 := g() }", ParserError, "Variable name must precede \",\" in multiple assignment.", dialect);
}
BOOST_AUTO_TEST_CASE(builtins_analysis)