Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion libsolidity/analysis/TypeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3175,13 +3175,19 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
size_t const initialMemberCount = possibleMembers.size();
if (initialMemberCount > 1 && arguments)
{
// do overload resolution
// Do overload resolution, and filter out non-functions when called with parentheses.
// This allows library functions like OpenZeppelin's Address.isContract() to work
// alongside Tron's native address.isContract property.
// Mirrors the identifier resolution pattern at lines 3693-3745 where
// VariableDeclarations are preferred without parentheses.
for (auto it = possibleMembers.begin(); it != possibleMembers.end();)
if (
it->type->category() == Type::Category::Function &&
!dynamic_cast<FunctionType const&>(*it->type).canTakeArguments(*arguments, exprType)
)
it = possibleMembers.erase(it);
else if (it->type->category() != Type::Category::Function)
it = possibleMembers.erase(it);
else
++it;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;

// Test that library function is preferred over native property when called with parentheses.
// This allows OpenZeppelin's Address.isContract() to work alongside Tron's native address.isContract property.
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
}

contract C {
using Address for address;

function check(address a) public view returns (bool) {
// With parentheses - should use library function
return a.isContract();
}
}
// ----
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;

// Test that accessing a member without parentheses when both a native property
// and a library function exist with the same name results in an ambiguity error.
// Users should use the native property syntax directly without "using for" to avoid this.
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
}

contract C {
using Address for address;

function check(address a) public view returns (bool) {
// Without parentheses - ambiguous between native property and library function
return a.isContract;
}
}
// ----
// TypeError 6675: (519-531): Member "isContract" not unique after argument-dependent lookup in address.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.8.0;

// Test Tron's native address.isContract property works without library.
contract C {
function check(address a) public view returns (bool) {
return a.isContract;
}
}
// ----