diff options
author | Liana Husikyan <liana@ethdev.com> | 2015-03-14 01:16:04 +0800 |
---|---|---|
committer | Liana Husikyan <liana@ethdev.com> | 2015-03-16 17:46:46 +0800 |
commit | ebb4d5e298cbe9d8d6bb6b1fa1d8f6f769d62fba (patch) | |
tree | 81ba1220fa9c3b57c792cb87806278ff3af51815 | |
parent | 7d6357ae531f604387fc1f91799fca9a9102e856 (diff) | |
download | dexon-solidity-ebb4d5e298cbe9d8d6bb6b1fa1d8f6f769d62fba.tar.gz dexon-solidity-ebb4d5e298cbe9d8d6bb6b1fa1d8f6f769d62fba.tar.zst dexon-solidity-ebb4d5e298cbe9d8d6bb6b1fa1d8f6f769d62fba.zip |
- added more tests to check constant specifier implementation
- deny use of const for local variables
- deny unitialized const variables
- only int, fixed strings, and enums can be declaired as const
-rw-r--r-- | AST.cpp | 7 | ||||
-rw-r--r-- | AST.h | 1 | ||||
-rw-r--r-- | Parser.cpp | 6 |
3 files changed, 12 insertions, 2 deletions
@@ -332,6 +332,13 @@ void VariableDeclaration::checkTypeRequirements() // sets the type. // Note that assignments before the first declaration are legal because of the special scoping // rules inherited from JavaScript. + if (m_isConstant) + { + 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) return; if (m_type) @@ -472,7 +472,6 @@ public: virtual bool isLValue() const override; virtual bool isPartOfExternalInterface() const override { return isPublic() && !m_isConstant; } - void checkTypeRequirements(); bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); } bool isExternalFunctionParameter() const; @@ -330,8 +330,11 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration( } if (token == Token::Const) { - m_scanner->next(); + solAssert(_options.isStateVariable, ""); + if (m_scanner->peekNextToken() != Token::Identifier && !Token::isElementaryTypeName(m_scanner->peekNextToken())) + BOOST_THROW_EXCEPTION(createParserError("Invalid use of \"constant\" specifier")); isDeclaredConst = true; + m_scanner->next(); } nodeFactory.markEndPosition(); @@ -920,6 +923,7 @@ Parser::LookAheadInfo Parser::peekStatementType() const // In all other cases, we have an expression statement. Token::Value token(m_scanner->getCurrentToken()); bool mightBeTypeName = (Token::isElementaryTypeName(token) || token == Token::Identifier); + if (token == Token::Mapping || token == Token::Var || (mightBeTypeName && m_scanner->peekNextToken() == Token::Identifier)) return LookAheadInfo::VariableDeclarationStatement; |