mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix overload resolution when conflict is with members of address (balance, transfer, etc)
This commit is contained in:
parent
010189d58e
commit
7cb4d714c7
@ -5,6 +5,8 @@ Features:
|
|||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Parser: Fix source location of VariableDeclarationStatement.
|
* Parser: Fix source location of VariableDeclarationStatement.
|
||||||
|
* Type Checker: Properly support overwriting members inherited from ``address`` in a contract
|
||||||
|
(such as ``balance``, ``transfer``, etc.)
|
||||||
|
|
||||||
### 0.4.17 (2017-09-21)
|
### 0.4.17 (2017-09-21)
|
||||||
|
|
||||||
|
@ -1720,12 +1720,34 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (possibleMembers.size() > 1)
|
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(
|
m_errorReporter.fatalTypeError(
|
||||||
_memberAccess.location(),
|
_memberAccess.location(),
|
||||||
"Member \"" + memberName + "\" not unique "
|
"Member \"" + memberName + "\" not unique "
|
||||||
"after argument-dependent lookup in " + exprType->toString() +
|
"after argument-dependent lookup in " + exprType->toString() +
|
||||||
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : "")
|
(memberName == "value" ? " - did you forget the \"payable\" modifier?" : "")
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
auto& annotation = _memberAccess.annotation();
|
auto& annotation = _memberAccess.annotation();
|
||||||
annotation.referencedDeclaration = possibleMembers.front().declaration;
|
annotation.referencedDeclaration = possibleMembers.front().declaration;
|
||||||
|
@ -10151,6 +10151,31 @@ BOOST_AUTO_TEST_CASE(constant_string)
|
|||||||
ABI_CHECK(callContractFunction("h()"), encodeDyn(string("hello")));
|
ABI_CHECK(callContractFunction("h()"), encodeDyn(string("hello")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(address_overload_resolution)
|
||||||
|
{
|
||||||
|
char const* sourceCode = R"(
|
||||||
|
contract C {
|
||||||
|
function balance() returns (uint) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
function transfer(uint amount) returns (uint) {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract D {
|
||||||
|
function f() returns (uint) {
|
||||||
|
return (new C()).balance();
|
||||||
|
}
|
||||||
|
function g() returns (uint) {
|
||||||
|
return (new C()).transfer(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
compileAndRun(sourceCode, 0, "D");
|
||||||
|
BOOST_CHECK(callContractFunction("f()") == encodeArgs(u256(1)));
|
||||||
|
BOOST_CHECK(callContractFunction("g()") == encodeArgs(u256(5)));
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -6953,6 +6953,29 @@ BOOST_AUTO_TEST_CASE(warn_about_suicide)
|
|||||||
CHECK_WARNING(text, "\"suicide\" has been deprecated in favour of \"selfdestruct\"");
|
CHECK_WARNING(text, "\"suicide\" has been deprecated in favour of \"selfdestruct\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(address_overload_resolution)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
contract C {
|
||||||
|
function balance() returns (uint) {
|
||||||
|
this.balance; // to avoid pureness warning
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
function transfer(uint amount) {
|
||||||
|
address(this).transfer(amount); // to avoid pureness warning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
contract D {
|
||||||
|
function f() {
|
||||||
|
var x = (new C()).balance();
|
||||||
|
x;
|
||||||
|
(new C()).transfer(5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
CHECK_SUCCESS(text);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user