diff --git a/libsolidity/inlineasm/AsmParser.cpp b/libsolidity/inlineasm/AsmParser.cpp index 5983d7fff8dd..88a0afc151bc 100644 --- a/libsolidity/inlineasm/AsmParser.cpp +++ b/libsolidity/inlineasm/AsmParser.cpp @@ -254,17 +254,6 @@ assembly::Expression Parser::parseExpression() if (operation.type() == typeid(Instruction)) { Instruction const& instr = boost::get(operation); - // Enforce functional notation for instructions requiring multiple arguments. - int args = instructionInfo(instr.instruction).args; - bool requireFunctionalNotation = (args > 0 || m_flavour != AsmFlavour::Loose); - if (requireFunctionalNotation && currentToken() != Token::LParen) - fatalParserError(string( - "Expected token \"(\" (\"" + - instructionNames().at(instr.instruction) + - "\" expects " + - boost::lexical_cast(args) + - " arguments)" - )); // Disallow instructions returning multiple values (and DUP/SWAP) as expression. if ( instructionInfo(instr.instruction).ret != 1 || @@ -276,6 +265,17 @@ assembly::Expression Parser::parseExpression() instructionNames().at(instr.instruction) + "\" not allowed in this context." ); + // Enforce functional notation for instructions requiring multiple arguments. + int args = instructionInfo(instr.instruction).args; + bool requireFunctionalNotation = (args > 0 || m_flavour != AsmFlavour::Loose); + if (requireFunctionalNotation && currentToken() != Token::LParen) + fatalParserError(string( + "Expected token \"(\" (\"" + + instructionNames().at(instr.instruction) + + "\" expects " + + boost::lexical_cast(args) + + " arguments)" + )); } if (currentToken() == Token::LParen) return parseCall(std::move(operation)); diff --git a/test/libsolidity/InlineAssembly.cpp b/test/libsolidity/InlineAssembly.cpp index 9e87849b659f..216e14225763 100644 --- a/test/libsolidity/InlineAssembly.cpp +++ b/test/libsolidity/InlineAssembly.cpp @@ -480,11 +480,11 @@ 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 token \"(\" (\"callvalue\" expects 0 arguments)"); + CHECK_STRICT_ERROR("{ pop(callvalue) }", ParserError, "Instruction \"callvalue\" 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, "Expected token \"(\" (\"callvalue\" expects 0 arguments)"); + CHECK_STRICT_ERROR("{ switch callvalue case 0 {} }", ParserError, "Instruction \"callvalue\" not allowed in this context"); } BOOST_AUTO_TEST_CASE(no_labels_in_strict) @@ -509,8 +509,8 @@ BOOST_AUTO_TEST_CASE(no_dup_swap_in_strict) 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, "Expected token \"(\" (\"dup1\" expects 1 arguments)"); - CHECK_STRICT_ERROR("{ switch dup1 case 0 {} }", ParserError, "Expected token \"(\" (\"dup1\" expects 1 arguments)"); + 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()