Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix handling of local assembly variables in ReferencesResolver #14820

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 12 additions & 6 deletions libsolidity/analysis/ReferencesResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ bool ReferencesResolver::visit(Block const& _block)
if (!m_resolveInsideCode)
return false;
m_resolver.setScope(&_block);
m_localAssemblyVariables.push({});
return true;
}

Expand All @@ -65,6 +66,7 @@ void ReferencesResolver::endVisit(Block const& _block)
return;

m_resolver.setScope(_block.scope());
m_localAssemblyVariables.pop();
}

bool ReferencesResolver::visit(TryCatchClause const& _tryCatchClause)
Expand Down Expand Up @@ -364,14 +366,19 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
else if (declarations.size() == 0)
{
if (
boost::algorithm::ends_with(_identifier.name.str(), "_slot") ||
boost::algorithm::ends_with(_identifier.name.str(), "_offset")
(
boost::algorithm::ends_with(_identifier.name.str(), "_slot") ||
boost::algorithm::ends_with(_identifier.name.str(), "_offset")
) &&
m_localAssemblyVariables.top().count(_identifier.name.str()) == 0
)
{
m_errorReporter.declarationError(
9467_error,
nativeLocationOf(_identifier),
"Identifier not found. Use \".slot\" and \".offset\" to access storage variables."
);
}
return;
}
if (auto var = dynamic_cast<VariableDeclaration const*>(declarations.front()))
Expand All @@ -396,10 +403,9 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
solAssert(nativeLocationOf(identifier) == originLocationOf(identifier), "");
validateYulIdentifierName(identifier.name, nativeLocationOf(identifier));

if (
auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str());
!declarations.empty()
)
m_localAssemblyVariables.top().insert(identifier.name.str());

if (auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str()); !declarations.empty())
{
SecondarySourceLocation ssl;
for (auto const* decl: declarations)
Expand Down
4 changes: 4 additions & 0 deletions libsolidity/analysis/ReferencesResolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

#include <list>
#include <map>
#include <set>
#include <stack>

namespace solidity::langutil
{
Expand Down Expand Up @@ -101,6 +103,8 @@ class ReferencesResolver: private ASTConstVisitor, private yul::ASTWalker
langutil::EVMVersion m_evmVersion;
/// Stack of function definitions.
std::vector<FunctionDefinition const*> m_functionDefinitions;
// Stack of sets to track local assembly variables and their scopes
std::stack<std::set<std::string>> m_localAssemblyVariables;
bool const m_resolveInsideCode;

InlineAssemblyAnnotation* m_yulAnnotation = nullptr;
Expand Down
13 changes: 13 additions & 0 deletions test/libsolidity/syntaxTests/inlineAssembly/local_variable_old.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
contract C {
fallback() external {
assembly {
let x_offset := 0
let x_slot := 0
{
x_offset := 1
x_slot := 1
}
}
}
}
// ----
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
contract C {
fallback() external {
assembly {
let x_offset := 0
let x_slot := 0
{
let x_offset := 1
let x_slot := 1
}
}
}
}
// ----
// DeclarationError 1395: (146-163): Variable name x_offset already taken in this scope.
// DeclarationError 1395: (180-195): Variable name x_slot already taken in this scope.