mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #6818 from ethereum/alwaysUseBuiltins
Provide builtin functions even in loose assembly mode.
This commit is contained in:
@@ -57,7 +57,7 @@ eth::AssemblyItems compileContract(std::shared_ptr<CharStream> _sourceCode)
|
||||
{
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
Parser parser(errorReporter);
|
||||
Parser parser(errorReporter, dev::test::Options::get().evmVersion());
|
||||
ASTPointer<SourceUnit> sourceUnit;
|
||||
BOOST_REQUIRE_NO_THROW(sourceUnit = parser.parse(make_shared<Scanner>(_sourceCode)));
|
||||
BOOST_CHECK(!!sourceUnit);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <liblangutil/Scanner.h>
|
||||
#include <liblangutil/Exceptions.h>
|
||||
#include <liblangutil/SourceReferenceFormatter.h>
|
||||
|
||||
#include <libevmasm/Assembly.h>
|
||||
|
||||
@@ -80,7 +81,12 @@ boost::optional<Error> parseAndReturnFirstError(
|
||||
if (_allowWarnings && e->type() == Error::Type::Warning)
|
||||
continue;
|
||||
if (error)
|
||||
BOOST_FAIL("Found more than one error.");
|
||||
{
|
||||
string errors;
|
||||
for (auto const& err: stack.errors())
|
||||
errors += SourceReferenceFormatter::formatErrorInformation(*err);
|
||||
BOOST_FAIL("Found more than one error:\n" + errors);
|
||||
}
|
||||
error = e;
|
||||
}
|
||||
if (!success)
|
||||
@@ -299,7 +305,7 @@ BOOST_AUTO_TEST_CASE(if_statement_invalid)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ if mload {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)");
|
||||
BOOST_CHECK("{ if calldatasize() {}");
|
||||
CHECK_PARSE_ERROR("{ if mstore(1, 1) {} }", ParserError, "Instruction \"mstore\" not allowed in this context");
|
||||
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'");
|
||||
}
|
||||
|
||||
@@ -328,7 +334,7 @@ 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 mstore(1, 1) default {} }", ParserError, "Instruction \"mstore\" not allowed in this context");
|
||||
CHECK_PARSE_ERROR("{ switch mstore(1, 1) default {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(switch_default_before_case)
|
||||
@@ -364,7 +370,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 {} mload {} {} }", ParserError, "Expected '(' (instruction \"mload\" expects 1 arguments)");
|
||||
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", ParserError, "Instruction \"mstore\" not allowed in this context");
|
||||
CHECK_PARSE_ERROR("{ for {} mstore(1, 1) {} {} }", TypeError, "Expected expression to return one item to the stack, but did return 0 items");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(for_visibility)
|
||||
@@ -417,13 +423,13 @@ BOOST_AUTO_TEST_CASE(function_calls)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(opcode_for_functions)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ function gas() { } }", ParserError, "Cannot use instruction names for identifier names.");
|
||||
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 instruction names for identifier names.");
|
||||
CHECK_PARSE_ERROR("{ function f() -> gas { } }", ParserError, "Cannot use instruction names for identifier names.");
|
||||
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)
|
||||
@@ -467,13 +473,13 @@ BOOST_AUTO_TEST_CASE(invalid_tuple_assignment)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(instruction_too_few_arguments)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ mul() }", ParserError, "Expected expression (instruction \"mul\" expects 2 arguments)");
|
||||
CHECK_PARSE_ERROR("{ mul(1) }", ParserError, "Expected ',' (instruction \"mul\" expects 2 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("{ mul(1, 2, 3) }", ParserError, "Expected ')' (instruction \"mul\" expects 2 arguments)");
|
||||
CHECK_PARSE_ERROR("{ pop(mul(1, 2, 3)) }", TypeError, "Function expects 2 arguments but got 3");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(recursion_depth)
|
||||
@@ -517,7 +523,7 @@ 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, "Expected '(' but got identifier");
|
||||
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'");
|
||||
@@ -692,12 +698,12 @@ BOOST_AUTO_TEST_CASE(designated_invalid_instruction)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_declaration)
|
||||
{
|
||||
CHECK_ASSEMBLE_ERROR("{ let gas := 1 }", ParserError, "Cannot use instruction names for identifier names.");
|
||||
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 instruction name.");
|
||||
CHECK_ASSEMBLE_ERROR("{ 2 =: gas }", ParserError, "Identifier expected, got builtin symbol");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(inline_assembly_shadowed_instruction_functional_assignment)
|
||||
|
||||
@@ -102,7 +102,9 @@ bytes compileFirstExpression(
|
||||
{
|
||||
ErrorList errors;
|
||||
ErrorReporter errorReporter(errors);
|
||||
sourceUnit = Parser(errorReporter).parse(make_shared<Scanner>(CharStream(_sourceCode, "")));
|
||||
sourceUnit = Parser(errorReporter, dev::test::Options::get().evmVersion()).parse(
|
||||
make_shared<Scanner>(CharStream(_sourceCode, ""))
|
||||
);
|
||||
if (!sourceUnit)
|
||||
return bytes();
|
||||
}
|
||||
|
||||
@@ -44,7 +44,10 @@ namespace
|
||||
ASTPointer<ContractDefinition> parseText(std::string const& _source, ErrorList& _errors)
|
||||
{
|
||||
ErrorReporter errorReporter(_errors);
|
||||
ASTPointer<SourceUnit> sourceUnit = Parser(errorReporter).parse(std::make_shared<Scanner>(CharStream(_source, "")));
|
||||
ASTPointer<SourceUnit> sourceUnit = Parser(
|
||||
errorReporter,
|
||||
dev::test::Options::get().evmVersion()
|
||||
).parse(std::make_shared<Scanner>(CharStream(_source, "")));
|
||||
if (!sourceUnit)
|
||||
return ASTPointer<ContractDefinition>();
|
||||
for (ASTPointer<ASTNode> const& node: sourceUnit->nodes())
|
||||
|
||||
@@ -6,4 +6,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// ParserError: (67-70): Cannot use instruction names for identifier names.
|
||||
// ParserError: (67-70): Cannot use builtin function name "mod" as identifier name.
|
||||
|
||||
+1
-1
@@ -7,4 +7,4 @@ contract C {
|
||||
}
|
||||
}
|
||||
// ----
|
||||
// ParserError: (102-105): Cannot use instruction names for identifier names.
|
||||
// ParserError: (102-105): Cannot use builtin function name "sub" as identifier name.
|
||||
|
||||
@@ -549,11 +549,11 @@ 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, "Expected '(' but got ':='", 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, "Expected '(' but got ','", 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)
|
||||
|
||||
Reference in New Issue
Block a user