Skip to content

Commit

Permalink
Simplify address overloading
Browse files Browse the repository at this point in the history
  • Loading branch information
axic committed Sep 27, 2017
1 parent 04aa668 commit e1eaf4e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 29 deletions.
34 changes: 6 additions & 28 deletions libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<FunctionType const&>(*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;
Expand Down
34 changes: 33 additions & 1 deletion libsolidity/ast/Types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<FunctionType const&>(*member.type).hasEqualArgumentTypes(dynamic_cast<FunctionType const&>(*it->type))
)
)
)
{
clash = true;
break;
}
}

if (!clash)
members.push_back(MemberList::Member(
it->name,
it->type,
it->declaration
));
}
return members;
}

Expand Down

0 comments on commit e1eaf4e

Please sign in to comment.