diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp index b6cd3eef0..75d47785a 100644 --- a/libsolidity/analysis/DeclarationContainer.cpp +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -123,7 +123,11 @@ bool DeclarationContainer::registerDeclaration( if (conflictingDeclaration(_declaration, _name)) return false; - if (m_enclosingContainer && _declaration.isVisibleAsUnqualifiedName()) + if ( + m_enclosingContainer && + _declaration.isVisibleAsUnqualifiedName() && + !_declaration.isParentInterface() + ) m_homonymCandidates.emplace_back(*_name, _location ? _location : &_declaration.location()); } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 9d754202d..1bca465b6 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -114,6 +114,9 @@ public: ///@todo make this const-safe by providing a different way to access the annotation virtual ASTAnnotation& annotation() const; + /// Whether this node is a child of Interface contract. + virtual bool isParentInterface() const { return false; } + ///@{ ///@name equality operators /// Equality relies on the fact that nodes cannot be copied. @@ -956,7 +959,8 @@ public: ASTPointer const& _parameters, std::vector> _modifiers, ASTPointer const& _returnParameters, - ASTPointer const& _body + ASTPointer const& _body, + bool _isParentInterface ): CallableDeclaration(_id, _location, _name, _nameLocation, _visibility, _parameters, _isVirtual, _overrides, _returnParameters), StructurallyDocumented(_documentation), @@ -965,7 +969,8 @@ public: m_free(_free), m_kind(_kind), m_functionModifiers(std::move(_modifiers)), - m_body(_body) + m_body(_body), + m_isParentInterface(_isParentInterface) { solAssert(_kind == Token::Constructor || _kind == Token::Function || _kind == Token::Fallback || _kind == Token::Receive, ""); solAssert(isOrdinary() == !name().empty(), ""); @@ -1026,12 +1031,16 @@ public: ContractDefinition const* _searchStart = nullptr ) const override; + /// Whether this node is a child of Interface contract. + bool isParentInterface() const override { return m_isParentInterface; } + private: StateMutability m_stateMutability; bool m_free; Token const m_kind; std::vector> m_functionModifiers; ASTPointer m_body; + bool m_isParentInterface; }; /** diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index dd7098aab..e028b2cf1 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -132,16 +132,17 @@ SourceLocation ASTJsonImporter::createValueNameSourceLocation(Json::Value const& } template -ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node) +ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _node, bool _isParentInterface) { - ASTPointer ret = dynamic_pointer_cast(convertJsonToASTNode(_node)); + ASTPointer ret = dynamic_pointer_cast(convertJsonToASTNode(_node, _isParentInterface)); astAssert(ret, "cast of converted json-node must not be nullptr"); return ret; } - -ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _json) -{ +ASTPointer ASTJsonImporter::convertJsonToASTNode( + Json::Value const& _json, + bool _isParentInterface +) { astAssert(_json["nodeType"].isString() && _json.isMember("id"), "JSON-Node needs to have 'nodeType' and 'id' fields."); string nodeType = _json["nodeType"].asString(); if (nodeType == "PragmaDirective") @@ -169,7 +170,7 @@ ASTPointer ASTJsonImporter::convertJsonToASTNode(Json::Value const& _js if (nodeType == "OverrideSpecifier") return createOverrideSpecifier(_json); if (nodeType == "FunctionDefinition") - return createFunctionDefinition(_json); + return createFunctionDefinition(_json, _isParentInterface); if (nodeType == "VariableDeclaration") return createVariableDeclaration(_json); if (nodeType == "ModifierDefinition") @@ -337,9 +338,10 @@ ASTPointer ASTJsonImporter::createContractDefinition(Json::V baseContracts.push_back(createInheritanceSpecifier(base)); std::vector> subNodes; + bool isInterface = (contractKind(_node) == ContractKind::Interface); for (auto& subnode: _node["nodes"]) - subNodes.push_back(convertJsonToASTNode(subnode)); + subNodes.push_back(convertJsonToASTNode(subnode, isInterface)); return createASTNode( _node, @@ -514,8 +516,10 @@ ASTPointer ASTJsonImporter::createOverrideSpecifier(Json::Val ); } -ASTPointer ASTJsonImporter::createFunctionDefinition(Json::Value const& _node) -{ +ASTPointer ASTJsonImporter::createFunctionDefinition( + Json::Value const& _node, + bool _isParentInterface +) { astAssert(_node["kind"].isString(), "Expected 'kind' to be a string!"); Token kind; @@ -562,7 +566,8 @@ ASTPointer ASTJsonImporter::createFunctionDefinition(Json::V createParameterList(member(_node, "parameters")), modifiers, createParameterList(member(_node, "returnParameters")), - memberAsBool(_node, "implemented") ? createBlock(member(_node, "body"), false) : nullptr + memberAsBool(_node, "implemented") ? createBlock(member(_node, "body"), false) : nullptr, + _isParentInterface ); } diff --git a/libsolidity/ast/ASTJsonImporter.h b/libsolidity/ast/ASTJsonImporter.h index b9a4d4950..6794c8109 100644 --- a/libsolidity/ast/ASTJsonImporter.h +++ b/libsolidity/ast/ASTJsonImporter.h @@ -62,11 +62,11 @@ private: std::optional> createSourceLocations(Json::Value const& _node) const; /// Creates an ASTNode for a given JSON-ast of unknown type /// @returns Pointer to a new created ASTNode - ASTPointer convertJsonToASTNode(Json::Value const& _ast); + ASTPointer convertJsonToASTNode(Json::Value const& _ast, bool _isParentInterface = false); /// @returns a pointer to the more specific subclass of ASTNode /// as indicated by the nodeType field of the json template - ASTPointer convertJsonToASTNode(Json::Value const& _node); + ASTPointer convertJsonToASTNode(Json::Value const& _node, bool _isParentInterface = false); langutil::SourceLocation createNameSourceLocation(Json::Value const& _node); /// @returns source location of a mapping key name @@ -89,7 +89,7 @@ private: ASTPointer createUserDefinedValueTypeDefinition(Json::Value const& _node); ASTPointer createParameterList(Json::Value const& _node); ASTPointer createOverrideSpecifier(Json::Value const& _node); - ASTPointer createFunctionDefinition(Json::Value const& _node); + ASTPointer createFunctionDefinition(Json::Value const& _node, bool _isParentInterface); ASTPointer createVariableDeclaration(Json::Value const& _node); ASTPointer createModifierDefinition(Json::Value const& _node); ASTPointer createModifierInvocation(Json::Value const& _node); diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index efbe85448..e3eef5292 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -368,6 +368,7 @@ ASTPointer Parser::parseContractDefinition() { documentation = parseStructuredDocumentation(); contractKind = parseContractKind(); + bool isInterfaceContract = (contractKind.first == ContractKind::Interface); tie(name, nameLocation) = expectIdentifierWithLocation(); if (m_scanner->currentToken() == Token::Is) do @@ -388,7 +389,7 @@ ASTPointer Parser::parseContractDefinition() currentTokenValue == Token::Receive || currentTokenValue == Token::Fallback ) - subNodes.push_back(parseFunctionDefinition()); + subNodes.push_back(parseFunctionDefinition(false, isInterfaceContract)); else if (currentTokenValue == Token::Struct) subNodes.push_back(parseStructDefinition()); else if (currentTokenValue == Token::Enum) @@ -618,7 +619,7 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari return result; } -ASTPointer Parser::parseFunctionDefinition(bool _freeFunction) +ASTPointer Parser::parseFunctionDefinition(bool _freeFunction, bool _isParentInterface) { RecursionGuard recursionGuard(*this); ASTNodeFactory nodeFactory(*this); @@ -688,7 +689,8 @@ ASTPointer Parser::parseFunctionDefinition(bool _freeFunction) header.parameters, header.modifiers, header.returnParameters, - block + block, + _isParentInterface ); } diff --git a/libsolidity/parsing/Parser.h b/libsolidity/parsing/Parser.h index 65e8f61f3..d081950a2 100644 --- a/libsolidity/parsing/Parser.h +++ b/libsolidity/parsing/Parser.h @@ -100,7 +100,7 @@ private: ASTPointer parseOverrideSpecifier(); StateMutability parseStateMutability(); FunctionHeaderParserResult parseFunctionHeader(bool _isStateVariable); - ASTPointer parseFunctionDefinition(bool _freeFunction = false); + ASTPointer parseFunctionDefinition(bool _freeFunction = false, bool isParentInterface = false); ASTPointer parseStructDefinition(); ASTPointer parseEnumDefinition(); ASTPointer parseUserDefinedValueTypeDefinition(); diff --git a/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/args b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/args new file mode 100644 index 000000000..803d244eb --- /dev/null +++ b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/args @@ -0,0 +1 @@ + --import-ast diff --git a/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/err b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/err new file mode 100644 index 000000000..ecea658fb --- /dev/null +++ b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/err @@ -0,0 +1,7 @@ +Warning: Source file does not specify required compiler version! +--> A + +Warning: This declaration shadows an existing declaration. + --> A:1:481: +Note: The shadowed declaration is here: + --> A:1:335: diff --git a/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/exit b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/exit new file mode 100644 index 000000000..573541ac9 --- /dev/null +++ b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/exit @@ -0,0 +1 @@ +0 diff --git a/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/input.sol b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/input.sol new file mode 100644 index 000000000..95db13ea8 --- /dev/null +++ b/test/cmdlineTests/ast_json_import_function_shadow_free_vs_Interface/input.sol @@ -0,0 +1,694 @@ +{ + "language": "SolidityAST", + "sources": { + "A": { + "ast": { + "absolutePath": "", + "exportedSymbols": + { + "C": + [ + 51 + ], + "I": + [ + 22 + ], + "f": + [ + 30 + ], + "h": + [ + 38 + ] + }, + "id": 52, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "canonicalName": "I", + "contractDependencies": [], + "contractKind": "interface", + "fullyImplemented": false, + "id": 22, + "linearizedBaseContracts": + [ + 22 + ], + "name": "I", + "nameLocation": "10:1:0", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "functionSelector": "b3de648b", + "id": 7, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "27:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 3, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 2, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 7, + "src": "29:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 1, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "29:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "28:6:0" + }, + "returnParameters": + { + "id": 6, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 5, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 7, + "src": "53:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 4, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "53:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "52:6:0" + }, + "scope": 22, + "src": "18:41:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "functionSelector": "e420264a", + "id": 14, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "g", + "nameLocation": "109:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 10, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 9, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 14, + "src": "111:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 8, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "111:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "110:6:0" + }, + "returnParameters": + { + "id": 13, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 12, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 14, + "src": "135:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 11, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "135:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "134:6:0" + }, + "scope": 22, + "src": "100:41:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + }, + { + "functionSelector": "cb97492a", + "id": 21, + "implemented": false, + "kind": "function", + "modifiers": [], + "name": "h", + "nameLocation": "191:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 17, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 16, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 21, + "src": "193:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 15, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "193:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "192:6:0" + }, + "returnParameters": + { + "id": 20, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 19, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 21, + "src": "217:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 18, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "217:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "216:6:0" + }, + "scope": 22, + "src": "182:41:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "external" + } + ], + "scope": 52, + "src": "0:261:0", + "usedErrors": [], + "usedEvents": [] + }, + { + "body": + { + "id": 29, + "nodeType": "Block", + "src": "295:2:0", + "statements": [] + }, + "id": 30, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "f", + "nameLocation": "272:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 25, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 24, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 30, + "src": "274:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 23, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "274:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "273:6:0" + }, + "returnParameters": + { + "id": 28, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 27, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 30, + "src": "289:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 26, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "289:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "288:6:0" + }, + "scope": 52, + "src": "263:34:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "body": + { + "id": 37, + "nodeType": "Block", + "src": "366:2:0", + "statements": [] + }, + "id": 38, + "implemented": true, + "kind": "freeFunction", + "modifiers": [], + "name": "h", + "nameLocation": "343:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 33, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 32, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 38, + "src": "345:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 31, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "345:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "344:6:0" + }, + "returnParameters": + { + "id": 36, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 35, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 38, + "src": "360:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 34, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "360:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "359:6:0" + }, + "scope": 52, + "src": "334:34:0", + "stateMutability": "nonpayable", + "virtual": false, + "visibility": "internal" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "C", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 51, + "linearizedBaseContracts": + [ + 51 + ], + "name": "C", + "nameLocation": "400:1:0", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 43, + "nodeType": "Block", + "src": "437:2:0", + "statements": [] + }, + "functionSelector": "e420264a", + "id": 44, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "g", + "nameLocation": "417:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 41, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 40, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 44, + "src": "419:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 39, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "419:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "418:6:0" + }, + "returnParameters": + { + "id": 42, + "nodeType": "ParameterList", + "parameters": [], + "src": "437:0:0" + }, + "scope": 51, + "src": "408:31:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + }, + { + "body": + { + "id": 49, + "nodeType": "Block", + "src": "509:2:0", + "statements": [] + }, + "functionSelector": "cb97492a", + "id": 50, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "h", + "nameLocation": "489:1:0", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 47, + "nodeType": "ParameterList", + "parameters": + [ + { + "constant": false, + "id": 46, + "mutability": "mutable", + "name": "", + "nameLocation": "-1:-1:-1", + "nodeType": "VariableDeclaration", + "scope": 50, + "src": "491:4:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": + { + "id": 45, + "name": "uint", + "nodeType": "ElementaryTypeName", + "src": "491:4:0", + "typeDescriptions": + { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "490:6:0" + }, + "returnParameters": + { + "id": 48, + "nodeType": "ParameterList", + "parameters": [], + "src": "509:0:0" + }, + "scope": 51, + "src": "480:31:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 52, + "src": "391:146:0", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "0:538:0" + } + } + } +} diff --git a/test/libsolidity/syntaxTests/scoping/name_shadowing_interface_function_vs_free_function.sol b/test/libsolidity/syntaxTests/scoping/name_shadowing_interface_function_vs_free_function.sol new file mode 100644 index 000000000..e1456fd66 --- /dev/null +++ b/test/libsolidity/syntaxTests/scoping/name_shadowing_interface_function_vs_free_function.sol @@ -0,0 +1,15 @@ +interface I { + function f(uint) external returns (uint); // Should not shadow or be shadowed + function g(uint) external returns (uint); // Should not shadow or be shadowed + function h(uint) external returns (uint); // Should not shadow or be shadowed +} + +function f(uint) returns (uint) {} // Should not shadow or be shadowed +function h(uint) returns (uint) {} // Shadowed by C.h() + +contract C { + function g(uint) public pure {} // Should not shadow or be shadowed + function h(uint) public pure {} // Shadows the free h() +} +// ---- +// Warning 2519: (480-511): This declaration shadows an existing declaration.