diff options
author | chriseth <chris@ethereum.org> | 2017-08-05 01:49:25 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-05 01:49:25 +0800 |
commit | f3af014afd1e6e70ab25ea30bff6f272cc73b0a9 (patch) | |
tree | d0828a5282a849ba6f899973d72375ad5b12da50 | |
parent | dc0f85c4fb65fa385bb7145c73cc5edaba195483 (diff) | |
parent | eacc67c43003c26e87f65dae41e448ddeb9fb317 (diff) | |
download | dexon-solidity-f3af014afd1e6e70ab25ea30bff6f272cc73b0a9.tar dexon-solidity-f3af014afd1e6e70ab25ea30bff6f272cc73b0a9.tar.gz dexon-solidity-f3af014afd1e6e70ab25ea30bff6f272cc73b0a9.tar.bz2 dexon-solidity-f3af014afd1e6e70ab25ea30bff6f272cc73b0a9.tar.lz dexon-solidity-f3af014afd1e6e70ab25ea30bff6f272cc73b0a9.tar.xz dexon-solidity-f3af014afd1e6e70ab25ea30bff6f272cc73b0a9.tar.zst dexon-solidity-f3af014afd1e6e70ab25ea30bff6f272cc73b0a9.zip |
Merge pull request #2692 from ethereum/shadowing-overload
Do not mark overloaded functions as shadowing
-rw-r--r-- | Changelog.md | 1 | ||||
-rw-r--r-- | libsolidity/analysis/DeclarationContainer.h | 1 | ||||
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 10 | ||||
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.h | 2 | ||||
-rw-r--r-- | test/libsolidity/SolidityNameAndTypeResolution.cpp | 41 |
5 files changed, 48 insertions, 7 deletions
diff --git a/Changelog.md b/Changelog.md index 86cf1058..7d3369f3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -5,6 +5,7 @@ Features: Bugfixes: * Code Generator: ``.delegatecall()`` should always return execution outcome. * Code Generator: Provide "new account gas" for low-level ``callcode`` and ``delegatecall``. + * Type Checker: Do not mark overloaded functions as shadowing other functions. * Type Checker: Disallow the ``.gas()`` modifier on ``ecrecover``, ``sha256`` and ``ripemd160``. ### 0.4.14 (2017-07-31) diff --git a/libsolidity/analysis/DeclarationContainer.h b/libsolidity/analysis/DeclarationContainer.h index 9c7c89e7..301998b7 100644 --- a/libsolidity/analysis/DeclarationContainer.h +++ b/libsolidity/analysis/DeclarationContainer.h @@ -53,6 +53,7 @@ public: bool registerDeclaration(Declaration const& _declaration, ASTString const* _name = nullptr, bool _invisible = false, bool _update = false); std::vector<Declaration const*> resolveName(ASTString const& _name, bool _recursive = false) const; ASTNode const* enclosingNode() const { return m_enclosingNode; } + DeclarationContainer const* enclosingContainer() const { return m_enclosingContainer; } std::map<ASTString, std::vector<Declaration const*>> const& declarations() const { return m_declarations; } /// @returns whether declaration is valid, and if not also returns previous declaration. Declaration const* conflictingDeclaration(Declaration const& _declaration, ASTString const* _name = nullptr) const; diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index df83f382..523e7176 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -452,13 +452,9 @@ bool DeclarationRegistrationHelper::registerDeclaration( _errorLocation = &_declaration.location(); Declaration const* shadowedDeclaration = nullptr; - if (_warnOnShadow && !_declaration.name().empty()) - for (auto const* decl: _container.resolveName(_declaration.name(), true)) - if (decl != &_declaration) - { - shadowedDeclaration = decl; - break; - } + if (_warnOnShadow && !_declaration.name().empty() && _container.enclosingContainer()) + for (auto const* decl: _container.enclosingContainer()->resolveName(_declaration.name(), true)) + shadowedDeclaration = decl; if (!_container.registerDeclaration(_declaration, _name, !_declaration.isVisibleInContract())) { diff --git a/libsolidity/analysis/NameAndTypeResolver.h b/libsolidity/analysis/NameAndTypeResolver.h index a498c7ba..59bd3b1f 100644 --- a/libsolidity/analysis/NameAndTypeResolver.h +++ b/libsolidity/analysis/NameAndTypeResolver.h @@ -169,6 +169,8 @@ private: void closeCurrentScope(); void registerDeclaration(Declaration& _declaration, bool _opensScope); + static bool isOverloadedFunction(Declaration const& _declaration1, Declaration const& _declaration2); + /// @returns the canonical name of the current scope. std::string currentCanonicalName() const; diff --git a/test/libsolidity/SolidityNameAndTypeResolution.cpp b/test/libsolidity/SolidityNameAndTypeResolution.cpp index 4fe52243..4d367d3a 100644 --- a/test/libsolidity/SolidityNameAndTypeResolution.cpp +++ b/test/libsolidity/SolidityNameAndTypeResolution.cpp @@ -6134,6 +6134,25 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_with_variables) CHECK_WARNING(text, "shadows a builtin symbol"); } +BOOST_AUTO_TEST_CASE(shadowing_builtins_with_storage_variables) +{ + char const* text = R"( + contract C { + uint msg; + } + )"; + CHECK_WARNING(text, "shadows a builtin symbol"); +} + +BOOST_AUTO_TEST_CASE(shadowing_builtin_at_global_scope) +{ + char const* text = R"( + contract msg { + } + )"; + CHECK_WARNING(text, "shadows a builtin symbol"); +} + BOOST_AUTO_TEST_CASE(shadowing_builtins_with_parameters) { char const* text = R"( @@ -6190,6 +6209,28 @@ BOOST_AUTO_TEST_CASE(shadowing_builtins_ignores_constructor) CHECK_SUCCESS_NO_WARNINGS(text); } +BOOST_AUTO_TEST_CASE(function_overload_is_not_shadowing) +{ + char const* text = R"( + contract C { + function f() {} + function f(uint) {} + } + )"; + CHECK_SUCCESS_NO_WARNINGS(text); +} + +BOOST_AUTO_TEST_CASE(function_override_is_not_shadowing) +{ + char const* text = R"( + contract D { function f() {} } + contract C is D { + function f(uint) {} + } + )"; + CHECK_SUCCESS_NO_WARNINGS(text); +} + BOOST_AUTO_TEST_CASE(callable_crash) { char const* text = R"( |