mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #1194 from ethereum/bound-functions
Proper type checking for bound functions
This commit is contained in:
commit
4f191d1f6f
@ -8,6 +8,7 @@ Features:
|
|||||||
|
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
* Disallow unknown options in `solc`
|
* Disallow unknown options in `solc`
|
||||||
|
* Proper type checking for bound functions.
|
||||||
* Code Generator: expect zero stack increase after `super` as an expression
|
* Code Generator: expect zero stack increase after `super` as an expression
|
||||||
* Inline assembly: support the `address` opcode
|
* Inline assembly: support the `address` opcode
|
||||||
* Inline assembly: fix parsing of assignment after a label.
|
* Inline assembly: fix parsing of assignment after a label.
|
||||||
|
@ -241,6 +241,7 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition
|
|||||||
seenFunctions.insert(function);
|
seenFunctions.insert(function);
|
||||||
FunctionType funType(*function, false);
|
FunctionType funType(*function, false);
|
||||||
if (auto fun = funType.asMemberFunction(true, true))
|
if (auto fun = funType.asMemberFunction(true, true))
|
||||||
|
if (_type.isImplicitlyConvertibleTo(*fun->selfType()))
|
||||||
members.push_back(MemberList::Member(function->name(), fun, function));
|
members.push_back(MemberList::Member(function->name(), fun, function));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2069,6 +2070,9 @@ TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) con
|
|||||||
|
|
||||||
FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound) const
|
FunctionTypePointer FunctionType::asMemberFunction(bool _inLibrary, bool _bound) const
|
||||||
{
|
{
|
||||||
|
if (_bound && m_parameterTypes.empty())
|
||||||
|
return FunctionTypePointer();
|
||||||
|
|
||||||
TypePointers parameterTypes;
|
TypePointers parameterTypes;
|
||||||
for (auto const& t: m_parameterTypes)
|
for (auto const& t: m_parameterTypes)
|
||||||
{
|
{
|
||||||
|
@ -872,7 +872,12 @@ public:
|
|||||||
m_isConstant(_isConstant),
|
m_isConstant(_isConstant),
|
||||||
m_isPayable(_isPayable),
|
m_isPayable(_isPayable),
|
||||||
m_declaration(_declaration)
|
m_declaration(_declaration)
|
||||||
{}
|
{
|
||||||
|
solAssert(
|
||||||
|
!m_bound || !m_parameterTypes.empty(),
|
||||||
|
"Attempted construction of bound function without self type"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
TypePointers parameterTypes() const;
|
TypePointers parameterTypes() const;
|
||||||
std::vector<std::string> parameterNames() const;
|
std::vector<std::string> parameterNames() const;
|
||||||
@ -940,8 +945,9 @@ public:
|
|||||||
/// removed and the location of reference types is changed from CallData to Memory.
|
/// removed and the location of reference types is changed from CallData to Memory.
|
||||||
/// This is needed if external functions are called on other contracts, as they cannot return
|
/// This is needed if external functions are called on other contracts, as they cannot return
|
||||||
/// dynamic values.
|
/// dynamic values.
|
||||||
|
/// Returns empty shared pointer on a failure. Namely, if a bound function has no parameters.
|
||||||
/// @param _inLibrary if true, uses DelegateCall as location.
|
/// @param _inLibrary if true, uses DelegateCall as location.
|
||||||
/// @param _bound if true, the argumenst are placed as `arg1.functionName(arg2, ..., argn)`.
|
/// @param _bound if true, the arguments are placed as `arg1.functionName(arg2, ..., argn)`.
|
||||||
FunctionTypePointer asMemberFunction(bool _inLibrary, bool _bound = false) const;
|
FunctionTypePointer asMemberFunction(bool _inLibrary, bool _bound = false) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -4020,6 +4020,25 @@ BOOST_AUTO_TEST_CASE(invalid_array_as_statement)
|
|||||||
BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
|
BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(using_directive_for_missing_selftype)
|
||||||
|
{
|
||||||
|
char const* text = R"(
|
||||||
|
library B {
|
||||||
|
function b() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
contract A {
|
||||||
|
using B for bytes;
|
||||||
|
|
||||||
|
function a() {
|
||||||
|
bytes memory x;
|
||||||
|
x.b();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
BOOST_CHECK(expectError(text, false) == Error::Type::TypeError);
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user