Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

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


### 0.8.8 (unreleased)
Expand Down
36 changes: 16 additions & 20 deletions libsolidity/analysis/ReferencesResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,28 +274,8 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
{
for (auto const& identifier: _varDecl.variables)
{
validateYulIdentifierName(identifier.name, identifier.debugData->location);


if (
auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str());
!declarations.empty()
)
{
SecondarySourceLocation ssl;
for (auto const* decl: declarations)
ssl.append("The shadowed declaration is here:", decl->location());
if (!ssl.infos.empty())
m_errorReporter.declarationError(
3859_error,
identifier.debugData->location,
ssl,
"This declaration shadows a declaration outside the inline assembly block."
);
}
}

if (_varDecl.value)
visit(*_varDecl.value);
}
Expand Down Expand Up @@ -385,4 +365,20 @@ void ReferencesResolver::validateYulIdentifierName(yul::YulString _name, SourceL
_location,
"The identifier name \"" + _name.str() + "\" is reserved."
);

auto declarations = m_resolver.nameFromCurrentScope(_name.str());
if (!declarations.empty())
{
SecondarySourceLocation ssl;
for (auto const* decl: declarations)
if (decl->location().hasText())
ssl.append("The shadowed declaration is here:", decl->location());
if (!ssl.infos.empty())
m_errorReporter.declarationError(
3859_error,
_location,
ssl,
"This declaration shadows a declaration outside the inline assembly block."
);
}
}
7 changes: 0 additions & 7 deletions libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -744,13 +744,6 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
bool
) -> bool
{
if (_context == yul::IdentifierContext::NonExternal)
{
// Hack until we can disallow any shadowing: If we found an internal reference,
// clear the external references, so that codegen does not use it.
_inlineAssembly.annotation().externalReferences.erase(& _identifier);
return false;
}
auto ref = _inlineAssembly.annotation().externalReferences.find(&_identifier);
if (ref == _inlineAssembly.annotation().externalReferences.end())
return false;
Expand Down
27 changes: 1 addition & 26 deletions libyul/AsmAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,6 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
}
}))
{
if (m_resolver)
// We found a local reference, make sure there is no external reference.
m_resolver(
_identifier,
yul::IdentifierContext::NonExternal,
m_currentScope->insideFunction()
);
}
else
{
Expand Down Expand Up @@ -315,7 +308,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)

validateInstructions(_funCall);
}
else if (m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{
else if (!m_currentScope->lookup(_funCall.functionName.name, GenericVisitor{
[&](Scope::Variable const&)
{
m_errorReporter.typeError(
Expand All @@ -330,16 +323,6 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
returnTypes = &_fun.returns;
}
}))
{
if (m_resolver)
// We found a local reference, make sure there is no external reference.
m_resolver(
_funCall.functionName,
yul::IdentifierContext::NonExternal,
m_currentScope->insideFunction()
);
}
else
{
if (!validateInstructions(_funCall))
m_errorReporter.declarationError(
Expand Down Expand Up @@ -556,14 +539,6 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT
bool found = false;
if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name))
{
if (m_resolver)
// We found a local reference, make sure there is no external reference.
m_resolver(
_variable,
yul::IdentifierContext::NonExternal,
m_currentScope->insideFunction()
);

if (!holds_alternative<Scope::Variable>(*var))
m_errorReporter.typeError(2657_error, _variable.debugData->location, "Assignment requires variable.");
else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))
Expand Down
2 changes: 1 addition & 1 deletion libyul/backends/evm/AbstractAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class AbstractAssembly
virtual void markAsInvalid() = 0;
};

enum class IdentifierContext { LValue, RValue, VariableDeclaration, NonExternal };
enum class IdentifierContext { LValue, RValue, VariableDeclaration };

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

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ contract C {
uint256 off1;
uint256 off2;
assembly {
function f() -> o1 {
function g() -> o1 {
sstore(z.slot, 7)
o1 := y.offset
}
off2 := f()
off2 := g()
}
assert(off2 == 2);
return true;
Expand Down
4 changes: 2 additions & 2 deletions test/libsolidity/semanticTests/inlineAssembly/leave.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
contract C {
function f() public pure returns (uint w) {
function g() public pure returns (uint w) {
assembly {
function f() -> t {
t := 2
Expand All @@ -14,4 +14,4 @@ contract C {
// compileToEwasm: also
// compileViaYul: also
// ----
// f() -> 2
// g() -> 2
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract C {
uint256 public z;

function f() public {
function g() public {
z = 42;
uint i = 32;
assembly {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract C {
function f() public pure {
assembly {
function f() {
function g() {
// Make sure this doesn't trigger the unimplemented assertion in the control flow builder.
leave
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {
function g() internal pure {
S storage c;
// this should warn about unreachable code, but currently function flow is ignored
assembly {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure {
function g() internal pure {
S storage c;
// this could be allowed, but currently control flow for functions is not analysed
assembly {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract C {
struct S { bool f; }
S s;
function f() internal pure returns (S storage c) {
function g() internal pure returns (S storage c) {
// this should warn about unreachable code, but currently function flow is ignored
assembly {
function f() { return(0, 0) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ contract C {
function f() internal pure returns (S storage c) {
// this could be allowed, but currently control flow for functions is not analysed
assembly {
function f() { revert(0, 0) }
f()
function g() { revert(0, 0) }
g()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ contract C {
}
}
// ----
// DeclarationError 3859: (103-104): This declaration shadows a declaration outside the inline assembly block.
// DeclarationError 6578: (123-124): Cannot access local Solidity variables from inside an inline assembly function.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
contract C {
function f() public pure {
function g() public pure {
assembly {
function f(a) {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract C {
function f() pure public {
assembly {
function f (a, b , c ) -> y,x,z {
function g (a, b , c ) -> y,x,z {
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
contract C {
function f() public pure {
assembly {
function f() {}
f := 1
function g() {}
g := 1
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
contract C {
function f() public pure {
function g() public pure {
assembly {
function f(a., x.b) -> t.b, b.. {}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
contract C {
function f() public pure {
function g() public pure {
assembly {
function f() -> x, y, z {}
let a., aa.b := f()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,5 @@ contract C {
// DeclarationError 4113: (595-600): The identifier name "super" is reserved.
// DeclarationError 4113: (645-646): The identifier name "_" is reserved.
// DeclarationError 4113: (759-763): The identifier name "this" is reserved.
// DeclarationError 3859: (759-763): This declaration shadows a declaration outside the inline assembly block.
// DeclarationError 4113: (785-790): The identifier name "super" is reserved.
// DeclarationError 3859: (785-790): This declaration shadows a declaration outside the inline assembly block.
// DeclarationError 4113: (812-813): The identifier name "_" is reserved.
2 changes: 1 addition & 1 deletion test/libsolidity/syntaxTests/inlineAssembly/leave.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract C {
function f() public pure {
assembly {
function f() {
function g() {
leave
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
contract C {
uint x;
function f() public pure {
assembly {
function g(f) -> x {}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, this wouldn't trigger the bug from the issue. But it's fine as long as such examples don't reach codegen.

}
}
}
// ----
// DeclarationError 3859: (98-99): This declaration shadows a declaration outside the inline assembly block.
// DeclarationError 3859: (104-105): This declaration shadows a declaration outside the inline assembly block.
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
contract C {
function f() public pure {
assembly {
function f() {}
}
}
}
// ----
// DeclarationError 3859: (75-90): This declaration shadows a declaration outside the inline assembly block.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
contract C {
function f() public pure {
uint a;
assembly {
function g(a) {}
}
}
}
// ----
// DeclarationError 3859: (102-103): This declaration shadows a declaration outside the inline assembly block.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,5 @@ contract C {
}
// ----
// DeclarationError 4113: (74-79): The identifier name "super" is reserved.
// DeclarationError 3859: (74-79): This declaration shadows a declaration outside the inline assembly block.
// DeclarationError 4113: (101-105): The identifier name "this" is reserved.
// DeclarationError 3859: (101-105): This declaration shadows a declaration outside the inline assembly block.
// DeclarationError 4113: (127-128): The identifier name "_" is reserved.
2 changes: 1 addition & 1 deletion test/libsolidity/syntaxTests/viewPureChecker/assembly.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ contract C {
assembly { for {} 1 { pop(sload(0)) } { } pop(gas()) }
}
function h() view public {
assembly { function g() { pop(blockhash(20)) } }
assembly { function g1() { pop(blockhash(20)) } }
}
function i() public {
assembly { pop(call(0, 1, 2, 3, 4, 5, 6)) }
Expand Down