From c286cdaa6275442ed67dabd41b478cec5cf5b8ca Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Fri, 6 Jul 2018 11:04:30 +0200 Subject: [PATCH 1/2] Fix crash for double variable declaration in the same scope. --- libsolidity/analysis/DeclarationContainer.cpp | 5 +++++ libsolidity/analysis/DeclarationContainer.h | 3 +++ libsolidity/analysis/NameAndTypeResolver.cpp | 3 ++- ...iable_declaration_same_and_disjoint_scope.sol | 10 ++++++++++ .../double_variable_declaration_same_scope.sol | 8 ++++++++ .../poly_variable_declaration_same_scope.sol | 16 ++++++++++++++++ 6 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol create mode 100644 test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol create mode 100644 test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp index 786272e45..9e2bf6d31 100644 --- a/libsolidity/analysis/DeclarationContainer.cpp +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -96,6 +96,11 @@ void DeclarationContainer::activateVariable(ASTString const& _name) m_invisibleDeclarations.erase(_name); } +bool DeclarationContainer::isInvisible(ASTString const& _name) const +{ + return m_invisibleDeclarations.count(_name); +} + bool DeclarationContainer::registerDeclaration( Declaration const& _declaration, ASTString const* _name, diff --git a/libsolidity/analysis/DeclarationContainer.h b/libsolidity/analysis/DeclarationContainer.h index a3e0bd0af..9d7a17a3b 100644 --- a/libsolidity/analysis/DeclarationContainer.h +++ b/libsolidity/analysis/DeclarationContainer.h @@ -62,6 +62,9 @@ public: /// VariableDeclarationStatements. void activateVariable(ASTString const& _name); + /// @returns true if declaration is currently invisible. + bool isInvisible(ASTString const& _name) const; + /// @returns existing declaration names similar to @a _name. /// Searches this and all parent containers. std::vector similarNames(ASTString const& _name) const; diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index b856544aa..fce98f710 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -156,7 +156,8 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) void NameAndTypeResolver::activateVariable(string const& _name) { solAssert(m_currentScope, ""); - m_currentScope->activateVariable(_name); + if (m_currentScope->isInvisible(_name)) + m_currentScope->activateVariable(_name); } vector NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol new file mode 100644 index 000000000..45c5ff2dc --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_and_disjoint_scope.sol @@ -0,0 +1,10 @@ +contract test { + function f() pure public { + uint x; + { uint x; } + uint x; + } +} +// ---- +// Warning: (73-79): This declaration shadows an existing declaration. +// DeclarationError: (91-97): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol new file mode 100644 index 000000000..72c31f73c --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/double_variable_declaration_same_scope.sol @@ -0,0 +1,8 @@ +contract test { + function f() pure public { + uint x; + uint x; + } +} +// ---- +// DeclarationError: (71-77): Identifier already declared. diff --git a/test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol b/test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol new file mode 100644 index 000000000..e414f6117 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/poly_variable_declaration_same_scope.sol @@ -0,0 +1,16 @@ +contract test { + function f() pure public { + uint x; + uint x; + uint x; + uint x; + uint x; + uint x; + } +} +// ---- +// DeclarationError: (71-77): Identifier already declared. +// DeclarationError: (87-93): Identifier already declared. +// DeclarationError: (103-109): Identifier already declared. +// DeclarationError: (119-125): Identifier already declared. +// DeclarationError: (135-141): Identifier already declared. From cee4775a589bc0047bc505b82fc174ddf07b703d Mon Sep 17 00:00:00 2001 From: Leonardo Alt Date: Tue, 10 Jul 2018 18:54:43 +0200 Subject: [PATCH 2/2] Add comment explaining new code --- libsolidity/analysis/NameAndTypeResolver.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index fce98f710..7c23c992d 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -156,6 +156,11 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration) void NameAndTypeResolver::activateVariable(string const& _name) { solAssert(m_currentScope, ""); + // Scoped local variables are invisible before activation. + // When a local variable is activated, its name is removed + // from a scope's invisible variables. + // This is used to avoid activation of variables of same name + // in the same scope (an error is returned). if (m_currentScope->isInvisible(_name)) m_currentScope->activateVariable(_name); }