Improve yul error messages around number of arguments and variables.

This commit is contained in:
chriseth 2018-12-04 11:22:49 +01:00
parent 336287821a
commit d829794737
4 changed files with 24 additions and 15 deletions

View File

@ -4,6 +4,7 @@ Language Features:
Compiler Features: Compiler Features:
* Inline Assembly: Improve error messages around invalid function argument count.
Bugfixes: Bugfixes:

View File

@ -244,9 +244,18 @@ bool AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
{ {
int const stackHeight = m_stackHeight; int const stackHeight = m_stackHeight;
success = boost::apply_visitor(*this, *_varDecl.value); success = boost::apply_visitor(*this, *_varDecl.value);
if ((m_stackHeight - stackHeight) != numVariables) int numValues = m_stackHeight - stackHeight;
if (numValues != numVariables)
{ {
m_errorReporter.declarationError(_varDecl.location, "Variable count mismatch."); m_errorReporter.declarationError(_varDecl.location,
"Variable count mismatch: " +
to_string(numVariables) +
" variables and " +
to_string(numValues) +
" values."
);
// Adjust stack height to avoid misleading additional errors.
m_stackHeight += numVariables - numValues;
return false; return false;
} }
} }
@ -288,7 +297,7 @@ bool AsmAnalyzer::operator()(FunctionCall const& _funCall)
{ {
solAssert(!_funCall.functionName.name.empty(), ""); solAssert(!_funCall.functionName.name.empty(), "");
bool success = true; bool success = true;
size_t arguments = 0; size_t parameters = 0;
size_t returns = 0; size_t returns = 0;
if (!m_currentScope->lookup(_funCall.functionName.name, Scope::Visitor( if (!m_currentScope->lookup(_funCall.functionName.name, Scope::Visitor(
[&](Scope::Variable const&) [&](Scope::Variable const&)
@ -310,7 +319,7 @@ bool AsmAnalyzer::operator()(FunctionCall const& _funCall)
[&](Scope::Function const& _fun) [&](Scope::Function const& _fun)
{ {
/// TODO: compare types too /// TODO: compare types too
arguments = _fun.arguments.size(); parameters = _fun.arguments.size();
returns = _fun.returns.size(); returns = _fun.returns.size();
} }
))) )))
@ -319,21 +328,23 @@ bool AsmAnalyzer::operator()(FunctionCall const& _funCall)
success = false; success = false;
} }
if (success) if (success)
{ if (_funCall.arguments.size() != parameters)
if (_funCall.arguments.size() != arguments)
{ {
m_errorReporter.typeError( m_errorReporter.typeError(
_funCall.functionName.location, _funCall.functionName.location,
"Expected " + to_string(arguments) + " arguments but got " + "Function expects " +
to_string(parameters) +
" arguments but got " +
to_string(_funCall.arguments.size()) + "." to_string(_funCall.arguments.size()) + "."
); );
success = false; success = false;
} }
}
for (auto const& arg: _funCall.arguments | boost::adaptors::reversed) for (auto const& arg: _funCall.arguments | boost::adaptors::reversed)
if (!expectExpression(arg)) if (!expectExpression(arg))
success = false; success = false;
m_stackHeight += int(returns) - int(arguments); // Use argument size instead of parameter count to avoid misleading errors.
m_stackHeight += int(returns) - int(_funCall.arguments.size());
m_info.stackHeightInfo[&_funCall] = m_stackHeight; m_info.stackHeightInfo[&_funCall] = m_stackHeight;
return success; return success;
} }

View File

@ -433,8 +433,7 @@ BOOST_AUTO_TEST_CASE(variable_access_cross_functions)
BOOST_AUTO_TEST_CASE(invalid_tuple_assignment) BOOST_AUTO_TEST_CASE(invalid_tuple_assignment)
{ {
/// The push(42) is added here to silence the unbalanced stack error, so that there's only one error reported. CHECK_PARSE_ERROR("{ let x, y := 1 }", DeclarationError, "Variable count mismatch: 2 variables and 1 values");
CHECK_PARSE_ERROR("{ 42 let x, y := 1 }", DeclarationError, "Variable count mismatch.");
} }
BOOST_AUTO_TEST_CASE(instruction_too_few_arguments) BOOST_AUTO_TEST_CASE(instruction_too_few_arguments)

View File

@ -10,7 +10,5 @@ contract C {
} }
} }
// ---- // ----
// TypeError: (87-88): Expected 1 arguments but got 0. // TypeError: (87-88): Function expects 1 arguments but got 0.
// SyntaxError: (87-90): Top-level expressions are not supposed to return values (this expression returns -1 values). Use ``pop()`` or assign them. // TypeError: (108-109): Function expects 1 arguments but got 2.
// TypeError: (108-109): Expected 1 arguments but got 2.
// SyntaxError: (108-115): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them.