Merge pull request #6022 from ethereum/fixFunctionScoping

Properly detect name clashes with functions before their definition.
This commit is contained in:
chriseth 2019-02-18 16:47:21 +01:00 committed by GitHub
commit e88765f936
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 35 additions and 3 deletions

View File

@ -7,6 +7,7 @@ Compiler Features:
Bugfixes:
* Yul: Properly detect name clashes with functions before their declaration.
Build System:

View File

@ -150,9 +150,16 @@ bool ScopeFiller::operator()(Block const& _block)
scope(&_block).superScope = m_currentScope;
m_currentScope = &scope(&_block);
// First visit all functions to make them create
// an entry in the scope according to their visibility.
for (auto const& s: _block.statements)
if (!boost::apply_visitor(*this, s))
success = false;
if (s.type() == typeid(FunctionDefinition))
if (!boost::apply_visitor(*this, s))
success = false;
for (auto const& s: _block.statements)
if (s.type() != typeid(FunctionDefinition))
if (!boost::apply_visitor(*this, s))
success = false;
m_currentScope = m_currentScope->superScope;
return success;

View File

@ -428,7 +428,31 @@ BOOST_AUTO_TEST_CASE(opcode_for_function_args)
BOOST_AUTO_TEST_CASE(name_clashes)
{
CHECK_PARSE_ERROR("{ let g := 2 function g() { } }", DeclarationError, "Function name g already taken in this scope");
CHECK_PARSE_ERROR("{ let g := 2 function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_subscope)
{
CHECK_PARSE_ERROR("{ function g() { function g() {} } }", DeclarationError, "Function name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_subscope_reverse)
{
CHECK_PARSE_ERROR("{ { function g() {} } function g() { } }", DeclarationError, "Function name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope)
{
CHECK_PARSE_ERROR("{ function g() { let g := 0 } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(name_clashes_function_variable_subscope_reverse)
{
CHECK_PARSE_ERROR("{ { let g := 0 } function g() { } }", DeclarationError, "Variable name g already taken in this scope");
}
BOOST_AUTO_TEST_CASE(functions_in_parallel_scopes)
{
BOOST_CHECK(successParse("{ { function g() {} } { function g() {} } }"));
}
BOOST_AUTO_TEST_CASE(variable_access_cross_functions)