aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiana Husikyan <liana@ethdev.com>2015-03-14 01:16:04 +0800
committerLiana Husikyan <liana@ethdev.com>2015-03-16 17:46:46 +0800
commitebb4d5e298cbe9d8d6bb6b1fa1d8f6f769d62fba (patch)
tree81ba1220fa9c3b57c792cb87806278ff3af51815
parent7d6357ae531f604387fc1f91799fca9a9102e856 (diff)
downloaddexon-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.cpp7
-rw-r--r--AST.h1
-rw-r--r--Parser.cpp6
3 files changed, 12 insertions, 2 deletions
diff --git a/AST.cpp b/AST.cpp
index 605f5352..d05eaf83 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -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)
diff --git a/AST.h b/AST.h
index 6a269e15..bedba396 100644
--- a/AST.h
+++ b/AST.h
@@ -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;
diff --git a/Parser.cpp b/Parser.cpp
index 9efa3006..9e299215 100644
--- a/Parser.cpp
+++ b/Parser.cpp
@@ -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;