Fix bug related to state variables of function type accessed via base contract.

This commit is contained in:
chriseth 2018-11-29 19:30:27 +01:00
parent 124a8def84
commit 73a64da041
4 changed files with 31 additions and 3 deletions

View File

@ -18,6 +18,7 @@ Bugfixes:
* Assembly output: Do not mix in/out jump annotations with arguments.
* Commandline interface: Fix crash when using ``--ast`` on empty runtime code.
* Code Generator: Annotate jump from calldata decoder to function as "jump in".
* Code Generator: Fix internal error related to state variables of function type access via base contract name.
* Optimizer: Fix nondeterminism bug related to the boost version and constants representation. The bug only resulted in less optimal but still correct code because the generated routine is always verified to be correct.
* Type Checker: Properly detect different return types when overriding an external interface function with a public contract function.
* Type Checker: Disallow struct return types for getters of public state variables unless the new ABI encoder is active.

View File

@ -1153,7 +1153,9 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
if (dynamic_cast<ContractType const*>(type->actualType().get()))
{
solAssert(_memberAccess.annotation().type, "_memberAccess has no type");
if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type.get()))
if (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
appendVariable(*variable, static_cast<Expression const&>(_memberAccess));
else if (auto funType = dynamic_cast<FunctionType const*>(_memberAccess.annotation().type.get()))
{
switch (funType->kind())
{
@ -1199,8 +1201,6 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess)
{
// no-op
}
else if (auto variable = dynamic_cast<VariableDeclaration const*>(_memberAccess.annotation().referencedDeclaration))
appendVariable(*variable, static_cast<Expression const&>(_memberAccess));
else
_memberAccess.expression().accept(*this);
}

View File

@ -14213,6 +14213,26 @@ BOOST_AUTO_TEST_CASE(external_public_override)
ABI_CHECK(callContractFunction("f()"), encodeArgs(2));
ABI_CHECK(callContractFunction("g()"), encodeArgs(2));
}
BOOST_AUTO_TEST_CASE(base_access_to_function_type_variables)
{
char const* sourceCode = R"(
contract C {
function () internal returns (uint) x;
function set() public {
C.x = g;
}
function g() public pure returns (uint) { return 2; }
function h() public returns (uint) { return C.x(); }
}
)";
compileAndRun(sourceCode);
ABI_CHECK(callContractFunction("g()"), encodeArgs(2));
ABI_CHECK(callContractFunction("h()"), encodeArgs());
ABI_CHECK(callContractFunction("set()"), encodeArgs());
ABI_CHECK(callContractFunction("h()"), encodeArgs(2));
}
BOOST_AUTO_TEST_SUITE_END()
}

View File

@ -0,0 +1,7 @@
contract C {
function () internal returns (uint) x;
constructor() public {
C.x = g;
}
function g() public pure returns (uint) {}
}