From 1af8ff01215f4d6ab5d5b3b1c4e2d1785a69c9c9 Mon Sep 17 00:00:00 2001 From: LianaHus Date: Fri, 21 Aug 2015 17:57:57 +0200 Subject: [PATCH] add tests for state variables accessors. normal and constant fixed the issue with accessors for constant state variables --- libsolidity/AST.cpp | 7 +++++-- libsolidity/AST.h | 2 +- libsolidity/Compiler.cpp | 5 ++++- libsolidity/ExpressionCompiler.cpp | 11 +++++++++++ libsolidity/ExpressionCompiler.h | 3 +++ test/libsolidity/SolidityEndToEndTest.cpp | 21 +++++++++++++++++++++ 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 8bad6ccf8..f7c84ccb8 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -554,8 +554,11 @@ void VariableDeclaration::checkTypeRequirements() { if (!dynamic_cast(getScope())) BOOST_THROW_EXCEPTION(createTypeError("Illegal use of \"constant\" specifier.")); - if ((m_type && !m_type->isValueType()) || !m_value) - BOOST_THROW_EXCEPTION(createTypeError("Unitialized \"constant\" variable.")); + if (!m_value) + BOOST_THROW_EXCEPTION(createTypeError("Uninitialized \"constant\" variable.")); + else if (!m_type->isValueType()) + // TODO: const is implemented only for uint, bytesXX and enums types. + BOOST_THROW_EXCEPTION(createTypeError("Illegal use of \"constant\" specifier. \"constant\" is not implemented for this type yet.")); } if (m_type) { diff --git a/libsolidity/AST.h b/libsolidity/AST.h index fb83d4e11..e2517c1d5 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -540,7 +540,7 @@ public: void setType(std::shared_ptr const& _type) { m_type = _type; } virtual bool isLValue() const override; - virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstant; } + virtual bool isPartOfExternalInterface() const override { return isPublic(); } void checkTypeRequirements(); bool isLocalVariable() const { return !!dynamic_cast(getScope()); } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index f0d1b38ea..d86e89904 100644 --- a/libsolidity/Compiler.cpp +++ b/libsolidity/Compiler.cpp @@ -390,7 +390,10 @@ bool Compiler::visit(VariableDeclaration const& _variableDeclaration) m_breakTags.clear(); m_continueTags.clear(); - ExpressionCompiler(m_context, m_optimize).appendStateVariableAccessor(_variableDeclaration); + if (_variableDeclaration.isConstant()) + ExpressionCompiler(m_context, m_optimize).appendConstStateVariableAccessor(_variableDeclaration); + else + ExpressionCompiler(m_context, m_optimize).appendStateVariableAccessor(_variableDeclaration); return false; } diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 0841089bc..acb056ed5 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -67,8 +67,19 @@ void ExpressionCompiler::appendStateVariableInitialization(VariableDeclaration c StorageItem(m_context, _varDecl).storeValue(*type, _varDecl.getLocation(), true); } +void ExpressionCompiler::appendConstStateVariableAccessor(VariableDeclaration const& _varDecl) +{ + solAssert(_varDecl.isConstant(), ""); + _varDecl.getValue()->accept(*this); + + // append return + m_context << eth::dupInstruction(_varDecl.getType()->getSizeOnStack() + 1); + m_context.appendJump(eth::AssemblyItem::JumpType::OutOfFunction); +} + void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const& _varDecl) { + solAssert(!_varDecl.isConstant(), ""); CompilerContext::LocationSetter locationSetter(m_context, _varDecl); FunctionType accessorType(_varDecl); diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index 642560c64..bd392c838 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -67,6 +67,9 @@ public: /// Appends code for a State Variable accessor function void appendStateVariableAccessor(VariableDeclaration const& _varDecl); + /// Appends code for a Constant State Variable accessor function + void appendConstStateVariableAccessor(const VariableDeclaration& _varDecl); + private: virtual bool visit(Assignment const& _assignment) override; virtual bool visit(UnaryOperation const& _unaryOperation) override; diff --git a/test/libsolidity/SolidityEndToEndTest.cpp b/test/libsolidity/SolidityEndToEndTest.cpp index ae2fc6dcf..d74fd1806 100644 --- a/test/libsolidity/SolidityEndToEndTest.cpp +++ b/test/libsolidity/SolidityEndToEndTest.cpp @@ -5161,6 +5161,27 @@ BOOST_AUTO_TEST_CASE(string_as_mapping_key) ) == encodeArgs(u256(7 + i))); } +BOOST_AUTO_TEST_CASE(accessor_for_state_variable) +{ + char const* sourceCode = R"( + contract Lotto{ + uint public ticketPrice = 500; + })"; + + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("ticketPrice()") == encodeArgs(u256(500))); +} + +BOOST_AUTO_TEST_CASE(accessor_for_const_state_variable) +{ + char const* sourceCode = R"( + contract Lotto{ + uint constant public ticketPrice = 555; + })"; + + compileAndRun(sourceCode); + BOOST_CHECK(callContractFunction("ticketPrice()") == encodeArgs(u256(555))); +} BOOST_AUTO_TEST_SUITE_END() }