Skip to content

Commit d247cd5

Browse files
authored
Merge pull request #11735 from ethereum/shadowing_inlineasm
Disallow shadowing for all identifiers in inline assembly
2 parents 0755d65 + aeb2438 commit d247cd5

27 files changed

+69
-89
lines changed

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
Breaking changes:
44
* `error` is now a keyword that can only be used for defining errors.
5+
* Inline Assembly: Consider functions, function parameters and return variables for shadowing checks.
56

67

78
### 0.8.8 (unreleased)

libsolidity/analysis/ReferencesResolver.cpp

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -274,28 +274,8 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
274274
void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
275275
{
276276
for (auto const& identifier: _varDecl.variables)
277-
{
278277
validateYulIdentifierName(identifier.name, identifier.debugData->location);
279278

280-
281-
if (
282-
auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str());
283-
!declarations.empty()
284-
)
285-
{
286-
SecondarySourceLocation ssl;
287-
for (auto const* decl: declarations)
288-
ssl.append("The shadowed declaration is here:", decl->location());
289-
if (!ssl.infos.empty())
290-
m_errorReporter.declarationError(
291-
3859_error,
292-
identifier.debugData->location,
293-
ssl,
294-
"This declaration shadows a declaration outside the inline assembly block."
295-
);
296-
}
297-
}
298-
299279
if (_varDecl.value)
300280
visit(*_varDecl.value);
301281
}
@@ -385,4 +365,20 @@ void ReferencesResolver::validateYulIdentifierName(yul::YulString _name, SourceL
385365
_location,
386366
"The identifier name \"" + _name.str() + "\" is reserved."
387367
);
368+
369+
auto declarations = m_resolver.nameFromCurrentScope(_name.str());
370+
if (!declarations.empty())
371+
{
372+
SecondarySourceLocation ssl;
373+
for (auto const* decl: declarations)
374+
if (decl->location().hasText())
375+
ssl.append("The shadowed declaration is here:", decl->location());
376+
if (!ssl.infos.empty())
377+
m_errorReporter.declarationError(
378+
3859_error,
379+
_location,
380+
ssl,
381+
"This declaration shadows a declaration outside the inline assembly block."
382+
);
383+
}
388384
}

libsolidity/analysis/TypeChecker.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -744,13 +744,6 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
744744
bool
745745
) -> bool
746746
{
747-
if (_context == yul::IdentifierContext::NonExternal)
748-
{
749-
// Hack until we can disallow any shadowing: If we found an internal reference,
750-
// clear the external references, so that codegen does not use it.
751-
_inlineAssembly.annotation().externalReferences.erase(& _identifier);
752-
return false;
753-
}
754747
auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);
755748
if (ref == _inlineAssembly.annotation().externalReferences.end())
756749
return false;

libyul/AsmAnalysis.cpp

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,6 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
146146
}
147147
}))
148148
{
149-
if (m_resolver)
150-
// We found a local reference, make sure there is no external reference.
151-
m_resolver(
152-
_identifier,
153-
yul::IdentifierContext::NonExternal,
154-
m_currentScope->insideFunction()
155-
);
156149
}
157150
else
158151
{
@@ -315,7 +308,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
315308

316309
validateInstructions(_funCall);
317310
}
318-
else if (m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{
311+
else if (!m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{
319312
[&](Scope::Variable const&)
320313
{
321314
m_errorReporter.typeError(
@@ -330,16 +323,6 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
330323
returnTypes = &_fun.returns;
331324
}
332325
}))
333-
{
334-
if (m_resolver)
335-
// We found a local reference, make sure there is no external reference.
336-
m_resolver(
337-
_funCall.functionName,
338-
yul::IdentifierContext::NonExternal,
339-
m_currentScope->insideFunction()
340-
);
341-
}
342-
else
343326
{
344327
if (!validateInstructions(_funCall))
345328
m_errorReporter.declarationError(
@@ -556,14 +539,6 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT
556539
bool found = false;
557540
if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name))
558541
{
559-
if (m_resolver)
560-
// We found a local reference, make sure there is no external reference.
561-
m_resolver(
562-
_variable,
563-
yul::IdentifierContext::NonExternal,
564-
m_currentScope->insideFunction()
565-
);
566-
567542
if (!holds_alternative<Scope::Variable>(*var))
568543
m_errorReporter.typeError(2657_error, _variable.debugData->location, "Assignment requires variable.");
569544
else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))

libyul/backends/evm/AbstractAssembly.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class AbstractAssembly
117117
virtual void markAsInvalid() = 0;
118118
};
119119

120-
enum class IdentifierContext { LValue, RValue, VariableDeclaration, NonExternal };
120+
enum class IdentifierContext { LValue, RValue, VariableDeclaration };
121121

122122
/// Object that is used to resolve references and generate code for access to identifiers external
123123
/// to inline assembly (not used in standalone assembly mode).

test/libsolidity/semanticTests/inlineAssembly/external_identifier_access_shadowing.sol

Lines changed: 0 additions & 12 deletions
This file was deleted.

test/libsolidity/semanticTests/inlineAssembly/inline_assembly_storage_access_inside_function.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ contract C {
77
uint256 off1;
88
uint256 off2;
99
assembly {
10-
function f() -> o1 {
10+
function g() -> o1 {
1111
sstore(z.slot, 7)
1212
o1 := y.offset
1313
}
14-
off2 := f()
14+
off2 := g()
1515
}
1616
assert(off2 == 2);
1717
return true;

test/libsolidity/semanticTests/inlineAssembly/leave.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
contract C {
2-
function f() public pure returns (uint w) {
2+
function g() public pure returns (uint w) {
33
assembly {
44
function f() -> t {
55
t := 2
@@ -14,4 +14,4 @@ contract C {
1414
// compileToEwasm: also
1515
// compileViaYul: also
1616
// ----
17-
// f() -> 2
17+
// g() -> 2

test/libsolidity/smtCheckerTests/inline_assembly/assembly_local_storage_access_inside_function.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
contract C {
22
uint256 public z;
33

4-
function f() public {
4+
function g() public {
55
z = 42;
66
uint i = 32;
77
assembly {

test/libsolidity/syntaxTests/controlFlow/leave_inside_function.sol

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
contract C {
22
function f() public pure {
33
assembly {
4-
function f() {
4+
function g() {
55
// Make sure this doesn't trigger the unimplemented assertion in the control flow builder.
66
leave
77
}

0 commit comments

Comments
 (0)