diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 43a77002d281..4393012522a8 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -1720,34 +1720,12 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess) ); } else if (possibleMembers.size() > 1) - { - // Remove builtins (i.e. not having a declaration) first - for (auto it = possibleMembers.begin(); it != possibleMembers.end();) - if ( - ( - // Overloaded functions without declaration (e.g. transfer(), send(), call(), etc.) - it->type->category() == Type::Category::Function && - !dynamic_cast(*it->type).hasDeclaration() - ) - || - ( - // Overloaded members (e.g. balance) - it->type->category() == Type::Category::Integer && - memberName == "balance" - ) - ) - it = possibleMembers.erase(it); - else - ++it; - - if (possibleMembers.size() > 1) - m_errorReporter.fatalTypeError( - _memberAccess.location(), - "Member \"" + memberName + "\" not unique " - "after argument-dependent lookup in " + exprType->toString() + - (memberName == "value" ? " - did you forget the \"payable\" modifier?" : "") - ); - } + m_errorReporter.fatalTypeError( + _memberAccess.location(), + "Member \"" + memberName + "\" not unique " + "after argument-dependent lookup in " + exprType->toString() + + (memberName == "value" ? " - did you forget the \"payable\" modifier?" : "") + ); auto& annotation = _memberAccess.annotation(); annotation.referencedDeclaration = possibleMembers.front().declaration; diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index ebf2cd8b34b3..e0b28ef2314e 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -1619,7 +1619,8 @@ string ContractType::canonicalName() const MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const*) const { // All address members and all interface functions - MemberList::MemberMap members(IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr)); + MemberList::MemberMap addressMembers = IntegerType(160, IntegerType::Modifier::Address).nativeMembers(nullptr); + MemberList::MemberMap members; if (m_super) { // add the most derived of all functions which are visible in derived contracts @@ -1661,6 +1662,37 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const*) con &it.second->declaration() )); } + // Add overloads from address only if there is no conflict + for (auto it = addressMembers.begin(); it != addressMembers.end(); ++it) + { + bool clash = false; + for (auto const member: members) + { + if ( + member.name == it->name && + ( + // Members with different types are not allowed + member.type->category() != it->type->category() || + // Members must overload functions without clash + ( + member.type->category() == Type::Category::Function && + dynamic_cast(*member.type).hasEqualArgumentTypes(dynamic_cast(*it->type)) + ) + ) + ) + { + clash = true; + break; + } + } + + if (!clash) + members.push_back(MemberList::Member( + it->name, + it->type, + it->declaration + )); + } return members; }