aboutsummaryrefslogtreecommitdiffstats
path: root/AST.cpp
diff options
context:
space:
mode:
authorchriseth <c@ethdev.com>2015-03-06 20:44:37 +0800
committerchriseth <c@ethdev.com>2015-03-06 20:47:32 +0800
commit28e88903dc7e503e6bf5981f08a56136b860927b (patch)
treea91cff3d7be7dcc08a78ce4d74204d31314cfa87 /AST.cpp
parent75b115195221a896fc19417111de3f185a274cb3 (diff)
downloaddexon-solidity-28e88903dc7e503e6bf5981f08a56136b860927b.tar.gz
dexon-solidity-28e88903dc7e503e6bf5981f08a56136b860927b.tar.zst
dexon-solidity-28e88903dc7e503e6bf5981f08a56136b860927b.zip
Fix type checks for storage variable initializer.
Diffstat (limited to 'AST.cpp')
-rw-r--r--AST.cpp51
1 files changed, 25 insertions, 26 deletions
diff --git a/AST.cpp b/AST.cpp
index 3a0aed11..79b755e9 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -328,8 +328,30 @@ bool VariableDeclaration::isLValue() const
void VariableDeclaration::checkTypeRequirements()
{
- if (m_value)
+ // Variables can be declared without type (with "var"), in which case the first assignment
+ // sets the type.
+ // Note that assignments before the first declaration are legal because of the special scoping
+ // rules inherited from JavaScript.
+ if (!m_value)
+ return;
+ if (m_type)
+ m_value->expectType(*m_type);
+ else
+ {
+ // no type declared and no previous assignment, infer the type
m_value->checkTypeRequirements();
+ TypePointer type = m_value->getType();
+ if (type->getCategory() == Type::Category::IntegerConstant)
+ {
+ auto intType = dynamic_pointer_cast<IntegerConstantType const>(type)->getIntegerType();
+ if (!intType)
+ BOOST_THROW_EXCEPTION(m_value->createTypeError("Invalid integer constant " + type->toString() + "."));
+ type = intType;
+ }
+ else if (type->getCategory() == Type::Category::Void)
+ BOOST_THROW_EXCEPTION(createTypeError("Variable cannot have void type."));
+ m_type = type;
+ }
}
bool VariableDeclaration::isExternalFunctionParameter() const
@@ -445,32 +467,9 @@ void Return::checkTypeRequirements()
void VariableDeclarationStatement::checkTypeRequirements()
{
- // Variables can be declared without type (with "var"), in which case the first assignment
- // sets the type.
- // Note that assignments before the first declaration are legal because of the special scoping
- // rules inherited from JavaScript.
- if (m_variable->getValue())
- {
- if (m_variable->getType())
- m_variable->getValue()->expectType(*m_variable->getType());
- else
- {
- // no type declared and no previous assignment, infer the type
- m_variable->getValue()->checkTypeRequirements();
- TypePointer type = m_variable->getValue()->getType();
- if (type->getCategory() == Type::Category::IntegerConstant)
- {
- auto intType = dynamic_pointer_cast<IntegerConstantType const>(type)->getIntegerType();
- if (!intType)
- BOOST_THROW_EXCEPTION(m_variable->getValue()->createTypeError("Invalid integer constant " + type->toString()));
- type = intType;
- }
- else if (type->getCategory() == Type::Category::Void)
- BOOST_THROW_EXCEPTION(m_variable->createTypeError("var cannot be void type"));
- m_variable->setType(type);
- }
- }
+ m_variable->checkTypeRequirements();
}
+
void Assignment::checkTypeRequirements()
{
m_leftHandSide->checkTypeRequirements();