mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2384 from ethereum/parseFunctionalInstructions
Enforce function arguments when parsing functional instructions.
This commit is contained in:
commit
fd5bf16101
@ -10,6 +10,7 @@ Features:
|
||||
|
||||
Bugfixes:
|
||||
* Unused variable warnings no longer issued for variables used inside inline assembly.
|
||||
* Inline Assembly: Enforce function arguments when parsing functional instructions.
|
||||
|
||||
### 0.4.11 (2017-05-03)
|
||||
|
||||
|
@ -318,8 +318,10 @@ would be written as follows
|
||||
|
||||
mstore(0x80, add(mload(0x80), 3))
|
||||
|
||||
Functional style and instructional style can be mixed, but any opcode inside a
|
||||
functional style expression has to return exactly one stack slot (most of the opcodes do).
|
||||
Functional style expressions cannot use instructional style internally, i.e.
|
||||
``1 2 mstore(0x80, add)`` is not valid assembly, it has to be written as
|
||||
``mstore(0x80, add(2, 1))``. For opcodes that do not take arguments, the
|
||||
parentheses can be omitted.
|
||||
|
||||
Note that the order of arguments is reversed in functional-style as opposed to the instruction-style
|
||||
way. If you use functional-style, the first argument will end up on the stack top.
|
||||
|
@ -174,6 +174,19 @@ assembly::Case Parser::parseCase()
|
||||
assembly::Statement Parser::parseExpression()
|
||||
{
|
||||
Statement operation = parseElementaryOperation(true);
|
||||
if (operation.type() == typeid(Instruction))
|
||||
{
|
||||
Instruction const& instr = boost::get<Instruction>(operation);
|
||||
int args = instructionInfo(instr.instruction).args;
|
||||
if (args > 0 && currentToken() != Token::LParen)
|
||||
fatalParserError(string(
|
||||
"Expected token \"(\" (\"" +
|
||||
instructionNames().at(instr.instruction) +
|
||||
"\" expects " +
|
||||
boost::lexical_cast<string>(args) +
|
||||
" arguments)"
|
||||
));
|
||||
}
|
||||
if (currentToken() == Token::LParen)
|
||||
return parseCall(std::move(operation));
|
||||
else
|
||||
|
@ -213,6 +213,16 @@ BOOST_AUTO_TEST_CASE(functional)
|
||||
BOOST_CHECK(successParse("{ let x := 2 add(7, mul(6, x)) mul(7, 8) add =: x }"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(functional_partial)
|
||||
{
|
||||
CHECK_PARSE_ERROR("{ let x := byte }", ParserError, "Expected token \"(\"");
|
||||
}
|
||||
|
||||
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 }"));
|
||||
@ -258,7 +268,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("{ 1 2 switch mul default {} }", ParserError, "Instructions are not supported as expressions for switch.");
|
||||
CHECK_PARSE_ERROR("{ switch calldatasize default {} }", ParserError, "Instructions are not supported as expressions for switch.");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(switch_default_before_case)
|
||||
|
Loading…
Reference in New Issue
Block a user