mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Fix error msg hint for non-payable contracts
This commit is contained in:
parent
f003696d7e
commit
10a9960eb3
@ -2064,7 +2064,8 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
||||
errorMsg += " Did you intend to call the function?";
|
||||
}
|
||||
}
|
||||
if (exprType->category() == Type::Category::Contract)
|
||||
else if (exprType->category() == Type::Category::Contract)
|
||||
{
|
||||
for (auto const& addressMember: AddressType::addressPayable().nativeMembers(nullptr))
|
||||
if (addressMember.name == memberName)
|
||||
{
|
||||
@ -2073,6 +2074,21 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
||||
errorMsg += " Use \"address(" + varName + ")." + memberName + "\" to access this address member.";
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (auto addressType = dynamic_cast<AddressType const*>(exprType.get()))
|
||||
{
|
||||
// Trigger error when using send or transfer with a non-payable fallback function.
|
||||
if (memberName == "send" || memberName == "transfer")
|
||||
{
|
||||
solAssert(
|
||||
addressType->stateMutability() != StateMutability::Payable,
|
||||
"Expected address not-payable as members were not found"
|
||||
);
|
||||
|
||||
errorMsg = "\"send\" and \"transfer\" are only available for objects of type \"address payable\", not \"" + exprType->toString() + "\".";
|
||||
}
|
||||
}
|
||||
|
||||
m_errorReporter.fatalTypeError(
|
||||
_memberAccess.location(),
|
||||
errorMsg
|
||||
@ -2115,26 +2131,6 @@ bool TypeChecker::visit(MemberAccess const& _memberAccess)
|
||||
annotation.isLValue = annotation.referencedDeclaration->isLValue();
|
||||
}
|
||||
|
||||
if (exprType->category() == Type::Category::Contract)
|
||||
{
|
||||
// Warn about using send or transfer with a non-payable fallback function.
|
||||
if (auto callType = dynamic_cast<FunctionType const*>(type(_memberAccess).get()))
|
||||
{
|
||||
auto kind = callType->kind();
|
||||
auto contractType = dynamic_cast<ContractType const*>(exprType.get());
|
||||
solAssert(!!contractType, "Should be contract type.");
|
||||
|
||||
if (
|
||||
(kind == FunctionType::Kind::Send || kind == FunctionType::Kind::Transfer) &&
|
||||
!contractType->isPayable()
|
||||
)
|
||||
m_errorReporter.typeError(
|
||||
_memberAccess.location(),
|
||||
"Value transfer to a contract without a payable fallback function."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO some members might be pure, but for example `address(0x123).balance` is not pure
|
||||
// although every subexpression is, so leaving this limited for now.
|
||||
if (auto tt = dynamic_cast<TypeType const*>(exprType.get()))
|
||||
|
@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
address(this).send(10);
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// TypeError: (47-65): "send" and "transfer" are only available for objects of type "address payable", not "address".
|
@ -0,0 +1,8 @@
|
||||
contract C {
|
||||
function f() public {
|
||||
address(this).transfer(10);
|
||||
}
|
||||
}
|
||||
|
||||
// ----
|
||||
// TypeError: (47-69): "send" and "transfer" are only available for objects of type "address payable", not "address".
|
Loading…
Reference in New Issue
Block a user