From 96ca706353f94b60c7e356f11aa7466a15eca33d Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Fri, 2 Dec 2016 12:03:39 +0100 Subject: test: add a test case for #1286 --- test/libsolidity/SolidityEndToEndTest.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index 94d4fb7f..d8539524 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -2770,6 +2770,28 @@ BOOST_AUTO_TEST_CASE(event_no_arguments) BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("Deposit()"))); } +BOOST_AUTO_TEST_CASE(event_access_through_base_name) +{ + char const* sourceCode = R"( + contract A { + event x(); + } + contract B is A { + function f() returns (uint) { + A.x(); + return 1; + } + } + )"; + compileAndRun(sourceCode); + callContractFunction("f()"); + BOOST_REQUIRE_EQUAL(m_logs.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].address, m_contractAddress); + BOOST_CHECK(m_logs[0].data.empty()); + BOOST_REQUIRE_EQUAL(m_logs[0].topics.size(), 1); + BOOST_CHECK_EQUAL(m_logs[0].topics[0], dev::keccak256(string("x()"))); +} + BOOST_AUTO_TEST_CASE(event_anonymous) { char const* sourceCode = R"( -- cgit v1.2.3 From 6a312233fcbaf9b7ec7b7088719a3be724ea228b Mon Sep 17 00:00:00 2001 From: Yoichi Hirai Date: Wed, 26 Oct 2016 13:08:00 +0200 Subject: ast, codegen: enable accessing events through contract names. Fixes #1286 --- Changelog.md | 3 +++ libsolidity/ast/AST.cpp | 3 +++ libsolidity/codegen/ExpressionCompiler.cpp | 42 +++++++++++++++++++++++------- 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Changelog.md b/Changelog.md index 9faf0f8e..a82e8744 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,8 @@ ### 0.4.8 (unreleased) +BugFixes: + * Type checker, code generator: enable access to events of base contracts' names. + ### 0.4.7 (2016-12-15) Features: diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 3cd1dfbe..78d8949c 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -217,6 +217,9 @@ vector const& ContractDefinition::inheritableMembers() const for (EnumDefinition const* e: definedEnums()) addInheritableMember(e); + + for (EventDefinition const* e: events()) + addInheritableMember(e); } return *m_inheritableMembers; } diff --git a/libsolidity/codegen/ExpressionCompiler.cpp b/libsolidity/codegen/ExpressionCompiler.cpp index a7fb8408..3922da88 100644 --- a/libsolidity/codegen/ExpressionCompiler.cpp +++ b/libsolidity/codegen/ExpressionCompiler.cpp @@ -908,19 +908,43 @@ bool ExpressionCompiler::visit(MemberAccess const& _memberAccess) solAssert(_memberAccess.annotation().type, "_memberAccess has no type"); if (auto funType = dynamic_cast(_memberAccess.annotation().type.get())) { - if (funType->location() != FunctionType::Location::Internal) - { - _memberAccess.expression().accept(*this); - m_context << funType->externalIdentifier(); - } - else + switch (funType->location()) { + case FunctionType::Location::Internal: // We do not visit the expression here on purpose, because in the case of an // internal library function call, this would push the library address forcing // us to link against it although we actually do not need it. - auto const* function = dynamic_cast(_memberAccess.annotation().referencedDeclaration); - solAssert(!!function, "Function not found in member access"); - utils().pushCombinedFunctionEntryLabel(*function); + if (auto const* function = dynamic_cast(_memberAccess.annotation().referencedDeclaration)) + utils().pushCombinedFunctionEntryLabel(*function); + else + solAssert(false, "Function not found in member access"); + break; + case FunctionType::Location::Event: + if (!dynamic_cast(_memberAccess.annotation().referencedDeclaration)) + solAssert(false, "event not found"); + // no-op, because the parent node will do the job + break; + case FunctionType::Location::External: + case FunctionType::Location::Creation: + case FunctionType::Location::DelegateCall: + case FunctionType::Location::CallCode: + case FunctionType::Location::Send: + case FunctionType::Location::Bare: + case FunctionType::Location::BareCallCode: + case FunctionType::Location::BareDelegateCall: + _memberAccess.expression().accept(*this); + m_context << funType->externalIdentifier(); + break; + case FunctionType::Location::Log0: + case FunctionType::Location::Log1: + case FunctionType::Location::Log2: + case FunctionType::Location::Log3: + case FunctionType::Location::Log4: + case FunctionType::Location::ECRecover: + case FunctionType::Location::SHA256: + case FunctionType::Location::RIPEMD160: + default: + solAssert(false, "unsupported member function"); } } else if (dynamic_cast(_memberAccess.annotation().type.get())) -- cgit v1.2.3