From 73a64da041efb2b64b1c89ed6012161cb278e24e Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 29 Nov 2018 19:30:27 +0100 Subject: Fix bug related to state variables of function type accessed via base contract. --- Changelog.md | 1 + libsolidity/codegen/ExpressionCompiler.cpp | 6 +++--- test/libsolidity/SolidityEndToEndTest.cpp | 20 ++++++++++++++++++++ .../memberLookup/internal_function_type.sol | 7 +++++++ 4 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 test/libsolidity/syntaxTests/memberLookup/internal_function_type.sol diff --git a/Changelog.md b/Changelog.md index 99c1ead8..a54b999f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -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. diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index 87eecd2e..121585d9 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -1153,7 +1153,9 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) if (dynamic_cast(type->actualType().get())) { solAssert(_memberAccess.annotation().type, "_memberAccess has no type"); - if (auto funType = dynamic_cast(_memberAccess.annotation().type.get())) + if (auto variable = dynamic_cast(_memberAccess.annotation().referencedDeclaration)) + appendVariable(*variable, static_cast(_memberAccess)); + else if (auto funType = dynamic_cast(_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(_memberAccess.annotation().referencedDeclaration)) - appendVariable(*variable, static_cast(_memberAccess)); else _memberAccess.expression().accept(*this); } diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 05bb7446..c6135a72 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -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() } diff --git a/test/libsolidity/syntaxTests/memberLookup/internal_function_type.sol b/test/libsolidity/syntaxTests/memberLookup/internal_function_type.sol new file mode 100644 index 00000000..560a6c2a --- /dev/null +++ b/test/libsolidity/syntaxTests/memberLookup/internal_function_type.sol @@ -0,0 +1,7 @@ +contract C { + function () internal returns (uint) x; + constructor() public { + C.x = g; + } + function g() public pure returns (uint) {} +} -- cgit v1.2.3