diff options
-rw-r--r-- | libsolidity/AST.cpp | 7 | ||||
-rw-r--r-- | libsolidity/AST.h | 2 | ||||
-rw-r--r-- | libsolidity/Compiler.cpp | 5 | ||||
-rw-r--r-- | libsolidity/ExpressionCompiler.cpp | 11 | ||||
-rw-r--r-- | libsolidity/ExpressionCompiler.h | 3 | ||||
-rw-r--r-- | test/libsolidity/SolidityEndToEndTest.cpp | 21 |
6 files changed, 45 insertions, 4 deletions
diff --git a/libsolidity/AST.cpp b/libsolidity/AST.cpp index 8bad6ccf..f7c84ccb 100644 --- a/libsolidity/AST.cpp +++ b/libsolidity/AST.cpp @@ -554,8 +554,11 @@ void VariableDeclaration::checkTypeRequirements() { if (!dynamic_cast<ContractDefinition const*>(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 fb83d4e1..e2517c1d 100644 --- a/libsolidity/AST.h +++ b/libsolidity/AST.h @@ -540,7 +540,7 @@ public: void setType(std::shared_ptr<Type const> 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<FunctionDefinition const*>(getScope()); } diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp index f0d1b38e..d86e8990 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 0841089b..acb056ed 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 642560c6..bd392c83 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 ae2fc6dc..d74fd180 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() } |