diff options
author | chriseth <c@ethdev.com> | 2015-03-06 20:44:37 +0800 |
---|---|---|
committer | chriseth <c@ethdev.com> | 2015-03-06 20:47:32 +0800 |
commit | 28e88903dc7e503e6bf5981f08a56136b860927b (patch) | |
tree | a91cff3d7be7dcc08a78ce4d74204d31314cfa87 /AST.cpp | |
parent | 75b115195221a896fc19417111de3f185a274cb3 (diff) | |
download | dexon-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.cpp | 51 |
1 files changed, 25 insertions, 26 deletions
@@ -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(); |