mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Use .slot and .offest to access storage items.
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include <liblangutil/Exceptions.h>
|
||||
|
||||
#include <libsolutil/StringUtils.h>
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
@@ -195,9 +196,10 @@ void ReferencesResolver::operator()(yul::FunctionDefinition const& _function)
|
||||
|
||||
void ReferencesResolver::operator()(yul::Identifier const& _identifier)
|
||||
{
|
||||
bool isSlot = boost::algorithm::ends_with(_identifier.name.str(), "_slot");
|
||||
bool isOffset = boost::algorithm::ends_with(_identifier.name.str(), "_offset");
|
||||
bool isSlot = boost::algorithm::ends_with(_identifier.name.str(), ".slot");
|
||||
bool isOffset = boost::algorithm::ends_with(_identifier.name.str(), ".offset");
|
||||
|
||||
// Could also use `pathFromCurrentScope`, split by '.'
|
||||
auto declarations = m_resolver.nameFromCurrentScope(_identifier.name.str());
|
||||
if (isSlot || isOffset)
|
||||
{
|
||||
@@ -207,19 +209,22 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
|
||||
return;
|
||||
string realName = _identifier.name.str().substr(0, _identifier.name.str().size() - (
|
||||
isSlot ?
|
||||
string("_slot").size() :
|
||||
string("_offset").size()
|
||||
string(".slot").size() :
|
||||
string(".offset").size()
|
||||
));
|
||||
if (realName.empty())
|
||||
{
|
||||
m_errorReporter.declarationError(
|
||||
4794_error,
|
||||
_identifier.location,
|
||||
"In variable names _slot and _offset can only be used as a suffix."
|
||||
"In variable names .slot and .offset can only be used as a suffix."
|
||||
);
|
||||
return;
|
||||
}
|
||||
declarations = m_resolver.nameFromCurrentScope(realName);
|
||||
if (!declarations.empty())
|
||||
// To support proper path resolution, we have to use pathFromCurrentScope.
|
||||
solAssert(!util::contains(realName, '.'), "");
|
||||
}
|
||||
if (declarations.size() > 1)
|
||||
{
|
||||
@@ -231,7 +236,18 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
|
||||
return;
|
||||
}
|
||||
else if (declarations.size() == 0)
|
||||
{
|
||||
if (
|
||||
boost::algorithm::ends_with(_identifier.name.str(), "_slot") ||
|
||||
boost::algorithm::ends_with(_identifier.name.str(), "_offset")
|
||||
)
|
||||
m_errorReporter.declarationError(
|
||||
9467_error,
|
||||
_identifier.location,
|
||||
"Identifier not found. Use ``.slot`` and ``.offset`` to access storage variables."
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (auto var = dynamic_cast<VariableDeclaration const*>(declarations.front()))
|
||||
if (var->isLocalVariable() && m_yulInsideFunction)
|
||||
{
|
||||
@@ -254,18 +270,9 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
|
||||
{
|
||||
validateYulIdentifierName(identifier.name, identifier.location);
|
||||
|
||||
bool isSlot = boost::algorithm::ends_with(identifier.name.str(), "_slot");
|
||||
bool isOffset = boost::algorithm::ends_with(identifier.name.str(), "_offset");
|
||||
|
||||
string namePrefix = identifier.name.str().substr(0, identifier.name.str().find('.'));
|
||||
if (isSlot || isOffset)
|
||||
m_errorReporter.declarationError(
|
||||
9155_error,
|
||||
identifier.location,
|
||||
"In variable declarations _slot and _offset can not be used as a suffix."
|
||||
);
|
||||
else if (
|
||||
auto declarations = m_resolver.nameFromCurrentScope(namePrefix);
|
||||
if (
|
||||
auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str());
|
||||
!declarations.empty()
|
||||
)
|
||||
{
|
||||
@@ -277,8 +284,6 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
|
||||
3859_error,
|
||||
identifier.location,
|
||||
ssl,
|
||||
namePrefix.size() < identifier.name.str().size() ?
|
||||
"The prefix of this declaration conflicts with a declaration outside the inline assembly block." :
|
||||
"This declaration shadows a declaration outside the inline assembly block."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
}
|
||||
else if (requiresStorage)
|
||||
{
|
||||
m_errorReporter.typeError(6617_error, _identifier.location, "The suffixes _offset and _slot can only be used on non-constant storage variables.");
|
||||
m_errorReporter.typeError(6617_error, _identifier.location, "The suffixes .offset and .slot can only be used on non-constant storage variables.");
|
||||
return false;
|
||||
}
|
||||
else if (var && var->value() && !var->value()->annotation().type && !dynamic_cast<Literal const*>(var->value().get()))
|
||||
@@ -795,7 +795,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
{
|
||||
if (!var->isStateVariable() && !var->type()->dataStoredIn(DataLocation::Storage))
|
||||
{
|
||||
m_errorReporter.typeError(3622_error, _identifier.location, "The suffixes _offset and _slot can only be used on storage variables.");
|
||||
m_errorReporter.typeError(3622_error, _identifier.location, "The suffixes .offset and .slot can only be used on storage variables.");
|
||||
return false;
|
||||
}
|
||||
else if (_context == yul::IdentifierContext::LValue)
|
||||
@@ -807,7 +807,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
}
|
||||
else if (identifierInfo.isOffset)
|
||||
{
|
||||
m_errorReporter.typeError(9739_error, _identifier.location, "Only _slot can be assigned to.");
|
||||
m_errorReporter.typeError(9739_error, _identifier.location, "Only .slot can be assigned to.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -816,12 +816,12 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
}
|
||||
else if (!var->isConstant() && var->isStateVariable())
|
||||
{
|
||||
m_errorReporter.typeError(1408_error, _identifier.location, "Only local variables are supported. To access storage variables, use the _slot and _offset suffixes.");
|
||||
m_errorReporter.typeError(1408_error, _identifier.location, "Only local variables are supported. To access storage variables, use the .slot and .offset suffixes.");
|
||||
return false;
|
||||
}
|
||||
else if (var->type()->dataStoredIn(DataLocation::Storage))
|
||||
{
|
||||
m_errorReporter.typeError(9068_error, _identifier.location, "You have to use the _slot or _offset suffix to access storage reference variables.");
|
||||
m_errorReporter.typeError(9068_error, _identifier.location, "You have to use the .slot or .offset suffix to access storage reference variables.");
|
||||
return false;
|
||||
}
|
||||
else if (var->type()->sizeOnStack() != 1)
|
||||
@@ -835,7 +835,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
|
||||
}
|
||||
else if (requiresStorage)
|
||||
{
|
||||
m_errorReporter.typeError(7944_error, _identifier.location, "The suffixes _offset and _slot can only be used on storage variables.");
|
||||
m_errorReporter.typeError(7944_error, _identifier.location, "The suffixes .offset and .slot can only be used on storage variables.");
|
||||
return false;
|
||||
}
|
||||
else if (_context == yul::IdentifierContext::LValue)
|
||||
|
||||
Reference in New Issue
Block a user